Compare commits

..

2608 Commits

Author SHA1 Message Date
Frappe PR Bot
1c3361cc00 chore(release): Bumped to Version 1.30.1 2026-09-03 09:19:35 +00:00
Sydney Gomes
14a828a9e8 Merge pull request #3752 from frappe/main-hotfix
chore(release): hotfix to main
2026-09-03 14:47:48 +05:30
Sydney Gomes
893a3f178c Merge pull request #3749 from frappe/mergify/bp/main-hotfix/pr-3741
fix(settings): blank empty states, always-visible Update Account, false typing indicator (backport #3741)
2026-09-03 14:22:21 +05:30
Sydney Gomes
bdc1b298f3 Merge pull request #3751 from frappe/mergify/bp/main-hotfix/pr-3739
fix: download attachments the browser cannot preview (backport #3739)
2026-09-03 14:20:26 +05:30
Sydney Gomes
33dc8297cd Merge pull request #3750 from frappe/mergify/bp/main-hotfix/pr-3742
fix: avoid  improper reply box closing for Grammarly suggestions (backport #3742)
2026-09-03 14:19:57 +05:30
Sydney Gomes
c89542d33b Merge pull request #3748 from frappe/mergify/bp/main-hotfix/pr-3743
fix(build): dedupe vue-router and dompurify for the linked @framework/ui (backport #3743)
2026-09-03 14:19:06 +05:30
Sydney Gomes
189e52adcc Merge pull request #3747 from frappe/mergify/bp/main-hotfix/pr-3746
fix: write portal defaults without saving the whole document (backport #3746)
2026-09-03 14:18:40 +05:30
Sydney
310a3ad8af fix: merge conflicts 2026-09-03 14:11:42 +05:30
Sydney
6c33937599 fix: download mov attachments instead of previewing
(cherry picked from commit 56947b47b8)
2026-09-03 08:06:05 +00:00
Sydney
77496fbd29 fix: keep mov, m4v, ico and apng previewable
(cherry picked from commit 8fe4b398cd)
2026-09-03 08:06:05 +00:00
Sydney
5e6dfd3ea9 fix: download attachments the browser cannot preview
(cherry picked from commit 5a3bff0630)
2026-09-03 08:06:05 +00:00
Sydney
ad5174391f fix: keep reply box open when using a Grammarly suggestion
Grammarly renders its suggestion card outside the reply box, so accepting one counted as a click outside and closed the box.

(cherry picked from commit beacb925f4)
2026-09-03 08:05:59 +00:00
Sydney
35f17ae126 fix(email): don't broadcast typing when the signature loads
The watcher on newEmail called onUserType() for any change, including
programmatic ones. An agent with a signature configured has it dropped
into the empty editor on load, which emitted helpdesk_ticket_typing - so
merely opening a ticket showed "is typing" to everyone else viewing it.

Skip content that is empty or only the signature. This also covers agents
with no signature, whose editor is filled with an empty paragraph.

(cherry picked from commit e2e5a3c198)
2026-09-03 08:05:51 +00:00
Sydney
6d812c00e9 fix(settings): show Update Account only when the account changed
The button was always visible, so clicking it with no edits only produced
a "No changes made" toast.

isDirty could not be reused as it stood: the form normalises what the
server sends (a 0 becomes false, a null becomes ""), then compared those
values back against the raw account, so every custom account reported
itself as changed. Compare against values built by the same initialisers
instead, and iterate the fields rather than listing them - the old chain
omitted use_tls, use_ssl_for_outgoing and four others, so editing only
those said "No changes made" and dropped the edit.

(cherry picked from commit a989a6bafc)

# Conflicts:
#	desk/src/components/Settings/EmailEdit.vue
2026-09-03 08:05:51 +00:00
Sydney
a4aa989f10 fix(settings): import EmptyState so empty screens render
Four settings screens use <EmptyState> in their template but never import
it. There is no component auto-import plugin, so Vue cannot resolve the tag
and renders nothing, leaving a blank pane where the empty state should be.

Email Accounts also showed its empty state while the list was still
loading; guard it on loading like the other three screens do.

(cherry picked from commit b8d701a56b)

# Conflicts:
#	desk/src/components/Settings/EmailAccountList.vue
2026-09-03 08:05:50 +00:00
Sydney
2312acb710 fix(build): dedupe vue-router and dompurify for the linked @framework/ui
They are peers of @framework/ui that nothing installs next to its
source, so a build where the frameworkUI plugin's dedupe is missing
cannot resolve them.

(cherry picked from commit 02d708f961)
2026-09-03 08:05:36 +00:00
Sydney
c5910c6863 fix: write portal defaults without saving the whole document
Saving Portal Settings validates every link on it, so a menu row left
behind by a deleted doctype failed the write and stopped migrate. Write
the two Single values directly, from one function install and the patch
now share.

(cherry picked from commit f2ac96a4c8)
2026-09-03 07:56:04 +00:00
Sydney Gomes
4390a4ae90 Merge pull request #3738 from frappe/pot_main-hotfix_2026-08-30
chore: update POT file
2026-08-31 12:51:36 +05:30
frappe-pr-bot
5232753554 chore: update POT file 2026-08-30 14:54:56 +00:00
Frappe PR Bot
488e5ce1f9 chore(release): Bumped to Version 1.30.0 2026-08-29 04:02:17 +00:00
RitvikSardana
d920e9710c Merge pull request #3736 from frappe/main-hotfix
chore(release): hotfix to main
2026-08-29 09:31:52 +05:30
Ritvik Sardana
21420635f0 fix: pass name argument to clear_doctype_map for frappe v15 compatibility 2026-08-29 09:12:04 +05:30
RitvikSardana
665758cb99 Merge pull request #3719 from frappe/pot_main-hotfix_2026-08-27
chore: update POT file
2026-08-29 02:41:55 +05:30
RitvikSardana
5586c81336 Merge pull request #3723 from frappe/mergify/bp/main-hotfix/pr-3711
fix: consider holidays for outside working hours banner (backport #3711)
2026-08-29 02:41:50 +05:30
Ritvik Sardana
1d0b252497 Merge remote-tracking branch 'upstream/main-hotfix' into bp-3711-update
# Conflicts:
#	helpdesk/helpdesk/doctype/hd_ticket/hd_ticket.py
2026-08-29 02:36:37 +05:30
RitvikSardana
3e6e46aa9c Merge pull request #3735 from frappe/mergify/bp/main-hotfix/pr-3696
fix: hide bulk reply, assign and edit from customer roles (backport #3696)
2026-08-29 02:33:36 +05:30
Ritvik Sardana
62954d117a fix: hide bulk reply, assign and edit from customer roles
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
(cherry picked from commit c3ae467da1)
2026-08-28 21:01:40 +00:00
RitvikSardana
f9cfce0c45 Merge pull request #3734 from frappe/mergify/bp/main-hotfix/pr-3693
feat: actions in saved replies (backport #3693)
2026-08-29 02:30:53 +05:30
RitvikSardana
41d1e9dc2d fix: use FrappeTestCase 2026-08-29 02:24:45 +05:30
RitvikSardana
acb8787f03 chore: resolve conflicts 2026-08-29 02:16:33 +05:30
Ritvik Sardana
2bfa9b771f fix: add telemetry event for saved reply actions
(cherry picked from commit ea1a302fb1)
2026-08-28 20:45:31 +00:00
Ritvik Sardana
8b63c63779 fix(ux): adding actions
(cherry picked from commit b32a2f0eac)
2026-08-28 20:45:31 +00:00
Ritvik Sardana
8dd4d6db06 fix: unified collapsed state for saved reply actions
(cherry picked from commit 729607fb68)
2026-08-28 20:45:30 +00:00
Ritvik Sardana
bca2cd83b7 fix: reject non string action values on save
(cherry picked from commit 7e06f188c4)
2026-08-28 20:45:30 +00:00
Ritvik Sardana
0dbe99a4fb fix: paginate saved reply selector
(cherry picked from commit f574a2caf6)
2026-08-28 20:45:29 +00:00
Ritvik Sardana
912fc09d4d fix: skip shadowed saved reply actions and silence ssti lint
(cherry picked from commit dccc7acc73)
2026-08-28 20:45:28 +00:00
Ritvik Sardana
e1c76c0882 fix: clear stale assignment rule cache after saved reply action tests
(cherry picked from commit 908c408847)
2026-08-28 20:45:28 +00:00
Ritvik Sardana
840f6831ed refactor: sla style table for saved reply actions
(cherry picked from commit c19afe3496)
2026-08-28 20:45:27 +00:00
Ritvik Sardana
3d43e39ec7 feat: editable comments from actions
(cherry picked from commit a8addfb8b7)
2026-08-28 20:45:26 +00:00
Ritvik Sardana
3bb83bb17a chore: truncate comment text
(cherry picked from commit 8dc39e144b)
2026-08-28 20:45:26 +00:00
Ritvik Sardana
2db7ef6f8c fix: ux for saved reply action failures
(cherry picked from commit 17e9393e96)
2026-08-28 20:45:25 +00:00
Ritvik Sardana
99280bbaf9 fix(styles): settings modal
(cherry picked from commit ede91aee21)

# Conflicts:
#	desk/src/components/layouts/SettingsLayoutBase.vue
2026-08-28 20:45:25 +00:00
Ritvik Sardana
fa112b1413 fix: keep staged saved reply actions when apply rolls back
(cherry picked from commit 1365b139ba)
2026-08-28 20:45:23 +00:00
Ritvik Sardana
c6afce1a89 fix: drop staged saved reply actions on failed apply, scope per agent
(cherry picked from commit 972ad7012d)
2026-08-28 20:45:23 +00:00
Ritvik Sardana
343a6329ee refactor: move replyComposer into modalStates
(cherry picked from commit 491573946f)
2026-08-28 20:45:22 +00:00
Ritvik Sardana
5bc67ed55e fix: update saved reply icon
(cherry picked from commit 3f05c90c14)
2026-08-28 20:45:21 +00:00
Ritvik Sardana
da95dcb3a2 fix(styles): saved reply selector filter
(cherry picked from commit 2d17b29909)
2026-08-28 20:45:21 +00:00
Ritvik Sardana
646f539a1a fix: select field saving on every keystroke
(cherry picked from commit 8e1c071f14)
2026-08-28 20:45:20 +00:00
Ritvik Sardana
a7342249ce feat: open the action picker from the whole chip
(cherry picked from commit 169820f8e7)
2026-08-28 20:45:20 +00:00
Ritvik Sardana
0528b77474 refactor: saved reply modal fetching
(cherry picked from commit 199a43302e)
2026-08-28 20:45:20 +00:00
Ritvik Sardana
f4b888a265 chore: code cleanup
(cherry picked from commit fd5704d128)
2026-08-28 20:45:19 +00:00
Ritvik Sardana
9cd95a1d58 refactor: cut saved reply action network calls
Build the action options once instead of per component: frappe-ui reloads a
cached list resource on every createListResource call, so each action chip
fired its own tags, ticket type and team requests.

Team and ticket type are now searched like link fields (debounced name query)
rather than fetched whole.

(cherry picked from commit 2c8a7c0e7d)
2026-08-28 20:45:19 +00:00
Ritvik Sardana
dba62142db fix: replacing a saved reply closes the reply editor
(cherry picked from commit e4589968d5)
2026-08-28 20:45:19 +00:00
Ritvik Sardana
bd0aadd999 fix: make saved reply actions field read only in desk
(cherry picked from commit 72a3d5623b)
2026-08-28 20:45:17 +00:00
Ritvik Sardana
de3052b6e3 fix: actions clearing bug
(cherry picked from commit 10145f63c0)
2026-08-28 20:45:17 +00:00
Ritvik Sardana
171b008a41 feat: edit actions from email editor
(cherry picked from commit 3f66824512)
2026-08-28 20:45:16 +00:00
Ritvik Sardana
1d8a2b79cd feat: add actions in email editor
Saved reply actions are staged in the composer and applied once the reply
is sent. Chips are individually removable, the staged comment is editable,
and applying another reply replaces the staged set.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
(cherry picked from commit 7ddc78a7d0)
2026-08-28 20:45:16 +00:00
Ritvik Sardana
87d89552b6 fix: add grouping in actions
(cherry picked from commit 3e87c14cb7)
2026-08-28 20:45:15 +00:00
Ritvik Sardana
108e9af294 feat(saved-replies): add actions table in Saved Reply
Saved replies can now carry actions (macros) that update the ticket when
the reply is sent: set status, priority, team or ticket type, assign an
agent or yourself, add/remove tags, and add a comment.

Backend
- HD Saved Reply gets an `actions` JSON field, with validation for the
  action type, its value, duplicates, and the one-assignment-per-reply
  and no-tag-in-both-lists rules
- `get_rendered_saved_reply` returns title, rendered message and the
  reply's still-valid actions
- `apply_saved_reply_actions` applies them to a ticket, skipping (not
  raising on) actions that went stale, since the email is already sent
- tests covering validation, permissions and application

Frontend
- Actions table in the saved reply settings form: one row per action,
  action type and its value edited in cells
- Rendered with the shared Grid component from @framework/ui

Note: the Grid props used here (emptyText, addLabel, selectable,
reorderable, rowAction) ship in a companion frappe PR.

(cherry picked from commit e37d817b19)
2026-08-28 20:45:15 +00:00
RitvikSardana
cb7285f589 Merge pull request #3733 from frappe/mergify/bp/main-hotfix/pr-3692
fix(hd-ticket): don't check update perms without a previous version (backport #3692)
2026-08-29 02:14:21 +05:30
Ritvik Sardana
7c496de9de fix(hd-ticket): don't check update perms without a previous version
check_update_perms() ran off self.is_new() as a proxy for "there is a
previous version to compare against". __islocal can be cleared during
insert() (any before_insert hook that persists the doc calls db_insert,
which sets it to False), so is_new() was False on create while
_doc_before_save was still None, and old_doc.status raised AttributeError.

Guard on the previous doc itself, which is what the check actually needs.

(cherry picked from commit 1642385558)
2026-08-28 20:33:42 +00:00
RitvikSardana
52a8d66b34 Merge pull request #3732 from frappe/mergify/bp/main-hotfix/pr-3690
fix: use the passed-in user for team permission checks (backport #3690)
2026-08-29 01:29:18 +05:30
Ritvik Sardana
a884388ebb fix: use the passed-in user for team permission checks
(cherry picked from commit 9a8adfa445)
2026-08-28 19:49:49 +00:00
RitvikSardana
3268a8e3e0 Merge pull request #3731 from frappe/mergify/bp/main-hotfix/pr-3689
feat: ticket analytics tab (backport #3689)
2026-08-29 01:10:15 +05:30
RitvikSardana
9ee72f3ae1 chore: resolve conflicts 2026-08-29 00:47:44 +05:30
Ritvik Sardana
88d395a883 fix: always label a late first response as Responded late
(cherry picked from commit 67df48e170)
2026-08-28 19:15:21 +00:00
Ritvik Sardana
622a0c8bb4 fix: place the resolution in the timeline instead of always last
(cherry picked from commit 2f8fbf8a3e)
2026-08-28 19:15:21 +00:00
Ritvik Sardana
b03b3b9196 fix: keep resolution date and redden the overdue leg
(cherry picked from commit 99ae84ade7)
2026-08-28 19:15:21 +00:00
Ritvik Sardana
1482a0e7eb refactor: variable names in TicketTimeline
(cherry picked from commit 3f17dded78)
2026-08-28 19:15:20 +00:00
Ritvik Sardana
cf7434b2b9 fix: shorten Average to Avg. in home page widgets
Widget titles read Average while the values inside them already read
Avg., so the same metric was labelled two ways on one screen.

(cherry picked from commit 422c39f6a1)
2026-08-28 19:15:20 +00:00
Ritvik Sardana
41512b8797 refactor: build agents_involved with get_user_info_for_avatar
The desk was resolving each agent through its user store. Use the standard
avatar helper so the payload carries name and image, matching how the rest
of the ticket APIs return users.

(cherry picked from commit c45594a3b5)
2026-08-28 19:15:20 +00:00
Ritvik Sardana
b7c8a22491 refactor: ticket_analytics api
- exclude SLA-paused time from the agent response gap so the metric card
  and the milestone badge measure the same interval
- drop the payload left over from the deleted SLA timeline and gap chart
  (exchanges node, leg_label, progress, first_response_target)
- include assignees in agents_involved, resolving sender emails to user ids
  so one person cannot appear twice
- return user ids only, the desk resolves names and avatars from its store
- move the resource into useTicket with a per-ticket cache, fetched by the
  tab rather than on every ticket open
- show an error state with retry instead of a permanently blank pane

(cherry picked from commit 33635792e8)
2026-08-28 19:15:20 +00:00
Ritvik Sardana
4793ae2f80 fix: isolate churn test from HD Team assignment rules
An HD Team insert leaks its auto-created assignment rule across test
transactions, breaking unrelated suites with 'Assignment Rule not
found'. The team change is now recorded directly as the Version diff
churn() reads. Also moves add_message and timeline_node helpers to
test_utils per repo convention.

(cherry picked from commit 016c5eb159)
2026-08-28 19:15:19 +00:00
Ritvik Sardana
44f73fbfae feat: reload analytics on status or priority change
(cherry picked from commit b2cbc94357)
2026-08-28 19:15:18 +00:00
Ritvik Sardana
cf6681c015 feat: show year on timeline date labels when it changes
Also removes the planning document from the repo.

(cherry picked from commit 30f6b829a0)
2026-08-28 19:15:18 +00:00
Ritvik Sardana
0c5e44f4c2 feat: unified ticket timeline
Replaces the SLA stepper and response gap chart with a single event rail:
split breach legs with a deadline tick, overdue stretch ending at a Today
marker, reworked metric cards (agent/customer gaps, hold time) and a
trimmed conversation summary.

(cherry picked from commit 8dcc83b732)
2026-08-28 19:15:18 +00:00
Ritvik Sardana
b07db40ef2 feat: response gap chart
Line chart of agent response gaps over the ticket, business-hours
durations on round tick steps. Espresso oklch tokens crash echarts'
hover restyle, so the series disables the emphasis state.

(cherry picked from commit 999fca4bda)
2026-08-28 19:15:17 +00:00
Ritvik Sardana
4a4069dd26 feat: SLA timeline stepper
Figma-styled stepper for the analytics tab: donut milestones for
created, first response, hold, exchanges and resolution; dashed blue
SLA-paused leg with duration; progress gradients for pending and
breached legs; hover badges with SLA verdicts.

(cherry picked from commit 3c0615ea4a)
2026-08-28 19:15:17 +00:00
Ritvik Sardana
3c2bb65522 feat: analytics tab with metrics and conversation summary
New Analytics tab on the agent ticket view: metric cards (avg agent
response gap, time to resolution, longest agent silence) and a
conversation summary with churn flags. Restores the hash tab on soft
navigation via an immediate watcher in useActiveTabManager.

(cherry picked from commit 38a2289995)

# Conflicts:
#	desk/src/types.ts
2026-08-28 19:15:17 +00:00
Ritvik Sardana
468074eb28 feat: per-ticket analytics API
get_ticket_analytics returns SLA timeline nodes, response-gap series,
metrics and conversation summary for the agent-facing Analytics tab.
Business-hours math via the ticket SLA calendar, wall-clock fallback
without one; churn from Version diffs and ToDo assignees.

(cherry picked from commit 394a77e611)
2026-08-28 19:15:15 +00:00
RitvikSardana
cb1101fde6 Merge pull request #3728 from frappe/mergify/bp/main-hotfix/pr-3680
feat(tickets): bulk edit and bulk assign from the selection banner (backport #3680)
2026-08-29 00:44:05 +05:30
RitvikSardana
d5fcf8c4ac chore: resolve conflicts 2026-08-29 00:28:31 +05:30
Ritvik Sardana
e816104aa5 fix(bulk-edit): match progress by task id, make status mandatory
(cherry picked from commit bf5a1bd83d)
2026-08-28 09:32:09 +00:00
Ritvik Sardana
c7ee53df9b refactor(tickets): surface Assign in the selection banner
Reply and Assign are the actions agents reach for on a selection, so they get
the banner buttons; Export, Edit and Delete move into the overflow menu.

Drops the icon scale classes: correcting one axis leaves the other wrong, and
correcting both distorts the glyph. Nothing CSS can do here.

(cherry picked from commit 852e58e62d)
2026-08-28 09:32:08 +00:00
Ritvik Sardana
952ea6c137 feat(tickets): bulk edit and bulk assign from the selection banner
Adds two actions to the ticket list selection banner alongside the existing
bulk reply:

- Bulk Edit: sets a field on every selected ticket via the framework's
  `submit_cancel_or_update_docs`.
- Bulk Assign: assigns agents to every selected ticket via `add_multiple`.

Bulk Assign reuses the ticket view's own agent picker. `AssignTo` now treats a
missing ticket injection as standalone mode: it reports its selection through
v-model and leaves saving to the parent, so both call sites share one picker
instead of a second, worse one.

The banner shows Reply and Edit as buttons and keeps the rest in the overflow
menu; actions opt in with `inline`. Labels drop the redundant "Bulk" prefix
since the banner already states the selection count.

Also hardens the SLA cells to check `first_responded_on` / `resolution_date`
before the target date, matching `useSLA`, so a cleared target no longer
renders as a countdown.

(cherry picked from commit f3c25b4524)

# Conflicts:
#	desk/src/components/ticket-agent/BulkReplyModal.vue
#	desk/src/pages/ticket/Tickets.vue
2026-08-28 09:32:07 +00:00
Ritvik Sardana
365b3f6828 fix(list-view): fetch SLA fields for custom ticket views
Saved views send only their own column keys as `rows`, so `first_responded_on`
and `resolution_date` never reached the client. The First Response / Resolution
cells then fell through to the live-countdown branch, showing a ticking deadline
for tickets that had already been responded to or resolved.

Append the whole set of fields the SLA cells read, the way `sla` alone was
already being appended.

(cherry picked from commit 5e097c4cb5)
2026-08-28 09:32:05 +00:00
RitvikSardana
65600b80ea Merge pull request #3727 from frappe/mergify/bp/main-hotfix/pr-3679
fix: use framework ui plugin (backport #3679)
2026-08-28 15:01:07 +05:30
RitvikSardana
a2b1fbad7d chore: update package.json
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
(cherry picked from commit 587d6547bd)
2026-08-28 08:23:18 +00:00
Ritvik Sardana
62bcec77ac fix: remove framework ui installation script from dev command
(cherry picked from commit ae78b48f1b)
2026-08-28 08:23:18 +00:00
Ritvik Sardana
f9640c267c fix: remove framework ui installation script
(cherry picked from commit a91e862358)
2026-08-28 08:23:18 +00:00
Ritvik Sardana
42c6bdd4c8 fix: use framework ui plugin
(cherry picked from commit 648f1f0c4d)
2026-08-28 08:23:17 +00:00
RitvikSardana
896ba8025d Merge pull request #3726 from frappe/mergify/bp/main-hotfix/pr-3639
refactor: allow tickets to not have any SLA (backport #3639)
2026-08-28 13:52:02 +05:30
Ritvik Sardana
5ab117b5c0 fix(tests): delete the status created for the SLA-only ticket test
Rollback runs per test class, so this status stayed behind and made
test_validate_one_min_status_category see a second Open category status,
which stopped the last-status-in-category guard from raising.
2026-08-28 13:12:51 +05:30
RitvikSardana
f4cc4f4212 chore: replace IntegrationTestCase with FrappeTestCase 2026-08-28 12:46:08 +05:30
RitvikSardana
113f47c83b chore: resolve conflicts 2026-08-28 12:38:57 +05:30
Ritvik Sardana
b89aaf4ff1 refactor: rename the shipped sla to "Standard"
(cherry picked from commit e80ee038a8)
2026-08-28 07:04:34 +00:00
Ritvik Sardana
47275ae03b fix: keep sla fulfilled ratio within bounds, index ticket sla
(cherry picked from commit c38af44f77)
2026-08-28 07:04:33 +00:00
Ritvik Sardana
2a8bcf7022 fix: clear fields when no sla is matched
(cherry picked from commit 321c3d55ee)
2026-08-28 07:04:33 +00:00
Ritvik Sardana
81e2d2e30a fix: sla analytics should only include tickets with sla
(cherry picked from commit d9a7a6975c)
2026-08-28 07:04:33 +00:00
Ritvik Sardana
85d1093f53 fix: list views and customer ticket view according to NO SLA
(cherry picked from commit ed0942d768)

# Conflicts:
#	desk/src/components/ticket/TicketAgentDetails.vue
2026-08-28 07:04:32 +00:00
Ritvik Sardana
c51668bb8d fix: keep pause anchor when a paused ticket detaches
(cherry picked from commit c06bf4cf65)
2026-08-28 07:04:31 +00:00
Ritvik Sardana
51d9b8c6c4 fix: remove on_hold_since if SLA is detached
(cherry picked from commit 27e738bcc7)
2026-08-28 07:04:30 +00:00
Ritvik Sardana
1295fe34c7 fix: clear resolution_time if SLA is not attached
(cherry picked from commit 9e33bdc029)
2026-08-28 07:04:29 +00:00
Ritvik Sardana
285f4dae5c refactor: allow tickets to not have any SLA
Removes three limitations that forced an SLA onto every ticket:

- every priority had to be present in every SLA
- exactly one SLA had to be marked default, and it could not be
  disabled or deleted
- every ticket had to carry an SLA

A policy now applies only when its condition matches and it includes the
ticket's priority. The Default SLA is optional, and is considered last.
When no policy applies, the ticket detaches: sla, response_by,
resolution_by and agreement_status are cleared, while the clock start and
any recorded breach are kept so flapping a condition buys no time.

Adds a rank field so the winner between two matching policies is explicit
rather than creation order. Removing a priority or unticking the Default
SLA now warns about the tickets that will detach, instead of blocking.

resolution_date is stamped by the ticket rather than the SLA, since a
ticket knows when it was resolved with or without a policy.

(cherry picked from commit b75761f044)

# Conflicts:
#	helpdesk/api/agent_home/test_agent_home.py
#	helpdesk/helpdesk/doctype/hd_service_level_agreement/test_hd_service_level_agreement.py
2026-08-28 07:04:28 +00:00
Sydney Gomes
d358559946 Merge pull request #3724 from aerodeval/fix/email-popover-width-main-hotfix
fix(email-select): truncate long recipient names in the popover (backport #3677)
2026-08-27 20:37:37 +05:30
Sydney
debec03a3d fix(email-select): truncate long recipient names in the popover (backport #3677) 2026-08-27 20:26:08 +05:30
Sydney Gomes
03048dee33 Merge pull request #3721 from frappe/mergify/bp/main-hotfix/pr-3638
fix(email): give agent replies their own Message-Id so threads hold (backport #3638)
2026-08-27 20:10:45 +05:30
Sydney Gomes
e088b16de3 Merge pull request #3720 from frappe/mergify/bp/main-hotfix/pr-3635
refactor: agent availability through the document lifecycle (backport #3635)
2026-08-27 20:10:11 +05:30
Sydney
db1fb29d10 fix: consider holidays for outside working hours banner
(cherry picked from commit 54e4587eb4)

# Conflicts:
#	helpdesk/helpdesk/doctype/hd_ticket/hd_ticket.py
2026-08-27 14:37:23 +00:00
Sydney
a7449c4a2c refactor(email): name the send result, trim the comments around it
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0169cvSxbDNjSX57e12eGY9j
(cherry picked from commit 4d2afa9dbe)
2026-08-27 14:17:43 +00:00
Sydney
32f893f119 fix(email): save a reply's Message-Id only once the mail has gone out
reply_via_agent saved the id before sending, so a reply that failed to send
kept an id the customer never received. bulk_reply logs failures instead of
raising, so that reply survived and the next reply answered it, putting an
In-Reply-To on the wire that resolves to nothing in the customer's mailbox.

Generate the id up front and pass it to sendmail as before, but write it to
the communication only after sendmail returns, and only if it queued
something - it returns nothing when every recipient is filtered out, which
is not a send either. A reply that never went out now keeps no id, so it can
never be answered. The row stays on the ticket so the agent still sees the
attempt.

A savepoint around each ticket was tried first and dropped: with HD Settings
instantly_send_email on, sendmail commits inside SendMailContext before the
SMTP attempt, which destroys the savepoint and makes the rollback throw,
hiding the real error.

Also reorder bulk_reply so nothing is written before everything is checked.
Permissions and get_doc ran per ticket inside the loop, so one bad id raised
out of the request and rolled back the replies that had already worked, and
attachments were linked ahead of the dedupe and the permission check.

Reported by Greptile on #3638.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
(cherry picked from commit 974f01f3b6)
2026-08-27 14:17:41 +00:00
Sydney
97b0b71195 test(email): cover the email workflow, drop a duplicate test helper
Tickets raised by email are the common case and had no threading test.
Add one: the first agent reply answers the customer's mail, later replies
follow the reply before them. Add a second test for replies that are never
emailed, which must not store an id at all.

Drop the local get_ticket_communications helper. It duplicated
get_latest_ticket_communication and its docstring claimed the canonical
helper could not order results - that is wrong. frappe.get_all falls back
to the doctype sort meta, and Communication sorts by creation desc, so the
existing helper was always correct. Callers lose the trailing [-1].

Trim the comments in reply_via_agent and the test docstrings to plain
English. The PR archaeology they carried is in the commit messages already.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
(cherry picked from commit 201f3187ae)
2026-08-27 14:17:41 +00:00
Sydney
1915209898 refactor(email): carry the thread anchor on the Communication itself
get_last_threadable_communication returned a two-field dict of which only
the name was ever read, and the caller parked it in a local that stayed
live across ~75 lines and an early return, re-deriving its nullability in
both an if and a ternary.

Return just the name and assign it straight onto communication.in_reply_to
- the row frappe reads it back from anyway - then pass that field to
sendmail. The local, the branch and the ternary all go. Making the helper
private stops it reading as a variant of get_last_communication, which
differs from it in mechanism, return type and error handling.

No behaviour change.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
(cherry picked from commit c1a56258e0)
2026-08-27 14:17:40 +00:00
Sydney
57f38c9bc9 fix(email): only store a Message-Id when the reply is actually sent
reply_via_agent stamped every Communication with a fresh Message-Id before
the early return for skip_email_workflow / enable_reply_email_via_agent. A
reply that was never emailed then qualified as a thread anchor, so the next
reply pointed In-Reply-To at an id that had reached no mailbox - failing in
exactly the same silent way as storing no id at all.

Gate the assignment on the same condition as the send, and name it
should_send_email, which also drops a duplicate HD Settings read.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
(cherry picked from commit 6bd8b705be)
2026-08-27 14:17:39 +00:00
Sydney
a72dcaf91f fix(email): give agent replies their own Message-Id so threads hold
Every agent reply shipped without an In-Reply-To header, so each one landed
as a separate thread in the customer's mail client.

frappe#32651 made In-Reply-To resolve through Communication.message_id.
helpdesk#2308, merged 77 minutes later, removed the only code that wrote
that column - correctly, since it was copying the parent's Message-Id onto
every reply in the ticket. Together they left the column permanently empty,
so no reply could ever anchor the next one and the chain died after a single
hop off an inbound customer email.

Mint a fresh id per reply, store it on the Communication, and send that same
value, which is what communication.email._make already does for
desk-composed mail. Pick the parent from the newest communication that
actually has an id, so a portal reply - which sends no email and therefore
has none - doesn't break the chain for every reply after it.

Measured on an affected site before the fix: 1,752 of 1,911 agent replies in
one week carried no threading header at all.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
(cherry picked from commit 67cd1dc16d)
2026-08-27 14:17:39 +00:00
Sydney
8644fe18d9 test: reset session user between HD Agent tests
frappe restores the session user per class, not per test, so the four
tests that call frappe.set_user leaked into every later one — the whole
class ran as test_user@test.com after the first of them.

Nothing fails today because the helpers save with ignore_permissions,
but test_manager_can_set_another_agents_availability calls add_roles(),
a permission-checked User.save(), under whatever session the previous
test left behind.

setUp/tearDown now restore Administrator, matching test_contact,
test_onboarding, test_tags, test_ticket_stats and test_agent_home.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
(cherry picked from commit c037dcf502)
2026-08-27 14:17:25 +00:00
Sydney
a4669f629a refactor: single predicate for "availability changed"
The controller was asking "did availability change?" in three different idioms:
a hand-rolled old_doc comparison in before_save, has_value_changed in validate
and publish, and has_value_changed plus a get_doc_before_save null check in the
telemetry capture. Collapse them onto one named predicate.

publish_availability_update previously fired on insert while the telemetry
capture did not, justified as letting clients learn a new agent's presence
without a refetch. That justification does not hold: liveStatuses is only ever
read as an overlay on agents already loaded from the list resource
(AssignTo.vue liveAvailability), and nothing iterates it, so an entry for an
agent the client has not fetched renders nowhere. Dropping the asymmetry lets
both side effects share availability_changed() and removes the comment that
existed only to explain the difference.

validate_availability deliberately keeps the raw has_value_changed — a new
agent must still be rejected for a disabled status — and now says so.

Tests: hoist the private helpers to the top of the class rather than leaving
one mid-file between tests, and collapse three copies of the client.set_value
payload onto a single helper.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WuJruCwPQFwBA3HyXogjD7
(cherry picked from commit 88348f3231)
2026-08-27 14:17:24 +00:00
Sydney
3a63dc0e65 test: drop telemetry assertions for agent availability
The capture_event calls are fire-and-forget analytics; asserting on a mock
adds little over the guard being readable in the controller.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WuJruCwPQFwBA3HyXogjD7
(cherry picked from commit 8c4914c2eb)
2026-08-27 14:17:24 +00:00
Sydney
3d0bc92561 feat: capture telemetry on agent availability change
Adds an agent_availability_updated telemetry event, following the existing
capture_update_telemetry_events shape in HD Ticket. Because it lives on the
controller it covers every write path, not just the desk UI.

Guarded on get_doc_before_save() so inserts are excluded: has_value_changed
returns True when there is no previous doc, so without it every agent created
would be counted as a status change. The realtime broadcast deliberately keeps
firing on insert — clients learn a new agent's presence without a refetch.

Also drops the unused trailing `return` from sent_invites, per review.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WuJruCwPQFwBA3HyXogjD7
(cherry picked from commit c3c1afa1cd)
2026-08-27 14:17:23 +00:00
Sydney
00cb691b24 refactor: route agent availability through the document lifecycle
set_my_availability wrote with frappe.db.set_value, which skips the HD Agent
controller entirely. That put three invariants in one API function and left
every other write path to HD Agent.availability broken:

- availability_changed_on was stamped by hand in the API, duplicating
  HDAgent.before_save, which never ran
- the "status must be enabled" check lived in the API, so the desk form, REST
  and frappe.client.set_value could all write a disabled status silently
- the agent_availability_updated broadcast fired only from that API, so a
  status changed from the desk form never reached connected clients

Move all three onto the controller — validate() rejects a disabled or unknown
status (guarded on has_value_changed so an agent already on a since-disabled
status can still save unrelated fields), before_save keeps the timestamp, and
on_update publishes the broadcast. The endpoint then has nothing left to do,
so the store calls frappe.client.set_value directly, matching how Settings
already writes HD Agent.is_active.

Dropping the endpoint also drops its agent_only + get_agent_name() self-scoping,
and the Agent role has blanket write on HD Agent, so add a has_permission hook:
an agent may only modify their own record, reads stay open for presence dots
and assignment pickers, managers are unrestricted.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WuJruCwPQFwBA3HyXogjD7
(cherry picked from commit 36c04bdc1f)
2026-08-27 14:17:22 +00:00
frappe-pr-bot
41614bb243 chore: update POT file 2026-08-27 07:59:03 +00:00
Pratham Sharma
3864b9d0ca Merge pull request #3702 from frappe/mergify/bp/main-hotfix/pr-3701
chore: auto generate POT files for main-hotfix (backport #3701)
2026-08-17 18:22:05 +05:30
Pratham
5bf53a9198 chore: auto generate POT files for main-hotfix
(cherry picked from commit 9c709ac2f8)
2026-08-17 10:31:27 +00:00
Frappe PR Bot
480486287b chore(release): Bumped to Version 1.29.0 2026-08-05 06:15:03 +00:00
RitvikSardana
010ba52b24 Merge pull request #3660 from frappe/main-hotfix
chore(release): hotfix to main
2026-08-05 11:44:28 +05:30
RitvikSardana
e66f847c21 chore: bump minimum frappe version 2026-08-05 00:36:49 +05:30
RitvikSardana
79cc5554d6 Merge pull request #3670 from frappe/mergify/bp/main-hotfix/pr-3661
fix: install @framework/ui deps before dev and build (backport #3661)
2026-08-05 00:35:25 +05:30
RitvikSardana
ca2bc945ad Merge branch 'main' into main-hotfix 2026-08-04 23:47:21 +05:30
RitvikSardana
81be827b56 Merge pull request #3672 from frappe/mergify/bp/main-hotfix/pr-3671
fix(telemetry): capture events for new features (backport #3671)
2026-08-04 23:46:51 +05:30
Ritvik Sardana
f682eea875 fix(telemetry): capture events for new features
(cherry picked from commit efe0688b29)
2026-08-04 18:16:33 +00:00
Ritvik Sardana
e0dfabb112 fix: dedupe reka-ui so linked @framework/ui resolves it
(cherry picked from commit d763279734)
2026-08-04 17:28:36 +00:00
Ritvik Sardana
3a9366ddf2 refactor: import Link from the @framework/ui package entry
(cherry picked from commit f021dcc365)
2026-08-04 17:28:36 +00:00
Ritvik Sardana
bd450bac22 fix: install @framework/ui deps before dev and build
`@framework/ui` is a `link:` dependency, so yarn never installs its own
dependencies and the build fails on missing imports. Run `yarn install`
in `frappe/ui` first, skipping it when `.yarn-integrity` shows a complete
install is already there.

(cherry picked from commit 50f15f6f83)
2026-08-04 17:28:36 +00:00
RitvikSardana
e57f2acab1 Merge pull request #3669 from frappe/mergify/bp/main-hotfix/pr-3668
fix: handle snug (backport #3668)
2026-08-04 22:57:21 +05:30
Ritvik Sardana
72d2f1784d fix: handle snug
(cherry picked from commit 4026cc3a8b)
2026-08-04 17:27:06 +00:00
RitvikSardana
de257b1342 Merge pull request #3667 from frappe/mergify/bp/main-hotfix/pr-3666
fix: line-height saved reply (backport #3666)
2026-08-04 17:26:21 +05:30
Ritvik Sardana
aedafb764a fix: line-height saved reply
(cherry picked from commit 5db4bb9c83)
2026-08-04 11:28:31 +00:00
RitvikSardana
f5641c8bc7 Merge pull request #3664 from frappe/mergify/bp/main-hotfix/pr-3663
fix: email editor closing on selecting recipients (backport #3663)
2026-08-04 14:04:06 +05:30
RitvikSardana
e0d16425dc Merge pull request #3665 from frappe/mergify/bp/main-hotfix/pr-3662
fix(cp): vertical axis alignment (backport #3662)
2026-08-04 14:03:52 +05:30
Ritvik Sardana
03bba6dee2 fix(cp): vertical axis alignment
(cherry picked from commit 5d16951788)
2026-08-04 08:33:31 +00:00
Ritvik Sardana
c00caf72ab fix: email editor closing on selecting recipients
(cherry picked from commit d289faead6)
2026-08-04 08:32:52 +00:00
RitvikSardana
7b091b52dd Merge pull request #3659 from frappe/mergify/bp/main-hotfix/pr-3637
fix(command-palette): rename saved reply group to Frequent replies (backport #3637)
2026-08-03 23:53:27 +05:30
Ritvik Sardana
e052336312 fix(command-palette): rename saved reply group to Frequent replies
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
(cherry picked from commit d1c2c06e65)
2026-08-03 18:21:28 +00:00
RitvikSardana
0c92f776bc Merge pull request #3658 from frappe/mergify/bp/main-hotfix/pr-3634
fix: onboarding questionnaire surface, button sizing and team-size default (backport #3634)
2026-08-03 23:50:06 +05:30
Sydney
63ec5d865f feat: report an unanswered team size as prefer_not_to_say
Team size is the only optional answer, so skipping it dropped the key
entirely and the persona event came through incomplete. Default it at
submitPersona, the one point both telemetry and routing read.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
(cherry picked from commit 535db2216d)
2026-08-03 18:17:49 +00:00
Sydney
84cddef7be fix: put the onboarding screen on the base surface
surface-gray-1 read as an off-white tint behind the questionnaire.
surface-base is pure white in light mode and still flips with the theme,
which bg-white would not.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
(cherry picked from commit 5d8b42a381)
2026-08-03 18:17:49 +00:00
Sydney
500f647e36 refactor: size the questionnaire Next button with the size prop
size="sm" already yields h-7 and the theme's button radius, so the !h-7
and !rounded-lg overrides were restating the default with !important.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
(cherry picked from commit 83f25c9462)
2026-08-03 18:17:48 +00:00
RitvikSardana
701a40637e Merge pull request #3657 from frappe/mergify/bp/main-hotfix/pr-3636
fix: line height in feedback component (backport #3636)
2026-08-03 23:46:42 +05:30
Ritvik Sardana
b3ca168e04 fix: line height in feedback component
(cherry picked from commit 027f36d790)
2026-08-03 18:12:21 +00:00
RitvikSardana
1971d920fe Merge pull request #3656 from frappe/mergify/bp/main-hotfix/pr-3542
fix: drop img src after setting embed so inline images render in emails (backport #3542)
2026-08-03 23:40:30 +05:30
Ritvik Sardana
cc88ba8a0e fix: drop img src after setting embed so inline images render in emails
Pasted images are uploaded as private files, and parse_content kept the
original src alongside the embed attribute. The framework's cid
replacement then produced a duplicate-src img tag, so email clients
could resolve the login-gated /private/files URL instead of the inline
cid attachment. Swap src for embed (site files only, external URLs and
data URIs untouched) so the inline attachment always wins.

(cherry picked from commit a8ca6f442f)
2026-08-03 18:08:26 +00:00
RitvikSardana
01ffd7d35a Merge pull request #3655 from RitvikSardana/backport/main-hotfix-pr-3626
feat(command-palette): contextual Cmd+K palette for the agent portal (backport #3626)
2026-08-03 23:37:11 +05:30
RitvikSardana
de5d23240e Merge pull request #3626 from RitvikSardana/feat/command-palette
feat(command-palette): contextual Cmd+K palette for the agent portal
2026-08-03 23:23:27 +05:30
RitvikSardana
aa2920d68a Merge pull request #3654 from frappe/mergify/bp/main-hotfix/pr-3629
perf(search): keep permission filtering bounded at any ticket count (backport #3629)
2026-08-03 21:46:45 +05:30
RitvikSardana
b19c486299 Merge pull request #3653 from frappe/mergify/bp/main-hotfix/pr-3631
fix: move ticket's feedback to sidepanel (backport #3631)
2026-08-03 21:45:22 +05:30
RitvikSardana
d278103b86 Merge pull request #3652 from frappe/mergify/bp/main-hotfix/pr-3624
fix(home): keep the last recent activity row out of the bottom fade (backport #3624)
2026-08-03 21:45:07 +05:30
Ritvik Sardana
9f116a7135 refactor(perf): grant the search test user HD Customer
A role-less user has no doctype-level read on HD Ticket, so get_list
raises PermissionError on a clean CI site. Real searching users are
agents or HD Customers; the test now models the latter.

(cherry picked from commit 6295521022)
2026-08-03 16:13:56 +00:00
Ritvik Sardana
7c333f9bab refactor(perf): trim comments, replace map() with a comprehension
The map() call tripped frappe's no-functional-code semgrep rule.

(cherry picked from commit fb11a89635)
2026-08-03 16:13:55 +00:00
Ritvik Sardana
583f555dd6 refactor(perf): bind facet permission list via json_each, not 3N placeholders
get_filter_options pasted the accessible-ticket list into the query three
times (name / reference_name / reference_ticket each carry the ticket for
a different row type), binding 3N variables — so it hit SQLite's
bound-variable ceiling at a third of the ticket count the search query
does.

The list now binds as one JSON string per column: 3 variables total,
regardless of site size. Same rows match, the ceiling is gone.

(cherry picked from commit 4a8bdb61af)
2026-08-03 16:13:55 +00:00
Ritvik Sardana
44496795f3 refactor(perf): bound the search permission prefilter, post-filter past the cap
frappe.get_list("HD Ticket", pluck="name") ran unbounded on every search
call, feeding a SQLite IN (...): linear cost per keystroke (108ms at 200k
tickets) and a hard OperationalError past the bound-variable ceiling,
which core's except sqlite3.Error turns into silently empty results.

get_search_filters now probes at most PREFILTER_LIMIT + 1 names. Under
the limit the exact prefilter binds as before; over it, the prefilter is
skipped and _drop_unpermitted permission-checks the returned results
(<=100) through one get_list, which applies every layer including User
Permissions. Rows without a resolvable ticket fail closed; Communication
rows resolve via reference_name.

(cherry picked from commit 292269e4a1)
2026-08-03 16:13:55 +00:00
Ritvik Sardana
f14bcb4fe3 fix: add feedback secton to right
(cherry picked from commit 2e1f38f4b4)
2026-08-03 16:13:37 +00:00
Ritvik Sardana
3bcfae6d74 refactor(ticket): move feedback from timeline to sidebar
Feedback no longer renders as a timeline entry on desktop. It now shows as
its own collapsible section under Ticket SLA, with Rating / Feedback /
Comment rows matching the customer portal labels.

Mobile keeps feedback in its activity list.

(cherry picked from commit 8155afaa4e)
2026-08-03 16:13:36 +00:00
Ritvik Sardana
cab77ee785 fix(home): keep the last recent activity row out of the bottom fade
The scroll fade is a fixed overlay, so the final row (and its hover state)
always sat under it. Pad the list by the fade height so content scrolls
clear of the gradient.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
(cherry picked from commit 487f4d1c22)
2026-08-03 16:13:21 +00:00
RitvikSardana
9a64e7e7d3 Merge pull request #3651 from frappe/mergify/bp/main-hotfix/pr-3623
fix(dashboard): show chart-specific empty states (backport #3623)
2026-08-03 21:42:11 +05:30
Ritvik Sardana
df0da3e118 fix(dashboard): show tag charts to managers only
Tag mix is org level insight. An agent's view is scoped to their own
tickets, where the tag breakdown reflects routing rather than anything
they can act on, so skip the section and its fetch for non managers.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
(cherry picked from commit 9e787d4c31)
2026-08-03 16:10:00 +00:00
Ritvik Sardana
ebaf629531 fix(dashboard): key empty states on a stable chart key
Chart titles are translated server side, so an English-keyed lookup misses
on non-English sites. Emit a stable key from the chart config builders and
match on it. Carry the chart title in the dashboard-wide empty state too,
so those cards render headers instead of placeholder bars.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
(cherry picked from commit b6fc94d2e0)
2026-08-03 16:10:00 +00:00
Ritvik Sardana
7e1e14b346 fix(dashboard): show chart-specific empty states
Only the empty-state title was overridden per chart, so every empty chart
fell back to the generic "Dashboard charts will appear here" message.
Map the copy by chart title and render the real chart header instead of
skeleton bars on empty cards.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
(cherry picked from commit 327315068c)
2026-08-03 16:09:59 +00:00
RitvikSardana
516bfae637 Merge pull request #3650 from frappe/mergify/bp/main-hotfix/pr-3625
fix(customisation): convert link_filters to dict before search_link (backport #3625)
2026-08-03 21:36:39 +05:30
Ritvik Sardana
bc612d8380 refactor(home): render recent activity rows as router links
Rows were divs with a click handler, so they were not real anchors. Middle
click and cmd click did nothing and the destination never showed on hover.
router-link renders an <a href> and keeps in-app navigation.

(cherry picked from commit 6d48587320)
2026-08-03 16:02:12 +00:00
Ritvik Sardana
8afa2aee36 fix(customisation): convert link_filters to dict before search_link
Customize Form stores link_filters as [[doctype, fieldname, operator,
value]], and parseField passed that list straight through as the filters
param of frappe.desk.search.search_link.

Most doctypes tolerate it because search_widget hands list filters to
frappe.get_list. Doctypes registered in standard_queries (User) skip that
path and receive filters untouched, and those queries only read dicts, so
user_query raises AttributeError on filters.get(). Any Link-to-User field
with link_filters set breaks the New Ticket page.

Convert to the dict form search_link expects, matching what the desk does
with get_filter_from_json.

(cherry picked from commit 85592330e2)
2026-08-03 16:02:12 +00:00
RitvikSardana
ab8fbc2b9f Merge pull request #3649 from frappe/mergify/bp/main-hotfix/pr-3621
feat: First Ticket tag and tag charts on the dashboard (backport #3621)
2026-08-03 21:31:04 +05:30
RitvikSardana
342314c9e3 chore: resolve conflicts 2026-08-03 21:26:14 +05:30
Ritvik Sardana
e3c8fa9404 fix: track hd_agent changes
(cherry picked from commit 465e14530f)
2026-08-03 15:46:30 +00:00
Ritvik Sardana
56dc6d98b3 refactor(tags): check for an earlier ticket instead of counting
`raised_by` is unindexed, so counting every ticket for a requester was a
full scan on each insert. An existence check stops at the first match.

(cherry picked from commit 27dbf50d80)
2026-08-03 15:46:29 +00:00
Ritvik Sardana
d6c3ce7bf4 fix(style): change sla due color
(cherry picked from commit 1198b0e922)

# Conflicts:
#	desk/src/components/ticket-agent/TicketSLA.vue
2026-08-03 15:46:29 +00:00
Ritvik Sardana
05c55b341f fix(tags): fill in a missing colour on an existing tag
A Tag master minted before colours existed, or by desk's tag sidebar,
keeps a null colour and renders gray forever. Treat a missing colour
the same as a claim and fill it in; a tag that already has one still
keeps it.

(cherry picked from commit d5354838e6)
2026-08-03 15:46:29 +00:00
Ritvik Sardana
b419f290e7 feat(dashboard): add Top Tags and Tag Trend charts
Two tag charts on the dashboard, reusing the existing date, team and
agent filters. Top Tags ranks the busiest tags on a horizontal bar so
long tag names get the long axis; Tag Trend stacks the top five tags
per day so a spike in one is visible. Tags live in Tag Link rather
than a scalar column, so these join instead of reusing the group-by
helpers the other master charts use.

Bar chart value axes now step by whole numbers. Every bar chart on
this dashboard counts tickets, and half a ticket is not a thing.

(cherry picked from commit 8d7aabb29e)
2026-08-03 15:46:28 +00:00
Ritvik Sardana
244fc2c965 feat(tags): tag a requester's first ticket
Tag the first ticket ever raised by a requester with "First Ticket"
instead of setting a custom field, so it filters, reports and slices
like any other tag. The count runs in after_insert, where a count of
one means this is the first, and goes through apply_tag so the Tag
master is claimed for helpdesk and shows in the picker.

(cherry picked from commit 55afea6641)
2026-08-03 15:46:28 +00:00
RitvikSardana
750977c127 Merge pull request #3648 from frappe/mergify/bp/main-hotfix/pr-3613
feat: new ticket sidepanel layout (backport #3613)
2026-08-03 21:13:20 +05:30
RitvikSardana
40917c52da chore: resolve conflicts 2026-08-03 20:38:34 +05:30
Ritvik Sardana
1bb25804ef fix: add tags in Ticket Filters
(cherry picked from commit b6636c1b33)
2026-08-03 15:02:47 +00:00
Ritvik Sardana
3702fa2885 fix: framework/ui build
(cherry picked from commit dd198e2246)
2026-08-03 15:02:47 +00:00
Ritvik Sardana
66f43e5ed3 fix(build): resolve @framework/ui imports from the desk root
@framework/ui is linked from source, so rollup resolves its imports
starting at apps/frappe/ui, and desk/node_modules is never on that
lookup chain. dompurify and reka-ui arrive there as frappe-ui deps, so
`bench build --app helpdesk` failed on CI where apps/frappe/ui has
nothing installed.

Deduping both forces them to resolve from the project root, the same
reason vue and frappe-ui are already listed.

(cherry picked from commit 22b15e7cc1)
2026-08-03 15:02:46 +00:00
Ritvik Sardana
8de38e527a refactor: tags component API
(cherry picked from commit 34229ac4c3)
2026-08-03 15:02:46 +00:00
Ritvik Sardana
f64a80b1c9 feat(tags): batch ticket tag edits into one request
Tag editing now runs as a session: chips update optimistically while the
picker is open, and the whole edit lands as a single update_tags call when
it closes, logging one activity instead of one per tag.

The colour step moves into its own TagColorPicker component, and the tag
components are grouped under ticket-agent/tag/.

(cherry picked from commit 4308f38d53)
2026-08-03 15:02:45 +00:00
Ritvik Sardana
4e59b7949d fix: remove dead code
(cherry picked from commit 950209e4c7)

# Conflicts:
#	desk/src/components/ticket-agent/TicketNavigation.vue
2026-08-03 15:02:44 +00:00
Ritvik Sardana
a96a0cbf33 fix: remove chevron
(cherry picked from commit 83a55e6d42)
2026-08-03 15:02:43 +00:00
Ritvik Sardana
314867c064 fix: hide navigation buttons
(cherry picked from commit 4171740a65)
2026-08-03 15:02:43 +00:00
Ritvik Sardana
eacf60e6aa fix: polish sidebar and priority
(cherry picked from commit eb27fb81c9)

# Conflicts:
#	desk/src/components/ticket-agent/AssignTo.vue
2026-08-03 15:02:43 +00:00
Ritvik Sardana
9c7ed23d9d fix: spacing in side panel
(cherry picked from commit b403afc692)
2026-08-03 15:02:42 +00:00
Ritvik Sardana
d62409ffae fix: polish SLA section
(cherry picked from commit e1bb4efbda)

# Conflicts:
#	desk/src/components/ticket-agent/TicketSLA.vue
2026-08-03 15:02:41 +00:00
Ritvik Sardana
239c7433fd chore: copy cleanup
(cherry picked from commit 7cbdd88364)
2026-08-03 15:02:40 +00:00
Ritvik Sardana
272cf168cf fix: restore add_priority_integer patch
This 2023 patch was dropped in fce245316 when integer_value was replaced
by level. Old patches must never be deleted from the ledger; the new
backfill_priority_level supersedes it by addition, not removal.

(cherry picked from commit 02c6d57e76)
2026-08-03 15:02:39 +00:00
Ritvik Sardana
9ffcc1dc77 chore: untrack stray .claude-worktrees gitlink
An accidental 160000 gitlink to the embed-private-images worktree was
committed in 865fdb4c9. Remove it and ignore .claude-worktrees so it
can't be re-added.

(cherry picked from commit 67d0601fef)
2026-08-03 15:02:39 +00:00
Ritvik Sardana
0da99615da fix: add chevron in status field
(cherry picked from commit a15be81f08)
2026-08-03 15:02:39 +00:00
Ritvik Sardana
1be3b2c474 fix: ux for max tags
(cherry picked from commit b192881de0)
2026-08-03 15:02:38 +00:00
Ritvik Sardana
191763d95c fix: SLA popover spacing
(cherry picked from commit 509d81b012)
2026-08-03 15:02:38 +00:00
Ritvik Sardana
253f502ce2 fix: tags UX
(cherry picked from commit 9cfcc1f72a)
2026-08-03 15:02:36 +00:00
Ritvik Sardana
ce1c4c76d2 fix: SLA time style
(cherry picked from commit 7fdcbd70d0)
2026-08-03 15:02:35 +00:00
Ritvik Sardana
62a44a5ec7 chore: code cleanup
(cherry picked from commit aad724d1a8)
2026-08-03 15:02:34 +00:00
Ritvik Sardana
71ed8e6c2c fix: spacing in sections
(cherry picked from commit ebf49e189b)
2026-08-03 15:02:33 +00:00
Ritvik Sardana
9f1792ed01 chore: update labels
(cherry picked from commit d63a356da5)
2026-08-03 15:02:32 +00:00
Ritvik Sardana
340094d14f fix: polish side panel
(cherry picked from commit 274271f80a)

# Conflicts:
#	desk/src/components/ticket-agent/AssignTo.vue
#	desk/src/components/ticket-agent/TicketSLA.vue
2026-08-03 15:02:31 +00:00
Ritvik Sardana
3727b84290 feat: add colors in Tags
(cherry picked from commit c61bb6df99)
2026-08-03 15:02:30 +00:00
Ritvik Sardana
b1befacc52 fix(ux): ticket value update
(cherry picked from commit 0cc6f5d23a)
2026-08-03 15:02:30 +00:00
Ritvik Sardana
54b1aff86f feat: tags in sidepanel
(cherry picked from commit 2c3a354009)
2026-08-03 15:02:29 +00:00
Ritvik Sardana
5ab8217408 feat: show priority level icon in agent ticket field
Render the HD Ticket Priority level icon before the selected value and
each option in the agent side panel priority Link (via the combobox
item-prefix slot, reused for the control). Keep the customer portal
priority as plain text for now.

(cherry picked from commit 6dd3a6af57)
2026-08-03 15:02:28 +00:00
Ritvik Sardana
8df33375e2 fix: make patch better
(cherry picked from commit 78167274b1)

# Conflicts:
#	helpdesk/patches/backfill_priority_level.py
2026-08-03 15:02:28 +00:00
Ritvik Sardana
d89d4ba921 feat: display ticket priority as icon and level
Replace the arbitrary integer_value on HD Ticket Priority with a purposeful
`level` Select field, and render priorities as an icon + name across the
agent ticket list, home pending tickets, customer portal, and SLA settings.

- Add `level` (Urgent/High/Medium/Low), remove integer_value
- Backfill patch: builtins map by name, custom priorities inherit the level
  of the nearest builtin above them (Medium when a site has no builtins)
- New TicketPriority.vue component and ticketPriority store
- Drop the now-unused priority-range colour pipeline in agent_home

(cherry picked from commit fce245316a)

# Conflicts:
#	helpdesk/patches.txt
#	helpdesk/patches/backfill_priority_level.py
2026-08-03 15:02:28 +00:00
Ritvik Sardana
4689e9f5c8 fix: assignee component width
(cherry picked from commit 700c48816c)

# Conflicts:
#	desk/src/components/MultipleAvatar.vue
#	desk/src/components/ticket-agent/AssignTo.vue
2026-08-03 15:02:27 +00:00
Ritvik Sardana
57d020bbea fix: assignTo focus state and animation
(cherry picked from commit a16c83a51c)

# Conflicts:
#	desk/src/components/ticket-agent/AssignTo.vue
2026-08-03 15:02:26 +00:00
Ritvik Sardana
89a83c118e fix: use link field from framework
(cherry picked from commit 20f65744a4)
2026-08-03 15:02:26 +00:00
Ritvik Sardana
19da3d3d5f fix: better SLA layout
(cherry picked from commit 53284913fa)

# Conflicts:
#	desk/src/components/ticket-agent/AssignTo.vue
#	desk/src/components/ticket-agent/TicketSLA.vue
2026-08-03 15:02:26 +00:00
Ritvik Sardana
789cd272a8 fix: reposition SLA layout
(cherry picked from commit 865fdb4c9a)

# Conflicts:
#	desk/src/components/ticket-agent/AssignTo.vue
#	desk/src/components/ticket-agent/TicketSLA.vue
2026-08-03 15:02:25 +00:00
RitvikSardana
babf2e766f Merge pull request #3647 from frappe/mergify/bp/main-hotfix/pr-3618
fix: attachment upload feedback + uploads while editing comments (backport #3618)
2026-08-03 20:28:44 +05:30
Sydney
114ac53a55 fix: exit comment edit mode reliably on save/discard
Toggling `editable` on an existing comment crashed Vue's patch ("Cannot read properties of null (reading 'insertBefore')" in processCommentNode) because the v-if edit affordances sit next to the renderless Editor's ProseMirror-managed DOM. The aborted update left the Save/Discard buttons stuck on screen and the comment never left edit mode.

Key the Editor on edit/view mode so switching cleanly remounts it instead of patching across ProseMirror's DOM.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
(cherry picked from commit 049935b60b)
2026-08-03 14:49:47 +00:00
Sydney
f819fea43d fix: allow file uploads when editing a ticket comment
The edit-comment Editor had no upload-function, so pasted or dropped media fell back to an orphaned private file (no attached_to) that 403s for other viewers. Wire up uploadFunction bound to the ticket, matching the new-comment editor.

Closes #3617

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
(cherry picked from commit 9d68631a74)
2026-08-03 14:49:47 +00:00
Sydney
38750b7a91 fix: show a spinner on the attachment button while uploading
The FileUploader attach button only disabled itself during an upload with no visible indicator, so users had no way to tell why the send button was disabled. Swap the paperclip for a LoadingIndicator while uploading in the comment, email, and compact editors.

Closes #3616

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
(cherry picked from commit 8b7958bbb6)
2026-08-03 14:49:46 +00:00
RitvikSardana
2fd96d5a37 Merge pull request #3646 from frappe/mergify/bp/main-hotfix/pr-3608
fix: unable to remove attachment (backport #3608)
2026-08-03 20:18:44 +05:30
RitvikSardana
5cdf129806 Merge pull request #3645 from frappe/mergify/bp/main-hotfix/pr-3607
feat: Recent Activity card on Home dashboard (backport #3607)
2026-08-03 20:17:32 +05:30
Ritvik Sardana
00db893fd7 refactor: shared AttachmentList with lucide icon and video preview
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
(cherry picked from commit 5038dd93a1)
2026-08-03 14:46:56 +00:00
Ritvik Sardana
36614bb75b fix: unable to remove attachment
(cherry picked from commit 316a1b6292)
2026-08-03 14:46:56 +00:00
Ritvik Sardana
5ea64d065a fix: line height
(cherry picked from commit 28a2385104)
2026-08-03 14:37:22 +00:00
Ritvik Sardana
60a8d85b51 fix: flaky tests in hd_agent
(cherry picked from commit 06fc790387)
2026-08-03 14:37:22 +00:00
Ritvik Sardana
a156999002 refactor: API function
(cherry picked from commit 381073c764)
2026-08-03 14:37:22 +00:00
Ritvik Sardana
f7d411b013 fix: dedupe recent activity per ticket before limiting
Group each source's events by ticket in SQL (MAX(creation)) so a single
busy ticket cannot consume the row limit and starve other eligible
tickets. Backfill the updated-action text for winning tickets, filter
inaccessible tickets before the cap, and add a regression test.

(cherry picked from commit ae5702abf0)
2026-08-03 14:37:21 +00:00
Ritvik Sardana
89929eda6b fix: better list of events
(cherry picked from commit 0415c75e9d)
2026-08-03 14:37:21 +00:00
Ritvik Sardana
b118c60604 fix: better empty state
(cherry picked from commit 28465bb1a6)
2026-08-03 14:37:21 +00:00
Ritvik Sardana
63d9fe173c feat: recent activity
(cherry picked from commit fd6e34b0c4)
2026-08-03 14:37:20 +00:00
RitvikSardana
06d6809248 Merge pull request #3644 from frappe/mergify/bp/main-hotfix/pr-3604
feat: display ticket priority as icon and level (backport #3604)
2026-08-03 19:51:02 +05:30
RitvikSardana
6497341f03 chore: resolve conflicts 2026-08-03 19:39:44 +05:30
Ritvik Sardana
1197f3dc55 fix: make patch better
(cherry picked from commit 04ac2c476f)
2026-08-03 14:08:15 +00:00
Ritvik Sardana
1f5556c3c9 chore: code cleanup
(cherry picked from commit a48e9e5a49)
2026-08-03 14:08:15 +00:00
Ritvik Sardana
60691268f0 feat: display ticket priority as icon and level
Replace the arbitrary integer_value on HD Ticket Priority with a purposeful
`level` Select field, and render priorities as an icon + name across the
agent ticket list, home pending tickets, customer portal, and SLA settings.

- Add `level` (Urgent/High/Medium/Low), remove integer_value
- Backfill patch: builtins map by name, custom priorities inherit the level
  of the nearest builtin above them (Medium when a site has no builtins)
- New TicketPriority.vue component and ticketPriority store
- Drop the now-unused priority-range colour pipeline in agent_home

(cherry picked from commit 2d124b8f36)

# Conflicts:
#	helpdesk/patches.txt
2026-08-03 14:08:14 +00:00
RitvikSardana
67265c6530 Merge pull request #3643 from frappe/mergify/bp/main-hotfix/pr-3569
feat(mobile): team switcher in agent ticket header + mobile fixes (backport #3569)
2026-08-03 19:33:51 +05:30
RitvikSardana
46f72e26d5 chore: resolve conflict 2026-08-03 19:32:48 +05:30
Sydney
6817cf63b6 fix(desk): dark-mode styling for collapsed quote toggle in EmailEditor
The "..." collapse toggle used a hardcoded light background (#e8eaed) with
no dark variant, rendering as a bright white pill in dark mode. Add the
dark rules already used by the read-only EmailContent view.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
(cherry picked from commit cd63d475ad)
2026-08-03 13:59:43 +00:00
Sydney
a05c3ef6de fix(mobile): ticket header row px-3 to sit on the same gutter as tabs
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
(cherry picked from commit d2e7ee7232)
2026-08-03 13:59:43 +00:00
Sydney
838d899ca0 fix(mobile): align tab lists with the header hamburger icon
The hamburger icon sits 12px from the screen edge (ms-1 + button
px-2) while tab lists used 20px (px-5), so the tab row started
visibly right of the header icon. Tab lists are now px-3 on mobile
across all tabbed views: agent ticket and customer portal ticket
(mobile-only tab bars, unconditional) and Contact/Customer pages
(max-sm variant so desktop keeps the default px-5).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
(cherry picked from commit 8b359ac378)
2026-08-03 13:59:43 +00:00
Sydney
13e390d7ac refactor: move activity deep-links from URL hash to ?highlight param
The hash was doing two jobs on ticket pages: useActiveTabManager
stores the active tab in it, and notification/search links used it to
point at one activity. The prefix allowlist only guarded the reader;
the writer side still interleaved: the post-highlight cleanup stripped
whatever hash existed 3s later (snapping desktop tabs picked during
the highlight window back to tab 0) and dropped ?view=, and on mobile
a deep-link hash was destroyed by the tab manager before its target
could ever mount.

Deep-link targets now travel as ?highlight=<element id> while the
hash carries only tab state. useActiveTabManager needs no changes --
it already preserves route.query in every navigation, so the two
writers own disjoint fields. Generators emit #activity (renders all
activity types on both form factors) plus the highlight param, making
mobile notification/search deep-links functional for the first time.
Cleanup removes only the consumed param, keeping ?view= and the tab
the user is on.

Supersedes the deepLinkPrefixes allowlist.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
(cherry picked from commit b2f01d90c9)
2026-08-03 13:59:42 +00:00
Sydney
ebb1d918bc refactor: allowlist deep-link prefixes instead of tab-name denylist
Deep-link ids are always prefixed (comment-, communication-), so match
on those instead of maintaining a list of tab names that must track
every tab rename or addition. Also prefixes MobileNotifications'
mention hash the way desktop Notifications.vue already does — the bare
comment name could never match the comment-<name> element ids.

Addresses greptile review on #3569.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
(cherry picked from commit 068a41d8e6)
2026-08-03 13:59:41 +00:00
Sydney
1e4f6c2b4e fix(mobile): align ticket header padding with tab list (px-5)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
(cherry picked from commit 70051fe5f2)
2026-08-03 13:59:40 +00:00
Sydney
3dcb1c84ff fix: truncate long single-assignee name in AssignTo trigger
A single assignee's full name rendered without ellipsis because every
flex ancestor kept min-width:auto; long names overflowed the trigger.
min-w-0 down the chain (Button label span, trigger row, MultipleAvatar)
lets the existing truncate class clip with an ellipsis.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
(cherry picked from commit af9aa8df76)

# Conflicts:
#	desk/src/components/ticket-agent/AssignTo.vue
2026-08-03 13:59:40 +00:00
Sydney
ec0e550173 fix(mobile): agent availability as native dropdown submenu
AvailabilityMenuMobile nested a right-placed Popover inside the
profile Dropdown; on narrow screens there is no room to the right so
the status panel landed on top of the menu items below it (theme
toggle). Replaced with a native Dropdown submenu option (same pattern
as the Apps entry) so reka-ui keeps it positioned inside the viewport,
and deleted the now-unused component.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
(cherry picked from commit b5592d6f91)
2026-08-03 13:59:40 +00:00
Sydney
bcf418b9a4 fix(mobile): match team switcher styling with assignee control
Renders the team Link through its target slot as the same outline
button AssignTo uses, and splits the header row evenly between the
two controls.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
(cherry picked from commit ea219b8c5b)
2026-08-03 13:59:39 +00:00
Sydney
ebeccffec3 fix(customer-portal): consistent text-p-sm in mobile details
Labels and values in the details tab now all use text-p-sm; the SLA
label width matches the other labels at 150px.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
(cherry picked from commit df1787a833)
2026-08-03 13:59:39 +00:00
Sydney
72f42996d8 fix(mobile): opaque sidebar background
frappe-ui Sidebar is transparent in dark mode by design; as a fixed
overlay on mobile the page content showed through. Same fix as
frappe/suite#108.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
(cherry picked from commit 9417f76547)
2026-08-03 13:59:39 +00:00
Sydney
3ab8830621 fix(mobile): don't treat active-tab hash as activity deep-link
useActiveTabManager stores the active tab in the URL hash, while
notification/search links use the hash to deep-link to one activity.
scrollToHash() treated any hash as a deep-link and stripped it from
the URL after highlighting, so opening the Activity tab on mobile
snapped back to Details a few seconds later (the lucide sprite's
<symbol id="activity"> even gave it an element to "scroll" to).
Tab-name hashes are now excluded from deep-link handling.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
(cherry picked from commit b8b8b85c8b)
2026-08-03 13:59:38 +00:00
Sydney
1ec1fbbf27 fix: skip get_apps fetch on customer portal
Customers lack permission for frappe.apps.get_apps and the call 403s.
The sidebar remounts on portal switch, so the flag re-evaluates for
agents.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
(cherry picked from commit 39af981753)
2026-08-03 13:59:38 +00:00
Sydney
2423771f34 feat(mobile): team switcher in agent ticket header
Adds an HD Team dropdown next to AssignTo in the mobile ticket
header so agents can reassign a ticket's team without opening the
details tab.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
(cherry picked from commit 02810a821f)
2026-08-03 13:59:38 +00:00
RitvikSardana
cc25a10d84 Merge pull request #3642 from RitvikSardana/chore/sync-locale-to-main-hotfix
chore: sync locale files from develop to main-hotfix
2026-08-03 19:17:47 +05:30
Ritvik Sardana
924d65822f chore: sync locale files from develop to main-hotfix
Takes helpdesk/locale wholesale from develop instead of backporting
#3517, #3522, #3539, #3531 and #3554 individually — those five stack on
the same .po/.pot files and mergify's cherry-picks land conflict markers
in the committed files (see #3641, and #3573 previously).

Backports #3517, #3522, #3539, #3531, #3554.
2026-08-03 19:11:26 +05:30
Frappe PR Bot
7b4b400a50 chore(release): Bumped to Version 1.28.1 2026-07-23 12:20:54 +00:00
RitvikSardana
929eb4cdeb Merge pull request #3612 from frappe/mergify/bp/main/pr-3610
fix: set default portal settings for existing sites (backport #3610)
2026-07-23 17:50:30 +05:30
RitvikSardana
aacdae406b Merge pull request #3611 from frappe/mergify/bp/main-hotfix/pr-3610
fix: set default portal settings for existing sites (backport #3610)
2026-07-23 17:41:52 +05:30
RitvikSardana
6c595ab0ec chore: resolve conflicts 2026-07-23 17:17:31 +05:30
RitvikSardana
3254cd2412 chore: resolve conflicts 2026-07-23 17:17:05 +05:30
Ritvik Sardana
8b1f711493 fix: set default portal settings for existing sites
Sets Portal Settings default_role to HD Customer and
default_portal_home to /helpdesk on existing sites, only when the
values are not already set. Previously this ran on fresh installs only.

(cherry picked from commit fbeeb0a5c3)

# Conflicts:
#	helpdesk/patches.txt
2026-07-23 11:39:02 +00:00
Ritvik Sardana
783bbb40c5 fix: set default portal settings for existing sites
Sets Portal Settings default_role to HD Customer and
default_portal_home to /helpdesk on existing sites, only when the
values are not already set. Previously this ran on fresh installs only.

(cherry picked from commit fbeeb0a5c3)

# Conflicts:
#	helpdesk/patches.txt
2026-07-23 11:38:43 +00:00
Sydney Gomes
e92a930a6d Merge pull request #3605 from aerodeval/backport/pr-3174-rtl-support
feat: rtl support (backport #3174)
2026-07-22 16:32:36 +05:30
Frappe PR Bot
840a683319 chore(release): Bumped to Version 1.28.0 2026-07-22 07:27:16 +00:00
RitvikSardana
42e8494bd1 Merge pull request #3603 from frappe/main-hotfix
chore(release): hotfix to main
2026-07-22 12:56:48 +05:30
Sydney Gomes
170c538b2e feat: rtl support (backport #3174)
Backport of frappe/helpdesk#3174 onto main-hotfix. main-hotfix already
carried the RTL boot infra (index.py dir/lang, is_rtl); this adds the
physical→logical Tailwind sweep (ms/me, ps/pe, start/end, border-s/e,
rounded-s/e, gap-x), rtl: variants and directional-icon rotations.

Conflicts resolved against main-hotfix's newer code: kept its refactors
(Sidebar→AppSidebar, EmptyState, Dialog API, token migration) and layered
the RTL swaps onto them. Reconciled SettingsLayoutBase so its restored
back-label/on-back/dirty API matches the 10 settings-view callers that
auto-merged to it. Dropped the 3 files main-hotfix had already removed
(MultiSelectInput, desk/global New{Contact,Customer}Dialog).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-22 02:01:06 +05:30
RitvikSardana
fba67b5d47 Merge pull request #3600 from frappe/mergify/bp/main-hotfix/pr-3599
fix: editor link and edit comment (backport #3599)
2026-07-20 13:02:06 +05:30
Ritvik Sardana
bab0eced47 fix(patch): editor link and edit comment
(cherry picked from commit 641ad86f1d)
2026-07-20 07:30:46 +00:00
RitvikSardana
e690904ca3 Merge pull request #3598 from frappe/mergify/bp/main-hotfix/pr-3568
fix: SidebarItem overflow (backport #3568)
2026-07-20 11:30:47 +05:30
RitvikSardana
3a449459f2 Merge pull request #3595 from frappe/mergify/bp/main-hotfix/pr-3565
fix: make headers sticky in TicketsTab (backport #3565)
2026-07-20 11:29:36 +05:30
RitvikSardana
1a30b1c316 Merge pull request #3596 from RitvikSardana/backport/3538-main-hotfix
feat: onboarding persona questionnaire (backport #3538)
2026-07-20 11:29:13 +05:30
Ritvik Sardana
8d522ec487 fix: rerendering of mention popover
(cherry picked from commit 984e5aa953)
2026-07-20 05:49:37 +00:00
Ritvik Sardana
9f2f99e3f6 fix: SidebarItem overflow
(cherry picked from commit 1264551c8a)
2026-07-20 05:49:36 +00:00
Ritvik Sardana
f1437131a5 fix: use FrappeTestCase for v15 compatibility 2026-07-20 05:12:52 +05:30
Sydney Gomes
b9e066ba5b Merge pull request #3538 from aerodeval/feat/onboarding-persona-questionnaire
feat: onboarding persona questionnaire
2026-07-20 05:02:06 +05:30
Ritvik Sardana
9923cf22ca chore: code cleanup
(cherry picked from commit db2971a5d9)
2026-07-19 23:25:53 +00:00
Ritvik Sardana
ac87f5d2fb fix: make headers sticky in TicketsTab
(cherry picked from commit 134142453c)
2026-07-19 23:25:52 +00:00
RitvikSardana
fe2c058f45 Merge pull request #3594 from frappe/mergify/bp/main-hotfix/pr-3563
fix: strip html comments from agent reply email content (backport #3563)
2026-07-20 04:54:44 +05:30
RitvikSardana
f52a47bc0a chore: resolve conflicts 2026-07-20 04:53:11 +05:30
Sydney
4d63958c62 fix: translate create button label on tickets page
(cherry picked from commit 2b83c4bb42)

# Conflicts:
#	desk/src/pages/ticket/Tickets.vue
2026-07-19 23:20:33 +00:00
Sydney
00cec608fe fix: strip html comments from agent reply email content
(cherry picked from commit 513bf1c312)
2026-07-19 23:20:32 +00:00
RitvikSardana
a5c623290d Merge pull request #3593 from frappe/mergify/bp/main-hotfix/pr-3562
fix: reuse existing contact as customer primary contact & accurate ticket counts (backport #3562)
2026-07-20 04:49:03 +05:30
Ritvik Sardana
49637ef615 fix: resolve backport conflicts 2026-07-20 04:41:16 +05:30
Ritvik Sardana
b7c7a11975 chore: match prettier indentation, drop unused doc prop, note tablist height coupling
(cherry picked from commit 9fe0925f92)
2026-07-19 23:07:18 +00:00
Ritvik Sardana
04cb546501 fix: ticket count in customer & contact page
(cherry picked from commit b2cd9f35ce)
2026-07-19 23:07:17 +00:00
Ritvik Sardana
2566e2d637 fix: if new contact invited via customer show in toast
(cherry picked from commit 534bc291bc)

# Conflicts:
#	desk/src/components/customer/NewCustomerDialog.vue
2026-07-19 23:07:17 +00:00
Ritvik Sardana
bdd1ce9f6a fix: dont invite primary contact if already exists
(cherry picked from commit 755ac8de7a)

# Conflicts:
#	desk/src/components/customer/NewCustomerDialog.vue
2026-07-19 23:07:17 +00:00
RitvikSardana
3d49cccbf3 Merge pull request #3592 from frappe/mergify/bp/main-hotfix/pr-3555
fix: replace emojis with icons for custom views (backport #3555)
2026-07-20 04:36:20 +05:30
Ritvik Sardana
0b03d540c4 fix: resolve backport conflicts 2026-07-20 04:28:09 +05:30
Ritvik Sardana
a43f0866f4 fix: use clock-alert icon for SLA Alerts view
triangle-alert reads as a generic error and hourglass is already used by
the Pending Tickets view. clock-alert conveys time-based urgency, which
matches SLA breach tracking. Existing sites pick it up via the
rename_and_update_std_views patch.

(cherry picked from commit 36eb9fd89a)
2026-07-19 22:51:01 +00:00
Ritvik Sardana
6ba91c9241 fix: restore customer portal permission banner in sidebar
The sidebar refactor to AppSidebar dropped CustomerPortalPermissionBanner
along with its showPermissionNoticeBanner computed. Restore it in the
footer slot with the original visibility logic (agent portal only,
manager/admin, HD Settings notice flag).

(cherry picked from commit 4767ca00e2)
2026-07-19 22:51:01 +00:00
Ritvik Sardana
93cbcdf58d fix: SavedReply filter
(cherry picked from commit a296498102)
2026-07-19 22:51:00 +00:00
Ritvik Sardana
a2d9d63b36 fix: notification panel wrt sidebar
(cherry picked from commit 8828d53fd7)

# Conflicts:
#	desk/src/stores/sidebar.ts
2026-07-19 22:51:00 +00:00
Ritvik Sardana
c605080208 fix: styles
(cherry picked from commit 698e6d274a)

# Conflicts:
#	desk/src/components/TicketField.vue
2026-07-19 22:50:59 +00:00
Ritvik Sardana
9370044adc fix: update sidebar code with new API
(cherry picked from commit aaa6cdf574)
2026-07-19 22:50:59 +00:00
Ritvik Sardana
7ccaa0619d fix: remove memoji package
(cherry picked from commit 827d865b9b)
2026-07-19 22:50:58 +00:00
Ritvik Sardana
ca7b486caa fix(views): use icons instead of emojis
(cherry picked from commit 8fa03b6478)

# Conflicts:
#	desk/src/components/SidebarLink.vue
#	desk/src/components/UserMenu.vue
#	desk/src/components/ViewModal.vue
#	desk/src/components/layouts/MobileSidebar.vue
#	desk/src/components/layouts/Sidebar.vue
#	desk/src/pages/ticket/Tickets.vue
2026-07-19 22:50:57 +00:00
RitvikSardana
679ac56131 Merge pull request #3591 from frappe/mergify/bp/main-hotfix/pr-3540
fix: agent reply fails on tickets with no prior communication (backport #3540)
2026-07-20 04:20:03 +05:30
Kaushal Shriwas
be31e71f28 fix: agent reply fails on tickets with no prior communication
(cherry picked from commit 18b59372aa)
2026-07-19 22:40:49 +00:00
RitvikSardana
c91f19ab56 Merge pull request #3590 from RitvikSardana/backport/3549-main-hotfix
fix: bump frappe UI to beta-24 (backport #3549)
2026-07-20 04:09:21 +05:30
RitvikSardana
cb14cb6faf Merge pull request #3549 from frappe/upgrade-fui
fix: bump frappe UI to beta-24
2026-07-20 03:55:38 +05:30
RitvikSardana
681fac25fd Merge pull request #3589 from frappe/mergify/bp/main-hotfix/pr-3541
fix: Customer portal permission banner (backport #3541)
2026-07-20 03:41:25 +05:30
Ritvik Sardana
e506798bf1 fix: dont let contact field change by end user
(cherry picked from commit c8fc81655b)
2026-07-19 22:01:27 +00:00
Ritvik Sardana
2057ebf902 fix: copy of dialog
(cherry picked from commit 0635405c64)
2026-07-19 22:01:27 +00:00
Ritvik Sardana
3df5dc6abd fix: bring back guest api call for config
(cherry picked from commit 9475349028)
2026-07-19 22:01:26 +00:00
Ritvik Sardana
94429b8f4d fix: add owner and creation field in bulk creation
(cherry picked from commit a96b6ff8cc)
2026-07-19 22:01:26 +00:00
Ritvik Sardana
5cccb330c1 fix(UI): linked customers in contact page
(cherry picked from commit 10e6f73dc3)
2026-07-19 22:01:26 +00:00
Ritvik Sardana
b93ae88392 fix: remove guest access from get_config
(cherry picked from commit 4606250025)
2026-07-19 22:01:25 +00:00
Ritvik Sardana
f43b5e41d1 fix: null check in field options
(cherry picked from commit 0b37b43932)
2026-07-19 22:01:25 +00:00
Ritvik Sardana
6ba1c725d5 perf: promote contacts to managers with set-based queries
Replace the per-customer document loop with a single child-table
update and a bulk Has Role insert, evicting stale role caches since
bulk_insert skips the ORM. Flip the notice flag via set_single_value
and publish the settings-updated event explicitly.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
(cherry picked from commit 28eb577ee9)
2026-07-19 22:01:25 +00:00
Ritvik Sardana
8089e18975 refactor: use $socket from global store in config store
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
(cherry picked from commit be0b6f7e48)
2026-07-19 22:01:24 +00:00
Ritvik Sardana
08961b9ded fix: update perms on banner
(cherry picked from commit b108f47c7b)
2026-07-19 22:01:24 +00:00
Ritvik Sardana
2e52ce2049 fix: restrict non-agents to their own contact on tickets
(cherry picked from commit a28ad43a50)
2026-07-19 22:01:24 +00:00
Ritvik Sardana
3677801fcc feat: scope ticket customer field to contact's customers on customer portal
(cherry picked from commit 1891b404c0)
2026-07-19 22:01:23 +00:00
Ritvik Sardana
8acc521fca chore: emphasize customer managers term in notice dialog
(cherry picked from commit c81c2dfe19)
2026-07-19 22:01:23 +00:00
Ritvik Sardana
6a0627b472 refactor: guard notice endpoints with agent_manager_only decorator
(cherry picked from commit 82765be52d)
2026-07-19 22:01:22 +00:00
Ritvik Sardana
7213bdc1c0 chore: state previous portal behaviour and shorten checkbox label
(cherry picked from commit 5666f55117)
2026-07-19 22:01:22 +00:00
Ritvik Sardana
beff059c99 chore: simplify notice dialog copy and state what managers can do
(cherry picked from commit 0557912621)
2026-07-19 22:01:22 +00:00
Ritvik Sardana
58e00e848a fix: sidebar banner layout
(cherry picked from commit 5f7a2e671c)
2026-07-19 22:01:22 +00:00
Ritvik Sardana
0db475fc93 feat: link permission update documentation in notice dialog
(cherry picked from commit 1e16325daa)
2026-07-19 22:01:21 +00:00
Ritvik Sardana
cfe8265452 feat: one-time notice for changed customer portal permissions
Agent managers see a sidebar banner explaining the new customer portal
permission model introduced by the customer contact management refactor.
The dialog offers to restore the previous behaviour by promoting every
existing customer contact to customer manager, so contacts can again see
all tickets of their customer.

The notice is enabled by a patch only on sites that have non-manager
customer members (i.e. sites migrated from the old contact model).

(cherry picked from commit 8492e6be56)
2026-07-19 22:01:21 +00:00
RitvikSardana
f63f7e623d Merge pull request #3588 from frappe/mergify/bp/main-hotfix/pr-3543
fix: recent tickets alignment (backport #3543)
2026-07-20 03:30:02 +05:30
RitvikSardana
e5609e66c7 chore: resolve conflicts 2026-07-20 03:28:43 +05:30
Ritvik Sardana
79a58f1943 fix: recent tickets alignment
(cherry picked from commit c26cf84d15)

# Conflicts:
#	desk/src/components/ticket-agent/AssignTo.vue
2026-07-19 21:55:09 +00:00
RitvikSardana
ed04e23cec Merge pull request #3586 from frappe/mergify/bp/main-hotfix/pr-3516
fix: pass uploadFunction prop (backport #3516)
2026-07-20 03:23:29 +05:30
Ritvik Sardana
b61e9095bb fix: null guard check
(cherry picked from commit 8fbf5c2b41)
2026-07-19 21:50:59 +00:00
Ritvik Sardana
9e0a92f3b2 fix: null guard check
(cherry picked from commit 44cfd1d5cb)
2026-07-19 21:50:59 +00:00
Ritvik Sardana
dca56a3d13 fix: pass uploadFunction prop
(cherry picked from commit 1b26e17dc9)
2026-07-19 21:50:58 +00:00
RitvikSardana
df18e26948 Merge pull request #3585 from frappe/mergify/bp/main-hotfix/pr-3515
fix: add auto set customer setting (backport #3515)
2026-07-20 03:19:57 +05:30
RitvikSardana
6416a56edc chore: resolve conflicts 2026-07-20 03:09:25 +05:30
Ritvik Sardana
d5bbb175c8 fix: auto set customer setting
(cherry picked from commit 06b488221e)

# Conflicts:
#	helpdesk/helpdesk/doctype/hd_settings/hd_settings.json
2026-07-19 21:37:48 +00:00
RitvikSardana
e389372b40 Merge pull request #3584 from frappe/mergify/bp/main-hotfix/pr-3514
fix: listview column resize & phone column (backport #3514)
2026-07-20 03:06:47 +05:30
Ritvik Sardana
5492b8b155 fix: listview column resize, phone column & max capping
(cherry picked from commit c4b07a935d)

# Conflicts:
#	desk/tsconfig.json
2026-07-19 21:35:37 +00:00
RitvikSardana
b19a100466 Merge pull request #3583 from frappe/mergify/bp/main-hotfix/pr-3513
fix: restore doctype permissions reverted in #3512 (backport #3513)
2026-07-20 03:04:34 +05:30
RitvikSardana
ceefe2a606 chore: resolve conflicts 2026-07-20 02:58:25 +05:30
Ritvik Sardana
584c4ed51b fix: query HD Ticket instead of Issue in support hour distribution
Restores the report query change from #3502 (reverted in #3512),
matching the report's ref_doctype change to HD Ticket.

(cherry picked from commit a5d4c45cda)
2026-07-19 21:26:34 +00:00
Ritvik Sardana
1bb8665c86 fix: use get_list for permission-aware article category queries
Restores the knowledge base API change from #3502 (reverted in #3512):
get_list enforces user permissions where get_all bypasses them.

(cherry picked from commit c5d09133e5)
2026-07-19 21:26:34 +00:00
Ritvik Sardana
74cafc7c93 fix: restore doctype permissions reverted in #3512
Re-applies the DocType permission changes that were bundled into #3502
and lost when it was reverted (#3512):

- HD Ticket: replace 'All' with 'HD Customer' and 'HD Customer Manager'
- HD View: replace 'Guest' with 'HD Customer' and 'HD Customer Manager'
- HD Article / HD Article Category / HD Ticket Type: add 'HD Customer Manager'
- HD Ticket Template: add 'Agent Manager'

Also restores the Support Hour Distribution report export.

(cherry picked from commit 209bda2bac)

# Conflicts:
#	helpdesk/helpdesk/doctype/hd_view/hd_view.json
2026-07-19 21:26:33 +00:00
RitvikSardana
8f27a81c39 Merge pull request #3582 from frappe/mergify/bp/main-hotfix/pr-3503
fix: set customer only for new tickets (backport #3503)
2026-07-20 02:55:28 +05:30
Ritvik Sardana
c15e1f91b3 fix: update logic
(cherry picked from commit 44571648bf)
2026-07-19 21:16:13 +00:00
Ritvik Sardana
7389ff13ca fix: set customer only for new tickets
(cherry picked from commit 12bc0109d2)
2026-07-19 21:16:13 +00:00
RitvikSardana
cfa26b6fdf Merge pull request #3581 from frappe/mergify/bp/main-hotfix/pr-3501
fix: remove overscroll-behavior (backport #3501)
2026-07-20 02:44:41 +05:30
Ritvik Sardana
baf38ac809 feat: add Read and Select permissions for Agent role on HD Ticket Status
(cherry picked from commit b9a6b2091d)
2026-07-19 21:12:19 +00:00
Ritvik Sardana
9b730c698e fix: remove overscroll-behavior: none to fix scroll chaining issue
(cherry picked from commit 717a967484)
2026-07-19 21:12:18 +00:00
RitvikSardana
1baaf42b09 Merge pull request #3580 from frappe/mergify/bp/main-hotfix/pr-3499
fix: dark mode issues (backport #3499)
2026-07-20 02:41:12 +05:30
Ritvik Sardana
e3a1e228bb fix: return submit promise in remove contact dialog
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
(cherry picked from commit 6d2c88466f)
2026-07-19 21:10:04 +00:00
Ritvik Sardana
428b777328 fix: badge color
(cherry picked from commit 2d99d87fca)
2026-07-19 21:10:03 +00:00
Ritvik Sardana
02e0badb68 fix: dark mode issues
(cherry picked from commit d47ac23c8f)
2026-07-19 21:10:03 +00:00
RitvikSardana
addbdba245 Merge pull request #3579 from frappe/mergify/bp/main-hotfix/pr-3488
fix: dedupe recent tickets, feedback rating by resolution date, staledashboard stats (backport #3488)
2026-07-20 02:38:52 +05:30
Ritvik Sardana
15ca8c90e7 fix: stale tickets
(cherry picked from commit cce4fc77b5)
2026-07-19 21:01:52 +00:00
Ritvik Sardana
a1591c32b5 fix: align feedback trend chart with number-card on resolution_date
get_feedback_trend_data plotted feedback by creation while
get_avg_feedback_score averages by resolution_date, so the trend and the
number card drew from different ticket populations. Key the trend off
resolution_date too so the graph explains the number-card figure.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
(cherry picked from commit 0618c671d8)
2026-07-19 21:01:51 +00:00
Ritvik Sardana
79cd14bfb1 fix: dedup recent tickets, feedback rating by resolution date, stale dashboard stats
- get_recent_tickets: exclude current + org tickets from the raised_by query
  so a ticket matching both customer and raised_by no longer appears twice.
- Dashboard avg feedback rating: filter on resolution_date instead of
  creation, so every ticket resolved in the period is counted regardless of
  when it was raised.
- Dashboard.vue: drop the static frappe-ui cache keys on the stat resources;
  the shared cached instance stayed bound to a previous mount's filters and
  sent stale params after navigating away and back.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
(cherry picked from commit 2ed7cf62fb)
2026-07-19 21:01:51 +00:00
RitvikSardana
85a765b23b Merge pull request #3578 from RitvikSardana/backport-3045
feat!: customer contact management (backport #3045)
2026-07-20 02:30:02 +05:30
Ritvik Sardana
d7cd3c1304 fix: don't delete seeded SLAs in agent home test cleanup 2026-07-20 02:21:30 +05:30
Ritvik Sardana
0867e6ee00 fix: use FrappeTestCase for main-hotfix compatibility 2026-07-20 02:07:07 +05:30
RitvikSardana
81e2805f38 feat!: customer contact management (backport #3045) 2026-07-20 02:00:59 +05:30
RitvikSardana
57e6e13367 Merge pull request #3577 from frappe/mergify/bp/main-hotfix/pr-3475
fix: assigned_on filter (backport #3475)
2026-07-20 01:48:40 +05:30
RitvikSardana
e99cf0ea6b chore: resolve conflicts 2026-07-20 01:40:24 +05:30
Ritvik Sardana
c3152c9b98 fix: filter assigned_on
(cherry picked from commit 7c0d464b19)

# Conflicts:
#	desk/src/components/Settings/Profile/UserEmailSettings.vue
2026-07-19 20:06:09 +00:00
RitvikSardana
db863aaa5d Merge pull request #3576 from frappe/mergify/bp/main-hotfix/pr-3449
fix: add animation in filter component (backport #3449)
2026-07-20 01:33:06 +05:30
Ritvik Sardana
4e79599bc1 fix: initial focus state
(cherry picked from commit 97a4d66caa)
2026-07-19 19:55:07 +00:00
Ritvik Sardana
f924c88fc2 feat: improve filter UX and rename filter module
- transactional replace: keep the existing condition until a new one is
  applied, swapping in place instead of deleting on click
- auto-return to overview after a discrete value pick (equals, is,
  timespan, single date/range)
- operator cycling shortcut moved to Alt/Opt + Up/Down (directional,
  no browser conflict) and works in list mode
- keyboard navigation for the 'Is' (Set/Not Set) list
- loading state for link-field search
- accessibility: listbox/option roles, aria-labels, focus-visible row
  actions, truncation tooltips
- rename filterCore.ts -> filter.ts, useFilterCore -> useFilter

(cherry picked from commit ed255f4de3)
2026-07-19 19:55:07 +00:00
Ritvik Sardana
b9ff084e8b fix: add replace filter functionality
(cherry picked from commit c742146f82)
2026-07-19 19:55:07 +00:00
Ritvik Sardana
21d8562957 fix: add animation in filter component
(cherry picked from commit cd06d9a550)
2026-07-19 19:55:06 +00:00
RitvikSardana
b633781086 Merge pull request #3575 from RitvikSardana/fix/resolve-3573-conflict-markers
fix: resolve conflict markers merged in #3573
2026-07-20 01:24:02 +05:30
Ritvik Sardana
2e9e456713 fix: resolve conflict markers merged in #3573 2026-07-20 01:15:36 +05:30
RitvikSardana
fe829b5079 Merge pull request #3573 from frappe/mergify/bp/main-hotfix/pr-3447
refactor: filter component UX (backport #3447)
2026-07-20 01:09:28 +05:30
Ritvik Sardana
4136d5b5de chore: code cleanup
(cherry picked from commit e0f5c81eac)
2026-07-19 19:39:16 +00:00
Ritvik Sardana
e28972e052 chore: rename component
(cherry picked from commit 22059e455f)
2026-07-19 19:39:16 +00:00
Ritvik Sardana
baf36ba188 refactor: filter component UX
(cherry picked from commit f079593bf0)

# Conflicts:
#	desk/src/components/view-controls/Filter.vue
#	helpdesk/helpdesk/doctype/hd_ticket/api.py
2026-07-19 19:39:15 +00:00
RitvikSardana
44d48df6dd Merge pull request #3572 from frappe/mergify/bp/main-hotfix/pr-3435
fix: allow agents added locally to reflect their status (backport #3435)
2026-07-20 01:05:51 +05:30
Sydney
6ebc3d5748 fix: allow agents added locally to reflect their status
(cherry picked from commit 171aa2a571)
2026-07-19 19:27:04 +00:00
Sydney Gomes
57d553749e Merge pull request #3559 from frappe/mergify/bp/main-hotfix/pr-3530
fix: preserve formatting for thunderbird received emails (backport #3530)
2026-07-17 12:29:51 +05:30
Sydney Gomes
325499cb3d Merge pull request #3560 from frappe/mergify/bp/main-hotfix/pr-3547
fix: ticket SLA policy application (backport #3547)
2026-07-17 12:22:12 +05:30
Sydney Gomes
580a7118e7 Merge pull request #3558 from frappe/mergify/bp/main-hotfix/pr-3529
fix: display proper labels for time elapsed (backport #3529)
2026-07-17 12:21:53 +05:30
Sydney Gomes
184c4d6849 Merge pull request #3557 from frappe/mergify/bp/main-hotfix/pr-3506
fix: redirect responses to correct merged ticket (backport #3506)
2026-07-17 12:21:34 +05:30
Sydney Gomes
807df054aa Merge pull request #3556 from frappe/mergify/bp/main-hotfix/pr-3472
fix: badges having borders & width truncation for texts (backport #3472)
2026-07-17 12:20:57 +05:30
Sydney Gomes
755e076de1 fix: merge conflicts 2026-07-17 12:20:25 +05:30
Sydney
d4c1b8899e test: blank SLA condition must not match ahead of the default SLA
Covers both halves of the catch-all fix: a non-default SLA with a
blank ("" or NULL) condition never matches a ticket, and demoting the
seeded "Default" SLA by promoting a new default doesn't leave the
demoted one winning every ticket.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
(cherry picked from commit d73f46742a)
2026-07-17 06:42:25 +00:00
Sydney
f12e657753 fix: default SLA checkbox double-toggles and never actually flips
(cherry picked from commit 5f63b65017)
2026-07-17 06:42:25 +00:00
Sydney
21dd194473 fix: don't let a blank SLA condition act as an implicit catch-all
An enabled, non-default SLA with no condition was matching every
ticket ahead of the actual default SLA, since a blank condition
short-circuited to "always match" in the loop. This is most visible
when the seeded "Default" SLA is demoted (a different SLA is flagged
default_sla) but keeps its blank condition — it then silently wins
for every ticket regardless of which SLA is now marked default.

Only SLAs with a real condition can be matched this way now; a blank
condition no longer qualifies as a candidate, leaving default_sla as
the only legitimate catch-all.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
(cherry picked from commit 00d7bb5c84)
2026-07-17 06:42:25 +00:00
Sydney
d5e9529138 fix: add pre-wrap to maintain spacing formatting
(cherry picked from commit dbac204a35)
2026-07-17 06:41:34 +00:00
Sydney
b9dd16b00d fix: add consistent variable naming
(cherry picked from commit c087f6fe10)
2026-07-17 06:41:34 +00:00
Sydney
88f682d7a5 fix: add support for thunderbird mails in replied content
(cherry picked from commit 18ca7518c3)
2026-07-17 06:41:33 +00:00
Sydney
4c4d53dcb4 fix: preserve line-height for thunderbird mails
(cherry picked from commit 0939bf8ff7)

# Conflicts:
#	desk/src/components/EmailContent.vue
2026-07-17 06:41:33 +00:00
Sydney
9cb6887023 fix: preserve formatting for thunderbird received emails
(cherry picked from commit bd22cf47df)
2026-07-17 06:41:33 +00:00
Sydney
552094eca6 fix: display proper labels for time elapsed
(cherry picked from commit 64d4499627)
2026-07-17 06:40:59 +00:00
Sydney
10b8bc17fb fix: correct invalid Check field default in HD Ticket
raised_outside_working_hours had default "False", which Frappe rejects
for Check fields (must be "0"/"1"). This broke any save_customization()
on HD Ticket, failing the field dependency form-script tests.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
(cherry picked from commit 4951c74712)
2026-07-17 06:39:40 +00:00
Sydney
c544ecc01e fix: handle replies when merge target can't be resolved
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
(cherry picked from commit 6610c58c7c)
2026-07-17 06:39:40 +00:00
Sydney
3664a8be26 fix: correctly route replies to merged tickets to the merge target
(cherry picked from commit 4819dfca35)
2026-07-17 06:39:40 +00:00
Sydney
ad4d17a95a test: add test cases for routing to correct communication
(cherry picked from commit 076cdc759f)
2026-07-17 06:39:40 +00:00
Sydney
c227e430ab fix: redirect replies on merged tickets to the merge target
(cherry picked from commit 644ce7926c)
2026-07-17 06:39:39 +00:00
Sydney
4f39f31278 fix: badges having borders & width truncation for texts
(cherry picked from commit 38341f6483)
2026-07-17 06:39:26 +00:00
RitvikSardana
6b423f8fba Merge pull request #3536 from frappe/mergify/bp/main/pr-3533
chore: add aerodeval as authorised user (backport #3533)
2026-07-12 01:59:40 +05:30
RitvikSardana
6d1e309425 Merge pull request #3535 from frappe/mergify/bp/main-hotfix/pr-3533
chore: add aerodeval as authorised user (backport #3533)
2026-07-12 01:59:29 +05:30
Sydney Gomes
ff66ab9ac0 Update workflow automation rules
Signed-off-by: Sydney Gomes <null>
(cherry picked from commit 47d5c70d02)
2026-07-10 10:42:32 +00:00
Sydney Gomes
9d53f46b0a Update workflow automation rules
Signed-off-by: Sydney Gomes <null>
(cherry picked from commit 47d5c70d02)
2026-07-10 10:42:21 +00:00
Frappe PR Bot
518c1c9758 chore(release): Bumped to Version 1.27.0 2026-07-10 10:35:12 +00:00
RitvikSardana
133eb369fb Merge pull request #3532 from frappe/main-hotfix
chore(release): hotfix to main
2026-07-10 16:04:44 +05:30
RitvikSardana
9642f96fc6 Merge branch 'main' into main-hotfix 2026-07-10 15:52:13 +05:30
Sydney Gomes
094eb5355d Merge pull request #3534 from aerodeval/fix/assign-to-single-agent-crash
fix: prevent AssignTo crash when current user is the only agent
2026-07-10 14:48:25 +05:30
Sydney
9e590d75d4 fix: prevent AssignTo crash when current user is the only agent
The dedup Set in agentOptions was renamed to `options` but the
current-agent branch still called `seen.add(...)`, which throws since
`seen` no longer exists. Vue then caches the failed computed as
undefined, so a re-render hits sortedAgentOptions.length on undefined —
surfacing as "Cannot read properties of undefined (reading 'length')".
Only triggers when the session user is themselves an agent.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-10 14:29:49 +05:30
Sydney Gomes
97ef107d35 Merge pull request #3511 from frappe/mergify/bp/main-hotfix/pr-3500
refactor: fetching agent availability (backport #3500)
2026-06-29 02:36:15 +05:30
Sydney
577467ea20 fix: remove duplicate import 2026-06-29 02:26:05 +05:30
Sydney Gomes
66613a5934 fix: merge conflicts 2026-06-29 02:15:30 +05:30
Sydney Gomes
df72dbb868 Merge pull request #3510 from frappe/mergify/bp/main-hotfix/pr-3448
fix: UI bugs (backport #3448)
2026-06-29 02:08:02 +05:30
Sydney Gomes
ad958d2a19 fix: merge conflicts 2026-06-29 01:59:19 +05:30
Sydney
1941ad4e05 fix: use onError instead of catch for promise rejection in setAvailability
(cherry picked from commit 9d1cbecc24)
2026-06-28 20:14:00 +00:00
Sydney
61ae0e3cff fix: drop redundant per ticket fetch for current agent in AssignTo
(cherry picked from commit 01ad287670)

# Conflicts:
#	desk/src/components/ticket-agent/AssignTo.vue
2026-06-28 20:14:00 +00:00
Sydney
6228dc722e refactor: update frontend to read availability from store
(cherry picked from commit 4b38d0c1f9)

# Conflicts:
#	desk/src/components/Settings/Profile/Profile.vue
2026-06-28 20:13:59 +00:00
Sydney
f3bdbd0b1b refactor: seed agent availability from session
(cherry picked from commit d2ea0ecd8d)

# Conflicts:
#	helpdesk/api/auth.py
2026-06-28 20:13:59 +00:00
Sydney
d1eafaa6aa fix: increase width for labels
(cherry picked from commit 342b0566f9)
2026-06-28 20:13:33 +00:00
Sydney
ed614e5a59 fix: add borders to customer fields
(cherry picked from commit 5dee0bf042)
2026-06-28 20:13:33 +00:00
Sydney
5e4bcc6dba fix: delete ticket error
(cherry picked from commit 3c2b1477cd)
2026-06-28 20:13:33 +00:00
Sydney
1e34589e20 Revert "fix: sidebar fc banner spacing"
This reverts commit e2b5619cc6.

(cherry picked from commit e3b9d8d01a)
2026-06-28 20:13:33 +00:00
Sydney
b2cb1cc981 fix: spacing and alligment for tabs
(cherry picked from commit a1ed7f5623)
2026-06-28 20:13:32 +00:00
Sydney
ec3c6565ba fix: improve customer portal layouting
(cherry picked from commit 6c3d8e7bc6)

# Conflicts:
#	desk/src/pages/ticket/TicketCustomer.vue
2026-06-28 20:13:32 +00:00
Sydney
182db14d74 fix: add back toggle theme to customer portal
(cherry picked from commit 2c8c6b7266)
2026-06-28 20:13:32 +00:00
Sydney
62403c9f31 fix: broken switches in field dependency and assignment rules
(cherry picked from commit cb7490ccb2)

# Conflicts:
#	desk/src/components/Settings/FieldDependency/FieldDependencyList.vue
2026-06-28 20:13:31 +00:00
Sydney
dd4d2bad16 fix: assign to agent indicators fix
(cherry picked from commit e93aaad32b)
2026-06-28 20:13:31 +00:00
Sydney
ce323770c5 fix: sidebar fc banner spacing
(cherry picked from commit e2b5619cc6)
2026-06-28 20:13:31 +00:00
Sydney
940645af86 fix: collapsed response 3 dots to be added
(cherry picked from commit 9160028ef7)
2026-06-28 20:13:30 +00:00
Sydney Gomes
b58204882a Merge pull request #3509 from frappe/mergify/bp/main-hotfix/pr-3431
fix: improve agent status UX (backport #3431)
2026-06-29 01:42:19 +05:30
Sydney
a89b995887 fix: dont show toast when self assigning a ticket
(cherry picked from commit e3b9e4047f)
2026-06-28 20:01:49 +00:00
Sydney
31a1f7ac82 fix: improve ux copy of tooltip
(cherry picked from commit 6ba980ec49)
2026-06-28 20:01:49 +00:00
Sydney
e6cfbcb974 fix: improve ux of the HD agent status doctype
(cherry picked from commit 60b4a0975e)
2026-06-28 20:01:49 +00:00
Sydney Gomes
ed907b1915 Merge pull request #3508 from frappe/mergify/bp/main-hotfix/pr-3439
fix: avoid calling agent availability for customer (backport #3439)
2026-06-29 01:27:16 +05:30
Sydney
3997225252 fix: avoid calling agent availability for customer
(cherry picked from commit b01cde3cad)
2026-06-28 19:47:17 +00:00
Sydney Gomes
c98239e895 Merge pull request #3507 from frappe/mergify/bp/main-hotfix/pr-3372
feat: agent  availability status (backport #3372)
2026-06-29 01:14:42 +05:30
Sydney
7f7e392dde fix: linter issues 2026-06-29 00:53:34 +05:30
Sydney Gomes
985ab90721 fix: merge conflicts 2026-06-29 00:34:53 +05:30
Sydney
9567012c5c fix: display availability select to only agents with HD agent
(cherry picked from commit 48cc2068b6)
2026-06-28 18:37:59 +00:00
Sydney
88bea73fcf fix: string for availability status
(cherry picked from commit 3d113d29f2)
2026-06-28 18:37:59 +00:00
Sydney
e89df08d59 fix: failing test cases
(cherry picked from commit 81b85f259f)
2026-06-28 18:37:58 +00:00
Sydney
1b50ce8fc2 fix: bulk update agent status in patch
(cherry picked from commit 5a7bfe0d4e)
2026-06-28 18:37:58 +00:00
Sydney
8e5fc050d8 fix: chage agent status order to status_order and its weights
(cherry picked from commit 379d5a25d3)
2026-06-28 18:37:58 +00:00
Sydney
cf09a210d4 fix: have atleast one active category available & enabled
(cherry picked from commit 14b39007d3)
2026-06-28 18:37:57 +00:00
Sydney
51f77f61ad fix: move make_status to test_utils
(cherry picked from commit 11de600874)
2026-06-28 18:37:57 +00:00
Sydney
2ea5d219b1 fix: delay toast of assignment succesful for away agents
(cherry picked from commit d4a22633eb)
2026-06-28 18:37:56 +00:00
Sydney
ee91203e3f fix: allow hd agent manager to create and edit status
(cherry picked from commit 7c1851c150)
2026-06-28 18:37:56 +00:00
Sydney
378136dbc7 fix: add setup and teardown for testcases
(cherry picked from commit 10441bdaca)
2026-06-28 18:37:56 +00:00
Sydney
bcdce16a67 fix: use frappe intergration testcase
(cherry picked from commit 3cc3b2307c)
2026-06-28 18:37:56 +00:00
Sydney
a174628e1d fix: user frappe intergration testcase
(cherry picked from commit 477f850b36)
2026-06-28 18:37:55 +00:00
Sydney
f3bf9dcbeb fix: improve mobile experience and code cleanup
(cherry picked from commit de6ed69a32)
2026-06-28 18:37:55 +00:00
Sydney
570df8fd46 refactor: use socket communicaiton to update agnet status
(cherry picked from commit 7bbc3129cc)
2026-06-28 18:37:54 +00:00
Sydney
d36b69ff46 fix: add get_agent_name in utils
(cherry picked from commit 599f8d11e4)
2026-06-28 18:37:54 +00:00
Sydney
345f9854b4 fix: imrove tooltip copy
(cherry picked from commit 14c1b1a6b0)
2026-06-28 18:37:54 +00:00
Sydney
f274879726 fix: allow default status to be set
(cherry picked from commit 9ec4bbe5f5)
2026-06-28 18:37:53 +00:00
Sydney
18d21689a6 fix: improve tooltip copy
(cherry picked from commit 374749adae)
2026-06-28 18:37:53 +00:00
Sydney
985d29c578 fix: update agent status & add tests
(cherry picked from commit 6c996e9f71)
2026-06-28 18:37:53 +00:00
Sydney
cd1dbfbcd5 fix: reallign with new hd status category
(cherry picked from commit 2be0694fe0)
2026-06-28 18:37:53 +00:00
Sydney
3b998f4e66 feat: add availability menu to profile and bring prreferences section to frontend
(cherry picked from commit 341591faf2)

# Conflicts:
#	desk/src/components/Settings/settingsModal.ts
#	desk/src/components/ticket-agent/AssignTo.vue
2026-06-28 18:37:52 +00:00
Sydney
7c230cdab2 fix: use agent status from HD Agent Status
(cherry picked from commit 75e4bbebec)
2026-06-28 18:37:52 +00:00
Sydney
12eb2f63c9 fix: connect HD Agent with HD Agent status
(cherry picked from commit 5b2800b6a4)
2026-06-28 18:37:51 +00:00
Sydney
b248d39fda feat: create HD Ticket Agent Status
(cherry picked from commit c0cca4c07a)
2026-06-28 18:37:51 +00:00
Sydney
c50371cfbd Revert "feat: add open tickets and avg first response in agents tab"
This reverts commit 85edb100f2.

(cherry picked from commit 065026b2b6)

# Conflicts:
#	desk/src/components/Settings/Agents.vue
2026-06-28 18:37:51 +00:00
Sydney
fe4a968289 feat: add open tickets and avg first response in agents tab
(cherry picked from commit 85edb100f2)

# Conflicts:
#	desk/src/components/Settings/Agents.vue
2026-06-28 18:37:51 +00:00
Sydney
2128002811 feat: calculate and display time from agent status change
(cherry picked from commit 9d970c5144)

# Conflicts:
#	desk/src/components/ticket-agent/AssignTo.vue
2026-06-28 18:37:50 +00:00
Sydney
37e2a83489 feat: add functionality for busy agents
(cherry picked from commit 4d394a0414)
2026-06-28 18:37:50 +00:00
Sydney
dec5dc43f2 test: add testcases for agent status
(cherry picked from commit 779d4a0662)

# Conflicts:
#	helpdesk/helpdesk/doctype/hd_agent/test_hd_agent.py
2026-06-28 18:37:50 +00:00
Sydney
dd7d7431a1 fix: generalize toast warnings for assign to modal
(cherry picked from commit b9fe65d96f)
2026-06-28 18:37:49 +00:00
Sydney
69a1404237 fix: change status name and display status in profile
(cherry picked from commit 83ec1baab7)
2026-06-28 18:37:49 +00:00
Sydney
a5272732b1 fix: use dropdown instead of select for agent status
(cherry picked from commit 0c6d1ba23b)
2026-06-28 18:37:49 +00:00
Sydney
5ca4302865 feat: add agent status indicators to frontend
(cherry picked from commit 630704fb4f)

# Conflicts:
#	desk/src/components/Settings/Profile/Profile.vue
2026-06-28 18:37:48 +00:00
Sydney
d31187a14b fix: add agent availabilty menu and color map for options
(cherry picked from commit e2dd43be18)
2026-06-28 18:37:48 +00:00
Sydney
f617f54adb fix: generalize filter for assignment rule in override
(cherry picked from commit 39adf83470)
2026-06-28 18:37:48 +00:00
Sydney
d5ce6e55d5 fix: override assignment rule for filtering out away agents
(cherry picked from commit 266adf8842)
2026-06-28 18:37:48 +00:00
Sydney
061f023b90 feat: handle manual assignment for away agents
(cherry picked from commit a9268b8621)

# Conflicts:
#	desk/src/components/ticket-agent/AssignTo.vue
2026-06-28 18:37:47 +00:00
Sydney
d9b946102b fix: add agent availability
(cherry picked from commit c7e1861fc8)
2026-06-28 18:37:47 +00:00
RitvikSardana
09ebb275ea Merge pull request #3495 from frappe/mergify/bp/main-hotfix/pr-3490
chore: update POT file (backport #3490)
2026-06-22 12:37:16 +05:30
frappe-pr-bot
a4862ba69a chore: update POT file
(cherry picked from commit a9d5d68a17)
2026-06-22 07:06:26 +00:00
RitvikSardana
d9c9edc07a Merge pull request #3494 from frappe/mergify/bp/main-hotfix/pr-3478
chore: sync translations from crowdin (backport #3478)
2026-06-22 12:35:17 +05:30
MochaMind
8df3228f71 chore: Bosnian translations
(cherry picked from commit 6187001eef)
2026-06-22 07:04:56 +00:00
MochaMind
074cb53294 chore: Croatian translations
(cherry picked from commit 25f6b212e5)
2026-06-22 07:04:55 +00:00
MochaMind
1c3e987863 chore: Persian translations
(cherry picked from commit 61ba2d37de)
2026-06-22 07:04:55 +00:00
MochaMind
b70a3143a4 chore: Portuguese translations
(cherry picked from commit 920fa0d928)
2026-06-22 07:04:55 +00:00
MochaMind
0671e7495f chore: Italian translations
(cherry picked from commit a3ac0b47ef)
2026-06-22 07:04:54 +00:00
MochaMind
e952bd25be chore: Swedish translations
(cherry picked from commit 4df56477f0)
2026-06-22 07:04:54 +00:00
MochaMind
cfe2875447 chore: Swedish translations
(cherry picked from commit e7f2bafe49)
2026-06-22 07:04:54 +00:00
MochaMind
c00d7865e7 chore: Bosnian translations
(cherry picked from commit 35c777ac49)
2026-06-22 07:04:54 +00:00
MochaMind
9ca4d02cfb chore: Croatian translations
(cherry picked from commit 21cfccb16e)
2026-06-22 07:04:53 +00:00
MochaMind
f3f559bfa6 chore: Bosnian translations
(cherry picked from commit a2ad9a9448)
2026-06-22 07:04:53 +00:00
MochaMind
19f7f95461 chore: Esperanto translations
(cherry picked from commit ac8f4b041c)
2026-06-22 07:04:53 +00:00
MochaMind
9cf263f7b4 chore: Serbian (Latin) translations
(cherry picked from commit 9f08f171a1)
2026-06-22 07:04:52 +00:00
MochaMind
4fa0ad25fa chore: Norwegian Bokmal translations
(cherry picked from commit 356a53b816)
2026-06-22 07:04:52 +00:00
MochaMind
d779f81b58 chore: Bosnian translations
(cherry picked from commit 67a8d95c34)
2026-06-22 07:04:52 +00:00
MochaMind
5e7534275d chore: Burmese translations
(cherry picked from commit 7c5c1439df)
2026-06-22 07:04:51 +00:00
MochaMind
666ef849f8 chore: Hindi translations
(cherry picked from commit 8719d7d67c)
2026-06-22 07:04:51 +00:00
MochaMind
aa60afade9 chore: Croatian translations
(cherry picked from commit a62c796d14)
2026-06-22 07:04:51 +00:00
MochaMind
7489a3efec chore: Thai translations
(cherry picked from commit ae9b6ae999)
2026-06-22 07:04:51 +00:00
MochaMind
a390789e42 chore: Persian translations
(cherry picked from commit 1c9916bed0)
2026-06-22 07:04:50 +00:00
MochaMind
b4f4631b5b chore: Indonesian translations
(cherry picked from commit 691d2f8c00)
2026-06-22 07:04:50 +00:00
MochaMind
341bb5d3c5 chore: Portuguese, Brazilian translations
(cherry picked from commit 8b4b199f89)
2026-06-22 07:04:50 +00:00
MochaMind
5edc6ffabf chore: Vietnamese translations
(cherry picked from commit 6292eb9a43)
2026-06-22 07:04:49 +00:00
MochaMind
4273a0a0ae chore: Chinese Simplified translations
(cherry picked from commit 499a7aaebb)
2026-06-22 07:04:49 +00:00
MochaMind
4f2b175dc7 chore: Turkish translations
(cherry picked from commit 8742d4b87e)
2026-06-22 07:04:49 +00:00
MochaMind
165993bde4 chore: Swedish translations
(cherry picked from commit 200346f101)
2026-06-22 07:04:48 +00:00
MochaMind
a846e82706 chore: Serbian (Cyrillic) translations
(cherry picked from commit d101e659f4)
2026-06-22 07:04:48 +00:00
MochaMind
019fb2b542 chore: Slovenian translations
(cherry picked from commit 2c66ac9eff)
2026-06-22 07:04:48 +00:00
MochaMind
7793ba82d7 chore: Russian translations
(cherry picked from commit 903ee9fad3)
2026-06-22 07:04:48 +00:00
MochaMind
48cc0afdbd chore: Portuguese translations
(cherry picked from commit ba46e54248)
2026-06-22 07:04:47 +00:00
MochaMind
e1b8d801b8 chore: Polish translations
(cherry picked from commit 1fb6e69345)
2026-06-22 07:04:47 +00:00
MochaMind
e1b5e66292 chore: Dutch translations
(cherry picked from commit 23e8443342)
2026-06-22 07:04:47 +00:00
MochaMind
10dafcc025 chore: Korean translations
(cherry picked from commit d158336851)
2026-06-22 07:04:46 +00:00
MochaMind
63b8977094 chore: Italian translations
(cherry picked from commit 447d8ce540)
2026-06-22 07:04:46 +00:00
MochaMind
d6e8e5fe75 chore: Hungarian translations
(cherry picked from commit 7d6633975c)
2026-06-22 07:04:46 +00:00
MochaMind
fb810bb5b6 chore: German translations
(cherry picked from commit 2ab9ea47af)
2026-06-22 07:04:45 +00:00
MochaMind
fe5c0b9e47 chore: Danish translations
(cherry picked from commit cf04339d30)
2026-06-22 07:04:45 +00:00
MochaMind
77e9862f71 chore: Czech translations
(cherry picked from commit 8647b7247e)
2026-06-22 07:04:45 +00:00
MochaMind
48d5a41288 chore: Arabic translations
(cherry picked from commit 1101402b97)
2026-06-22 07:04:45 +00:00
MochaMind
618e4a4a7e chore: Spanish translations
(cherry picked from commit c4c134b858)
2026-06-22 07:04:44 +00:00
MochaMind
76d29e7eac chore: French translations
(cherry picked from commit 3101a55d48)
2026-06-22 07:04:44 +00:00
RitvikSardana
47aaf15b1e Merge pull request #3493 from frappe/mergify/bp/main/pr-3492
fix: add missing imports (backport #3492)
2026-06-22 12:33:39 +05:30
RitvikSardana
9868507cec chore: resolve conflicts 2026-06-22 12:33:12 +05:30
Ritvik Sardana
d058478cd5 chore: bump version
(cherry picked from commit 99e94b21a9)

# Conflicts:
#	helpdesk/__init__.py
2026-06-22 07:01:42 +00:00
Ritvik Sardana
633f83218d fix: add missing imports
(cherry picked from commit 9a8ef23c8b)
2026-06-22 07:01:42 +00:00
RitvikSardana
1e14633039 Merge pull request #3492 from RitvikSardana/missing-import
fix: add missing imports
2026-06-22 12:31:22 +05:30
Ritvik Sardana
99e94b21a9 chore: bump version 2026-06-22 12:30:19 +05:30
Ritvik Sardana
9a8ef23c8b fix: add missing imports 2026-06-22 12:28:03 +05:30
Frappe PR Bot
fa7fe76c83 chore(release): Bumped to Version 1.26.1 2026-06-17 10:27:36 +00:00
Sydney Gomes
27f771f6f7 Merge pull request #3484 from frappe/main-hotfix
chore(release): hotfix to main
2026-06-17 15:57:04 +05:30
Sydney Gomes
ca44c12862 Merge pull request #3485 from frappe/mergify/bp/main-hotfix/pr-3481
fix: ticket unexpectedly auto-closed due to inactivity (backport #3481)
2026-06-17 15:48:37 +05:30
Sydney
b6f0228d7f fix: deploy type issue 2026-06-17 15:39:47 +05:30
Sydney
b8538b5ed8 fix: linter issues
(cherry picked from commit f106e04c04)
2026-06-17 09:29:31 +00:00
Sydney
9d9d3cfd25 fix: remove failing lint file:
(cherry picked from commit 0b191398e3)
2026-06-17 09:29:30 +00:00
Sydney
7d213e5a9f fix: update all communications for the ticket
(cherry picked from commit d216bbd0a3)
2026-06-17 09:29:30 +00:00
Sydney
eec28340b2 fix: compute auto-close inactivity cutoff in system timezone
(cherry picked from commit 6d0ed2ea83)
2026-06-17 09:29:30 +00:00
RitvikSardana
fb0d6e48de Merge pull request #3477 from frappe/mergify/bp/main-hotfix/pr-3474
chore: sync translations from crowdin (backport #3474)
2026-06-15 16:17:45 +05:30
MochaMind
b5f20223d7 chore: Esperanto translations
(cherry picked from commit 048e090978)
2026-06-15 07:55:56 +00:00
MochaMind
6c44a0796c chore: Serbian (Latin) translations
(cherry picked from commit 14313d1512)
2026-06-15 07:55:56 +00:00
MochaMind
bc63c9daea chore: Norwegian Bokmal translations
(cherry picked from commit 0f367d3ee8)
2026-06-15 07:55:56 +00:00
MochaMind
2f394bdb2a chore: Bosnian translations
(cherry picked from commit 2032f0e6ce)
2026-06-15 07:55:55 +00:00
MochaMind
163cab81bf chore: Burmese translations
(cherry picked from commit c20df2883a)
2026-06-15 07:55:55 +00:00
MochaMind
e112cf12d6 chore: Hindi translations
(cherry picked from commit a8fe77ed04)
2026-06-15 07:55:55 +00:00
MochaMind
c7f09d0fd6 chore: Croatian translations
(cherry picked from commit 996f3cafd3)
2026-06-15 07:55:55 +00:00
MochaMind
31b90b25c8 chore: Thai translations
(cherry picked from commit 988c9dff77)
2026-06-15 07:55:54 +00:00
MochaMind
2f1ef7b365 chore: Persian translations
(cherry picked from commit 3b3fda017e)
2026-06-15 07:55:54 +00:00
MochaMind
7a611d42ba chore: Indonesian translations
(cherry picked from commit 69be149305)
2026-06-15 07:55:54 +00:00
MochaMind
af0e85a497 chore: Portuguese, Brazilian translations
(cherry picked from commit da5f35cff8)
2026-06-15 07:55:53 +00:00
MochaMind
ded9f7c8f0 chore: Vietnamese translations
(cherry picked from commit d696354a08)
2026-06-15 07:55:53 +00:00
MochaMind
080a14badb chore: Chinese Simplified translations
(cherry picked from commit 8518cdee98)
2026-06-15 07:55:53 +00:00
MochaMind
372dbc5044 chore: Turkish translations
(cherry picked from commit 2f3ece2b72)
2026-06-15 07:55:52 +00:00
MochaMind
ce9a035994 chore: Swedish translations
(cherry picked from commit 06334aa8d3)
2026-06-15 07:55:52 +00:00
MochaMind
9c49a747b7 chore: Serbian (Cyrillic) translations
(cherry picked from commit c960ec66ee)
2026-06-15 07:55:52 +00:00
MochaMind
a2ce982bfe chore: Slovenian translations
(cherry picked from commit ad85f77a19)
2026-06-15 07:55:51 +00:00
MochaMind
8485481432 chore: Russian translations
(cherry picked from commit 5ac09b533a)
2026-06-15 07:55:51 +00:00
MochaMind
e5e25f05b5 chore: Portuguese translations
(cherry picked from commit 0fe243c076)
2026-06-15 07:55:51 +00:00
MochaMind
13d9439e25 chore: Polish translations
(cherry picked from commit 77321ebe91)
2026-06-15 07:55:50 +00:00
MochaMind
94c4661cfc chore: Dutch translations
(cherry picked from commit 5921597d4a)
2026-06-15 07:55:50 +00:00
MochaMind
e4ebfb9046 chore: Korean translations
(cherry picked from commit 57d76f6739)
2026-06-15 07:55:50 +00:00
MochaMind
60245a09eb chore: Italian translations
(cherry picked from commit bd29aa9f6a)
2026-06-15 07:55:50 +00:00
MochaMind
94845cacc6 chore: Hungarian translations
(cherry picked from commit ab56e09cb7)
2026-06-15 07:55:49 +00:00
MochaMind
d46b1a527b chore: German translations
(cherry picked from commit faf3a1e9f6)
2026-06-15 07:55:49 +00:00
MochaMind
5e0863738d chore: Danish translations
(cherry picked from commit 6c16a8e0f5)
2026-06-15 07:55:49 +00:00
MochaMind
8b8fe37bd5 chore: Czech translations
(cherry picked from commit c455caf515)
2026-06-15 07:55:48 +00:00
MochaMind
457293777e chore: Arabic translations
(cherry picked from commit 312e7cfdd4)
2026-06-15 07:55:48 +00:00
MochaMind
4200e9932d chore: Spanish translations
(cherry picked from commit e753544ddf)
2026-06-15 07:55:48 +00:00
MochaMind
496c9747b1 chore: French translations
(cherry picked from commit 5d45612436)
2026-06-15 07:55:48 +00:00
RitvikSardana
626108c53a Merge pull request #3476 from frappe/mergify/bp/main-hotfix/pr-3473
chore: update POT file (backport #3473)
2026-06-15 13:15:20 +05:30
RitvikSardana
1a3455df30 chore: resolve conflicts 2026-06-15 13:08:58 +05:30
frappe-pr-bot
ec708011d7 chore: update POT file
(cherry picked from commit c0af24a43d)

# Conflicts:
#	helpdesk/locale/main.pot
2026-06-15 07:36:23 +00:00
RitvikSardana
f4cba24df6 Merge pull request #3469 from frappe/main-hotfix
chore(release): hotfix to main
2026-06-11 23:47:19 +05:30
RitvikSardana
f96798dad4 Merge branch 'main' into main-hotfix 2026-06-11 23:38:37 +05:30
RitvikSardana
b937b1b870 chore: version bump 2026-06-11 23:37:59 +05:30
RitvikSardana
ad05bdbe90 Merge pull request #3471 from frappe/mergify/bp/main-hotfix/pr-3412
chore: update POT file (backport #3412)
2026-06-11 23:28:35 +05:30
frappe-pr-bot
c50e8636bd chore: update POT file
(cherry picked from commit 49eb0f257f)
2026-06-11 17:57:46 +00:00
RitvikSardana
d49570e199 Merge pull request #3470 from frappe/mergify/bp/main-hotfix/pr-3410
chore: sync translations from crowdin (backport #3410)
2026-06-11 23:27:17 +05:30
MochaMind
802bb87646 chore: Hungarian translations
(cherry picked from commit 8e46d58491)
2026-06-11 17:56:07 +00:00
MochaMind
059c17fa13 chore: Swedish translations
(cherry picked from commit f13a64d23e)
2026-06-11 17:56:07 +00:00
MochaMind
918c243220 chore: Hungarian translations
(cherry picked from commit 3aef20c244)
2026-06-11 17:56:06 +00:00
MochaMind
5ca75b8881 chore: Chinese Simplified translations
(cherry picked from commit a2dc3d34ac)
2026-06-11 17:56:06 +00:00
MochaMind
483385cc24 chore: Hungarian translations
(cherry picked from commit 4451389e9e)
2026-06-11 17:56:06 +00:00
MochaMind
792bb9162b chore: Korean translations
(cherry picked from commit 37f174cddd)
2026-06-11 17:56:05 +00:00
MochaMind
4c6dc853db chore: Czech translations
(cherry picked from commit bc99a267e3)
2026-06-11 17:56:05 +00:00
MochaMind
3c290fdcd8 chore: Hungarian translations
(cherry picked from commit c8d0d91185)
2026-06-11 17:56:04 +00:00
RitvikSardana
c2d1978d27 Merge pull request #3468 from RitvikSardana/cleanup-helpdesk-ui-hotfix
fix: cleanup helpdesk UI (backport #3248)
2026-06-11 21:00:04 +05:30
Ritvik Sardana
d39d384f04 fix: cleanup helpdesk UI (#3248) 2026-06-11 20:22:23 +05:30
RitvikSardana
0fd5482fff Merge pull request #3467 from frappe/mergify/bp/main-hotfix/pr-3446
fix(field-dependency): show selected values first, refresh options (backport #3446)
2026-06-11 20:21:54 +05:30
RitvikSardana
b237c38dd1 Merge pull request #3466 from frappe/mergify/bp/main-hotfix/pr-3394
feat: bulk reply (backport #3394)
2026-06-11 20:21:37 +05:30
RitvikSardana
76ab7ff40f chore: code cleanup 2026-06-11 20:11:59 +05:30
RitvikSardana
649627fe17 chore: resolve conflicts 2026-06-11 20:09:20 +05:30
RitvikSardana
725974efdd chore: resolve conflicts 2026-06-11 20:06:45 +05:30
Ritvik Sardana
bb63b2cfbe fix(field-dependency): show selected values first, refresh options, fix toggle
- Order child values that were selected on load to the top, frozen to the
  saved selections so the list does not reorder while toggling
- Clear the cached field options when the editor mounts so newly created
  link/select values (e.g. a new ticket type) appear instead of stale ones
- Update the list-view enabled toggle to reflect state locally so disabling
  actually persists (the controlled Switch was re-sending the same value)

(cherry picked from commit 1140533f1b)
2026-06-11 14:33:41 +00:00
RitvikSardana
4a4348f26e chore: resolve conflicts 2026-06-11 20:02:07 +05:30
Ritvik Sardana
babbee8ca6 fix: attachment logic
(cherry picked from commit cbf8324eba)
2026-06-11 14:28:53 +00:00
Ritvik Sardana
c831ad0bb4 chore: remove md file
(cherry picked from commit bae7d65b73)
2026-06-11 14:28:53 +00:00
Ritvik Sardana
6bc26784f7 fix: test case
(cherry picked from commit aa90218ec8)
2026-06-11 14:28:53 +00:00
Ritvik Sardana
adba515eaf test: bulk reply
(cherry picked from commit 8b68e28ac4)

# Conflicts:
#	helpdesk/test_utils.py
2026-06-11 14:28:53 +00:00
Ritvik Sardana
ff1461db1a refactor: bulk reply modal
(cherry picked from commit 47e543629f)
2026-06-11 14:28:52 +00:00
Ritvik Sardana
29a16a4fcf chore: code cleanup
(cherry picked from commit 4994e03ef5)
2026-06-11 14:28:52 +00:00
Ritvik Sardana
3dc9115b70 fix: save reply in local storage
(cherry picked from commit eb8d647c64)
2026-06-11 14:28:52 +00:00
Ritvik Sardana
cf42834fad fix: better logging message
(cherry picked from commit d7c5c1e32e)
2026-06-11 14:28:51 +00:00
Ritvik Sardana
a1e0a5ceb5 fix: better defaults
(cherry picked from commit 2d0552fa91)
2026-06-11 14:28:51 +00:00
Ritvik Sardana
511361ebde fix: bulk reply icon
(cherry picked from commit 5efaf89e4d)

# Conflicts:
#	desk/src/components/AttachmentItem.vue
2026-06-11 14:28:51 +00:00
Ritvik Sardana
2decada3d7 chore: code cleanup
(cherry picked from commit f6947f115d)

# Conflicts:
#	desk/src/components/CommentTextEditor.vue
#	desk/src/components/EmailEditor.vue
2026-06-11 14:28:51 +00:00
Ritvik Sardana
cbddd06771 refactor: code structure
(cherry picked from commit 000ad30f03)
2026-06-11 14:28:50 +00:00
Ritvik Sardana
53c2e6acd0 fix: add attachment feature
(cherry picked from commit 9b7b779d08)
2026-06-11 14:28:50 +00:00
Ritvik Sardana
00ab05583b fix: better copy
(cherry picked from commit a1cb277151)
2026-06-11 14:28:49 +00:00
Ritvik Sardana
e98843d2be feat: bulk reply in ticket list view
(cherry picked from commit 016ac63148)

# Conflicts:
#	desk/src/components/Settings/SavedReplies/SavedReplyView.vue
2026-06-11 14:28:49 +00:00
RitvikSardana
3ed469f1ad Merge pull request #3464 from frappe/mergify/bp/main-hotfix/pr-3438
fix: placeholder in filters (backport #3438)
2026-06-11 19:54:45 +05:30
RitvikSardana
fd8cae3e74 Merge pull request #3463 from frappe/mergify/bp/main-hotfix/pr-3437
fix(Ticket ListView): don't show failed resolution when the ticket it not resolved (backport #3437)
2026-06-11 19:54:33 +05:30
RitvikSardana
a99181642a Merge pull request #3462 from frappe/mergify/bp/main-hotfix/pr-3436
fix(multiselect): click pill to copy its value (backport #3436)
2026-06-11 19:54:13 +05:30
RitvikSardana
5c973bbb6b chore: resolve conflicts 2026-06-11 18:27:11 +05:30
Ritvik Sardana
dbe6dd076f fix: placeholder in filters
(cherry picked from commit e3d4cede79)
2026-06-11 12:54:43 +00:00
Ritvik Sardana
fab2744549 fix(overflow): first field in quick filters
(cherry picked from commit fc417dc5e8)

# Conflicts:
#	desk/src/components/view-controls/QuickFilters.vue
2026-06-11 12:54:16 +00:00
Ritvik Sardana
14d8bb6744 fix: dont show failed resolution when the ticket it not resolved
(cherry picked from commit baf2d88e38)
2026-06-11 12:54:15 +00:00
RitvikSardana
198cc2683a chore: resolve conflicts 2026-06-11 18:23:10 +05:30
RitvikSardana
014d382dba Merge pull request #3460 from frappe/mergify/bp/main-hotfix/pr-3428
fix: empty state fix for cross browser compatibility (backport #3428)
2026-06-11 18:22:47 +05:30
Ritvik Sardana
5480d68de2 feat(multiselect): click pill to copy its value
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
(cherry picked from commit 40a5cfefa1)

# Conflicts:
#	desk/src/components/MultiSelectInput.vue
2026-06-11 12:48:33 +00:00
Ritvik Sardana
df29c8387f fix(saved-replies): keep email box open when dismissing modal
Clicking the saved-replies modal backdrop also collapsed the reply box:
the Dialog portals to body and its backdrop (.dialog-overlay) lacks
role="dialog", so CommunicationArea's onClickOutside treated it as an
outside click. Ignore .dialog-overlay so dialog-portal clicks are skipped.

Also guards editorRef access and autofocuses the search input on open.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
(cherry picked from commit 42cdaa80ea)
2026-06-11 12:48:33 +00:00
RitvikSardana
bd2cf36405 Merge pull request #3461 from frappe/mergify/bp/main-hotfix/pr-3434
fix: recents tickets condition (backport #3434)
2026-06-11 18:17:38 +05:30
Ritvik Sardana
19aeb91c32 fix: recents tickets condition
(cherry picked from commit 5e2aa06b4a)
2026-06-11 12:46:53 +00:00
RitvikSardana
2d60e42675 chore: resolve conflicts 2026-06-11 18:15:39 +05:30
Sydney
9ce6e94c68 fix: empty state fix for cross browser compatibility
(cherry picked from commit 3f4abcd49e)

# Conflicts:
#	desk/src/components/ListViewBuilder.vue
#	desk/src/components/Settings/SavedReplies/SavedRepliesList.vue
2026-06-11 12:35:23 +00:00
RitvikSardana
a3ad94c806 Merge pull request #3458 from RitvikSardana/upgrade-frappe-ui-hotfix
refactor: upgrade frappe UI (backport #3422)
2026-06-11 18:01:37 +05:30
RitvikSardana
91cf9a6ef7 Merge pull request #3459 from frappe/mergify/bp/main-hotfix/pr-3427
refactor: point ticket assignment notifications to agent portal (backport #3427)
2026-06-11 17:53:00 +05:30
Sydney
4b904e2296 refactor: extend notification log to route to HD portal on assignment
(cherry picked from commit 194913f303)
2026-06-11 12:22:36 +00:00
Ritvik Sardana
367cd99587 chore: bump node version 2026-06-11 17:49:30 +05:30
Ritvik Sardana
809700bcae refactor: upgrade frappe UI (#3422) 2026-06-11 17:30:36 +05:30
RitvikSardana
bed8d42e4b Merge pull request #3457 from frappe/mergify/bp/main-hotfix/pr-3416
refactor(ERPNext Integration): use doc_events instead of override_doctype_class (backport #3416)
2026-06-11 17:05:07 +05:30
RitvikSardana
fc852b31cb Merge pull request #3418 from frappe/mergify/bp/main-hotfix/pr-3417
fix: add session user as raised_by while creating from the API (backport #3417)
2026-06-11 16:45:23 +05:30
RitvikSardana
da47faa90b fix: setup erpnext in tests 2026-06-11 16:43:32 +05:30
RitvikSardana
ee70da731f chore: resolve conflicts 2026-06-11 16:26:18 +05:30
Ritvik Sardana
b7cb580789 fix: better copy
(cherry picked from commit e6236388f3)
2026-06-11 10:45:39 +00:00
Ritvik Sardana
9963ba08f4 fix: add loading state
(cherry picked from commit f06db95103)
2026-06-11 10:45:39 +00:00
Ritvik Sardana
bde3812d90 chore: improve copy
(cherry picked from commit 839232774e)

# Conflicts:
#	helpdesk/integrations/erpnext/api.py
2026-06-11 10:45:38 +00:00
Ritvik Sardana
edc76ca85e fix: improve integration layout
(cherry picked from commit 573ade93dc)
2026-06-11 10:45:38 +00:00
Ritvik Sardana
7ee822347f fix: move ERPNext integration components
(cherry picked from commit ac44791470)

# Conflicts:
#	desk/src/components/Settings/General/General.vue
2026-06-11 10:45:37 +00:00
Ritvik Sardana
b96ecd9f40 fix: better UX for desk button
(cherry picked from commit 96e502e472)
2026-06-11 10:45:37 +00:00
Ritvik Sardana
6b8133ac7d refactor: make field syncing extensible
(cherry picked from commit 86c3ac52b7)
2026-06-11 10:45:37 +00:00
Ritvik Sardana
69d23b996d refactor(UI): enable integration settings
(cherry picked from commit 86dc72ed4e)

# Conflicts:
#	desk/src/components/erpnext-integration/ERPNextCustomerSyncButton.vue
#	helpdesk/integrations/erpnext/api.py
#	helpdesk/public/erpnext/customer_list.js
#	helpdesk/www/helpdesk/index.py
2026-06-11 10:45:36 +00:00
Ritvik Sardana
e695f28dbd refactor: use doc_events instead of override_doctype
(cherry picked from commit eae877c1c3)
2026-06-11 10:45:35 +00:00
RitvikSardana
18dd02ac0b Merge pull request #3456 from frappe/mergify/bp/main-hotfix/pr-3415
fix: UI bugs caused due to RTL (backport #3415)
2026-06-11 16:14:30 +05:30
RitvikSardana
699301126c chore: code cleanup 2026-06-11 16:02:42 +05:30
RitvikSardana
4670fb0d7f chore: resolve conflicts 2026-06-11 15:59:46 +05:30
RitvikSardana
c65f9e64cf chore: resolve conflict 2026-06-11 15:47:25 +05:30
Sydney
aec4e761d9 fix: add setting modal fixes
(cherry picked from commit 4621b799cd)

# Conflicts:
#	desk/src/components/ticket/TicketMergeModal.vue
2026-06-11 09:57:04 +00:00
Sydney
935500d567 fix: rtl regression
(cherry picked from commit bfc79662d1)

# Conflicts:
#	desk/src/components/Settings/EmailAccountList.vue
#	desk/src/components/Settings/SavedReplies/SavedRepliesList.vue
#	desk/src/components/Settings/SettingsModal.vue
#	desk/src/components/frappe-ui/Link.vue
#	desk/src/components/layouts/Sidebar.vue
#	desk/src/pages/MobileNotifications.vue
#	desk/src/pages/knowledge-base/Article.vue
#	helpdesk/www/helpdesk/index.py
2026-06-11 09:57:03 +00:00
RitvikSardana
b45bdbc1de Merge pull request #3455 from frappe/mergify/bp/main-hotfix/pr-3414
fix: check if ERPNext is installed (backport #3414)
2026-06-11 15:25:54 +05:30
Ritvik Sardana
e2086427a5 fix: check if erp_next is installed
(cherry picked from commit d60ec14bcb)
2026-06-11 09:54:18 +00:00
RitvikSardana
659d43bb4f Merge pull request #3454 from frappe/mergify/bp/main-hotfix/pr-3404
fix: better button labels (backport #3404)
2026-06-11 15:23:27 +05:30
Ritvik Sardana
e8ebc3c02c fix: better button labels
(cherry picked from commit 5651411fd0)
2026-06-11 09:52:09 +00:00
RitvikSardana
fc1f9b949c Merge pull request #3453 from frappe/mergify/bp/main-hotfix/pr-3361
feat: sync ERPNext customer with HD customer (backport #3361)
2026-06-11 15:20:06 +05:30
RitvikSardana
1a84c36189 chore: update erpnext version 2026-06-11 15:09:06 +05:30
RitvikSardana
87fc71e282 chore: resolve conflict 2026-06-11 14:58:39 +05:30
Ritvik Sardana
3d29027543 chore: code cleanup
(cherry picked from commit c5c687fa73)
2026-06-11 09:24:58 +00:00
Ritvik Sardana
43883d2ef5 fix: dont throw error for agent role
(cherry picked from commit 5229c333b7)
2026-06-11 09:24:58 +00:00
Ritvik Sardana
123bb690ff chore: code cleanup
(cherry picked from commit 8de2ad89c0)
2026-06-11 09:24:58 +00:00
Ritvik Sardana
8ae299f6b8 fix: handle bulk delete properly
(cherry picked from commit 48c4721488)
2026-06-11 09:24:58 +00:00
Ritvik Sardana
ec7fa8a3ff fix: enqueue job ID
(cherry picked from commit 6ce4499536)
2026-06-11 09:24:57 +00:00
Ritvik Sardana
c6c511b9c8 refactor: add class to contain common methods
(cherry picked from commit 0ffca6862a)
2026-06-11 09:24:57 +00:00
Ritvik Sardana
6aa5af4dbe chore: code cleanup
(cherry picked from commit 93c2d17fe1)
2026-06-11 09:24:57 +00:00
Ritvik Sardana
876833426b fix: dont force delete
(cherry picked from commit 536232e10d)
2026-06-11 09:24:56 +00:00
Ritvik Sardana
6f64d793d2 fix: better in_sync logic
(cherry picked from commit 890d9aa903)
2026-06-11 09:24:56 +00:00
Ritvik Sardana
f925151294 fix: make UserPerms mirroring more verbose
(cherry picked from commit cc2f8c3755)
2026-06-11 09:24:56 +00:00
Ritvik Sardana
9884be6a89 fix: handle updating sync on user perm or share update
(cherry picked from commit b9f6b200c1)
2026-06-11 09:24:56 +00:00
Ritvik Sardana
34f36afecc fix: handle renaming
(cherry picked from commit cf5660595d)
2026-06-11 09:24:55 +00:00
Ritvik Sardana
0055e47268 fix: import path and file name
(cherry picked from commit 919dea3090)
2026-06-11 09:24:55 +00:00
Ritvik Sardana
8f32cfa0be fix: add on_trash events for DocShare & User Permissions
(cherry picked from commit bf44131e35)
2026-06-11 09:24:54 +00:00
Ritvik Sardana
16513eead5 fix: sync DocShare
(cherry picked from commit 3a8f31e5eb)
2026-06-11 09:24:53 +00:00
Ritvik Sardana
7d279eeee8 chore: change import paths
(cherry picked from commit a506b5cf7b)
2026-06-11 09:24:53 +00:00
Ritvik Sardana
6d8a7ec22e chore: code cleanup
(cherry picked from commit e582a68b68)
2026-06-11 09:24:52 +00:00
Ritvik Sardana
46948f36e3 fix: sync user perms
(cherry picked from commit 4a38da39e8)
2026-06-11 09:24:52 +00:00
Ritvik Sardana
5edb70c98d fix: show manager the erpnext setting in UI
(cherry picked from commit 68812f153b)
2026-06-11 09:24:51 +00:00
Ritvik Sardana
a4fa0e8086 fix: better folder structure and erpnext settings
(cherry picked from commit f69ad1f383)
2026-06-11 09:24:51 +00:00
Ritvik Sardana
943ae77b03 fix: better UX for enabling integration from Settings
(cherry picked from commit 9387e52e27)
2026-06-11 09:24:50 +00:00
Ritvik Sardana
eb5df6967f fix: create hd_customer custom field in before_tests
(cherry picked from commit f3d660cbb9)
2026-06-11 09:24:50 +00:00
Ritvik Sardana
0da10a0bed chore: code cleanup
(cherry picked from commit 352b1f45db)
2026-06-11 09:24:50 +00:00
Ritvik Sardana
c6c79ce85e fix: make hd_customer field hidden
(cherry picked from commit e042c72bb9)
2026-06-11 09:24:49 +00:00
Ritvik Sardana
3f3e76023f fix: add perms in HD Settings
(cherry picked from commit ec1f86d1cc)
2026-06-11 09:24:49 +00:00
Ritvik Sardana
13a545b0e3 fix(ci): install apps on test-site
(cherry picked from commit 7c3db92544)
2026-06-11 09:24:49 +00:00
Ritvik Sardana
b4e953640a test: skip HD Customer sync tests when ERPNext is not installed
(cherry picked from commit a0b5f39112)
2026-06-11 09:24:48 +00:00
Ritvik Sardana
d7ce8cf6de fix: dont always show sync button in erpnext
(cherry picked from commit fd240682c8)
2026-06-11 09:24:48 +00:00
Ritvik Sardana
41ebac63ff chore: code cleanup
(cherry picked from commit 835e0818f4)
2026-06-11 09:24:48 +00:00
Ritvik Sardana
69222eb827 fix: use custom class instead of doc events hook
(cherry picked from commit 60efc65b52)
2026-06-11 09:24:48 +00:00
Ritvik Sardana
4e41f39d43 fix: dont show sync button if erpnext not installed
(cherry picked from commit 9bac8ae0c8)
2026-06-11 09:24:47 +00:00
Ritvik Sardana
a7d37d133b fix: add perm guard in whitelisted methods
(cherry picked from commit cee84c8506)
2026-06-11 09:24:47 +00:00
Ritvik Sardana
746e8fd79b fix: install CI
(cherry picked from commit 94862dc3fa)
2026-06-11 09:24:47 +00:00
Ritvik Sardana
a2606e414c fix: add erpnext to install.sh
(cherry picked from commit deed869a88)
2026-06-11 09:24:46 +00:00
Ritvik Sardana
f2f0fb882e fix: add patch for adding erpnext customers to HD
(cherry picked from commit 71b664adeb)
2026-06-11 09:24:46 +00:00
Ritvik Sardana
ba0b58047d test: write test cases for hd_customer erpnext_customer sync
(cherry picked from commit 8a31a0a1fc)
2026-06-11 09:24:46 +00:00
Ritvik Sardana
776c85256e fix: only show system manager the ERPNext Integration setting
(cherry picked from commit addaf967e7)
2026-06-11 09:24:45 +00:00
Ritvik Sardana
d9206c375a fix: add ERPNext Integration setting in Settings Modal
(cherry picked from commit 7f70e4907f)

# Conflicts:
#	desk/src/components/Settings/General/General.vue
2026-06-11 09:24:45 +00:00
Ritvik Sardana
a0c42e05c0 feat: sync erpnext customer with hd customer
(cherry picked from commit ee540d64ec)
2026-06-11 09:24:44 +00:00
Ritvik Sardana
ada38a4a2d feat: erpnext hd customer master sync
(cherry picked from commit b1250c737f)
2026-06-11 09:24:43 +00:00
RitvikSardana
8055d50557 Merge pull request #3452 from frappe/mergify/bp/main-hotfix/pr-3288
fix: add weighted_users support in hd team  (backport #3288)
2026-06-11 14:51:02 +05:30
RitvikSardana
6f7d537e26 chore: update frappe required version 2026-06-11 14:36:28 +05:30
RitvikSardana
21f02412f8 chore: code cleanup 2026-06-11 14:29:19 +05:30
RitvikSardana
0b41b00321 chore: resolve conflict 2026-06-11 14:26:43 +05:30
Ritvik Sardana
4c987ad1c6 chore: code cleanup
(cherry picked from commit a319b47b8c)

# Conflicts:
#	helpdesk/setup/install.py
2026-06-11 08:40:25 +00:00
Ritvik Sardana
6407336ccd chore: update agents.md
(cherry picked from commit 5a47bbd31d)
2026-06-11 08:40:24 +00:00
Ritvik Sardana
2af4245203 chore: update ts_config
(cherry picked from commit ab34c77b42)

# Conflicts:
#	desk/tsconfig.json
2026-06-11 08:40:24 +00:00
Ritvik Sardana
f32594532c fix: use same rename dialog in team edit and list view
(cherry picked from commit 5f693fee2f)
2026-06-11 08:40:24 +00:00
Ritvik Sardana
9bf35dff64 refactor: team edit view
(cherry picked from commit fb9df9865e)
2026-06-11 08:40:23 +00:00
Ritvik Sardana
930520bcb3 chore: code cleanup
(cherry picked from commit b124594c9c)
2026-06-11 08:40:23 +00:00
Ritvik Sardana
57ad9a7514 fix: add enable check while creating new team in UI
(cherry picked from commit 215475d080)

# Conflicts:
#	desk/src/components/Settings/Teams/NewTeam.vue
2026-06-11 08:40:23 +00:00
Ritvik Sardana
151373f659 refactor: HD Team doctype codebase
(cherry picked from commit d39d56f67d)
2026-06-11 08:40:22 +00:00
Ritvik Sardana
40178bd386 fix: test utils for creating team
(cherry picked from commit 4d34520232)
2026-06-11 08:40:22 +00:00
Ritvik Sardana
917dc555c1 chore: code cleanup
(cherry picked from commit 2f1bccd869)

# Conflicts:
#	helpdesk/helpdesk/doctype/hd_ticket/hd_ticket.json
2026-06-11 08:40:21 +00:00
Ritvik Sardana
7ea65ed193 fix: handle app installation
(cherry picked from commit 5947ae3f04)
2026-06-11 08:40:21 +00:00
Ritvik Sardana
1396807eb6 chore: code cleanup
(cherry picked from commit 3b206b9b3e)

# Conflicts:
#	desk/src/composables/useTicket.ts
2026-06-11 08:40:21 +00:00
Ritvik Sardana
0573a5aaa8 fix: update link_filters in HDTicket
(cherry picked from commit 71956484ff)

# Conflicts:
#	helpdesk/helpdesk/doctype/hd_ticket/hd_ticket.json
2026-06-11 08:40:20 +00:00
Ritvik Sardana
e28272262d fix: add team disable in UI
(cherry picked from commit 8b41331457)
2026-06-11 08:40:19 +00:00
Ritvik Sardana
0011816b9c fix: sync disable state of HD Team with Assignment Rule
(cherry picked from commit a9dfa9a1b4)

# Conflicts:
#	desk/src/components/Settings/Teams/TeamsList.vue
2026-06-11 08:40:19 +00:00
Ritvik Sardana
2078fe5383 fix: add disabled field in hd_team
(cherry picked from commit d583d140c7)
2026-06-11 08:40:18 +00:00
Ritvik Sardana
7b3543e88b fix: remove two way sync
(cherry picked from commit c5e062a25f)

# Conflicts:
#	helpdesk/setup/install.py
2026-06-11 08:40:18 +00:00
Sydney Gomes
bcacd4f4bd Merge pull request #3442 from frappe/mergify/bp/main-hotfix/pr-3359
fix: border in ticket fields (backport #3359)
2026-06-09 16:11:00 +05:30
Sydney Gomes
f2da2f2076 fix: merge conflicts 2026-06-09 16:04:21 +05:30
Ritvik Sardana
85255edec8 chore: code cleanup
(cherry picked from commit 2c3548b54c)

# Conflicts:
#	desk/src/components/ticket-agent/AssignTo.vue
2026-06-09 10:30:10 +00:00
Ritvik Sardana
bd54a6a750 fix: border in ticket fields
(cherry picked from commit eba1d2624e)
2026-06-09 10:30:08 +00:00
Sydney Gomes
f116cca184 Merge pull request #3441 from frappe/mergify/bp/main-hotfix/pr-3366
fix: dark mode regressions (backport #3366)
2026-06-09 15:58:05 +05:30
Harish Chandran
485dc08d77 fix: make KB new article title input theme-aware
(cherry picked from commit 0fb37f2742)
2026-06-09 10:22:06 +00:00
Harish Chandran
1687d7a43a fix: use theme-stable mobile sidebar backdrop
(cherry picked from commit 962546b56a)
2026-06-09 10:22:06 +00:00
Harish Chandran
999c1b3e17 fix: make <hr> dividers visible in Settings list views
(cherry picked from commit b2124c076c)
2026-06-09 10:22:06 +00:00
Sydney Gomes
c87feff8ad Merge pull request #3440 from aerodeval/backport/pr-3246-dark-mode
feat: dark mode (backport #3246)
2026-06-09 15:49:05 +05:30
RitvikSardana
8dca64bb4b feat: dark mode (backport #3246)
Backport of frappe/helpdesk#3246 (feat: dark mode) from develop onto
main-hotfix. Resolved 15 conflicts, preserving main-hotfix's functional
and layout changes while adopting the PR's semantic dark-mode tokens.

Co-Authored-By: Harish Chandran <harish3304.work@gmail.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 14:46:35 +05:30
Ritvik Sardana
1186367f36 fix: add session user as raised_by while creating from the API
(cherry picked from commit 61c90a1ea2)
2026-06-02 05:39:55 +00:00
Sydney Gomes
415cdbaf5b Merge pull request #3413 from frappe/mergify/bp/main-hotfix/pr-3393
refactor: get_users function to optimize role fetching and user retrieval (backport #3393)
2026-06-01 16:19:18 +05:30
saadchaudharry
a05c0d6a99 refactor: get_users function to optimize role fetching and user retrieval
(cherry picked from commit ed567fa6fe)
2026-06-01 06:27:06 +00:00
RitvikSardana
59b54e6bd5 Merge pull request #3407 from frappe/mergify/bp/main-hotfix/pr-3389
fix: resolve @me filters during export in Helpdesk Portal (backport #3389)
2026-05-30 00:23:42 +05:30
Sydney
4e324537ec fix: resolve @me in assigned to filter during export
(cherry picked from commit 240b361744)
2026-05-29 11:46:54 +00:00
HemilSangani
afb249a788 refactor: improve @me filter export handling comments
(cherry picked from commit 1f4b36ff60)
2026-05-29 11:46:53 +00:00
HemilSangani
74c3bd5ac8 fix: resolve @me filters during export in Helpdesk Portal
(cherry picked from commit d8942c308f)
2026-05-29 11:46:53 +00:00
RitvikSardana
a8fafc498f Merge pull request #3402 from frappe/mergify/bp/main-hotfix/pr-3401
chore: sync translations from crowdin (backport #3401)
2026-05-29 17:16:39 +05:30
RitvikSardana
c741c80372 chore: Bump version to 1.25.1 2026-05-29 11:36:34 +05:30
MochaMind
14304ea73a chore: Burmese translations
(cherry picked from commit 523aab61f9)
2026-05-28 15:45:40 +00:00
MochaMind
2fa6febf38 chore: Thai translations
(cherry picked from commit 0612bb7685)
2026-05-28 15:45:39 +00:00
MochaMind
a3afc7a807 chore: Slovenian translations
(cherry picked from commit d9dbfafe62)
2026-05-28 15:45:39 +00:00
MochaMind
219526983b chore: Hungarian translations
(cherry picked from commit b0260a4efb)
2026-05-28 15:45:38 +00:00
MochaMind
34be6de61e chore: German translations
(cherry picked from commit e5bff7196a)
2026-05-28 15:45:38 +00:00
MochaMind
589864e242 chore: Danish translations
(cherry picked from commit 0388d09e53)
2026-05-28 15:45:38 +00:00
MochaMind
dbddb2ca7c chore: Spanish translations
(cherry picked from commit 236f867b2c)
2026-05-28 15:45:37 +00:00
MochaMind
077b76b2af chore: French translations
(cherry picked from commit a81145b72b)
2026-05-28 15:45:37 +00:00
Frappe PR Bot
d10e615ea6 chore(release): Bumped to Version 1.25.0 2026-05-28 10:40:08 +00:00
RitvikSardana
acb18c4825 Merge pull request #3400 from frappe/main-hotfix
chore(release): hotfix to main
2026-05-28 15:47:12 +05:30
RitvikSardana
d83606ca34 Merge pull request #3399 from frappe/mergify/bp/main-hotfix/pr-3398
chore: sync translations from crowdin (backport #3398)
2026-05-28 14:20:51 +05:30
MochaMind
d2f73c557e chore: Korean translations
(cherry picked from commit 9704a69797)
2026-05-28 08:41:18 +00:00
MochaMind
c36f8a5efc chore: Esperanto translations
(cherry picked from commit 10760560b2)
2026-05-28 08:41:18 +00:00
MochaMind
8a99393e4f chore: Russian translations
(cherry picked from commit ad34fd7656)
2026-05-28 08:41:18 +00:00
MochaMind
3c6d9ba055 chore: Serbian (Latin) translations
(cherry picked from commit b0000976f6)
2026-05-28 08:41:17 +00:00
MochaMind
39cb21e79a chore: Norwegian Bokmal translations
(cherry picked from commit c57f736e71)
2026-05-28 08:41:17 +00:00
MochaMind
460f311ed7 chore: Bosnian translations
(cherry picked from commit a6226b1562)
2026-05-28 08:41:17 +00:00
MochaMind
32de07517b chore: Burmese translations
(cherry picked from commit c0fa6b48dd)
2026-05-28 08:41:16 +00:00
MochaMind
7f9ded209f chore: Croatian translations
(cherry picked from commit 5a9c113087)
2026-05-28 08:41:16 +00:00
MochaMind
ea34a56fbb chore: Thai translations
(cherry picked from commit e8b65d056f)
2026-05-28 08:41:15 +00:00
MochaMind
1d73ed96bc chore: Persian translations
(cherry picked from commit 37cd9fd7ae)
2026-05-28 08:41:15 +00:00
MochaMind
bf1123cddd chore: Indonesian translations
(cherry picked from commit 100ac35cc4)
2026-05-28 08:41:15 +00:00
MochaMind
71b39f0e0e chore: Portuguese, Brazilian translations
(cherry picked from commit 049e1c554b)
2026-05-28 08:41:14 +00:00
MochaMind
dc37fa54a5 chore: Vietnamese translations
(cherry picked from commit 92a3832d5c)
2026-05-28 08:41:14 +00:00
MochaMind
ec7d9d82f5 chore: Chinese Simplified translations
(cherry picked from commit 7373292684)
2026-05-28 08:41:14 +00:00
MochaMind
a17e6c602d chore: Turkish translations
(cherry picked from commit 8468faf501)
2026-05-28 08:41:13 +00:00
MochaMind
673d255411 chore: Swedish translations
(cherry picked from commit cbb3536df5)
2026-05-28 08:41:13 +00:00
MochaMind
e2b63384dc chore: Serbian (Cyrillic) translations
(cherry picked from commit eb7d392b8b)
2026-05-28 08:41:12 +00:00
MochaMind
b57b22878a chore: Slovenian translations
(cherry picked from commit 139e3d019c)
2026-05-28 08:41:12 +00:00
MochaMind
05292febdb chore: Portuguese translations
(cherry picked from commit 8d520703d6)
2026-05-28 08:41:12 +00:00
MochaMind
1945099fb7 chore: Polish translations
(cherry picked from commit 1a5a94785d)
2026-05-28 08:41:12 +00:00
MochaMind
f7a4214bc1 chore: Dutch translations
(cherry picked from commit 859fb683d6)
2026-05-28 08:41:11 +00:00
MochaMind
057390ca6b chore: Italian translations
(cherry picked from commit 723afc0c67)
2026-05-28 08:41:11 +00:00
MochaMind
0bfa46a2ee chore: Hungarian translations
(cherry picked from commit 2047e83fd4)
2026-05-28 08:41:10 +00:00
MochaMind
08f1e9138a chore: German translations
(cherry picked from commit 367f2415c5)
2026-05-28 08:41:10 +00:00
MochaMind
cb7ee8bd7c chore: Danish translations
(cherry picked from commit ed871686af)
2026-05-28 08:41:10 +00:00
MochaMind
7bd8885568 chore: Czech translations
(cherry picked from commit fd462c8b43)
2026-05-28 08:41:09 +00:00
MochaMind
876b469be9 chore: Arabic translations
(cherry picked from commit 8a76b6745f)
2026-05-28 08:41:09 +00:00
MochaMind
1e3a3c2e0b chore: Spanish translations
(cherry picked from commit d6e89d748d)
2026-05-28 08:41:09 +00:00
MochaMind
8d495cbd71 chore: French translations
(cherry picked from commit bf2a0b16f4)
2026-05-28 08:41:08 +00:00
RitvikSardana
e1bf33da88 Merge pull request #3396 from frappe/mergify/bp/main-hotfix/pr-3386
chore: update POT file (backport #3386)
2026-05-26 20:56:49 +05:30
frappe-pr-bot
36844b9f3f chore: update POT file
(cherry picked from commit 947f6a5524)
2026-05-26 15:17:37 +00:00
RitvikSardana
69b2e6cc1e Merge pull request #3395 from frappe/mergify/bp/main-hotfix/pr-3371
chore: sync translations from crowdin (backport #3371)
2026-05-26 20:40:01 +05:30
MochaMind
43d54281a9 chore: Swedish translations
(cherry picked from commit cdbb0b29fe)
2026-05-26 15:01:35 +00:00
MochaMind
592f9d1d73 chore: Swedish translations
(cherry picked from commit 60d7dcf47a)
2026-05-26 15:01:34 +00:00
MochaMind
df8413803d chore: French translations
(cherry picked from commit 68f04c3c34)
2026-05-26 15:01:34 +00:00
MochaMind
a377c2b04d chore: French translations
(cherry picked from commit d1a8b12458)
2026-05-26 15:01:33 +00:00
MochaMind
18958c910b chore: Esperanto translations
(cherry picked from commit b60463736f)
2026-05-26 15:01:33 +00:00
MochaMind
a5b0f388bb chore: Russian translations
(cherry picked from commit ae6039da5b)
2026-05-26 15:01:32 +00:00
MochaMind
f2515ef17b chore: Serbian (Latin) translations
(cherry picked from commit b173c84ff3)
2026-05-26 15:01:32 +00:00
MochaMind
14ba2b9cfa chore: Norwegian Bokmal translations
(cherry picked from commit 5912022f4b)
2026-05-26 15:01:31 +00:00
MochaMind
0edd696cba chore: Bosnian translations
(cherry picked from commit 0f366341d3)
2026-05-26 15:01:31 +00:00
MochaMind
c007d980ca chore: Burmese translations
(cherry picked from commit 9a80854c95)
2026-05-26 15:01:30 +00:00
MochaMind
ae9de80b66 chore: Croatian translations
(cherry picked from commit a49c7378a9)
2026-05-26 15:01:30 +00:00
MochaMind
708d279cbc chore: Thai translations
(cherry picked from commit c7ac7db049)
2026-05-26 15:01:29 +00:00
MochaMind
245646d3a4 chore: Persian translations
(cherry picked from commit c49fcd0e5d)
2026-05-26 15:01:29 +00:00
MochaMind
0eb4219d31 chore: Indonesian translations
(cherry picked from commit ff634daa7e)
2026-05-26 15:01:28 +00:00
MochaMind
f296f99674 chore: Portuguese, Brazilian translations
(cherry picked from commit 784d7ab53c)
2026-05-26 15:01:28 +00:00
MochaMind
dbcafdbdab chore: Vietnamese translations
(cherry picked from commit f67c39ea94)
2026-05-26 15:01:27 +00:00
MochaMind
47b9489060 chore: Chinese Simplified translations
(cherry picked from commit aa5399df04)
2026-05-26 15:01:27 +00:00
MochaMind
092f507570 chore: Turkish translations
(cherry picked from commit 81928e2117)
2026-05-26 15:01:26 +00:00
MochaMind
4ebcc0a045 chore: Swedish translations
(cherry picked from commit 8a936cb486)
2026-05-26 15:01:26 +00:00
MochaMind
fdd648f334 chore: Serbian (Cyrillic) translations
(cherry picked from commit eae44520cc)
2026-05-26 15:01:25 +00:00
MochaMind
6773d95b30 chore: Slovenian translations
(cherry picked from commit 64c964002d)
2026-05-26 15:01:25 +00:00
MochaMind
40e5aac0ff chore: Portuguese translations
(cherry picked from commit 4cec7f83ae)
2026-05-26 15:01:25 +00:00
MochaMind
5d3ff81a9f chore: Polish translations
(cherry picked from commit 25940eea86)
2026-05-26 15:01:24 +00:00
MochaMind
54d8d5a2ec chore: Dutch translations
(cherry picked from commit fd5773a10c)
2026-05-26 15:01:24 +00:00
MochaMind
2b3c7e1b5c chore: Italian translations
(cherry picked from commit 368dc1a3a6)
2026-05-26 15:01:23 +00:00
MochaMind
78cb9baac0 chore: Hungarian translations
(cherry picked from commit 7c5a093f47)
2026-05-26 15:01:23 +00:00
MochaMind
5f929f5693 chore: German translations
(cherry picked from commit 6dd10ca425)
2026-05-26 15:01:23 +00:00
MochaMind
932cd7b67b chore: Danish translations
(cherry picked from commit 3c45873ad3)
2026-05-26 15:01:22 +00:00
MochaMind
0b5f3e1af9 chore: Czech translations
(cherry picked from commit dbdec8cd3c)
2026-05-26 15:01:22 +00:00
MochaMind
9577051bd1 chore: Arabic translations
(cherry picked from commit 29f63a1a8d)
2026-05-26 15:01:22 +00:00
MochaMind
9767f97943 chore: Spanish translations
(cherry picked from commit e4ff6aaeb1)
2026-05-26 15:01:21 +00:00
MochaMind
14efd61662 chore: French translations
(cherry picked from commit 95a231f878)
2026-05-26 15:01:21 +00:00
RitvikSardana
3376776584 Merge pull request #3380 from frappe/mergify/bp/main-hotfix/pr-3354
fix: overdue resolution time in SLA (backport #3354)
2026-05-26 20:10:50 +05:30
RitvikSardana
e2d2885ada chore: resolve conflict 2026-05-26 17:35:22 +05:30
RitvikSardana
f24f9222b0 Merge pull request #3381 from frappe/mergify/bp/main-hotfix/pr-3297
fix: sla header in ticket view (backport #3297)
2026-05-26 16:54:56 +05:30
RitvikSardana
d12ae03848 Merge branch 'main-hotfix' into mergify/bp/main-hotfix/pr-3297 2026-05-26 16:48:06 +05:30
RitvikSardana
7286f9b67e Merge pull request #3390 from frappe/mergify/bp/main-hotfix/pr-3276
feat: change ticket ID format to string-based naming series (backport #3276)
2026-05-26 15:06:51 +05:30
RitvikSardana
214fa80646 chore: resolve conflict 2026-05-26 12:30:36 +05:30
Ritvik Sardana
d9c903ed75 chore: code cleanup
(cherry picked from commit e8daf87e08)

# Conflicts:
#	helpdesk/patches.txt
2026-05-26 06:53:20 +00:00
Ritvik Sardana
13e7630a5a fix: default ticket id width in ListView
(cherry picked from commit cb4d90a1cd)
2026-05-26 06:53:19 +00:00
Harshit Raizada
fa640e7079 chore: fixed patch file name in patch.txt
(cherry picked from commit ef72e3b071)

# Conflicts:
#	helpdesk/patches.txt
2026-05-26 06:53:19 +00:00
Harshit Raizada
348c5dc0db chore: added the patch name in patch file
(cherry picked from commit d0f5bec3e0)

# Conflicts:
#	helpdesk/patches.txt
2026-05-26 06:53:18 +00:00
Harshit Raizada
64a73139b2 chore: sync patches.txt with develop
(cherry picked from commit e54c9d2c31)

# Conflicts:
#	helpdesk/patches.txt
2026-05-26 06:53:17 +00:00
Harshit Raizada
d173c02daa chore: remove redundant parentheses
(cherry picked from commit 728cb53ff4)
2026-05-26 06:53:17 +00:00
Harshit Raizada
2c56b90672 chore: remove legacy number types from TS interfaces for tickets
(cherry picked from commit c2ba5dfddc)

# Conflicts:
#	desk/src/composables/useTicket.ts
#	desk/src/pages/ticket/MobileTicketAgent.vue
2026-05-26 06:53:17 +00:00
Harshit Raizada
029f1b3276 chore: remove legacy str | int type hints for ticket docs
(cherry picked from commit 079327f3d1)
2026-05-26 06:53:16 +00:00
Harshit Raizada
080787bb66 chore: fix black formatting
(cherry picked from commit f1d823a52c)
2026-05-26 06:53:15 +00:00
Harshit Raizada
53428e9a57 feat: change ticket ID format to string-based naming series
(cherry picked from commit 09b260e263)

# Conflicts:
#	helpdesk/patches.txt
2026-05-26 06:53:15 +00:00
RitvikSardana
1cb6beb377 chore: use FrappeTestCase 2026-05-26 11:27:10 +05:30
RitvikSardana
ffaa17143b chore: code cleanup 2026-05-25 21:36:44 +05:30
RitvikSardana
86613e54bf Merge branch 'main-hotfix' into mergify/bp/main-hotfix/pr-3297 2026-05-25 21:32:13 +05:30
Sydney Gomes
00175eddc3 Merge pull request #3384 from frappe/mergify/bp/main-hotfix/pr-3376
fix: loader appearing on top in SLa view (backport #3376)
2026-05-24 15:09:40 +05:30
Sydney Gomes
45a75c9bdf Merge pull request #3385 from frappe/mergify/bp/main-hotfix/pr-3370
fix: add pointer-events-none to empty state overlay (backport #3370)
2026-05-24 15:09:21 +05:30
Sydney
cb17c8a0c3 fix: remove unused z-index
(cherry picked from commit bfa81e08d2)
2026-05-24 09:30:42 +00:00
Sydney
5ad7c61537 fix: disable pointer-events on empty state overlay to unblock header actions
(cherry picked from commit 4b27fc1ce7)
2026-05-24 09:30:42 +00:00
Sydney
fc9211cf1b fix: improper logic used to display loading state
(cherry picked from commit ad8ff52580)
2026-05-24 09:30:26 +00:00
Sydney
1d730d5038 fix: loader appearing on top in SLa view
(cherry picked from commit b0c846c67c)
2026-05-24 09:30:26 +00:00
Sydney Gomes
4726631985 Merge pull request #3377 from frappe/mergify/bp/main-hotfix/pr-3353
refactor(frontend): reduce code duplication across components and some ui fixes (backport #3353)
2026-05-24 14:58:43 +05:30
Sydney
94ba469ffa fix: remove duplicate imports 2026-05-24 14:52:22 +05:30
Sydney Gomes
e966b73ece fix: merge conflicts 2026-05-24 14:40:37 +05:30
Sydney Gomes
e89cf32d43 Merge pull request #3383 from frappe/mergify/bp/main-hotfix/pr-3378
fix: add missing conditions in ticket merge modal (backport #3378)
2026-05-24 14:34:11 +05:30
Sydney Gomes
0d6de50d87 fix: merge conflicts in Merge modal 2026-05-24 14:27:57 +05:30
Sydney
623106697a fix: add missing conditions in ticket merge modal
(cherry picked from commit 146a389a7a)

# Conflicts:
#	desk/src/components/ticket/TicketMergeModal.vue
2026-05-24 08:53:14 +00:00
Sydney Gomes
249ff789e4 Merge pull request #3382 from frappe/mergify/bp/main-hotfix/pr-3266
fix: allow sending with bcc/cc (backport #3266)
2026-05-24 14:06:27 +05:30
Sydney
c03ff1ea39 fix: improve code quality
(cherry picked from commit 777619925a)
2026-05-24 08:20:11 +00:00
Sydney
17bfdb09d5 fix: improve test cases
(cherry picked from commit 33195dcf02)
2026-05-24 08:20:11 +00:00
Sydney
261f9956e3 fix: remove throwing exception when to, cc or bcc is empty and failing testcase
(cherry picked from commit 298b465d9a)
2026-05-24 08:20:10 +00:00
Sydney
1c5f52b48f fix: add test cases and avoid sending mail without any field in backend
(cherry picked from commit b1e2bf0e6c)
2026-05-24 08:20:09 +00:00
Sydney
658f884e8c fix: allow sending mails only with bcc & cc in frontend
(cherry picked from commit e9203d21fc)
2026-05-24 08:20:09 +00:00
Sydney
5380bf2782 fix: remove ticket raised_by fallback for to mails
(cherry picked from commit 13357c7b77)
2026-05-24 08:20:08 +00:00
Ritvik Sardana
d75f1f0d2e fix: dont update resolution when status_category remains the same of 'Resolved'
(cherry picked from commit 4af5fac05e)
2026-05-23 18:03:11 +00:00
Ritvik Sardana
b1accfd025 fix: sla formatting in UI
(cherry picked from commit d802e76038)
2026-05-23 18:03:10 +00:00
Ritvik Sardana
35fc242757 chore: code cleanup
(cherry picked from commit 881a0c484f)

# Conflicts:
#	helpdesk/patches.txt
2026-05-23 18:03:10 +00:00
Ritvik Sardana
4f9257b004 fix: add patch for backfiling the fields for tickets raised in last 180 days
(cherry picked from commit a1f305edb4)

# Conflicts:
#	helpdesk/patches.txt
2026-05-23 18:03:09 +00:00
Ritvik Sardana
47ed9f3990 fix: add test cases for response and resolution failed_by
(cherry picked from commit e7c57a1c04)

# Conflicts:
#	helpdesk/helpdesk/doctype/hd_ticket/test_hd_ticket.py
2026-05-23 18:03:09 +00:00
Ritvik Sardana
1107b854d5 fix: introduce failed_by field for response and resolution field
(cherry picked from commit fece6ce14f)
2026-05-23 18:03:08 +00:00
Ritvik Sardana
a16ea52c3e fix: show proper SLA timing in Ticket View
(cherry picked from commit 49d9da6891)
2026-05-23 18:03:07 +00:00
Ritvik Sardana
cb915f5ee6 chore: align SLA status
(cherry picked from commit 264c1f3c78)

# Conflicts:
#	desk/src/components/ticket-agent/TicketSLA.vue
2026-05-23 18:01:29 +00:00
Ritvik Sardana
0811601a64 fix: overdue resolution time in SLA
(cherry picked from commit 4c44d4aa59)

# Conflicts:
#	desk/src/components/ticket-agent/TicketSLA.vue
2026-05-23 18:01:29 +00:00
Sydney
65bce9ce0c fix: flicker when tabs are changed
(cherry picked from commit ec40d5a3e3)

# Conflicts:
#	desk/src/pages/home/components/PendingTickets.vue
2026-05-20 20:57:00 +00:00
Sydney
99a2d8c7a0 fix: ui issues with centering of loading states and loading indicator
(cherry picked from commit 197e8c5334)

# Conflicts:
#	desk/src/pages/home/components/PendingTickets.vue
2026-05-20 20:57:00 +00:00
Sydney
91a8bb25b6 fix: make dropdown lost mobile friendly
(cherry picked from commit 684bf0d80c)
2026-05-20 20:56:59 +00:00
Sydney
665159e397 fix: view breadcrumbs dropdown fix
(cherry picked from commit 171f62e07b)
2026-05-20 20:56:59 +00:00
Sydney
85f83eb79e fix: linter issues
(cherry picked from commit 431e95d450)

# Conflicts:
#	desk/src/components/frappe-ui/Autocomplete.vue
#	desk/src/components/ticket-agent/AssignTo.vue
2026-05-20 20:56:58 +00:00
Sydney
120eba4fd3 fix: dark mode ui issues
(cherry picked from commit 0af8b49ab2)
2026-05-20 20:56:58 +00:00
Sydney
2135a8b8cd fix: breadcrumbs fix for mobile and UI issues
(cherry picked from commit 0e0d460e2e)
2026-05-20 20:56:57 +00:00
Sydney
c326904e10 fix: breadcrumbs and empty states centered
(cherry picked from commit bf879318f9)
2026-05-20 20:56:57 +00:00
Sydney
5b2e5ca0d4 fix: center empty states all over
(cherry picked from commit 2ed16f1232)
2026-05-20 20:56:57 +00:00
Sydney
7f1867de4f fix: improve edit name in profile component
(cherry picked from commit 704d887f35)
2026-05-20 20:56:56 +00:00
Sydney
cd0b1c2383 fix: use reusable components for EmptyState and Badge transtions
(cherry picked from commit 1982d5d83a)

# Conflicts:
#	desk/src/components/Settings/Teams/NewTeam.vue
#	desk/src/components/Settings/Teams/TeamsList.vue
2026-05-20 20:56:56 +00:00
RitvikSardana
6b88ea12ca Merge pull request #3365 from frappe/mergify/bp/main-hotfix/pr-3363
chore: update POT file (backport #3363)
2026-05-20 01:25:57 +05:30
RitvikSardana
4adcb7639d cho: resolve conflict 2026-05-19 16:27:45 +05:30
frappe-pr-bot
cd93aecf89 chore: update POT file
(cherry picked from commit 4982ef6ce1)

# Conflicts:
#	helpdesk/locale/main.pot
2026-05-18 09:29:56 +00:00
RitvikSardana
e646675b75 Merge pull request #3349 from frappe/mergify/bp/main-hotfix/pr-3342
chore: sync translations from crowdin (backport #3342)
2026-05-14 18:45:59 +05:30
Sydney Gomes
90ef3f8066 Merge pull request #3352 from frappe/mergify/bp/main-hotfix/pr-3327
fix: make onboarding steps to depend on ticket creation (backport #3327)
2026-05-14 02:36:47 +05:30
Sydney
c5eafe7cf6 fix: onboarding steps to depend on ticket creation
(cherry picked from commit ae73d2d342)
2026-05-13 20:58:50 +00:00
Sydney Gomes
09cd388981 Merge pull request #3350 from frappe/mergify/bp/main-hotfix/pr-3348
test: add test cases for from-email switching (backport #3348)
2026-05-14 02:26:25 +05:30
Sydney
2c1fa66edd fix: code cleanup 2026-05-14 02:19:36 +05:30
Sydney
7c2a68c227 fix: test cases merge conflicts 2026-05-14 02:10:19 +05:30
Sydney Gomes
0fe31e08bc Merge pull request #3351 from frappe/mergify/bp/main-hotfix/pr-3329
fix: UI bugs  (backport #3329)
2026-05-14 01:59:08 +05:30
Sydney
c5dabc22ce fix: ticket view ui fixes
(cherry picked from commit c0cb774f73)
2026-05-13 08:50:16 +00:00
Sydney
9f875dd58e fix: improve code quality in hd_ticket
(cherry picked from commit 6e3a910555)
2026-05-13 08:50:15 +00:00
Sydney
8a851ee48d fix: ui bugs in ticket view page and settings
(cherry picked from commit 11382aa429)
2026-05-13 08:50:15 +00:00
Sydney
d8dcd980b7 fix: select box sizing in invite agents
(cherry picked from commit 8956558d27)
2026-05-13 08:50:14 +00:00
Sydney
eac201a42b fix: multiple toasts in invite agent flow and ui fix
(cherry picked from commit 8036ccc8f4)
2026-05-13 08:50:14 +00:00
Sydney
31d0fcf02a fix: use combobox instead of Autocomplete and fix quick filters
(cherry picked from commit 9702df6d32)
2026-05-13 08:50:14 +00:00
Sydney
9e42ca0d45 fix: ensure email signature is applied on editor open
(cherry picked from commit df6643fc73)
2026-05-13 08:50:13 +00:00
Sydney
84733efdae fix: ui issues in frontend
(cherry picked from commit be8a417c17)
2026-05-13 08:50:13 +00:00
Sydney
f0f77f2c86 fix: general settings update toggle without save
(cherry picked from commit 7a175e4fab)
2026-05-13 08:50:13 +00:00
Sydney
2276555be9 fix: general ui fixes
(cherry picked from commit 75f7b69613)
2026-05-13 08:50:13 +00:00
Sydney
685de4b126 fix: frappe-ui dropdown changes and combobox width fixes
(cherry picked from commit bf20db015c)
2026-05-13 08:50:12 +00:00
Sydney
4cddb7139b fix: breadcrumbs listview dropdown appearing on the end
(cherry picked from commit c142a79d65)
2026-05-13 08:50:11 +00:00
Sydney
0dfa68bf28 test: add test cases for from-email switching
(cherry picked from commit 54c32cc5be)

# Conflicts:
#	helpdesk/helpdesk/doctype/hd_ticket/test_hd_ticket.py
2026-05-13 08:49:18 +00:00
MochaMind
7b7ca8e8a1 chore: Bosnian translations
(cherry picked from commit b5385a6b3c)
2026-05-13 06:15:35 +00:00
MochaMind
69e323f535 chore: Croatian translations
(cherry picked from commit 06f04f757a)
2026-05-13 06:15:35 +00:00
MochaMind
e00575b191 chore: Swedish translations
(cherry picked from commit bc7338bee6)
2026-05-13 06:15:35 +00:00
RitvikSardana
3477d29e00 Merge pull request #3345 from frappe/mergify/bp/main-hotfix/pr-3344
fix: broken article search  (backport #3344)
2026-05-12 12:49:40 +05:30
Ritvik Sardana
e329fe154a chore: remove unwanted code
(cherry picked from commit f6842abe93)
2026-05-12 07:19:17 +00:00
RitvikSardana
0900ea9663 Merge pull request #3339 from frappe/mergify/bp/main-hotfix/pr-3338
refactor: Remove HD Ticket indexing from redis based search (backport #3338)
2026-05-12 01:27:39 +05:30
Niraj Gautam
6453ae4bd5 chore: Fix lint issue
(cherry picked from commit 5f6e1d7b5c)
2026-05-11 19:28:28 +00:00
Niraj Gautam
92b47e5007 fix: Remove HD Ticket indexing from redis based search
(cherry picked from commit 777466a744)
2026-05-11 19:28:28 +00:00
RitvikSardana
57e8cb2288 Merge pull request #3332 from frappe/mergify/bp/main-hotfix/pr-3331
chore: sync translations from crowdin (backport #3331)
2026-05-11 14:34:40 +05:30
MochaMind
d93262e8e7 chore: Esperanto translations
(cherry picked from commit f702fa2d14)
2026-05-11 08:50:55 +00:00
MochaMind
c51df3d91e chore: Russian translations
(cherry picked from commit be5a4dbdda)
2026-05-11 08:50:54 +00:00
MochaMind
ddae4fa975 chore: Serbian (Latin) translations
(cherry picked from commit 633c712678)
2026-05-11 08:50:54 +00:00
MochaMind
41e942171c chore: Norwegian Bokmal translations
(cherry picked from commit 9f4cefd92a)
2026-05-11 08:50:53 +00:00
MochaMind
007f14f75d chore: Bosnian translations
(cherry picked from commit b6c22d78a7)
2026-05-11 08:50:53 +00:00
MochaMind
65fd14d473 chore: Burmese translations
(cherry picked from commit d3c0b6d288)
2026-05-11 08:50:52 +00:00
MochaMind
2a38efa5d5 chore: Croatian translations
(cherry picked from commit 29f634e48f)
2026-05-11 08:50:52 +00:00
MochaMind
78f218f70e chore: Thai translations
(cherry picked from commit 5582e9f326)
2026-05-11 08:50:51 +00:00
MochaMind
4c1357956f chore: Persian translations
(cherry picked from commit 1d2dfcf20f)
2026-05-11 08:50:51 +00:00
MochaMind
e5b35cd74e chore: Indonesian translations
(cherry picked from commit f84f9db434)
2026-05-11 08:50:50 +00:00
MochaMind
f78dd61080 chore: Portuguese, Brazilian translations
(cherry picked from commit a1cecb3f2b)
2026-05-11 08:50:50 +00:00
MochaMind
8f90ca3306 chore: Vietnamese translations
(cherry picked from commit 5ec41b1500)
2026-05-11 08:50:49 +00:00
MochaMind
7a64c7208a chore: Chinese Simplified translations
(cherry picked from commit 8faabcf831)
2026-05-11 08:50:49 +00:00
MochaMind
133bb024f3 chore: Turkish translations
(cherry picked from commit 09a72dbcc5)
2026-05-11 08:50:48 +00:00
MochaMind
ac5f000808 chore: Swedish translations
(cherry picked from commit 0b6f2c828f)
2026-05-11 08:50:48 +00:00
MochaMind
8c1c8c8580 chore: Serbian (Cyrillic) translations
(cherry picked from commit d923677bd6)
2026-05-11 08:50:47 +00:00
MochaMind
460de8c3a9 chore: Slovenian translations
(cherry picked from commit 0edeaed550)
2026-05-11 08:50:46 +00:00
MochaMind
33a8e0243f chore: Portuguese translations
(cherry picked from commit 29f17bd05b)
2026-05-11 08:50:46 +00:00
MochaMind
c4ddf6a038 chore: Polish translations
(cherry picked from commit 68e16f8825)
2026-05-11 08:50:45 +00:00
MochaMind
099d70bf3b chore: Dutch translations
(cherry picked from commit 5e9ca4413f)
2026-05-11 08:50:45 +00:00
MochaMind
78c06e634f chore: Italian translations
(cherry picked from commit c804633e37)
2026-05-11 08:50:44 +00:00
MochaMind
8aaad0ba82 chore: Hungarian translations
(cherry picked from commit e7fea47bef)
2026-05-11 08:50:44 +00:00
MochaMind
41519272f5 chore: German translations
(cherry picked from commit 0ba8df95ca)
2026-05-11 08:50:44 +00:00
MochaMind
663f2faf9c chore: Danish translations
(cherry picked from commit 73839ab2e6)
2026-05-11 08:50:43 +00:00
MochaMind
1a42c590b4 chore: Czech translations
(cherry picked from commit ffbb3bcf01)
2026-05-11 08:50:43 +00:00
MochaMind
fb35d105a8 chore: Arabic translations
(cherry picked from commit 26eaa73192)
2026-05-11 08:50:43 +00:00
MochaMind
5264c7f498 chore: Spanish translations
(cherry picked from commit 54cd0b6000)
2026-05-11 08:50:42 +00:00
MochaMind
f20eeb4b0f chore: French translations
(cherry picked from commit 8dda232d76)
2026-05-11 08:50:41 +00:00
RitvikSardana
94ef9cbe3b chore: resolve merge conflict 2026-05-11 11:22:31 +05:30
RitvikSardana
48dd9fbdf1 Merge pull request #3330 from frappe/mergify/bp/main-hotfix/pr-3328
chore: update POT file (backport #3328)
2026-05-11 11:18:31 +05:30
frappe-pr-bot
491a60a86a chore: update POT file
(cherry picked from commit b909a6f6fc)

# Conflicts:
#	helpdesk/locale/main.pot
2026-05-11 05:43:14 +00:00
Frappe PR Bot
92de4ab5e9 chore(release): Bumped to Version 1.24.1 2026-05-08 03:15:03 +00:00
RitvikSardana
549e597f45 Merge pull request #3326 from frappe/mergify/bp/main/pr-3324
fix: dashboard filters fix (backport #3324)
2026-05-08 08:44:28 +05:30
Sydney
274bbdaa55 fix: dashboard filters fix
(cherry picked from commit be7eb8f370)
2026-05-08 03:14:04 +00:00
Sydney Gomes
9857531404 Merge pull request #3325 from frappe/mergify/bp/main-hotfix/pr-3324
fix: dashboard filters fix (backport #3324)
2026-05-08 04:04:30 +05:30
Sydney
59f3344653 fix: dashboard filters fix
(cherry picked from commit be7eb8f370)
2026-05-07 22:29:13 +00:00
Frappe PR Bot
5c1b180265 chore(release): Bumped to Version 1.24.0 2026-05-07 21:52:10 +00:00
RitvikSardana
a8f85bf190 Merge pull request #3323 from frappe/main-hotfix
chore(release): hotfix to main
2026-05-08 03:21:34 +05:30
RitvikSardana
21914035d7 Merge pull request #3322 from frappe/mergify/bp/main-hotfix/pr-3295
fix: parse period filter (backport #3295)
2026-05-08 03:14:56 +05:30
Sydney Gomes
ca0bc1c8cd Merge pull request #3258 from frappe/mergify/bp/main-hotfix/pr-3242
fix: article layouting (backport #3242)
2026-05-08 03:10:21 +05:30
Sydney
7b43977eec fix: linter issues 2026-05-08 03:07:57 +05:30
Sydney
2d714ceee1 fix: linter issues 2026-05-08 03:04:39 +05:30
Sydney Gomes
c8176db23c Merge branch 'main-hotfix' into mergify/bp/main-hotfix/pr-3295 2026-05-08 03:02:51 +05:30
Sydney Gomes
1df1d89020 Merge pull request #3294 from aerodeval/backport-agent-landing-fix
fix: standard view filter, UI bugs add My Replies card (backport #3141)
2026-05-08 02:58:36 +05:30
Sydney Gomes
8b69eeddcb Merge branch 'main-hotfix' into mergify/bp/main-hotfix/pr-3242 2026-05-08 02:56:45 +05:30
gajjug004
7f6e105668 fix: parse period filter
(cherry picked from commit a73870f22e)

# Conflicts:
#	desk/src/pages/dashboard/Dashboard.vue
2026-05-07 21:23:54 +00:00
Sydney Gomes
4dfa154b73 Merge pull request #3321 from frappe/mergify/bp/main-hotfix/pr-3278
fix: prevent request from being sent if name is unchanged (backport #3278)
2026-05-08 02:50:44 +05:30
Sydney Gomes
23e0844191 Merge branch 'main-hotfix' into backport-agent-landing-fix 2026-05-08 02:50:10 +05:30
RitvikSardana
a3e14c3ce7 Merge pull request #3320 from frappe/mergify/bp/main-hotfix/pr-3292
chore: sync translations from crowdin (backport #3292)
2026-05-08 02:46:31 +05:30
Sydney Gomes
b205240293 Merge pull request #3319 from frappe/mergify/bp/main-hotfix/pr-3256
fix: avoid saving signature in cache of email content (backport #3256)
2026-05-08 02:44:43 +05:30
Sydney Gomes
3bf3c5ea52 Merge pull request #3317 from frappe/mergify/bp/main-hotfix/pr-3252
fix: keep image size intact in customer portal (backport #3252)
2026-05-08 02:41:45 +05:30
Sydney
26e879d507 fix: dirty state of save button when name is changed
(cherry picked from commit e9d973d496)
2026-05-07 21:11:24 +00:00
Sydney
2f18f544d2 fix: prevent request from being sent if name is unchanged
(cherry picked from commit 46450cf922)
2026-05-07 21:11:24 +00:00
MochaMind
fddd033f5b chore: Persian translations
(cherry picked from commit 168968f1b9)
2026-05-07 21:08:38 +00:00
Sydney Gomes
8734e1ab21 Merge pull request #3315 from frappe/mergify/bp/main-hotfix/pr-3247
fix: add saved replies before signature and fix cursor position (backport #3247)
2026-05-08 02:38:25 +05:30
Sydney
c82a188431 fix: avoid saving signature in cache of email content
(cherry picked from commit fce59cfbae)
2026-05-07 21:08:03 +00:00
RitvikSardana
b5f81ef45d Merge pull request #3318 from frappe/mergify/bp/main-hotfix/pr-3316
chore(ci): bump node version in relase ci (backport #3316)
2026-05-08 02:37:05 +05:30
Ritvik Sardana
77640c0955 chore(ci): bump node version in relase ci
(cherry picked from commit 850c054797)
2026-05-07 21:06:51 +00:00
Sydney
e8d04a0fb8 fix: keep images intact in customer portal
(cherry picked from commit 20a2ca833e)
2026-05-07 21:06:18 +00:00
Sydney
0bf40eea89 chore: code cleanup
(cherry picked from commit c0b05f9a34)
2026-05-07 21:03:08 +00:00
Sydney
3034de0f30 fix: add saved replies before signature and fix cursor position
(cherry picked from commit 3c44b626ab)
2026-05-07 21:03:07 +00:00
Sydney Gomes
67ab8364b0 Merge pull request #3309 from frappe/mergify/bp/main-hotfix/pr-3188
feat: email signature (backport #3188)
2026-05-08 02:31:43 +05:30
RitvikSardana
d754919f85 Merge pull request #3314 from frappe/mergify/bp/main-hotfix/pr-3277
fix: SLA Status Logic (backport #3277)
2026-05-08 02:23:48 +05:30
RitvikSardana
c9ff2f5ad3 chore: resolve conflict 2026-05-08 02:17:46 +05:30
Ritvik Sardana
bea506f204 fix: add job for auto updating SLA status
(cherry picked from commit 2c9329368c)

# Conflicts:
#	helpdesk/helpdesk/doctype/hd_ticket/hd_ticket.py
2026-05-07 20:45:18 +00:00
Ritvik Sardana
dc884cefd9 fix: more debounce in contact search
(cherry picked from commit 5bf232771d)
2026-05-07 20:45:18 +00:00
Ritvik Sardana
8716d53533 fix: Contact avatar in ticket view
(cherry picked from commit 36ac5a1332)
2026-05-07 20:45:17 +00:00
Ritvik Sardana
baf4c2e0a8 fix: allow event bubbling in EmailContent
(cherry picked from commit 703d7f0f2b)
2026-05-07 20:45:17 +00:00
Ritvik Sardana
296c72e24b fix: agreement_status logic
(cherry picked from commit a433538aa3)
2026-05-07 20:45:17 +00:00
RitvikSardana
acedd7acf7 Merge pull request #3313 from frappe/mergify/bp/main-hotfix/pr-3272
fix: dont always set default type (backport #3272)
2026-05-08 02:13:32 +05:30
RitvikSardana
9c3d632bbb chore: resolve conflict 2026-05-08 02:08:25 +05:30
Ritvik Sardana
26c1ce1c89 fix: dont change raised by if exists
(cherry picked from commit 1aef41eba9)

# Conflicts:
#	helpdesk/helpdesk/doctype/hd_ticket/hd_ticket.py
2026-05-07 20:35:17 +00:00
Ritvik Sardana
72e5b49888 fix: dont always set default type
(cherry picked from commit c673db3ecd)

# Conflicts:
#	helpdesk/helpdesk/doctype/hd_ticket/hd_ticket.py
2026-05-07 20:35:17 +00:00
RitvikSardana
c691b98b23 Merge pull request #3312 from frappe/mergify/bp/main-hotfix/pr-3271
fix: priority validation (backport #3271)
2026-05-08 02:04:24 +05:30
RitvikSardana
9dde7f298c chore: code cleanup 2026-05-08 01:59:03 +05:30
RitvikSardana
1dcf6d1910 chore: code cleanup 2026-05-08 01:53:09 +05:30
Ritvik Sardana
c46ae6002f fix: show only enabled priorities
(cherry picked from commit 43c7dfca05)
2026-05-07 20:16:51 +00:00
Ritvik Sardana
bb6cedb8d0 fix: layout adjustment in ticket sidepanel
(cherry picked from commit 1d9776aa5a)
2026-05-07 20:16:51 +00:00
Ritvik Sardana
b1fe2cf8dc fix: priority validation
(cherry picked from commit 4acec85d40)
2026-05-07 20:16:51 +00:00
RitvikSardana
3dda124a51 Merge pull request #3270 from frappe/mergify/bp/main-hotfix/pr-3267
fix: add disabled field in ticket priority (backport #3267)
2026-05-08 01:45:19 +05:30
Sydney Gomes
c8d2bceb1b fix: merge conflicts 2026-05-08 01:40:02 +05:30
Sydney Gomes
df9c341db1 feat: email signature (#3188)
* fix: add email signature in frontend

* feat: add email signature in profile frontend

* fix: improve fetching code

* fix: simplfy and improve dirty state handling for signature

* fix: cursor placement bugs and improve editor experience

* fix: remove tiptap focus on end of content code

* fix: remove strict image styles after parsing of image in email content and improve signature editor

* refactor: improve profile section and add preferences section in settings modal

* fix: add autocomplete in place of combobox

* fix: move preferences back to profile and add transitions for badges

* fix: add null check guards and maintain consistency

* fix: remove duplicated code

* fix: keep correct sender in communications and add switching of from email through editor

* fix: add fallback for from as session user if no from mail is found

* fix: expand content on select all for replied content

* fix: add back email content css

* fix: resolve bugs and use email doctype for sender name

* fix: linter issues

* fix: copy changes

* fix: add loading states for button inputs

* fix: use from email through useStorage

* fix: improve code quality

* fix: code cleanup

* fix: add type select back to form control

* fix: sender email bug

* fix: give preference to user info while display communication name

* fix: improve code quality and sync from emails without reload

* fix: use div instead of button for notifications panel

* fix: flicker while selecting from mail

* fix: remove extra padding

* fix: improve dirty badge state in Email Preferences

* fix: reduce number of calls made for emails

* fix: spacing between like and dislike buttons

* fix: improve from email mapping logic and ui fixes

(cherry picked from commit 91c175fcad)

# Conflicts:
#	desk/src/components/EmailContent.vue
#	desk/src/components/EmailEditor.vue
2026-05-07 19:56:58 +00:00
RitvikSardana
ccbe5fb92d Merge pull request #3308 from frappe/mergify/bp/main-hotfix/pr-3260
fix: broken dropdowns in home page (backport #3260)
2026-05-08 01:12:50 +05:30
Sydney
c93e62360c fix: broken dropdowns in home page
(cherry picked from commit 3ca26f4526)
2026-05-07 19:40:50 +00:00
RitvikSardana
8b9f401212 Merge pull request #3307 from frappe/mergify/bp/main-hotfix/pr-3253
fix: update breadcrumbs dropdown code to use new dropdown slots from fui (backport #3253)
2026-05-08 01:03:07 +05:30
Sydney
87742da4c8 fix: border-radius for hover button
(cherry picked from commit 3e06d66288)
2026-05-07 19:29:09 +00:00
Sydney
ba986bc622 fix: add more menu dropdown in list item
(cherry picked from commit cd53d89ef2)
2026-05-07 19:29:09 +00:00
Sydney
7c7e4ccda1 fix: update breadcrumbs dropdown code to use new dropdown slots from frappe ui
(cherry picked from commit 88c47f4157)
2026-05-07 19:29:08 +00:00
RitvikSardana
f12e7d2fc7 Merge pull request #3306 from frappe/mergify/bp/main-hotfix/pr-3251
fix: add message in field allow reply via contact to show ticket message (backport #3251)
2026-05-08 00:57:43 +05:30
Sydney
665a67e5fa fix: ui inconsistency in text in Message header
(cherry picked from commit 1bfa382d9d)
2026-05-07 19:25:06 +00:00
Sydney
75052d77f5 fix: add message field allow reply via contact to show ticket message
(cherry picked from commit 3e1a179767)
2026-05-07 19:25:06 +00:00
RitvikSardana
8d76f2b849 Merge pull request #3305 from frappe/mergify/bp/main-hotfix/pr-3241
fix: mobile ui issues (backport #3241)
2026-05-08 00:43:50 +05:30
Sydney
8a2d6fba6d fix: mobile issues where text was misalligned and agent response was missing
(cherry picked from commit 7bccf8e3e0)
2026-05-07 19:07:00 +00:00
RitvikSardana
b16f7b14a8 Merge pull request #3304 from frappe/mergify/bp/main-hotfix/pr-3232
fix: use v-show instead of v-if (backport #3232)
2026-05-08 00:35:12 +05:30
Ritvik Sardana
0f264e6f09 fix: use v-show instead of v-if
(cherry picked from commit 03e32cf5a2)
2026-05-07 19:02:12 +00:00
RitvikSardana
e87198c78c Merge pull request #3303 from frappe/mergify/bp/main-hotfix/pr-3231
fix: apply saved reply on the email editor (backport #3231)
2026-05-08 00:30:44 +05:30
Ritvik Sardana
c2c1ccc776 fix: apply saved reply on the email editor
(cherry picked from commit 767fdef7b9)
2026-05-07 18:58:35 +00:00
RitvikSardana
b322cbc2fe Merge pull request #3302 from frappe/mergify/bp/main-hotfix/pr-3230
fix: ticket title (backport #3230)
2026-05-08 00:27:12 +05:30
Ritvik Sardana
0fd58a501a fix: ticket title
(cherry picked from commit ce4c09bf39)
2026-05-07 18:56:05 +00:00
RitvikSardana
0207098165 Merge pull request #3301 from frappe/mergify/bp/main-hotfix/pr-3229
fix: indicator color (backport #3229)
2026-05-08 00:25:02 +05:30
Ritvik Sardana
81c324dfba fix: indicator color
(cherry picked from commit 5275aa94ba)
2026-05-07 18:53:42 +00:00
RitvikSardana
8ca98473ca Merge pull request #3300 from frappe/mergify/bp/main-hotfix/pr-3228
fix(ticket-view): padding and font (backport #3228)
2026-05-08 00:22:37 +05:30
Ritvik Sardana
9b80a4f3fd fix(ticket-view): padding and font
(cherry picked from commit f9e920ce37)
2026-05-07 18:50:56 +00:00
RitvikSardana
bdec1ad012 Merge pull request #3299 from frappe/mergify/bp/main-hotfix/pr-3224
fix(ticketAgent): sidepanel and reply icons (backport #3224)
2026-05-08 00:19:57 +05:30
RitvikSardana
8c3dc607be chore: resolve conflict 2026-05-08 00:12:22 +05:30
RitvikSardana
b8ad480c91 chore: resolve conflict 2026-05-08 00:07:03 +05:30
Ritvik Sardana
415e436d8d fix: indicator icon size
(cherry picked from commit c749fb52d7)
2026-05-07 18:32:45 +00:00
Ritvik Sardana
3a90279ce7 fix: better way to show reply buttons
(cherry picked from commit 36417e2b81)
2026-05-07 18:32:44 +00:00
Ritvik Sardana
9aeb6cbb61 fix: show activity header only for calls
(cherry picked from commit 405a0acffe)
2026-05-07 18:32:44 +00:00
Ritvik Sardana
2411b067a7 fix: animation in communication area
(cherry picked from commit 9468c830be)
2026-05-07 18:32:44 +00:00
Ritvik Sardana
caa7642249 fix: dont show border when not needed
(cherry picked from commit 3913f4bbb4)
2026-05-07 18:32:43 +00:00
Ritvik Sardana
4e892492d4 fix: unwanted backend calls
(cherry picked from commit 9f7407869f)
2026-05-07 18:32:43 +00:00
Ritvik Sardana
64434ad45a fix: loading state of activities
(cherry picked from commit c41ed00541)
2026-05-07 18:32:43 +00:00
Ritvik Sardana
ca6e748fb3 fix: assign message
(cherry picked from commit f2040c931f)
2026-05-07 18:32:42 +00:00
Ritvik Sardana
3fec86493c fix: hover state
(cherry picked from commit 3cdad35ae6)

# Conflicts:
#	desk/src/components/ticket-agent/TicketSLA.vue
2026-05-07 18:32:42 +00:00
Ritvik Sardana
c5d99a2b6d fix: sidepanel styles
(cherry picked from commit 62027ba60e)
2026-05-07 18:32:41 +00:00
Ritvik Sardana
4160ecf7ce chore: code cleanup
(cherry picked from commit 874609f674)
2026-05-07 18:32:41 +00:00
Ritvik Sardana
9626ebfe36 fix: dont show unnecessary fields in sidebar
(cherry picked from commit 72d8bae552)
2026-05-07 18:32:40 +00:00
Ritvik Sardana
47ad7876e6 refactor: ticket side panel design
(cherry picked from commit 3b1bfdb02a)

# Conflicts:
#	desk/src/components/Section.vue
#	desk/src/components/ticket-agent/TicketContactTab.vue
#	desk/src/components/ticket-agent/TicketDetailsTab.vue
2026-05-07 18:32:40 +00:00
Ritvik Sardana
e432b2c983 fix: email icon color
(cherry picked from commit 75c3b4845e)
2026-05-07 18:32:39 +00:00
Ritvik Sardana
f7c5321ddf fix: spacing in reply buttons
(cherry picked from commit d24e30ec28)
2026-05-07 18:32:39 +00:00
Ritvik Sardana
efefb0ec13 fix: activity header dropdown placement
(cherry picked from commit 6d8fd5435e)
2026-05-07 18:32:39 +00:00
Ritvik Sardana
197afb5e9d fix: icon width
(cherry picked from commit 1c184f8339)

# Conflicts:
#	desk/src/components/TicketField.vue
2026-05-07 18:32:38 +00:00
RitvikSardana
8fcd933421 Merge pull request #3298 from RitvikSardana/ui-fixes3
fix: UI inconsistency in ticket view (backport #3199)
2026-05-08 00:00:53 +05:30
Ritvik Sardana
e207cf6105 chore: code cleanup 2026-05-07 23:58:15 +05:30
Ritvik Sardana
b57e0b85a6 fix: subject cut in Ticket View 2026-05-07 23:57:54 +05:30
Ritvik Sardana
3e82ff68fd fix: alignment in timeline 2026-05-07 23:57:54 +05:30
Ritvik Sardana
51688f788d chore: remove duplicate code 2026-05-07 23:57:54 +05:30
Ritvik Sardana
b5383a6837 fix: editor styles 2026-05-07 23:57:54 +05:30
Ritvik Sardana
d761866fec fix: add new assignTo component 2026-05-07 23:57:54 +05:30
Ritvik Sardana
774ac1d0c0 fix: breadcrumbs padding 2026-05-07 23:57:54 +05:30
Ritvik Sardana
60cddaad13 fix: layout shift when toggle between contact and details tab 2026-05-07 23:57:54 +05:30
Ritvik Sardana
6daa524bd0 fix(styles): email and comment box 2026-05-07 23:57:54 +05:30
Ritvik Sardana
69513f8816 fix: font-color in To 2026-05-07 23:57:54 +05:30
Ritvik Sardana
068b555d1f fix: resizer in sidebar 2026-05-07 23:57:54 +05:30
Ritvik Sardana
54996c6a4f fix(ticket-sidebar): fix layout overflow and field truncation in details tab 2026-05-07 23:57:54 +05:30
Ritvik Sardana
0e31689c3c fix: max height in side panel 2026-05-07 23:57:54 +05:30
Ritvik Sardana
838b6bb2c3 fix(vite): dedupe prosemirror packages to prevent duplicate instances with local frappe-ui 2026-05-07 23:57:54 +05:30
Ritvik Sardana
75cdfd7889 fix(autocomplete): fix x button overlapping search input text 2026-05-07 23:57:53 +05:30
RitvikSardana
a55a8e4e17 Merge pull request #3296 from frappe/mergify/bp/main-hotfix/pr-3206
fix: filter unexpected behaviour and view routing (backport #3206)
2026-05-07 23:48:33 +05:30
Sydney
0111e0b979 fix: remove row click routing to ticket
(cherry picked from commit c780b3b60f)
2026-05-07 18:13:09 +00:00
Sydney
dd3397d697 fix: revert a11y code added for tab navigation in list view
(cherry picked from commit e0c04bcc41)
2026-05-07 18:13:08 +00:00
Sydney
2762f0fe0e fix: backport agent landing page fixes 2026-05-07 15:05:53 +05:30
Sydney Gomes
ac4fc0e2e1 Merge pull request #3293 from aerodeval/backport-agent-landing
feat: add agent landing page (backport #2796)
2026-05-07 14:12:45 +05:30
Sydney
4c528042e0 fix: breaking test cases 2026-05-07 14:03:30 +05:30
Sydney
bf7ac3e5ac fix: backport agent landing page 2026-05-07 13:16:54 +05:30
Sydney Gomes
efae5ce262 Merge pull request #3201 from frappe/mergify/bp/main-hotfix/pr-2969
refactor: fix UI inconsistency all over Helpdesk (backport #2969)
2026-05-07 02:12:35 +05:30
Sydney
1cf5db09aa fix: broken test cases 2026-05-07 02:05:31 +05:30
Sydney
93ebf04dcc fix: merge conflicts 2026-05-07 01:53:22 +05:30
Sydney Gomes
4223b4d51f Merge branch 'main-hotfix' into mergify/bp/main-hotfix/pr-2969 2026-05-07 01:34:37 +05:30
RitvikSardana
05897bdf9d Merge pull request #3291 from frappe/main-hotfix
chore(release): hotfix to main
2026-05-06 18:50:13 +05:30
RitvikSardana
14a8a7eba6 Merge pull request #3290 from frappe/mergify/bp/main-hotfix/pr-3289
chore: telephony version (backport #3289)
2026-05-06 18:49:01 +05:30
RitvikSardana
e169b7c7fe chore: resolve conflice 2026-05-06 18:47:36 +05:30
Ritvik Sardana
fb48d91bc1 chore: telephony version
(cherry picked from commit 356170dea7)

# Conflicts:
#	pyproject.toml
2026-05-06 13:14:47 +00:00
RitvikSardana
1252eabcfb Merge pull request #3287 from frappe/main-hotfix
chore(release): hotfix to main
2026-05-06 14:20:16 +05:30
RitvikSardana
7e330dc662 Merge pull request #3286 from frappe/mergify/bp/main-hotfix/pr-3285
Revert "chore: add telephony dependency" (backport #3285)
2026-05-06 14:19:41 +05:30
RitvikSardana
e9ffb19362 chore: resolve conflict 2026-05-06 14:19:28 +05:30
RitvikSardana
36333b7f1d Revert "chore: add telephony dependency"
(cherry picked from commit f56b112cec)

# Conflicts:
#	pyproject.toml
2026-05-06 08:48:38 +00:00
Frappe PR Bot
032f9e079d chore(release): Bumped to Version 1.23.0 2026-05-06 07:30:03 +00:00
RitvikSardana
ec58d27abf Merge pull request #3284 from frappe/main-hotfix
chore(release): hotfix to main
2026-05-06 12:59:33 +05:30
RitvikSardana
d7117bc225 Merge pull request #3283 from frappe/mergify/bp/main-hotfix/pr-3282
chore: add telephony dependency (backport #3282)
2026-05-06 11:47:48 +05:30
RitvikSardana
b3ea74539f chore: resolve conflict 2026-05-06 11:41:46 +05:30
Ritvik Sardana
c17041606d chore: update version
(cherry picked from commit 05415f77ef)

# Conflicts:
#	pyproject.toml
2026-05-06 06:10:19 +00:00
Ritvik Sardana
b0b9394324 chore: add telephony dependency
(cherry picked from commit e0d1031f17)

# Conflicts:
#	pyproject.toml
2026-05-06 06:10:19 +00:00
RitvikSardana
4ceafbcc64 Merge pull request #3281 from frappe/mergify/bp/main-hotfix/pr-3275
chore: sync translations from crowdin (backport #3275)
2026-05-05 20:12:58 +05:30
MochaMind
68a7a34605 chore: Esperanto translations
(cherry picked from commit f756f0fbd2)
2026-05-05 11:06:09 +00:00
MochaMind
5a69d72052 chore: Russian translations
(cherry picked from commit e1093e39e2)
2026-05-05 11:06:09 +00:00
MochaMind
4ccad8d3ec chore: Serbian (Latin) translations
(cherry picked from commit e55533a2f4)
2026-05-05 11:06:08 +00:00
MochaMind
e11fdc6057 chore: Norwegian Bokmal translations
(cherry picked from commit a015642c9e)
2026-05-05 11:06:08 +00:00
MochaMind
1664830d16 chore: Bosnian translations
(cherry picked from commit 7b872266f7)
2026-05-05 11:06:08 +00:00
MochaMind
7e437b08d1 chore: Burmese translations
(cherry picked from commit 34d400e8d7)
2026-05-05 11:06:07 +00:00
MochaMind
68efd51796 chore: Croatian translations
(cherry picked from commit 912097c157)
2026-05-05 11:06:07 +00:00
MochaMind
8aed2d8659 chore: Thai translations
(cherry picked from commit 13e63be3ce)
2026-05-05 11:06:07 +00:00
MochaMind
aa0f16460e chore: Persian translations
(cherry picked from commit e6aecafb8b)
2026-05-05 11:06:07 +00:00
MochaMind
d80f09ebd3 chore: Indonesian translations
(cherry picked from commit 8d506f283b)
2026-05-05 11:06:06 +00:00
MochaMind
8a6cfb458a chore: Portuguese, Brazilian translations
(cherry picked from commit 9bb524882d)
2026-05-05 11:06:06 +00:00
MochaMind
e27cfd63d4 chore: Vietnamese translations
(cherry picked from commit 2c86d2ebb4)
2026-05-05 11:06:06 +00:00
MochaMind
3952ec39e4 chore: Chinese Simplified translations
(cherry picked from commit 283094dcfb)
2026-05-05 11:06:06 +00:00
MochaMind
62313c4eab chore: Turkish translations
(cherry picked from commit ec5aa09e54)
2026-05-05 11:06:05 +00:00
MochaMind
04c519c9c2 chore: Swedish translations
(cherry picked from commit d57e18111d)
2026-05-05 11:06:05 +00:00
MochaMind
7349b7ad7c chore: Serbian (Cyrillic) translations
(cherry picked from commit 8c837b36e4)
2026-05-05 11:06:05 +00:00
MochaMind
e26b94afbb chore: Slovenian translations
(cherry picked from commit 67dd674b69)
2026-05-05 11:06:05 +00:00
MochaMind
7d550fe96b chore: Portuguese translations
(cherry picked from commit 6b3f0f8b39)
2026-05-05 11:06:04 +00:00
MochaMind
6249038c39 chore: Polish translations
(cherry picked from commit 727b3e598d)
2026-05-05 11:06:04 +00:00
MochaMind
9871d521a6 chore: Dutch translations
(cherry picked from commit 46cf803665)
2026-05-05 11:06:04 +00:00
MochaMind
6a2f0194e5 chore: Italian translations
(cherry picked from commit e7b6858113)
2026-05-05 11:06:04 +00:00
MochaMind
442792f7fa chore: Hungarian translations
(cherry picked from commit 9f5041bd68)
2026-05-05 11:06:03 +00:00
MochaMind
9f212895f7 chore: German translations
(cherry picked from commit ed3b2eab9c)
2026-05-05 11:06:03 +00:00
MochaMind
480ba1d983 chore: Danish translations
(cherry picked from commit dd9d512b9b)
2026-05-05 11:06:03 +00:00
MochaMind
8e56ce4735 chore: Czech translations
(cherry picked from commit 16f645dc9d)
2026-05-05 11:06:03 +00:00
MochaMind
904b9df8c2 chore: Arabic translations
(cherry picked from commit bbee7e0e0a)
2026-05-05 11:06:02 +00:00
MochaMind
563509c7a4 chore: Spanish translations
(cherry picked from commit 2b648194e0)
2026-05-05 11:06:02 +00:00
MochaMind
2a33c4f2b3 chore: French translations
(cherry picked from commit 01f1b2bc6a)
2026-05-05 11:06:02 +00:00
RitvikSardana
316b5d2a4e Merge pull request #3274 from frappe/mergify/bp/main-hotfix/pr-3273
chore: update POT file (backport #3273)
2026-05-04 10:45:23 +05:30
frappe-pr-bot
9ac517257c chore: update POT file
(cherry picked from commit 079f50508a)
2026-05-04 05:08:05 +00:00
Ritvik Sardana
e5c92df923 chore: code cleanup
(cherry picked from commit b7750f8172)
2026-05-01 08:01:54 +00:00
Ritvik Sardana
bf358d4247 test: team and assignment rule creation
(cherry picked from commit c29dba481b)
2026-05-01 08:01:53 +00:00
Ritvik Sardana
8a6bcd2739 test: setting ticket_type in hd_ticket
(cherry picked from commit c3e496ff4a)
2026-05-01 08:01:53 +00:00
Ritvik Sardana
fe8bb51b84 fix: add disable field in ticket priority
(cherry picked from commit d2ee2ea9f2)
2026-05-01 08:01:52 +00:00
RitvikSardana
728f9cde95 Merge pull request #3269 from frappe/mergify/bp/main-hotfix/pr-3268
chore: sync translations from crowdin (backport #3268)
2026-05-01 13:07:37 +05:30
MochaMind
8fe8317675 chore: Esperanto translations
(cherry picked from commit c66181a50d)
2026-05-01 07:01:01 +00:00
MochaMind
6cdbb57681 chore: Russian translations
(cherry picked from commit c34a5ed7fd)
2026-05-01 07:01:01 +00:00
MochaMind
f4ac752eb6 chore: Serbian (Latin) translations
(cherry picked from commit 2282bc310f)
2026-05-01 07:01:00 +00:00
MochaMind
54e3c5d6c8 chore: Norwegian Bokmal translations
(cherry picked from commit d5ccac5333)
2026-05-01 07:01:00 +00:00
MochaMind
f9e0394766 chore: Bosnian translations
(cherry picked from commit 4cb8e00353)
2026-05-01 07:01:00 +00:00
MochaMind
1bcc245efd chore: Burmese translations
(cherry picked from commit c82e2030f2)
2026-05-01 07:00:59 +00:00
MochaMind
1662911fab chore: Croatian translations
(cherry picked from commit 6bd5307664)
2026-05-01 07:00:59 +00:00
MochaMind
c7f9b189c9 chore: Thai translations
(cherry picked from commit 52668e07b7)
2026-05-01 07:00:59 +00:00
MochaMind
23a94ab0a1 chore: Persian translations
(cherry picked from commit cdfc59df2e)
2026-05-01 07:00:58 +00:00
MochaMind
643d5bd650 chore: Indonesian translations
(cherry picked from commit 805c400798)
2026-05-01 07:00:58 +00:00
MochaMind
97dea3cd25 chore: Portuguese, Brazilian translations
(cherry picked from commit 50d745c29f)
2026-05-01 07:00:57 +00:00
MochaMind
de8a5d9584 chore: Vietnamese translations
(cherry picked from commit 85df9cbba9)
2026-05-01 07:00:57 +00:00
MochaMind
0cc98175ee chore: Chinese Simplified translations
(cherry picked from commit 29251e84fb)
2026-05-01 07:00:57 +00:00
MochaMind
dcd7e650e5 chore: Turkish translations
(cherry picked from commit 801394b84b)
2026-05-01 07:00:56 +00:00
MochaMind
99a03928eb chore: Swedish translations
(cherry picked from commit 8ece98ff2e)
2026-05-01 07:00:56 +00:00
MochaMind
9a51344b40 chore: Serbian (Cyrillic) translations
(cherry picked from commit 66c925150e)
2026-05-01 07:00:56 +00:00
MochaMind
93839ab8ec chore: Slovenian translations
(cherry picked from commit 20f6071b95)
2026-05-01 07:00:55 +00:00
MochaMind
e94ff9caab chore: Portuguese translations
(cherry picked from commit c543cb1c88)
2026-05-01 07:00:55 +00:00
MochaMind
cfb2f6136b chore: Polish translations
(cherry picked from commit aa91da426e)
2026-05-01 07:00:55 +00:00
MochaMind
880841267b chore: Dutch translations
(cherry picked from commit d3819bc77e)
2026-05-01 07:00:54 +00:00
MochaMind
e5a4110842 chore: Italian translations
(cherry picked from commit 9869ffa2b5)
2026-05-01 07:00:54 +00:00
MochaMind
e96e0d6903 chore: Hungarian translations
(cherry picked from commit 3fd6a01d58)
2026-05-01 07:00:54 +00:00
MochaMind
96a555e5d0 chore: German translations
(cherry picked from commit 2f5ed0760e)
2026-05-01 07:00:53 +00:00
MochaMind
77c30a0e97 chore: Danish translations
(cherry picked from commit e87dc69716)
2026-05-01 07:00:53 +00:00
MochaMind
4f29baa525 chore: Czech translations
(cherry picked from commit 557dc5b914)
2026-05-01 07:00:53 +00:00
MochaMind
3c90db49a5 chore: Arabic translations
(cherry picked from commit 676a44820e)
2026-05-01 07:00:52 +00:00
MochaMind
d99b1841ff chore: Spanish translations
(cherry picked from commit a896503b68)
2026-05-01 07:00:52 +00:00
MochaMind
7c47bac15a chore: French translations
(cherry picked from commit cd3f23df2a)
2026-05-01 07:00:52 +00:00
RitvikSardana
a4103e28d4 Merge pull request #3265 from frappe/mergify/bp/main-hotfix/pr-2821
ci: setup semantic-release gh workflow (backport #2821)
2026-05-01 12:29:54 +05:30
KerollesFathy
d96aa29250 fix: move release.yml to workflows dir
(cherry picked from commit 782313a084)
2026-04-30 05:35:03 +00:00
KerollesFathy
18bb6962a8 ci: setup semantic-release workflow
(cherry picked from commit df2270a9c8)
2026-04-30 05:35:03 +00:00
RitvikSardana
1f907e6580 Merge pull request #3222 from frappe/mergify/bp/main-hotfix/pr-3221
fix: placeholder color (backport #3221)
2026-04-30 10:42:11 +05:30
RitvikSardana
a4abde214c Merge pull request #3264 from frappe/mergify/bp/main-hotfix/pr-3249
chore: update POT file (backport #3249)
2026-04-30 10:38:59 +05:30
RitvikSardana
4adc3411b8 chore: resolve conflict 2026-04-30 10:36:09 +05:30
frappe-pr-bot
c1116032ac chore: update POT file
(cherry picked from commit 75da8a7880)

# Conflicts:
#	helpdesk/locale/main.pot
2026-04-30 04:56:08 +00:00
RitvikSardana
1a0f0eef5b Merge pull request #3263 from frappe/mergify/bp/main-hotfix/pr-3219
chore: update POT file (backport #3219)
2026-04-30 10:22:14 +05:30
RitvikSardana
a6f0e5e88d chore: resolve conflict 2026-04-30 10:19:54 +05:30
frappe-pr-bot
16e8b0096c chore: update POT file
(cherry picked from commit 5ee0d85dfc)

# Conflicts:
#	helpdesk/locale/main.pot
2026-04-30 04:46:47 +00:00
RitvikSardana
b11736e7dd Merge pull request #3262 from frappe/mergify/bp/main-hotfix/pr-3212
chore: update POT file (backport #3212)
2026-04-30 10:13:24 +05:30
frappe-pr-bot
43d700eb6d chore: update POT file
(cherry picked from commit 171e92ce23)
2026-04-30 04:42:13 +00:00
RitvikSardana
aea0887c05 Merge pull request #3261 from frappe/mergify/bp/main-hotfix/pr-3202
chore: sync translations from crowdin (backport #3202)
2026-04-30 09:54:05 +05:30
MochaMind
14345c18fa chore: Burmese translations
(cherry picked from commit 2cc25cdc6a)
2026-04-30 04:22:30 +00:00
MochaMind
b34c63fc3a chore: Persian translations
(cherry picked from commit 8e7ae52bd8)
2026-04-30 04:22:30 +00:00
MochaMind
3656e95c4b chore: Indonesian translations
(cherry picked from commit 207970f51f)
2026-04-30 04:22:30 +00:00
MochaMind
c0f912f2a5 chore: Portuguese, Brazilian translations
(cherry picked from commit 05e6a2ab8f)
2026-04-30 04:22:29 +00:00
MochaMind
2f0ecbb8f7 chore: Turkish translations
(cherry picked from commit 7079d22504)
2026-04-30 04:22:29 +00:00
MochaMind
0c158ac7bd chore: Slovenian translations
(cherry picked from commit 7591625336)
2026-04-30 04:22:29 +00:00
MochaMind
754a44ddcf chore: Portuguese translations
(cherry picked from commit ff6f299b6b)
2026-04-30 04:22:28 +00:00
MochaMind
c828d26e34 chore: Polish translations
(cherry picked from commit cbf3acdd02)
2026-04-30 04:22:28 +00:00
MochaMind
529c4ac0f6 chore: Dutch translations
(cherry picked from commit 16e3cf109b)
2026-04-30 04:22:27 +00:00
MochaMind
393e575f1d chore: Italian translations
(cherry picked from commit a58c2ff9b1)
2026-04-30 04:22:27 +00:00
MochaMind
a93b0eb1ec chore: Danish translations
(cherry picked from commit 6d1b35afa5)
2026-04-30 04:22:27 +00:00
MochaMind
c1b9a2ca55 chore: Czech translations
(cherry picked from commit 4a00bcaec9)
2026-04-30 04:22:26 +00:00
MochaMind
2aaab4e2be chore: French translations
(cherry picked from commit b072a11c3e)
2026-04-30 04:22:26 +00:00
MochaMind
1432f294d1 chore: Indonesian translations
(cherry picked from commit 4b970831b3)
2026-04-30 04:22:26 +00:00
MochaMind
95b4ee40e8 chore: Portuguese, Brazilian translations
(cherry picked from commit 255662d424)
2026-04-30 04:22:25 +00:00
MochaMind
b2fc2a0359 chore: Portuguese translations
(cherry picked from commit b7112f939f)
2026-04-30 04:22:25 +00:00
MochaMind
58a282d471 chore: Polish translations
(cherry picked from commit 28fc229779)
2026-04-30 04:22:25 +00:00
MochaMind
ab967f167d chore: Italian translations
(cherry picked from commit 6583968b20)
2026-04-30 04:22:24 +00:00
MochaMind
35f8fff2bb chore: Danish translations
(cherry picked from commit d25f12e666)
2026-04-30 04:22:24 +00:00
MochaMind
2441f3399e chore: French translations
(cherry picked from commit 650275150a)
2026-04-30 04:22:23 +00:00
MochaMind
2d6ea323da chore: Burmese translations
(cherry picked from commit ff16b9dea7)
2026-04-30 04:22:23 +00:00
MochaMind
6f690967d8 chore: Persian translations
(cherry picked from commit 67778b4022)
2026-04-30 04:22:23 +00:00
MochaMind
5414599e86 chore: Indonesian translations
(cherry picked from commit 5a71390b3d)
2026-04-30 04:22:22 +00:00
MochaMind
56eab74c82 chore: Portuguese, Brazilian translations
(cherry picked from commit 823a3772fe)
2026-04-30 04:22:22 +00:00
MochaMind
56521c47a8 chore: Turkish translations
(cherry picked from commit bfdce5a65c)
2026-04-30 04:22:21 +00:00
MochaMind
0ad0637f84 chore: Slovenian translations
(cherry picked from commit 56ea1c109d)
2026-04-30 04:22:21 +00:00
MochaMind
01d6de31a5 chore: Portuguese translations
(cherry picked from commit ae646e71d9)
2026-04-30 04:22:20 +00:00
MochaMind
35b77f762b chore: Polish translations
(cherry picked from commit 210e96452b)
2026-04-30 04:22:20 +00:00
MochaMind
f7acf24970 chore: Italian translations
(cherry picked from commit a9cb7597d6)
2026-04-30 04:22:19 +00:00
MochaMind
b89ec8cc4e chore: Hungarian translations
(cherry picked from commit d2120fdf62)
2026-04-30 04:22:19 +00:00
MochaMind
7367f7d961 chore: Danish translations
(cherry picked from commit 7d9ed7dfe6)
2026-04-30 04:22:18 +00:00
MochaMind
0a28c9a92e chore: Czech translations
(cherry picked from commit f770dedb7f)
2026-04-30 04:22:18 +00:00
MochaMind
ef38f84039 chore: French translations
(cherry picked from commit d541ef0980)
2026-04-30 04:22:17 +00:00
MochaMind
e681b52615 chore: Burmese translations
(cherry picked from commit 2e6a271561)
2026-04-30 04:22:17 +00:00
MochaMind
44fb4a7e72 chore: Persian translations
(cherry picked from commit fa672a3e8b)
2026-04-30 04:22:16 +00:00
MochaMind
950a358cbf chore: Indonesian translations
(cherry picked from commit 208ee525b7)
2026-04-30 04:22:16 +00:00
MochaMind
74b237e7bb chore: Portuguese, Brazilian translations
(cherry picked from commit 8ac14bb462)
2026-04-30 04:22:16 +00:00
MochaMind
2d89f5317e chore: Vietnamese translations
(cherry picked from commit f1a973b1c6)
2026-04-30 04:22:15 +00:00
MochaMind
6da5d2794c chore: Turkish translations
(cherry picked from commit a7a974b41e)
2026-04-30 04:22:15 +00:00
MochaMind
9b51a36afe chore: Slovenian translations
(cherry picked from commit 5a2646d951)
2026-04-30 04:22:15 +00:00
MochaMind
03a59ac9aa chore: Portuguese translations
(cherry picked from commit 9d9570fd71)
2026-04-30 04:22:14 +00:00
MochaMind
83e3066f1c chore: Polish translations
(cherry picked from commit 86b5ca7b79)
2026-04-30 04:22:14 +00:00
MochaMind
5f4db9f44c chore: Dutch translations
(cherry picked from commit 616f1ccb09)
2026-04-30 04:22:13 +00:00
MochaMind
975502127b chore: Italian translations
(cherry picked from commit 155d4d4932)
2026-04-30 04:22:13 +00:00
MochaMind
d35f01681b chore: Danish translations
(cherry picked from commit 1eaaf2f58e)
2026-04-30 04:22:13 +00:00
MochaMind
4463f22390 chore: Czech translations
(cherry picked from commit de60d726c1)
2026-04-30 04:22:12 +00:00
MochaMind
806dccb135 chore: Spanish translations
(cherry picked from commit 00ac7b9c9d)
2026-04-30 04:22:12 +00:00
MochaMind
2194d9e313 chore: French translations
(cherry picked from commit 571373bd0c)
2026-04-30 04:22:12 +00:00
MochaMind
ac747bc812 chore: Burmese translations
(cherry picked from commit 090cceca70)
2026-04-30 04:22:11 +00:00
MochaMind
82267b9287 chore: Persian translations
(cherry picked from commit a9975abb12)
2026-04-30 04:22:11 +00:00
MochaMind
e052cd35df chore: Indonesian translations
(cherry picked from commit b7cd6c1b11)
2026-04-30 04:22:10 +00:00
MochaMind
e60c21280e chore: Portuguese, Brazilian translations
(cherry picked from commit d1c76d940d)
2026-04-30 04:22:10 +00:00
MochaMind
57743d3da0 chore: Vietnamese translations
(cherry picked from commit 6abc29f5f0)
2026-04-30 04:22:10 +00:00
MochaMind
05495e0fed chore: Turkish translations
(cherry picked from commit 37e472c377)
2026-04-30 04:22:09 +00:00
MochaMind
d844322628 chore: Slovenian translations
(cherry picked from commit 0b24d4481e)
2026-04-30 04:22:09 +00:00
MochaMind
0a2a340a28 chore: Portuguese translations
(cherry picked from commit 7c631a47d2)
2026-04-30 04:22:09 +00:00
MochaMind
3e5874ad74 chore: Polish translations
(cherry picked from commit 8a3f31b37a)
2026-04-30 04:22:08 +00:00
MochaMind
dde2fe349d chore: Italian translations
(cherry picked from commit e900050d5b)
2026-04-30 04:22:08 +00:00
MochaMind
b2d875de4d chore: Danish translations
(cherry picked from commit 826cebc1c8)
2026-04-30 04:22:08 +00:00
MochaMind
f612bae8bf chore: Czech translations
(cherry picked from commit b245b67999)
2026-04-30 04:22:07 +00:00
MochaMind
c7db8f65f3 chore: French translations
(cherry picked from commit e8d40fb369)
2026-04-30 04:22:07 +00:00
MochaMind
93f22e57a0 chore: Thai translations
(cherry picked from commit 9106b8cf2f)
2026-04-30 04:22:06 +00:00
MochaMind
1870690a12 chore: Croatian translations
(cherry picked from commit 2c718daf3c)
2026-04-30 04:22:06 +00:00
MochaMind
0bb76e23d5 chore: Swedish translations
(cherry picked from commit dfccb2f813)
2026-04-30 04:22:06 +00:00
MochaMind
d1a91ab53b chore: German translations
(cherry picked from commit 0a40369688)
2026-04-30 04:22:05 +00:00
MochaMind
cfd8eac256 chore: Esperanto translations
(cherry picked from commit a460667826)
2026-04-30 04:22:05 +00:00
MochaMind
8a17e941c4 chore: Russian translations
(cherry picked from commit e56454ed41)
2026-04-30 04:22:05 +00:00
MochaMind
673b20a5dd chore: Serbian (Latin) translations
(cherry picked from commit ca5cb4677a)
2026-04-30 04:22:04 +00:00
MochaMind
a8f54b3b11 chore: Norwegian Bokmal translations
(cherry picked from commit ae19aaf296)
2026-04-30 04:22:04 +00:00
MochaMind
3c52145c84 chore: Bosnian translations
(cherry picked from commit 45710b3af1)
2026-04-30 04:22:04 +00:00
MochaMind
a1b9eb0179 chore: Burmese translations
(cherry picked from commit 4b66df45fc)
2026-04-30 04:22:03 +00:00
MochaMind
872879ffbc chore: Croatian translations
(cherry picked from commit e1e6975728)
2026-04-30 04:22:03 +00:00
MochaMind
dce1ed841b chore: Thai translations
(cherry picked from commit c1adfa0c5d)
2026-04-30 04:22:03 +00:00
MochaMind
8905f54ce2 chore: Persian translations
(cherry picked from commit 689a0a36e0)
2026-04-30 04:22:02 +00:00
MochaMind
47a66ade25 chore: Indonesian translations
(cherry picked from commit edacc94a74)
2026-04-30 04:22:02 +00:00
MochaMind
593f3e2668 chore: Portuguese, Brazilian translations
(cherry picked from commit c72fddfea0)
2026-04-30 04:22:02 +00:00
MochaMind
d5f57543e6 chore: Vietnamese translations
(cherry picked from commit aaf6e8c8f0)
2026-04-30 04:22:01 +00:00
MochaMind
62aa1c14fd chore: Chinese Simplified translations
(cherry picked from commit f8c92eaece)
2026-04-30 04:22:01 +00:00
MochaMind
b59bd640ed chore: Turkish translations
(cherry picked from commit e4f4294601)
2026-04-30 04:22:01 +00:00
MochaMind
a11ca2e23e chore: Swedish translations
(cherry picked from commit bb3a2f75c5)
2026-04-30 04:22:00 +00:00
MochaMind
18ca176ce0 chore: Serbian (Cyrillic) translations
(cherry picked from commit 1f19dbd72c)
2026-04-30 04:22:00 +00:00
MochaMind
8eaeebd730 chore: Slovenian translations
(cherry picked from commit c4c39d30ec)
2026-04-30 04:21:59 +00:00
MochaMind
d95250ef8d chore: Portuguese translations
(cherry picked from commit 1e3dd15269)
2026-04-30 04:21:59 +00:00
MochaMind
02533e858d chore: Polish translations
(cherry picked from commit 3a76af7b46)
2026-04-30 04:21:59 +00:00
MochaMind
a5988ae7ff chore: Dutch translations
(cherry picked from commit ae91fde698)
2026-04-30 04:21:59 +00:00
MochaMind
ef31a68560 chore: Italian translations
(cherry picked from commit 1a758ac4a2)
2026-04-30 04:21:58 +00:00
MochaMind
778ef82054 chore: Hungarian translations
(cherry picked from commit 588d5624d2)
2026-04-30 04:21:58 +00:00
MochaMind
6774a7be03 chore: German translations
(cherry picked from commit c26e1ba9b8)
2026-04-30 04:21:58 +00:00
MochaMind
79eda30776 chore: Danish translations
(cherry picked from commit cb184d6301)
2026-04-30 04:21:57 +00:00
MochaMind
444cc943fa chore: Czech translations
(cherry picked from commit 80cccf6864)
2026-04-30 04:21:57 +00:00
MochaMind
b52bc29b4c chore: Arabic translations
(cherry picked from commit 69379c3560)
2026-04-30 04:21:57 +00:00
MochaMind
5921dc5722 chore: Spanish translations
(cherry picked from commit 9e56ae2e11)
2026-04-30 04:21:56 +00:00
MochaMind
e2f5a4a7a6 chore: French translations
(cherry picked from commit 5c2b2f5e81)
2026-04-30 04:21:56 +00:00
Sydney Gomes
6e7b3a253b Merge pull request #3259 from frappe/mergify/bp/main-hotfix/pr-3215
fix: handle missing headers in email threading (backport #3215)
2026-04-29 15:57:31 +05:30
Sydney Gomes
939ff58b77 Merge pull request #3220 from frappe/mergify/bp/main-hotfix/pr-3211
fix: add clear formatting utility in text editor (backport #3211)
2026-04-29 15:56:14 +05:30
Sydney
4453017fc3 fix: improve logic for threading and cleanup code
(cherry picked from commit 11c8e281d8)
2026-04-29 10:22:03 +00:00
Sydney
72bf05fff3 fix: handle forwarded and missing headers in email threading
(cherry picked from commit 3257a438f6)
2026-04-29 10:22:03 +00:00
Sydney
436b7d3dac fix: spacing between like and dislike buttons
(cherry picked from commit 1fbf122261)
2026-04-29 10:21:28 +00:00
Sydney
3c76b8d22e fix: article layouting
(cherry picked from commit 38e5f06913)

# Conflicts:
#	desk/src/pages/knowledge-base/Article.vue
2026-04-29 10:21:28 +00:00
RitvikSardana
11f74d65bd Merge pull request #3226 from frappe/main-hotfix
chore(release): hotfix to main
2026-04-22 00:14:31 +05:30
RitvikSardana
4a0c34477a Merge branch 'main' into main-hotfix 2026-04-21 23:52:29 +05:30
RitvikSardana
9821e46012 chore: version bump 2026-04-21 23:50:42 +05:30
RitvikSardana
90e49cab7f Merge pull request #3225 from frappe/mergify/bp/main-hotfix/pr-3223
fix: restrict Helpdesk app visibility by role (backport #3223)
2026-04-21 23:22:21 +05:30
Ritvik Sardana
eaf3923a9d chore: code cleanup
(cherry picked from commit 51824e90ff)
2026-04-21 17:10:27 +00:00
Faris Ansari
fcba625540 fix: restrict helpdesk app visibility by role
(cherry picked from commit d8181027d3)
2026-04-21 17:10:27 +00:00
RitvikSardana
b4d9164972 chore: resolve merge conflict 2026-04-20 09:18:19 +05:30
Ritvik Sardana
067ed85b38 fix: placeholder color
(cherry picked from commit 0932744558)

# Conflicts:
#	desk/src/components/Autocomplete.vue
#	desk/src/components/frappe-ui/Autocomplete.vue
2026-04-20 03:46:58 +00:00
Sydney
035cb0fe0c fix: add extenstion for text editor used in customer portal
(cherry picked from commit 0aab4f694f)
2026-04-19 16:27:15 +00:00
Sydney
f1e74cfbfb fix: reorganise utilities in customer ticket portal
(cherry picked from commit dc40aab97a)
2026-04-19 16:27:15 +00:00
Sydney
4f5fdc89aa fix: improve grouping of editor utilities
(cherry picked from commit d9c6992a73)
2026-04-19 16:27:15 +00:00
Sydney
d3c8bd30eb chore: improve formatting of css code
(cherry picked from commit 3a6798d6b0)
2026-04-19 16:27:14 +00:00
Sydney
6a7231060d fix: add stricter selection for pre tags
(cherry picked from commit fd1ff8fffd)
2026-04-19 16:27:14 +00:00
Sydney
9ead1c3b9a feat: add clear formatting utility for all text editor based components
(cherry picked from commit 3fac3ab859)
2026-04-19 16:27:14 +00:00
Sydney
72a48a5027 fix: add proper direction handling based on text and fix pre tag bugs
(cherry picked from commit 2b9209a859)
2026-04-19 16:27:13 +00:00
RitvikSardana
b15016fbd2 Merge pull request #3198 from frappe/mergify/bp/main-hotfix/pr-3065
fix: patch authorization and privilege escalation (backport #3065)
2026-04-14 19:23:47 +05:30
RitvikSardana
b94e46aa1f Merge pull request #3217 from dankgarlic1/fix-mergify-hotfix
chore: auto-format test file using black
2026-04-14 19:18:48 +05:30
Harshit Raizada
9e336dafdc chore: auto-format test file using black 2026-04-14 16:26:55 +05:30
RitvikSardana
0ae782acf0 Merge pull request #3216 from dankgarlic1/fix-mergify-hotfix
fix: test isolation and override in_test bypass for security checks
2026-04-14 15:59:45 +05:30
Harshit Raizada
b2c841ef3d fix: test isolation and override in_test bypass for security checks 2026-04-14 02:25:43 +05:30
RitvikSardana
0fd76cc430 chore: code cleanup 2026-04-13 23:14:55 +05:30
Sydney Gomes
5ce49fb7fb Merge pull request #3200 from frappe/mergify/bp/main-hotfix/pr-3175
fix: truncate text for translations in settings menu (backport #3175)
2026-04-10 18:26:44 +05:30
Sydney
7cc400a3ca fix: remove merge conflicts 2026-04-10 18:17:58 +05:30
RitvikSardana
993245ffa6 chore: resolve conflict 2026-04-08 00:38:19 +05:30
Sydney Gomes
1da703f861 fix: solve merge conflicts 2026-04-06 17:18:10 +05:30
Sydney Gomes
2abb2e108b Merge pull request #2969 from aerodeval/fix/-fix-ui-inconsistency
refactor: fix UI inconsistency all over Helpdesk
(cherry picked from commit 15b246e31a)

# Conflicts:
#	desk/src/components/Settings/Telephony/Telephony.vue
#	desk/src/components/layouts/layoutSettings.ts
#	desk/src/components/view-controls/QuickFilters.vue
#	desk/src/pages/dashboard/Dashboard.vue
#	desk/src/pages/ticket/TicketAgent.vue
#	desk/src/pages/ticket/Tickets.vue
#	package.json
2026-04-06 11:37:07 +00:00
Sydney
f5bb8dd3b4 fix: add translation for tooltip labels
(cherry picked from commit 4b458035f0)

# Conflicts:
#	desk/src/components/Settings/SettingsModal.vue
2026-04-06 10:40:12 +00:00
Sydney
c849132ca1 fix: truncation bugs for mobile and sidebar
(cherry picked from commit c3079c9061)

# Conflicts:
#	desk/src/components/Settings/SettingsModal.vue
2026-04-06 10:40:12 +00:00
Sydney
1a75162626 fix: truncate text for translations in settings menu
(cherry picked from commit 2d583532fd)

# Conflicts:
#	desk/src/components/Settings/SettingsModal.vue
2026-04-06 10:40:12 +00:00
Harshit Raizada
975e7bf04d fix: remove manual override of frappe in_test flag
(cherry picked from commit 2f0689bf5f)
2026-04-06 10:20:06 +00:00
Ritvik Sardana
b77819ee7e chore: remove unwanted code
(cherry picked from commit 22647bbba2)
2026-04-06 10:20:05 +00:00
Harshit Raizada
2594183b05 fix: address reviewer comments
(cherry picked from commit 95bfd47f92)
2026-04-06 10:20:05 +00:00
Harshit Raizada
85ac217596 fix: isort ordering for frappe imports
(cherry picked from commit 03fb98df2f)

# Conflicts:
#	helpdesk/helpdesk/doctype/hd_ticket/test_hd_ticket.py
2026-04-06 10:20:05 +00:00
Harshit Raizada
119a56a94a chore(format): fix linting and formatting for CI
(cherry picked from commit 90a3319825)

# Conflicts:
#	helpdesk/helpdesk/doctype/hd_ticket/test_hd_ticket.py
2026-04-06 10:20:04 +00:00
Harshit Raizada
9fe63f4a25 chore(underscore): removed extra underscore
(cherry picked from commit f339ea98fb)
2026-04-06 10:20:03 +00:00
Harshit Raizada
3978a653e9 chore(leftover): forgot to stage
(cherry picked from commit 738909db35)
2026-04-06 10:20:00 +00:00
Harshit Raizada
ed5f599d9f test(security): add tests for agent role escalation and parameter injection
(cherry picked from commit 3f23513ca6)
2026-04-06 10:19:59 +00:00
Harshit Raizada
ec957e9588 test(hd_ticket): add security tests for unauthorized actions and info disclosure
(cherry picked from commit 345c34a6c6)

# Conflicts:
#	helpdesk/helpdesk/doctype/hd_ticket/test_hd_ticket.py
2026-04-06 10:19:58 +00:00
Harshit Raizada
cd1cde66ea fix(security): patch authorization and privilege escalation vulnerabilities
(cherry picked from commit e79107eec0)
2026-04-06 10:19:58 +00:00
Sydney Gomes
873712c930 Merge pull request #3189 from frappe/mergify/bp/main-hotfix/pr-3178
fix: add debounce to filter component (backport #3178)
2026-04-06 14:27:54 +05:30
Sydney Gomes
f452486493 Merge pull request #3197 from aerodeval/fix-main-code-cleanup
fix: remove git conflicts
2026-04-06 14:25:13 +05:30
Sydney
210fbce8d0 fix: remove git conflicts 2026-04-06 14:13:43 +05:30
Sydney Gomes
d313336b81 Merge pull request #3190 from frappe/mergify/bp/main-hotfix/pr-3176 2026-04-06 13:59:56 +05:30
RitvikSardana
b144e9ac02 Merge pull request #3196 from frappe/mergify/bp/main-hotfix/pr-3187
chore: update POT file (backport #3187)
2026-04-06 13:54:48 +05:30
frappe-pr-bot
526f542259 chore: update POT file
(cherry picked from commit 11bfebe13f)
2026-04-06 08:23:59 +00:00
RitvikSardana
c0d85ff097 Merge pull request #3195 from frappe/mergify/bp/main-hotfix/pr-3171
chore: sync translations from crowdin (backport #3171)
2026-04-06 13:53:26 +05:30
MochaMind
75b67f41ee chore: Bosnian translations
(cherry picked from commit bcb483fe57)
2026-04-06 08:21:14 +00:00
MochaMind
4cf4ba9ff3 chore: Croatian translations
(cherry picked from commit 4669332bc9)
2026-04-06 08:21:13 +00:00
MochaMind
81d2df5be0 chore: Esperanto translations
(cherry picked from commit 4b11cca96b)
2026-04-06 08:21:13 +00:00
MochaMind
6840c29ff8 chore: Russian translations
(cherry picked from commit cf22f8331c)
2026-04-06 08:21:13 +00:00
MochaMind
eb364d4c73 chore: Serbian (Latin) translations
(cherry picked from commit 9c2fcc283e)
2026-04-06 08:21:13 +00:00
MochaMind
5fb59d2078 chore: Norwegian Bokmal translations
(cherry picked from commit cf7d0fbb3e)
2026-04-06 08:21:12 +00:00
MochaMind
c292addab4 chore: Bosnian translations
(cherry picked from commit 6c24921eb6)
2026-04-06 08:21:12 +00:00
MochaMind
a8178aa584 chore: Burmese translations
(cherry picked from commit 491fabdf84)
2026-04-06 08:21:12 +00:00
MochaMind
56f9cab005 chore: Croatian translations
(cherry picked from commit e735f1fc4c)
2026-04-06 08:21:11 +00:00
MochaMind
4b7b6cb7da chore: Thai translations
(cherry picked from commit 615e5166d0)
2026-04-06 08:21:11 +00:00
MochaMind
7dcc094a53 chore: Persian translations
(cherry picked from commit 93bba4b570)
2026-04-06 08:21:11 +00:00
MochaMind
f3fbc16cbc chore: Indonesian translations
(cherry picked from commit a8f836dbcf)
2026-04-06 08:21:10 +00:00
MochaMind
da78a5bac3 chore: Portuguese, Brazilian translations
(cherry picked from commit 839654b343)
2026-04-06 08:21:10 +00:00
MochaMind
3b11e381f6 chore: Vietnamese translations
(cherry picked from commit 06c5b1a48e)
2026-04-06 08:21:10 +00:00
MochaMind
d683c5d9f1 chore: Chinese Simplified translations
(cherry picked from commit 2dfe252029)
2026-04-06 08:21:09 +00:00
MochaMind
b7d52b97b4 chore: Turkish translations
(cherry picked from commit 412ada7775)
2026-04-06 08:21:09 +00:00
MochaMind
b355a514dd chore: Swedish translations
(cherry picked from commit 89996fe94c)
2026-04-06 08:21:09 +00:00
MochaMind
2d46cc1f1e chore: Serbian (Cyrillic) translations
(cherry picked from commit 26a2dca117)
2026-04-06 08:21:09 +00:00
MochaMind
27988dbb61 chore: Slovenian translations
(cherry picked from commit 399bea9c20)
2026-04-06 08:21:08 +00:00
MochaMind
5a260045fd chore: Portuguese translations
(cherry picked from commit 5b64bbec28)
2026-04-06 08:21:08 +00:00
MochaMind
55fc572069 chore: Polish translations
(cherry picked from commit 4cff3ee8e4)
2026-04-06 08:21:08 +00:00
MochaMind
3f33765f55 chore: Dutch translations
(cherry picked from commit d883a09b97)
2026-04-06 08:21:08 +00:00
MochaMind
44e6b09eef chore: Italian translations
(cherry picked from commit d0d9a6ac68)
2026-04-06 08:21:07 +00:00
MochaMind
75c96fd91f chore: Hungarian translations
(cherry picked from commit 573cf539f3)
2026-04-06 08:21:07 +00:00
MochaMind
dc5d0e6128 chore: German translations
(cherry picked from commit 550d5a7886)
2026-04-06 08:21:07 +00:00
MochaMind
53b0e1ebe2 chore: Danish translations
(cherry picked from commit 82dd647877)
2026-04-06 08:21:07 +00:00
MochaMind
dfd111cf82 chore: Czech translations
(cherry picked from commit fef8589dca)
2026-04-06 08:21:06 +00:00
MochaMind
2c4550f243 chore: Arabic translations
(cherry picked from commit 86722702df)
2026-04-06 08:21:06 +00:00
MochaMind
0808eb6817 chore: Spanish translations
(cherry picked from commit c4d69e16a6)
2026-04-06 08:21:06 +00:00
MochaMind
8ab3466232 chore: French translations
(cherry picked from commit fb1fa5d9fa)
2026-04-06 08:21:05 +00:00
RitvikSardana
42f3605899 Merge pull request #3193 from frappe/mergify/bp/main-hotfix/pr-3191
fix: new submodule setup (backport #3191)
2026-04-06 13:39:10 +05:30
RitvikSardana
c72fc2f285 Merge pull request #3194 from frappe/mergify/bp/main-hotfix/pr-3192
fix: iframe click does not close popover (backport #3192)
2026-04-06 13:17:00 +05:30
RitvikSardana
e0fbf2af46 chore: resolve conflict 2026-04-06 13:16:00 +05:30
Ritvik Sardana
df1001b597 fix: iframe click does not close popover
(cherry picked from commit 1716acc427)
2026-04-06 07:43:36 +00:00
Ritvik Sardana
27e694cf44 fix: new submodule setup
(cherry picked from commit b2ae6d8fc0)

# Conflicts:
#	package.json
#	yarn.lock
2026-04-06 07:43:18 +00:00
Sydney
383e5d9ec2 fix: improve sidepanel scrollbar and fix quick filters
(cherry picked from commit 7c3088de2c)

# Conflicts:
#	desk/src/components/view-controls/QuickFilters.vue
#	desk/src/index.css
2026-04-06 07:16:05 +00:00
Sydney
209d27c59e fix: add debounce to filters
(cherry picked from commit a4ede50fa4)
2026-04-06 07:10:41 +00:00
Sydney Gomes
15639edce5 Merge pull request #3173 from frappe/mergify/bp/main-hotfix/pr-3170
fix: display only date & datetime fields in date format in Ticket SIdebar (backport #3170)
2026-04-03 00:19:47 +05:30
Sydney
e872829e9b fix: code cleanup
(cherry picked from commit 02cb007537)
2026-04-02 18:41:02 +00:00
Sydney
b0c6ca0ec5 fix: prevent non-date fields from being parsed as valid dates
(cherry picked from commit 8cc10bcd16)
2026-04-02 18:41:02 +00:00
Sydney
a53cd0fdf8 fix: display only date & datetime fields in date format
(cherry picked from commit e72627aa79)
2026-04-02 18:41:02 +00:00
RitvikSardana
eef7c4d427 Merge pull request #3169 from frappe/mergify/bp/main/pr-3168
chore: bump fui (backport #3168)
2026-04-01 19:13:54 +05:30
Ritvik Sardana
2a4286d418 chore: bump fui
(cherry picked from commit f554b6c94b)
2026-04-01 13:40:36 +00:00
RitvikSardana
cf26bbd54b Merge pull request #3168 from RitvikSardana/fui-bump-bp
chore: bump fui
2026-04-01 19:09:26 +05:30
Ritvik Sardana
f554b6c94b chore: bump fui 2026-04-01 19:03:02 +05:30
RitvikSardana
83dd0a99c0 Merge pull request #3167 from frappe/revert-3166-mergify/bp/main-hotfix/pr-3165
Revert "chore: bump fui (backport #3165)"
2026-04-01 18:56:45 +05:30
RitvikSardana
e0d9ef815e Revert "chore: bump fui (backport #3165)" 2026-04-01 18:56:30 +05:30
RitvikSardana
be229438b2 Merge pull request #3166 from frappe/mergify/bp/main-hotfix/pr-3165
chore: bump fui (backport #3165)
2026-04-01 18:56:05 +05:30
Ritvik Sardana
4aa6f7a8bd chore: bump fui
(cherry picked from commit e61c82041f)

# Conflicts:
#	yarn.lock
2026-04-01 13:24:44 +00:00
RitvikSardana
c3b7de4d3f Merge pull request #3164 from frappe/main-hotfix
chore(release): hotfix to main
2026-04-01 18:14:26 +05:30
RitvikSardana
ba49e22437 Merge pull request #3161 from frappe/mergify/bp/main-hotfix/pr-3160
chore: version bump (backport #3160)
2026-04-01 18:02:29 +05:30
RitvikSardana
aabe2a5f2e Merge pull request #3163 from frappe/mergify/bp/main-hotfix/pr-3150
chore: update POT file (backport #3150)
2026-04-01 18:00:40 +05:30
RitvikSardana
08eadb73d6 chore: resolve conflict 2026-04-01 18:00:25 +05:30
RitvikSardana
325197766f Merge pull request #3162 from frappe/mergify/bp/main-hotfix/pr-3147
chore: sync translations from crowdin (backport #3147)
2026-04-01 17:50:23 +05:30
frappe-pr-bot
5d157ceac1 chore: update POT file
(cherry picked from commit 8beed8cb04)

# Conflicts:
#	helpdesk/locale/main.pot
2026-04-01 12:20:01 +00:00
MochaMind
7364f6f5aa chore: Russian translations
(cherry picked from commit 3196c9c69c)
2026-04-01 12:19:44 +00:00
MochaMind
e1bbaa2b2a chore: Serbian (Latin) translations
(cherry picked from commit ecbc05aed6)
2026-04-01 12:19:43 +00:00
MochaMind
d89d8b2bbd chore: Serbian (Cyrillic) translations
(cherry picked from commit 4fd3c7314a)
2026-04-01 12:19:43 +00:00
MochaMind
871364b63c chore: Russian translations
(cherry picked from commit 16abb01689)
2026-04-01 12:19:43 +00:00
MochaMind
af6b97fc13 chore: Esperanto translations
(cherry picked from commit 2e23acc137)
2026-04-01 12:19:43 +00:00
MochaMind
18c999fdf0 chore: Russian translations
(cherry picked from commit 18a93a48c8)
2026-04-01 12:19:42 +00:00
MochaMind
8b2298ee38 chore: Serbian (Latin) translations
(cherry picked from commit 6bba0c2a56)
2026-04-01 12:19:42 +00:00
MochaMind
117b62f3c2 chore: Norwegian Bokmal translations
(cherry picked from commit 1d108baeff)
2026-04-01 12:19:42 +00:00
MochaMind
e9f469bea8 chore: Bosnian translations
(cherry picked from commit 06912cd7c1)
2026-04-01 12:19:41 +00:00
MochaMind
eb20b78903 chore: Burmese translations
(cherry picked from commit b73cd1ac70)
2026-04-01 12:19:41 +00:00
MochaMind
d5a3f5f01e chore: Croatian translations
(cherry picked from commit 85aee81b4f)
2026-04-01 12:19:41 +00:00
MochaMind
496c89713b chore: Thai translations
(cherry picked from commit b7836e7468)
2026-04-01 12:19:41 +00:00
MochaMind
01f2df8629 chore: Persian translations
(cherry picked from commit 43cb0814b1)
2026-04-01 12:19:40 +00:00
MochaMind
c356f6142e chore: Indonesian translations
(cherry picked from commit 048b62d255)
2026-04-01 12:19:40 +00:00
MochaMind
324c3ef65d chore: Portuguese, Brazilian translations
(cherry picked from commit 703db19eea)
2026-04-01 12:19:40 +00:00
MochaMind
3dca4df2cc chore: Vietnamese translations
(cherry picked from commit 7a570724ee)
2026-04-01 12:19:40 +00:00
MochaMind
31af40a680 chore: Chinese Simplified translations
(cherry picked from commit 158cfe2fff)
2026-04-01 12:19:39 +00:00
MochaMind
16a32cedf6 chore: Turkish translations
(cherry picked from commit 7b712e1e87)
2026-04-01 12:19:39 +00:00
MochaMind
7fe52fa1b9 chore: Swedish translations
(cherry picked from commit 3f08f67d1e)
2026-04-01 12:19:38 +00:00
MochaMind
4f345f2232 chore: Serbian (Cyrillic) translations
(cherry picked from commit 0693d0c34a)
2026-04-01 12:19:38 +00:00
MochaMind
9eb3301656 chore: Slovenian translations
(cherry picked from commit da3d1099ec)
2026-04-01 12:19:38 +00:00
MochaMind
ae399c85e9 chore: Portuguese translations
(cherry picked from commit 8b0ddf74f2)
2026-04-01 12:19:37 +00:00
MochaMind
9a978f9303 chore: Polish translations
(cherry picked from commit 98214151af)
2026-04-01 12:19:37 +00:00
MochaMind
474f3a305f chore: Dutch translations
(cherry picked from commit 21b2a3f7c4)
2026-04-01 12:19:37 +00:00
MochaMind
cec199bed6 chore: Italian translations
(cherry picked from commit 4dbc5c1722)
2026-04-01 12:19:37 +00:00
MochaMind
54ac7719c0 chore: Hungarian translations
(cherry picked from commit 1ace98c4d8)
2026-04-01 12:19:36 +00:00
MochaMind
e8c3a5c270 chore: German translations
(cherry picked from commit d800ae4571)
2026-04-01 12:19:36 +00:00
MochaMind
297ef5cec2 chore: Danish translations
(cherry picked from commit a5a04535ec)
2026-04-01 12:19:36 +00:00
MochaMind
aa414c4496 chore: Czech translations
(cherry picked from commit b6bf8b6f3d)
2026-04-01 12:19:35 +00:00
MochaMind
f38d683014 chore: Arabic translations
(cherry picked from commit d78984ca0d)
2026-04-01 12:19:35 +00:00
MochaMind
c2ce4f3484 chore: Spanish translations
(cherry picked from commit e3c7e5935f)
2026-04-01 12:19:35 +00:00
MochaMind
ece507a310 chore: French translations
(cherry picked from commit 3af0fabc87)
2026-04-01 12:19:35 +00:00
Sydney Gomes
fa0498cad8 Merge pull request #3157 from aerodeval/feat-custom-domain-support
feat(settings): select Email Domain for custom email accounts (backport #2850)
2026-04-01 17:11:46 +05:30
Sydney
2239bf7e96 fix: add missing imports and configs 2026-04-01 16:52:36 +05:30
Sydney
b46c843d5d fix: add back setting imap folder to inbox 2026-04-01 16:35:05 +05:30
RitvikSardana
0d03c1acce chore: version bump
(cherry picked from commit e7f927a895)
2026-04-01 10:57:04 +00:00
RitvikSardana
eb48bf1d71 Merge pull request #3159 from frappe/mergify/bp/main-hotfix/pr-3154
fix: scrollable table (backport #3154)
2026-04-01 16:21:11 +05:30
Ritvik Sardana
e20a890fc4 chore: code cleanup
(cherry picked from commit 788f1577b0)
2026-04-01 10:50:34 +00:00
Ritvik Sardana
234b68151f fix: scrollable table
(cherry picked from commit d905078245)
2026-04-01 10:50:34 +00:00
Sydney Gomes
15bb2c9898 Merge pull request #3158 from frappe/mergify/bp/main-hotfix/pr-3156
fix: utilize tiptap select all command for tiptap based elements in dom (backport #3156)
2026-04-01 15:53:17 +05:30
Sydney
550be35a09 fix: run tip-tap inbuilt select all after focus guard check
(cherry picked from commit 160b4c9f83)
2026-04-01 09:29:37 +00:00
Sydney
31099aa202 fix: utilize tiptap select all command for tiptap based elements in dom
(cherry picked from commit 3990ce5f6f)
2026-04-01 09:29:37 +00:00
Sydney
e33d16422b fix: solve linter issues 2026-04-01 13:54:37 +05:30
Sydney
ff8f442840 feat: backport custom domain feature support 2026-04-01 01:09:45 +05:30
Sydney Gomes
8fcd963e68 Merge pull request #3152 from aerodeval/chore/bump-tiptap
fix: bump tiptap and frappe ui and update yarn files (backport #3131)
2026-03-30 11:57:42 +05:30
Sydney
1760b34e53 fix: update yarn.lock in desk 2026-03-30 11:28:02 +05:30
Sydney
d36599963f fix: bump tiptap and frappe ui and update yarn files 2026-03-30 10:54:25 +05:30
Sydney Gomes
9962c9cfd4 Merge pull request #3149 from frappe/mergify/bp/main-hotfix/pr-3148
refactor: improve welcome email content (backport #3148)
2026-03-27 22:26:59 +05:30
Sydney Gomes
bf3692afa0 refactor: improve welcome email content for onboarding(#3148)
* chore: improve onboarding experience

* fix: fix imports for image and gif

* fix: fix layout issues for the mailer

* fix: update layout of welcome mail and add user name in mail

* fix: update gifs

* chore: use videos instead of gifs for faster load

* fix: incorrect first name fetching in mail

* fix: handle administrator name scenario

* fix: update demo videos

* fix: update videos for demo

* fix: improve copy

(cherry picked from commit 0a4de51eb9)
2026-03-27 16:49:03 +00:00
RitvikSardana
cb1e6ca24c Merge pull request #3145 from frappe/mergify/bp/main-hotfix/pr-3140
chore: sync translations from crowdin (backport #3140)
2026-03-25 16:10:48 +05:30
MochaMind
04d3693d31 chore: Vietnamese translations
(cherry picked from commit 9bac2c2c62)
2026-03-25 10:40:33 +00:00
MochaMind
084098debc chore: Spanish translations
(cherry picked from commit 5b7c2f33df)
2026-03-25 10:40:33 +00:00
MochaMind
32566c5d80 chore: Swedish translations
(cherry picked from commit 40c9741396)
2026-03-25 10:40:33 +00:00
RitvikSardana
a404a850d5 Merge pull request #3144 from frappe/mergify/bp/main-hotfix/pr-3139
chore: update POT file (backport #3139)
2026-03-25 16:10:07 +05:30
frappe-pr-bot
7f1ad2be57 chore: update POT file
(cherry picked from commit b115e0875e)

# Conflicts:
#	helpdesk/locale/main.pot
2026-03-25 10:39:48 +00:00
Jayanta
5d3bb6361a Merge pull request #3143 from frappe/mergify/bp/main-hotfix/pr-3137
fix: set Link field page limit to 999 (backport #3137)
2026-03-25 10:07:52 +05:30
Jayanta
2d5a622bf4 fix: set Link field page limit to 999 (#3137)
* fix: set pageLength to 999 for Link field type

(cherry picked from commit a853d8eb60)
2026-03-25 04:30:47 +00:00
RitvikSardana
77d9632845 Merge pull request #3133 from frappe/mergify/bp/main-hotfix/pr-3126
chore: update POT file (backport #3126)
2026-03-18 13:04:39 +05:30
frappe-pr-bot
a1e48699ec chore: update POT file
(cherry picked from commit 20b5ee931f)
2026-03-18 07:04:20 +00:00
RitvikSardana
c659aec522 Merge pull request #3132 from frappe/mergify/bp/main-hotfix/pr-3118
chore: sync translations from crowdin (backport #3118)
2026-03-18 12:33:52 +05:30
MochaMind
1812ea2a85 chore: Spanish translations
(cherry picked from commit 02afcd4c3c)
2026-03-18 05:47:12 +00:00
MochaMind
957a2b7eab chore: Portuguese, Brazilian translations
(cherry picked from commit 865bd99df0)
2026-03-18 05:47:11 +00:00
MochaMind
cb2fa44412 chore: Swedish translations
(cherry picked from commit 4870d001d5)
2026-03-18 05:47:11 +00:00
MochaMind
4e56b4e87f chore: Swedish translations
(cherry picked from commit 1cc3671930)
2026-03-18 05:47:11 +00:00
RitvikSardana
0d82fa0a50 Merge pull request #3114 from frappe/main-hotfix
chore(release): hotfix to main
2026-03-10 01:09:11 +05:30
RitvikSardana
4ad1991cb0 Merge pull request #3116 from frappe/mergify/bp/main-hotfix/pr-3115
chore: bump frappe-ui (backport #3115)
2026-03-10 01:03:46 +05:30
RitvikSardana
10028686b4 chore: resolve conflict 2026-03-10 01:02:25 +05:30
Ritvik Sardana
6c7ca130b4 chore: bump frappe-ui
(cherry picked from commit 0d4ca83f5f)

# Conflicts:
#	yarn.lock
2026-03-09 19:30:34 +00:00
RitvikSardana
e9543ad4e4 Merge pull request #3113 from frappe/mergify/bp/main-hotfix/pr-3110
chore: update POT file (backport #3110)
2026-03-10 00:41:00 +05:30
RitvikSardana
0c593846f6 Merge pull request #3112 from frappe/mergify/bp/main-hotfix/pr-3107
chore: sync translations from crowdin (backport #3107)
2026-03-10 00:40:55 +05:30
RitvikSardana
9782f5b893 Merge pull request #3111 from frappe/mergify/bp/main-hotfix/pr-3106
fix: excel pasting formating in text editor (backport #3106)
2026-03-10 00:40:32 +05:30
RitvikSardana
ae630f4061 chore: formatting 2026-03-10 00:35:18 +05:30
RitvikSardana
b1699ec728 chore: resolve conflict 2026-03-10 00:33:37 +05:30
frappe-pr-bot
7364697bc3 chore: update POT file
(cherry picked from commit 6be18800ac)
2026-03-09 19:03:08 +00:00
MochaMind
da99dc51b7 chore: Serbian (Latin) translations
(cherry picked from commit 86ca1cc939)
2026-03-09 19:02:53 +00:00
MochaMind
269d7e1c88 chore: Serbian (Cyrillic) translations
(cherry picked from commit cf67e5982e)
2026-03-09 19:02:53 +00:00
MochaMind
d0a2ae16f6 chore: Esperanto translations
(cherry picked from commit f7ae670d3e)
2026-03-09 19:02:52 +00:00
MochaMind
b2651d26c8 chore: Serbian (Latin) translations
(cherry picked from commit 06c7cb2e0d)
2026-03-09 19:02:52 +00:00
MochaMind
f1f3b9bd2b chore: Norwegian Bokmal translations
(cherry picked from commit ce5fd9807d)
2026-03-09 19:02:52 +00:00
MochaMind
ae0784fda2 chore: Bosnian translations
(cherry picked from commit beee851fc8)
2026-03-09 19:02:51 +00:00
MochaMind
e939bd7141 chore: Burmese translations
(cherry picked from commit 97cc8df3a1)
2026-03-09 19:02:51 +00:00
MochaMind
1173616af1 chore: Croatian translations
(cherry picked from commit 47e6aa93cf)
2026-03-09 19:02:51 +00:00
MochaMind
873e55c945 chore: Thai translations
(cherry picked from commit 0a39dfc819)
2026-03-09 19:02:51 +00:00
MochaMind
86f3833618 chore: Persian translations
(cherry picked from commit f10a0ead76)
2026-03-09 19:02:50 +00:00
MochaMind
a110493400 chore: Indonesian translations
(cherry picked from commit 2f82d784f6)
2026-03-09 19:02:50 +00:00
MochaMind
2017ebd81e chore: Portuguese, Brazilian translations
(cherry picked from commit 445633e1f3)
2026-03-09 19:02:50 +00:00
MochaMind
c2d8beef06 chore: Vietnamese translations
(cherry picked from commit a08b365b04)
2026-03-09 19:02:49 +00:00
MochaMind
538e6e8222 chore: Chinese Simplified translations
(cherry picked from commit 16c09008c0)
2026-03-09 19:02:49 +00:00
MochaMind
c526cb8f1c chore: Turkish translations
(cherry picked from commit ee02d83e83)
2026-03-09 19:02:49 +00:00
MochaMind
8f50495f22 chore: Swedish translations
(cherry picked from commit 68c56fb564)
2026-03-09 19:02:48 +00:00
MochaMind
5f448d37ea chore: Serbian (Cyrillic) translations
(cherry picked from commit 99e167563b)
2026-03-09 19:02:48 +00:00
MochaMind
1d5970cc5c chore: Slovenian translations
(cherry picked from commit 85b5973a34)
2026-03-09 19:02:47 +00:00
MochaMind
1b9e379361 chore: Portuguese translations
(cherry picked from commit b0fbd842c2)
2026-03-09 19:02:47 +00:00
MochaMind
a0fd1cee25 chore: Polish translations
(cherry picked from commit 19b847569f)
2026-03-09 19:02:47 +00:00
MochaMind
52ae3528bb chore: Dutch translations
(cherry picked from commit 3a0b8d0b0c)
2026-03-09 19:02:47 +00:00
MochaMind
afbd3a7398 chore: Italian translations
(cherry picked from commit 76ceb80a72)
2026-03-09 19:02:46 +00:00
MochaMind
297d7685f5 chore: Hungarian translations
(cherry picked from commit 0aa2d91512)
2026-03-09 19:02:46 +00:00
MochaMind
b63a23fd94 chore: German translations
(cherry picked from commit b931fea9f5)
2026-03-09 19:02:46 +00:00
MochaMind
0be89a8655 chore: Danish translations
(cherry picked from commit 7e5fdb03dc)
2026-03-09 19:02:46 +00:00
MochaMind
d7a3d9994b chore: Czech translations
(cherry picked from commit f689beb8e8)
2026-03-09 19:02:44 +00:00
MochaMind
efda04cfdc chore: Arabic translations
(cherry picked from commit 5b092db083)
2026-03-09 19:02:44 +00:00
MochaMind
cad3b7a5db chore: Spanish translations
(cherry picked from commit 5f2648c93e)
2026-03-09 19:02:44 +00:00
MochaMind
9f84945651 chore: French translations
(cherry picked from commit fbffed7ffb)
2026-03-09 19:02:43 +00:00
MochaMind
065b299e5a chore: Russian translations
(cherry picked from commit 2aae85be24)
2026-03-09 19:02:43 +00:00
Ritvik Sardana
f3abb26d0d fix: move cursor to after the table
(cherry picked from commit daac5f8ccc)
2026-03-09 19:02:15 +00:00
Sydney
d66224942c fix: add additional support for tabular data
(cherry picked from commit 08f3cd3cad)
2026-03-09 19:02:14 +00:00
Ritvik Sardana
6626514c28 chore: version bump
(cherry picked from commit 401dcb85c9)

# Conflicts:
#	helpdesk/__init__.py
2026-03-09 19:02:14 +00:00
Ritvik Sardana
19d92395d2 fix: enhance excel pasted data
(cherry picked from commit 16429b781e)
2026-03-09 19:02:14 +00:00
RitvikSardana
c98b317beb Merge pull request #3104 from frappe/mergify/bp/main-hotfix/pr-2648
fix: frappe ui z index issues (backport #2648)
2026-03-10 00:31:38 +05:30
Sydney Gomes
14a3a870dd Merge pull request #3109 from frappe/mergify/bp/main-hotfix/pr-3108
fix: allow shift+enter by removing .stop from keydown handler (backport #3108)
2026-03-08 15:28:53 +05:30
Sydney
6f7951518f fix: allow shift+enter by removing .stop from keydown handler
(cherry picked from commit 4b3b431749)
2026-03-08 09:52:53 +00:00
Pratik Badhe
40a04c40ee fix: handle on hover apps dropdown
(cherry picked from commit c21247015b)
2026-03-06 06:25:35 +00:00
Pratik Badhe
625ae93e1c fix: apps list hover state
(cherry picked from commit 95301a2a9f)
2026-03-06 06:25:35 +00:00
Pratik Badhe
95dd2c004c refactor: change apps list UI
(cherry picked from commit 0175b4e5fc)
2026-03-06 06:25:35 +00:00
Pratik Badhe
2a0ad52055 fix: frappe ui z index issues
(cherry picked from commit de95204c72)
2026-03-06 06:25:35 +00:00
RitvikSardana
8f8066101d Merge pull request #3103 from frappe/main-hotfix
chore(release): hotfix to main
2026-03-06 10:47:14 +05:30
RitvikSardana
077a1c0ef5 chore: version bump 2026-03-06 10:33:52 +05:30
RitvikSardana
c421db13d8 Merge pull request #3102 from frappe/mergify/bp/main-hotfix/pr-3086
chore: sync translations from crowdin (backport #3086)
2026-03-06 10:28:29 +05:30
RitvikSardana
2a325f5c2f Merge pull request #3101 from frappe/mergify/bp/main-hotfix/pr-3085
chore: update POT file (backport #3085)
2026-03-06 10:27:50 +05:30
RitvikSardana
0727894cb2 chore: resolve conflict 2026-03-06 10:27:12 +05:30
MochaMind
3a59a4a2d1 chore: Russian translations
(cherry picked from commit 65a93f7a68)
2026-03-06 04:54:32 +00:00
MochaMind
9f1df7a79a chore: Swedish translations
(cherry picked from commit a1d16363b9)
2026-03-06 04:54:31 +00:00
MochaMind
d0cc9adc93 chore: Spanish translations
(cherry picked from commit 298f899ae9)
2026-03-06 04:54:31 +00:00
MochaMind
d0f6befa7c chore: French translations
(cherry picked from commit 678213f31c)
2026-03-06 04:54:31 +00:00
MochaMind
db08a86f8a chore: Russian translations
(cherry picked from commit 662b17f748)
2026-03-06 04:54:31 +00:00
MochaMind
fb22c610c9 chore: Russian translations
(cherry picked from commit 1ad6d8d4f9)
2026-03-06 04:54:30 +00:00
frappe-pr-bot
ab42160ea1 chore: update POT file
(cherry picked from commit 158e6f5bdf)

# Conflicts:
#	helpdesk/locale/main.pot
2026-03-06 04:54:23 +00:00
Sydney Gomes
7ad7824d22 Merge pull request #3100 from aerodeval/fix/handle-email-formatting
fix: handle email formatting ( backport #2975)
2026-03-06 02:19:47 +05:30
Sydney
cb14a5b086 fix: handle email formatting 2026-03-06 02:10:11 +05:30
RitvikSardana
e40716e2dc Merge pull request #3099 from frappe/mergify/bp/main-hotfix/pr-3098
fix: dont delete src tag (backport #3098)
2026-03-06 01:49:53 +05:30
Ritvik Sardana
6b57346a2d chore: code cleanup
(cherry picked from commit 4979045fb6)
2026-03-05 20:12:15 +00:00
Ritvik Sardana
c5650b48aa fix: dont delete src tag
(cherry picked from commit b0e4b3be64)
2026-03-05 20:12:14 +00:00
Sydney Gomes
169bc57da2 Merge pull request #3091 from frappe/mergify/bp/main-hotfix/pr-3090
fix: fix saved replies scope filtering (backport #3090)
2026-03-02 14:04:43 +05:30
Sydney
3957380164 fix: fix saved replies scope filtering
(cherry picked from commit 91ed2d6c54)
2026-03-02 08:29:11 +00:00
RitvikSardana
2ab7d8f5b2 Merge pull request #3083 from frappe/mergify/bp/main-hotfix/pr-3082
chore: sync translations from crowdin (backport #3082)
2026-02-28 12:39:35 +05:30
MochaMind
f73c3a5eb8 chore: Russian translations
(cherry picked from commit e3ffb460d0)
2026-02-28 06:41:05 +00:00
MochaMind
134938f0e1 chore: Spanish translations
(cherry picked from commit 52ee89f7ba)
2026-02-28 06:41:04 +00:00
RitvikSardana
1a8bf43578 Merge pull request #3081 from frappe/main-hotfix
chore(release): hotfix to main
2026-02-27 18:28:43 +05:30
RitvikSardana
3c6a22c6d6 Merge pull request #3078 from frappe/mergify/bp/main-hotfix/pr-3077
fix: handle excel pasting in email editor (backport #3077)
2026-02-27 16:48:50 +05:30
RitvikSardana
95dc627b09 Merge pull request #3080 from frappe/mergify/bp/main-hotfix/pr-3079
fix: remove depends_on in raised_by field (backport #3079)
2026-02-27 16:45:53 +05:30
Ritvik Sardana
dc70c83fc3 chore: version bump
(cherry picked from commit e7ba190fbe)
2026-02-27 11:14:57 +00:00
Ritvik Sardana
132d86d8d7 fix: remove unwanted depends on in raised_by field
(cherry picked from commit 94637de7ff)
2026-02-27 11:14:57 +00:00
Sydney
f334b90837 fix: fix improper key in extension
(cherry picked from commit b8c160f22b)
2026-02-27 11:00:22 +00:00
Sydney
1275da1ccb fix: handle excel pasting in email editor
(cherry picked from commit 5f682fe8ef)
2026-02-27 11:00:22 +00:00
Sydney Gomes
0bd0be0ad1 Merge pull request #3076 from frappe/mergify/bp/main-hotfix/pr-3006
fix: comment box mentions bug on edit (backport #3006)
2026-02-27 12:17:20 +05:30
Sydney
bca54632d1 feat: add keyup event support for saving comments
(cherry picked from commit 7fb269ff04)
2026-02-27 06:22:32 +00:00
Sydney
5101822c0b fix: comments discard button bug fix and mentions fix
(cherry picked from commit 0f1abb75a1)
2026-02-27 06:22:31 +00:00
Sydney
e364335845 fix: fix flaky mentions rendering when agent list not populated
(cherry picked from commit 5f03f0d144)
2026-02-27 06:22:31 +00:00
Sydney
a096eaee95 chore: remove unecessary storeToRef
(cherry picked from commit b9b82b48cd)
2026-02-27 06:22:31 +00:00
Sydney
56550aa821 chore: remove redundant code
(cherry picked from commit 13e5a14867)
2026-02-27 06:22:31 +00:00
Sydney
4c948a6be6 chore: code cleanup
(cherry picked from commit bfa2dcc2a3)
2026-02-27 06:22:31 +00:00
Sydney
a9ad34ad7e chore: remove debugging print statements
(cherry picked from commit f8311a98c7)
2026-02-27 06:22:30 +00:00
Sydney
a9f123090e chore: added test case to check if multiple notifications are not sent on adding mention when edited
(cherry picked from commit bdda40443c)
2026-02-27 06:22:30 +00:00
Sydney
a81f4c9f9e fix: comment box edit mentions fix
(cherry picked from commit fd94e0bc12)
2026-02-27 06:22:30 +00:00
RitvikSardana
12a47792b8 Merge pull request #3075 from frappe/mergify/bp/main-hotfix/pr-3063
chore: sync translations from crowdin (backport #3063)
2026-02-27 11:10:33 +05:30
MochaMind
488bf6fced chore: Serbian (Latin) translations
(cherry picked from commit 0112488cdd)
2026-02-27 05:25:54 +00:00
MochaMind
be763b020d chore: Swedish translations
(cherry picked from commit 0006e98d44)
2026-02-27 05:25:54 +00:00
MochaMind
efd539bad9 chore: Serbian (Cyrillic) translations
(cherry picked from commit 0f056060fc)
2026-02-27 05:25:53 +00:00
MochaMind
992cfca6ee chore: Spanish translations
(cherry picked from commit ee8b612ca7)
2026-02-27 05:25:53 +00:00
MochaMind
a83b7c9ae0 chore: Esperanto translations
(cherry picked from commit 890dedad69)
2026-02-27 05:25:53 +00:00
MochaMind
fa968132a6 chore: Serbian (Latin) translations
(cherry picked from commit 62518c0843)
2026-02-27 05:25:52 +00:00
MochaMind
20f799ec57 chore: Norwegian Bokmal translations
(cherry picked from commit 44750ec641)
2026-02-27 05:25:52 +00:00
MochaMind
cd006a95ad chore: Bosnian translations
(cherry picked from commit 343809f489)
2026-02-27 05:25:52 +00:00
MochaMind
b270b02563 chore: Burmese translations
(cherry picked from commit 9acf110b42)
2026-02-27 05:25:52 +00:00
MochaMind
a3ad1a937a chore: Croatian translations
(cherry picked from commit 5eec882f14)
2026-02-27 05:25:51 +00:00
MochaMind
a126a20d0c chore: Thai translations
(cherry picked from commit fb97216bca)
2026-02-27 05:25:51 +00:00
MochaMind
9cf61eeca9 chore: Persian translations
(cherry picked from commit 01437abc7e)
2026-02-27 05:25:51 +00:00
MochaMind
cf0024ec6f chore: Indonesian translations
(cherry picked from commit 8f7df1627a)
2026-02-27 05:25:51 +00:00
MochaMind
fe7ddfa9bd chore: Portuguese, Brazilian translations
(cherry picked from commit dfd08b6c85)
2026-02-27 05:25:50 +00:00
MochaMind
672ad53541 chore: Vietnamese translations
(cherry picked from commit 5a63a92b5c)
2026-02-27 05:25:50 +00:00
MochaMind
93924bc707 chore: Chinese Simplified translations
(cherry picked from commit 944b9f7b19)
2026-02-27 05:25:50 +00:00
MochaMind
f30f1b7919 chore: Turkish translations
(cherry picked from commit a9bbcfad00)
2026-02-27 05:25:49 +00:00
MochaMind
4f7a8a2c31 chore: Swedish translations
(cherry picked from commit e609efad07)
2026-02-27 05:25:49 +00:00
MochaMind
341af00ca2 chore: Serbian (Cyrillic) translations
(cherry picked from commit f441217c31)
2026-02-27 05:25:49 +00:00
MochaMind
f5547b0db8 chore: Slovenian translations
(cherry picked from commit bcd6c0a3a0)
2026-02-27 05:25:49 +00:00
MochaMind
ae4f7754b4 chore: Russian translations
(cherry picked from commit 4f664db460)
2026-02-27 05:25:48 +00:00
MochaMind
a14ce55394 chore: Portuguese translations
(cherry picked from commit fd2dc00e21)
2026-02-27 05:25:48 +00:00
MochaMind
794e2ffe36 chore: Polish translations
(cherry picked from commit 18f3d81410)
2026-02-27 05:25:48 +00:00
MochaMind
13d805981e chore: Dutch translations
(cherry picked from commit ec934009ad)
2026-02-27 05:25:47 +00:00
MochaMind
4f770a919f chore: Italian translations
(cherry picked from commit bf64aa02ee)
2026-02-27 05:25:47 +00:00
MochaMind
7ed70afb4a chore: Hungarian translations
(cherry picked from commit 0ae8afb535)
2026-02-27 05:25:47 +00:00
MochaMind
75553f5ab6 chore: German translations
(cherry picked from commit a33bc988b7)
2026-02-27 05:25:47 +00:00
MochaMind
d8cfb43e0b chore: Danish translations
(cherry picked from commit e2ccef3334)
2026-02-27 05:25:46 +00:00
MochaMind
6d86b6a3f6 chore: Czech translations
(cherry picked from commit 95226cd273)
2026-02-27 05:25:46 +00:00
MochaMind
8078f22e9f chore: Arabic translations
(cherry picked from commit 99d6710e0b)
2026-02-27 05:25:46 +00:00
MochaMind
b1daf1ebf9 chore: Spanish translations
(cherry picked from commit c189521c0a)
2026-02-27 05:25:46 +00:00
Sydney Gomes
6b7fd287cb Merge pull request #3073 from aerodeval/fix/remove-unused-stop-session
chore: remove stop session code
2026-02-26 19:17:13 +05:30
Sydney
648a062738 chore: remove stop session code 2026-02-26 19:07:29 +05:30
Sydney Gomes
5dcfc6d289 Merge pull request #3070 from frappe/mergify/bp/main-hotfix/pr-3009 2026-02-26 18:47:46 +05:30
Sydney Gomes
8492c5addb chore: fix merge conflicts 2026-02-26 18:47:22 +05:30
RitvikSardana
8fe0656521 Merge pull request #3072 from frappe/mergify/bp/main-hotfix/pr-3071
fix(auth): allow export api endpoint (backport #3071)
2026-02-26 17:39:07 +05:30
Ritvik Sardana
a6816dfd42 fix(auth): allow export api endpoint
(cherry picked from commit 2a062809e3)
2026-02-26 12:08:49 +00:00
Sydney
94564058b2 chore: code cleanup
(cherry picked from commit a2394c2b59)

# Conflicts:
#	desk/src/components/ticket/TicketCustomerSidebar.vue
2026-02-26 10:25:49 +00:00
Sydney
c6e1bb1870 chore: truncate text for autocomplete
(cherry picked from commit e8cb8fc799)
2026-02-26 10:25:49 +00:00
Sydney
1e7efe91bc fix: autocomplete import fixed
(cherry picked from commit 5a0edfe4d7)
2026-02-26 10:25:49 +00:00
Sydney
9893b14520 chore: code cleanup
(cherry picked from commit 173cd745eb)
2026-02-26 10:25:48 +00:00
Sydney
4f9b149acf fix: hard reload after timezone is changed
(cherry picked from commit a4bf8967c4)
2026-02-26 10:25:48 +00:00
Sydney
ff63f9a1a5 fix: force hard reload after language change and delay it so toast is visible
(cherry picked from commit 85824b6908)
2026-02-26 10:25:48 +00:00
Sydney
12d2dc4467 feat: add autocomplete switching in profile settings
(cherry picked from commit 70c621225e)
2026-02-26 10:25:48 +00:00
Sydney
9b1409a97b chore: Revert chore: Delete desk/src/types/doctypes.ts
This reverts commit 90e2a7bd3f.

(cherry picked from commit f7fbcce42e)

# Conflicts:
#	desk/src/types/doctypes.ts
2026-02-26 10:25:47 +00:00
Sydney Gomes
4fb4df29d7 chore: Delete desk/src/types/doctypes.ts
(cherry picked from commit 90e2a7bd3f)

# Conflicts:
#	desk/src/types/doctypes.ts
2026-02-26 10:25:47 +00:00
Sydney
fd2eb4ca3b chore: code cleanup
(cherry picked from commit 0928581960)
2026-02-26 10:25:47 +00:00
Sydney
3303e209d0 chore: cleanup redundant code
(cherry picked from commit bb8ef76156)
2026-02-26 10:25:47 +00:00
Sydney
78e87c0a52 fix: fix localization all over helpdesk and fix config fetching and setting
(cherry picked from commit d2ea5904b5)

# Conflicts:
#	desk/src/App.vue
2026-02-26 10:25:46 +00:00
Sydney
ff775012b1 fix: use prettyDate function to handle edge cases
(cherry picked from commit e6f13d4cf3)
2026-02-26 10:25:46 +00:00
Sydney
e4983dc963 chore: add dayjs local for support in different timezones
(cherry picked from commit d46429165f)

# Conflicts:
#	desk/src/components/ticket-agent/TicketSLA.vue
2026-02-26 10:25:46 +00:00
RitvikSardana
0bd5a5c35c Merge pull request #3069 from frappe/mergify/bp/main-hotfix/pr-3068
fix(field): handle case when no options are set for select field (backport #3068)
2026-02-26 15:17:35 +05:30
RitvikSardana
cb17035fc3 chore: code cleanup 2026-02-26 15:17:19 +05:30
Ritvik Sardana
a79468f749 fix(field): handle case when no options are set for select field
(cherry picked from commit 2f5099fbba)
2026-02-26 07:55:47 +00:00
RitvikSardana
a332917fc9 Merge pull request #3061 from frappe/main-hotfix
chore(release): hotfix to main
2026-02-25 16:41:16 +05:30
RitvikSardana
d0050ef489 chore: code cleanup 2026-02-25 16:36:28 +05:30
RitvikSardana
beb5b2ef9d chore: code cleanup 2026-02-25 16:31:26 +05:30
RitvikSardana
6c2149ba78 Merge branch 'main' into main-hotfix 2026-02-25 16:27:24 +05:30
RitvikSardana
10f1eae002 Merge pull request #3060 from frappe/mergify/bp/main-hotfix/pr-3057
feat: telemetry with pulse (backport #3057)
2026-02-25 16:25:57 +05:30
RitvikSardana
f20e8f393e chore: resolve merge conflict 2026-02-25 16:17:30 +05:30
Ritvik Sardana
e64c71447a chore: bump version
(cherry picked from commit b6ade86b5b)
2026-02-25 10:38:40 +00:00
Ritvik Sardana
f83dbd3db2 fix: better placeholder if no user is found
(cherry picked from commit fbc2c66d08)
2026-02-25 10:38:40 +00:00
Ritvik Sardana
4e06436571 fix: dont capture events for pre-filled data
(cherry picked from commit 334345f73f)
2026-02-25 10:38:40 +00:00
Ritvik Sardana
2edce1df53 fix: dont index hd_ticket twice
(cherry picked from commit a6a88791f2)
2026-02-25 10:38:39 +00:00
Ritvik Sardana
0eb09c6ea1 chore: add site data for analytics
(cherry picked from commit 7c80701fe2)
2026-02-25 10:38:39 +00:00
Ritvik Sardana
3fa5aa86f7 fix: add event for hd_team
(cherry picked from commit 17fa75759a)
2026-02-25 10:38:39 +00:00
Ritvik Sardana
c7c65344ee feat: telemetry with pulse
(cherry picked from commit 7f07d6bfca)

# Conflicts:
#	desk/src/components/Settings/EmailAdd.vue
#	desk/src/components/layouts/Sidebar.vue
2026-02-25 10:38:39 +00:00
RitvikSardana
0b909703b8 Merge pull request #3059 from frappe/mergify/bp/main-hotfix/pr-3050
fix: email send button bug and null value appearing in saved replies (backport #3050)
2026-02-25 12:00:29 +05:30
Sydney
df74338e08 fix: broken replies section and reply content bug
(cherry picked from commit f6a7c1868f)
2026-02-25 05:39:49 +00:00
Sydney
74167d55ad fix: email send button bug where null value allowed send button to be active
(cherry picked from commit ee3f456009)
2026-02-25 05:39:48 +00:00
RitvikSardana
2626824fc5 Merge pull request #3058 from frappe/mergify/bp/main-hotfix/pr-3056
fix(filters): model-value for select component (backport #3056)
2026-02-25 11:09:15 +05:30
Ritvik Sardana
fa0dd4b18e chore: code cleanup
(cherry picked from commit d917e42dcb)
2026-02-25 05:34:54 +00:00
Ritvik Sardana
f2d07d5aef fix(filters): model-value for select component
(cherry picked from commit d3aeefb327)
2026-02-25 05:34:54 +00:00
RitvikSardana
3d487f13c6 Merge pull request #3055 from frappe/mergify/bp/main-hotfix/pr-3047
chore: update POT file (backport #3047)
2026-02-24 11:34:27 +05:30
RitvikSardana
c6b8d5dad6 fix: merge conflict 2026-02-24 10:25:13 +05:30
RitvikSardana
de7f001f1b Merge pull request #3054 from frappe/mergify/bp/main-hotfix/pr-3046
chore: sync translations from crowdin (backport #3046)
2026-02-24 10:23:25 +05:30
frappe-pr-bot
93e9d1c558 chore: update POT file
(cherry picked from commit fcea5fd3ae)

# Conflicts:
#	helpdesk/locale/main.pot
2026-02-24 04:52:38 +00:00
MochaMind
9e77e1ec16 chore: Swedish translations
(cherry picked from commit fcd775ba0b)
2026-02-24 04:52:31 +00:00
MochaMind
5b0b0bdf2c chore: Thai translations
(cherry picked from commit b64e56e40c)
2026-02-24 04:52:31 +00:00
MochaMind
eb9429a245 chore: Vietnamese translations
(cherry picked from commit 1e33702c79)
2026-02-24 04:52:31 +00:00
MochaMind
a6f847870b chore: Swedish translations
(cherry picked from commit 15f86f2026)
2026-02-24 04:52:30 +00:00
MochaMind
f2005f1907 chore: Serbian (Cyrillic) translations
(cherry picked from commit 3cd5fcbbe5)
2026-02-24 04:52:30 +00:00
MochaMind
222492a78b chore: Dutch translations
(cherry picked from commit 6c588ead84)
2026-02-24 04:52:30 +00:00
MochaMind
a6caf2de47 chore: Spanish translations
(cherry picked from commit 7a8716b465)
2026-02-24 04:52:29 +00:00
RitvikSardana
a7450d4c9e Merge pull request #3053 from RitvikSardana/import-dashboard
fix: Imports in dashboard
2026-02-24 10:18:15 +05:30
Ritvik Sardana
a2360a78ea fix: add DateRangePicker import in Dashboard 2026-02-24 10:17:15 +05:30
RitvikSardana
0e0e6f42a6 Merge pull request #3052 from frappe/mergify/bp/main-hotfix/pr-3051
fix: add disabled field in HD Ticket Type (backport #3051)
2026-02-24 09:47:37 +05:30
RitvikSardana
26dd7a4d78 fix: merge conflict 2026-02-24 09:34:16 +05:30
Ritvik Sardana
820d199f68 fix: add disabled field in HD Ticket Type
(cherry picked from commit c00ab76168)

# Conflicts:
#	helpdesk/helpdesk/doctype/hd_ticket/hd_ticket.json
2026-02-24 04:01:23 +00:00
RitvikSardana
165b74a035 Merge pull request #3049 from frappe/mergify/bp/main-hotfix/pr-3048
fix: check for months and years while formatting date (backport #3048)
2026-02-23 12:01:57 +05:30
Ritvik Sardana
c59cdfb6fc fix: check for months and years while formatting date
(cherry picked from commit 69504c0ec4)
2026-02-23 06:31:35 +00:00
RitvikSardana
32977ac0a6 chore: Remove permission check in get_call_logs function
Removed permission check for viewing call logs.
2026-02-23 10:18:25 +05:30
RitvikSardana
7e33c6a238 chore: bump version to 1.20.2 2026-02-23 10:16:00 +05:30
RitvikSardana
546b09b7bc chore: Bump version to 1.20.1 2026-02-23 10:15:07 +05:30
RitvikSardana
b4d68d40dd chore: Remove permission check in get_call_logs function
Removed permission check for viewing call logs.
2026-02-23 10:14:17 +05:30
RitvikSardana
f5f26c3fa3 Merge pull request #3043 from frappe/main-hotfix
chore(release): hotfix to main
2026-02-19 18:40:59 +05:30
RitvikSardana
bc54aae6e3 Merge pull request #3042 from frappe/mergify/bp/main-hotfix/pr-3041
chore: bump version (backport #3041)
2026-02-19 18:35:17 +05:30
Ritvik Sardana
1234197c46 chore: bump version
(cherry picked from commit abc5058b0b)
2026-02-19 13:04:43 +00:00
RitvikSardana
95b1382247 Merge pull request #3037 from frappe/mergify/bp/main-hotfix/pr-3004
chore: sync translations from crowdin (backport #3004)
2026-02-19 18:13:08 +05:30
RitvikSardana
7345580368 Merge pull request #3022 from frappe/mergify/bp/main-hotfix/pr-3000
fix: socket and saved reply (backport #3000)
2026-02-19 18:12:22 +05:30
RitvikSardana
6437f3f95d Merge branch 'main-hotfix' into mergify/bp/main-hotfix/pr-3000 2026-02-19 18:05:57 +05:30
RitvikSardana
1472c5954e Merge pull request #3040 from aerodeval/feat/outside-working-hours-banner
feat: add outside working hours banner feature (backport #2902)
2026-02-19 18:04:04 +05:30
RitvikSardana
d1bece41a2 fix: resolve merge conflict 2026-02-19 16:59:15 +05:30
RitvikSardana
73cd8695c5 Merge pull request #3025 from frappe/mergify/bp/main-hotfix/pr-3024
fix: type check for ticket doctype with int | str (backport #3024)
2026-02-19 16:56:41 +05:30
Sydney
76e0771a68 feat: add outside working hours banner 2026-02-19 16:54:16 +05:30
RitvikSardana
5e305eaf17 Merge branch 'main-hotfix' into mergify/bp/main-hotfix/pr-3024 2026-02-19 14:30:53 +05:30
RitvikSardana
eef1020137 Merge pull request #3038 from frappe/mergify/bp/main-hotfix/pr-3016
fix: add type hints for all API endpoints (backport #3016)
2026-02-19 14:25:06 +05:30
RitvikSardana
93037d56e6 fix: resolve merge conflicts 2026-02-19 14:18:29 +05:30
Ritvik Sardana
5c2918ee2c fix: add hook for type checking
(cherry picked from commit bfd4cb6a9b)

# Conflicts:
#	helpdesk/hooks.py
2026-02-19 08:47:12 +00:00
Ritvik Sardana
1224c7b01e fix: add type hints for all API endpoints
(cherry picked from commit 02b1b0473c)
2026-02-19 08:47:11 +00:00
MochaMind
f7d77f17e7 chore: Serbian (Latin) translations
(cherry picked from commit 1b4fe28b01)
2026-02-19 08:43:29 +00:00
MochaMind
dc1ce1afb1 chore: Persian translations
(cherry picked from commit fa2c98cb0d)
2026-02-19 08:43:28 +00:00
MochaMind
524096c000 chore: Spanish translations
(cherry picked from commit ed91deca37)
2026-02-19 08:43:28 +00:00
MochaMind
4a2d5bd4dd chore: Esperanto translations
(cherry picked from commit 5468734b33)
2026-02-19 08:43:28 +00:00
MochaMind
955c10b996 chore: Serbian (Latin) translations
(cherry picked from commit 6ea82815fd)
2026-02-19 08:43:28 +00:00
MochaMind
009bb8904c chore: Norwegian Bokmal translations
(cherry picked from commit 0872507484)
2026-02-19 08:43:27 +00:00
MochaMind
0e35cc797a chore: Bosnian translations
(cherry picked from commit c23c23f542)
2026-02-19 08:43:27 +00:00
MochaMind
17de104af5 chore: Burmese translations
(cherry picked from commit 4144fb67a2)
2026-02-19 08:43:27 +00:00
MochaMind
124288fa0c chore: Croatian translations
(cherry picked from commit 65921275f6)
2026-02-19 08:43:26 +00:00
MochaMind
22cf2ccc84 chore: Thai translations
(cherry picked from commit a94a3b9244)
2026-02-19 08:43:26 +00:00
MochaMind
efe621ae15 chore: Persian translations
(cherry picked from commit 951bd54aae)
2026-02-19 08:43:26 +00:00
MochaMind
13e01b287f chore: Indonesian translations
(cherry picked from commit bef6f0ce92)
2026-02-19 08:43:26 +00:00
MochaMind
904dccaa1b chore: Portuguese, Brazilian translations
(cherry picked from commit 884e7eab6c)
2026-02-19 08:43:25 +00:00
MochaMind
42172333f5 chore: Vietnamese translations
(cherry picked from commit ec49fa7546)
2026-02-19 08:43:25 +00:00
MochaMind
f11240e804 chore: Chinese Simplified translations
(cherry picked from commit fb75199f52)
2026-02-19 08:43:25 +00:00
MochaMind
bfc46366c9 chore: Turkish translations
(cherry picked from commit 123abdce36)
2026-02-19 08:43:25 +00:00
MochaMind
ffad2013bf chore: Swedish translations
(cherry picked from commit 6c27f5b9d5)
2026-02-19 08:43:24 +00:00
MochaMind
184d024af5 chore: Serbian (Cyrillic) translations
(cherry picked from commit e609c19d96)
2026-02-19 08:43:24 +00:00
MochaMind
793ac1d584 chore: Slovenian translations
(cherry picked from commit ec63f41e73)
2026-02-19 08:43:24 +00:00
MochaMind
7c1ecfd6a7 chore: Russian translations
(cherry picked from commit 1da2f63f16)
2026-02-19 08:43:23 +00:00
MochaMind
baa87bbd77 chore: Portuguese translations
(cherry picked from commit 2084349da9)
2026-02-19 08:43:23 +00:00
MochaMind
6758e94a4f chore: Polish translations
(cherry picked from commit b7a30c80be)
2026-02-19 08:43:23 +00:00
MochaMind
c3b46e2d3f chore: Dutch translations
(cherry picked from commit 9e4505a18e)
2026-02-19 08:43:23 +00:00
MochaMind
098c7a11fb chore: Italian translations
(cherry picked from commit 138825d6b4)
2026-02-19 08:43:22 +00:00
MochaMind
c449bd7e29 chore: Hungarian translations
(cherry picked from commit 1ddb560979)
2026-02-19 08:43:22 +00:00
MochaMind
af386e7075 chore: German translations
(cherry picked from commit ae5990e1dc)
2026-02-19 08:43:22 +00:00
MochaMind
51860ac408 chore: Danish translations
(cherry picked from commit 6c540b917f)
2026-02-19 08:43:22 +00:00
MochaMind
421bd3088f chore: Czech translations
(cherry picked from commit f4266ebaa0)
2026-02-19 08:43:21 +00:00
MochaMind
674e08091a chore: Arabic translations
(cherry picked from commit c211f817ae)
2026-02-19 08:43:21 +00:00
MochaMind
5549159ea5 chore: Spanish translations
(cherry picked from commit d8db4a0e6b)
2026-02-19 08:43:21 +00:00
MochaMind
ef3736c12d chore: French translations
(cherry picked from commit 015a800d90)
2026-02-19 08:43:21 +00:00
MochaMind
6e4291ad6a chore: Persian translations
(cherry picked from commit 9c87f0d089)
2026-02-19 08:43:20 +00:00
MochaMind
abbc9c0ccc chore: Serbian (Latin) translations
(cherry picked from commit 40d72b6af2)
2026-02-19 08:43:20 +00:00
MochaMind
70f65febee chore: Serbian (Cyrillic) translations
(cherry picked from commit 228fa9ff8d)
2026-02-19 08:43:20 +00:00
MochaMind
bad8cc43ae chore: Russian translations
(cherry picked from commit fb802a0ea7)
2026-02-19 08:43:20 +00:00
MochaMind
fc25efa84a chore: Spanish translations
(cherry picked from commit 0541976cea)
2026-02-19 08:43:19 +00:00
MochaMind
23cd1448be chore: Serbian (Latin) translations
(cherry picked from commit 8b182a2201)
2026-02-19 08:43:19 +00:00
MochaMind
35076b0c61 chore: Burmese translations
(cherry picked from commit 03cc38c06f)
2026-02-19 08:43:19 +00:00
MochaMind
8c060aa8c5 chore: Bosnian translations
(cherry picked from commit 164f8e3c91)
2026-02-19 08:43:18 +00:00
MochaMind
543755505a chore: Croatian translations
(cherry picked from commit e1024b017a)
2026-02-19 08:43:18 +00:00
MochaMind
00c8c50c80 chore: Swedish translations
(cherry picked from commit 4b2c340d84)
2026-02-19 08:43:18 +00:00
MochaMind
7c20a1a933 chore: Italian translations
(cherry picked from commit 27b8b014ea)
2026-02-19 08:43:18 +00:00
RitvikSardana
69717779b6 Merge pull request #3036 from frappe/mergify/bp/main-hotfix/pr-2999
chore: sync translations from crowdin (backport #2999)
2026-02-19 14:06:04 +05:30
Jannat Patel
5d02353472 chore: Swedish translations
(cherry picked from commit efb274ecbd)
2026-02-19 08:31:53 +00:00
RitvikSardana
0654ff724c Merge pull request #3035 from frappe/mergify/bp/main-hotfix/pr-2990
chore: sync translations from crowdin (backport #2990)
2026-02-19 14:01:03 +05:30
Jannat Patel
8ae9661106 chore: Esperanto translations
(cherry picked from commit 8bb50ac347)
2026-02-19 08:29:57 +00:00
Jannat Patel
78a72da39a chore: Serbian (Latin) translations
(cherry picked from commit b858fdcf54)
2026-02-19 08:29:57 +00:00
Jannat Patel
dc7049e757 chore: Norwegian Bokmal translations
(cherry picked from commit 20615dc619)
2026-02-19 08:29:57 +00:00
Jannat Patel
16f2b857f7 chore: Bosnian translations
(cherry picked from commit cbd313d18d)
2026-02-19 08:29:56 +00:00
Jannat Patel
338b48bb9b chore: Burmese translations
(cherry picked from commit 7f8135f1ba)
2026-02-19 08:29:56 +00:00
Jannat Patel
58caa8c556 chore: Croatian translations
(cherry picked from commit 76915db34a)
2026-02-19 08:29:56 +00:00
Jannat Patel
144ccda231 chore: Thai translations
(cherry picked from commit 29efce94ed)
2026-02-19 08:29:55 +00:00
Jannat Patel
7659f06491 chore: Persian translations
(cherry picked from commit e9fafea0ac)
2026-02-19 08:29:55 +00:00
Jannat Patel
b6f1ecc30a chore: Indonesian translations
(cherry picked from commit fd7751756f)
2026-02-19 08:29:55 +00:00
Jannat Patel
b94a330c93 chore: Portuguese, Brazilian translations
(cherry picked from commit d04cea4724)
2026-02-19 08:29:55 +00:00
Jannat Patel
5d3b3140a3 chore: Vietnamese translations
(cherry picked from commit 46f5c903e4)
2026-02-19 08:29:54 +00:00
Jannat Patel
b906a33cf8 chore: Chinese Simplified translations
(cherry picked from commit f94bafd44f)
2026-02-19 08:29:54 +00:00
Jannat Patel
fc7c240535 chore: Turkish translations
(cherry picked from commit afe1a18779)
2026-02-19 08:29:54 +00:00
Jannat Patel
1399795a5c chore: Swedish translations
(cherry picked from commit 1fc57f4325)
2026-02-19 08:29:54 +00:00
Jannat Patel
a5da3503dd chore: Serbian (Cyrillic) translations
(cherry picked from commit fdc3c610aa)
2026-02-19 08:29:53 +00:00
Jannat Patel
7e175c157e chore: Slovenian translations
(cherry picked from commit 2eef45125e)
2026-02-19 08:29:53 +00:00
Jannat Patel
68f9523151 chore: Russian translations
(cherry picked from commit 7c62431e4c)
2026-02-19 08:29:53 +00:00
Jannat Patel
6e721bf17a chore: Portuguese translations
(cherry picked from commit d26d2c90f5)
2026-02-19 08:29:52 +00:00
Jannat Patel
a9d28b530b chore: Polish translations
(cherry picked from commit e835e58695)
2026-02-19 08:29:52 +00:00
Jannat Patel
6026b1e2a3 chore: Dutch translations
(cherry picked from commit e3c3967465)
2026-02-19 08:29:52 +00:00
Jannat Patel
be75ad2617 chore: Italian translations
(cherry picked from commit 680053d1a3)
2026-02-19 08:29:52 +00:00
Jannat Patel
2f4c20b8f0 chore: Hungarian translations
(cherry picked from commit 80052ed221)
2026-02-19 08:29:51 +00:00
Jannat Patel
00b9cbe8ca chore: German translations
(cherry picked from commit c37250eb06)
2026-02-19 08:29:51 +00:00
Jannat Patel
f542c86d1a chore: Danish translations
(cherry picked from commit 042d496497)
2026-02-19 08:29:51 +00:00
Jannat Patel
4b54c60e87 chore: Czech translations
(cherry picked from commit 2c1a9775e1)
2026-02-19 08:29:50 +00:00
Jannat Patel
00f175b16b chore: Arabic translations
(cherry picked from commit 87b3a32814)
2026-02-19 08:29:50 +00:00
Jannat Patel
f62a66411b chore: Spanish translations
(cherry picked from commit 61d4738a84)
2026-02-19 08:29:50 +00:00
Jannat Patel
fb139c06fd chore: French translations
(cherry picked from commit b266ee5072)
2026-02-19 08:29:50 +00:00
Jannat Patel
51cd8bf11c chore: Italian translations
(cherry picked from commit 9cebf53ea4)
2026-02-19 08:29:49 +00:00
RitvikSardana
79b2bf4a25 Merge pull request #3034 from frappe/mergify/bp/main-hotfix/pr-2970
fix: add type hints (backport #2970)
2026-02-19 13:58:32 +05:30
Ritvik Sardana
b2781617ff fix: add type hints
(cherry picked from commit f9240bc248)
2026-02-19 08:27:43 +00:00
RitvikSardana
4b1c447bc2 Merge pull request #3033 from frappe/mergify/bp/main-hotfix/pr-2966
fix: perm issues (backport #2966)
2026-02-19 13:56:49 +05:30
RitvikSardana
8592645e0e fix: resolve merge conflict 2026-02-19 13:51:13 +05:30
Pratik
a6a515cce3 fix: use standard api for fetching agent
(cherry picked from commit 064110d940)

# Conflicts:
#	desk/vite.config.js
2026-02-19 08:18:28 +00:00
Pratik
d365afc249 fix: security issues
(cherry picked from commit 348884a912)

# Conflicts:
#	desk/src/types.ts
#	desk/vite.config.js
2026-02-19 08:18:28 +00:00
RitvikSardana
0d65b35dff Merge pull request #3032 from frappe/mergify/bp/main-hotfix/pr-2960
fix: remove unwanted files (backport #2960)
2026-02-19 13:47:05 +05:30
RitvikSardana
9de29f4122 fix: resolve merge conflict 2026-02-19 13:42:21 +05:30
Pratik
f4b35e718b fix: use standard api for fetching agent
(cherry picked from commit 69c8626f80)
2026-02-19 08:05:01 +00:00
Pratik
1dcf550f52 fix: security issues
(cherry picked from commit b3b6ac9a04)

# Conflicts:
#	desk/src/types.ts
2026-02-19 08:05:01 +00:00
Ritvik Sardana
f86732e1a8 fix: version bump
(cherry picked from commit b219aefb20)

# Conflicts:
#	helpdesk/__init__.py
2026-02-19 08:05:00 +00:00
Ritvik Sardana
87e84e2574 fix: version bump
(cherry picked from commit d150c290fb)

# Conflicts:
#	helpdesk/__init__.py
2026-02-19 08:05:00 +00:00
Ritvik Sardana
8279162135 fix(test): update test cases
(cherry picked from commit d2dbddd5a4)
2026-02-19 08:05:00 +00:00
Ritvik Sardana
8de2124435 fix: add perm checks for API endpoints
(cherry picked from commit e4ee29f95e)
2026-02-19 08:04:59 +00:00
Ritvik Sardana
a566adbde1 fix: select perms instead of read perm for correct doctypes
(cherry picked from commit 0da0b73dc8)
2026-02-19 08:04:59 +00:00
Ritvik Sardana
2ffaa84659 fix(security): remove roles and unwanted files
(cherry picked from commit b45a658b01)
2026-02-19 08:04:59 +00:00
RitvikSardana
fc4bf5460c Merge pull request #3030 from frappe/mergify/bp/main-hotfix/pr-2932
fix(patch): ticket id not found (backport #2932)
2026-02-19 13:33:49 +05:30
Ritvik Sardana
a24c08853b fix(patch): ticket id not found
(cherry picked from commit 73604e7f11)
2026-02-19 07:57:17 +00:00
RitvikSardana
998c7c0232 Merge pull request #3029 from frappe/mergify/bp/main-hotfix/pr-2900
fix: add fields for last customer and agent response (backport #2900)
2026-02-19 13:26:20 +05:30
RitvikSardana
ffd8243d7b fix: resolve merge conflict 2026-02-19 13:21:14 +05:30
Ritvik Sardana
8d24279974 chore: code cleanup
(cherry picked from commit af46f0b818)

# Conflicts:
#	desk/src/components/notifications/Notifications.vue
2026-02-19 07:47:17 +00:00
Ritvik Sardana
0f570d8e71 chore: code cleanup
(cherry picked from commit 8f2baba838)
2026-02-19 07:47:17 +00:00
Ritvik Sardana
51c5cdbfe4 fix: better patch
(cherry picked from commit 41578afca1)
2026-02-19 07:47:17 +00:00
Ritvik Sardana
3200592b6f fix: better patch
(cherry picked from commit b3fa7241d7)
2026-02-19 07:47:16 +00:00
Ritvik Sardana
622bd684a6 fix: add fields for last customer and agent response
(cherry picked from commit 9eb3902f63)
2026-02-19 07:47:16 +00:00
RitvikSardana
628e1ef95a Merge pull request #3028 from frappe/mergify/bp/main-hotfix/pr-2930
fix: notification styles and order by (backport #2930)
2026-02-19 13:10:59 +05:30
Ritvik Sardana
916092ef18 fix: notification styles and order by
(cherry picked from commit c96b00db75)
2026-02-19 07:36:16 +00:00
RitvikSardana
49fae54f1b Merge pull request #2908 from frappe/mergify/bp/main-hotfix/pr-2907
fix: duplicate mention notification (backport #2907)
2026-02-19 13:05:20 +05:30
RitvikSardana
ed0903a59f Merge branch 'main-hotfix' into mergify/bp/main-hotfix/pr-2907 2026-02-19 12:51:56 +05:30
RitvikSardana
0adb24c28d Merge pull request #3027 from frappe/mergify/bp/main-hotfix/pr-2812
feat: add comment reactions (thumbs up) feature (backport #2812)
2026-02-19 12:50:41 +05:30
RitvikSardana
fb4106f057 fix: merge conflicts 2026-02-19 12:45:14 +05:30
Ritvik Sardana
816b216ee4 fix(styles): reaction tooltip
(cherry picked from commit 2c3e8dbcb2)
2026-02-19 07:06:50 +00:00
samarth93
ec34dde51d test: enable comment reactions setting in test setup
(cherry picked from commit 96faca2b87)
2026-02-19 07:06:50 +00:00
Ritvik Sardana
e0b1b426a3 chore: arrange child table properly
(cherry picked from commit 813841f2b2)
2026-02-19 07:06:49 +00:00
Ritvik Sardana
89af35bc94 fix: add socket support and make color changes
(cherry picked from commit c8ab762d89)
2026-02-19 07:06:49 +00:00
samarth93
253201838e feat: add enable_comment_reactions setting to toggle feature
(cherry picked from commit 0b05a7c021)

# Conflicts:
#	desk/src/stores/config.ts
#	helpdesk/api/config.py
2026-02-19 07:06:49 +00:00
samarth93
074229ab7d fix: use format() instead of f-string for Python 3.14 compatibility
(cherry picked from commit 7a18b330ca)
2026-02-19 07:06:48 +00:00
samarth93
67fa875028 style: remove trailing comma for prettier
(cherry picked from commit 8d1101c7eb)
2026-02-19 07:06:48 +00:00
samarth93
702e51c478 test: update assertions for new notification message format
(cherry picked from commit de070ed4ef)
2026-02-19 07:06:48 +00:00
samarth93
300427a5e5 style: apply prettier formatting
(cherry picked from commit 1ca388de7b)

# Conflicts:
#	desk/src/components/notifications/Notifications.vue
2026-02-19 07:06:47 +00:00
samarth93
477560e098 fix: improve reaction notification display and routing
(cherry picked from commit f69de39a09)

# Conflicts:
#	desk/src/components/notifications/Notifications.vue
2026-02-19 07:06:47 +00:00
samarth93
31c5191fee fix: wrap user-facing strings in translate function
(cherry picked from commit f313fd00b1)
2026-02-19 07:06:47 +00:00
samarth93
66de85079c fix: prettier formatting
(cherry picked from commit 270ece00f9)
2026-02-19 07:06:46 +00:00
samarth93
abbff7d4e0 fix: pre-commit formatting
(cherry picked from commit 73673ea050)
2026-02-19 07:06:46 +00:00
samarth93
3fa46f9806 feat: grouped notifications and UI refinements for comment reactions
(cherry picked from commit 7535c416a1)
2026-02-19 07:06:46 +00:00
samarth93
620404292f chore: remove temporary pr description file
(cherry picked from commit 18c2aa1f69)
2026-02-19 07:06:45 +00:00
samarth93
f658c54933 fix: use dynamic ticket name in tests
The test was failing because it tried to use hardcoded
'TEST-TICKET-001' name but HD Ticket uses autoname.

Changed to:
- Create ticket dynamically and store in self.test_ticket
- Reference self.test_ticket.name for comments
- Clean up ticket in tearDown

(cherry picked from commit 3a3c3941df)
2026-02-19 07:06:45 +00:00
samarth93
8f46d5acc3 fix: remove unused username variable
Fixes linter error from unused variable

(cherry picked from commit 6733de3f00)
2026-02-19 07:06:45 +00:00
samarth93
0357db16b2 feat: implement preset emojis with validation and comprehensive tests
Addressing feedback:
1. One reaction per user (not multiple)
2. Preset emojis only: ['👍', '👎', '❤️', '🎉', '👀', '✅']
3. API validation to block non-preset emojis
4. Updated notification message: 'reacted with X on your comment'
5. Comprehensive test cases covering all requirements

Backend changes:
- Add PRESET_EMOJIS constant
- Add emoji validation in toggle_reaction API
- Change to one reaction per user (replaces on different emoji)
- Update notification message format
- Add get_preset_emojis() API

Frontend changes:
- Update emojiList to match preset emojis

Test cases added:
- test_one_reaction_per_user: Verifies only one reaction allowed
- test_reaction_count_accuracy: Tests count with 10 hearts, 3 thumbs up
- test_notification_created_on_reaction: Validates HD Notification creation
- test_only_preset_emojis_allowed: Ensures only preset emojis accepted
- test_reaction_toggle_behavior: Tests toggle on/off behavior
- test_get_reactions_returns_correct_data: Validates API response structure

(cherry picked from commit 5671b4baa8)
2026-02-19 07:06:45 +00:00
samarth93
0142096774 fix: rename to HD Comment Reaction and allow multiple reactions
Addressing feedback from @RitvikSardana:
1. Renamed child table from 'HD Reaction' to 'HD Comment Reaction'
2. Allow users to add multiple different reactions (not just one)
3. Updated PR description with screenshot

Changes:
- Rename HD Reaction → HD Comment Reaction (DocType name)
- Update toggle_reaction logic to allow multiple reactions per user
- Users can now react with different emojis (👍 + ❤️ + 🎉 etc)
- Clicking same emoji toggles it off
- Updated all references in code

(cherry picked from commit 26a20ac1d7)
2026-02-19 07:06:44 +00:00
samarth93
8c8480d558 refactor: store reactions as child table with emoji picker
Based on feedback from @RitvikSardana:
- Replace standalone HD Comment Reaction with HD Reaction child table
- Store reactions inside HD Ticket Comment (like Gameplan)
- Add emoji picker with multiple emoji options (👍👎❤️😄🎉😕👀🚀)
- Users can only have one reaction per comment (clicking different emoji replaces)

Changes:
- New HD Reaction DocType (child table with emoji + user)
- Add reactions Table field to HD Ticket Comment
- Add toggle_reaction() and get_reactions() APIs
- Update CommentBox.vue with emoji picker popover
- Remove old HD Comment Reaction standalone DocType

(cherry picked from commit 55ce67903b)
2026-02-19 07:06:44 +00:00
samarth93
61ff676bf4 feat: add comment reactions (thumbs up) feature
Allows users to react to comments with a thumbs up emoji instead of
creating new comments. This reduces ticket clutter when acknowledging
a comment.

Changes:
- Add new HD Comment Reaction DocType to store reactions
- Add toggle_reaction and get_comment_reactions API endpoints
- Add reaction UI to CommentBox.vue with hover tooltip showing users
- Send notification to comment author when reaction is added

Backend:
- helpdesk/helpdesk/doctype/hd_comment_reaction/ - new DocType
- API: toggle_reaction(comment, reaction) - add/remove reaction
- API: get_comment_reactions(comment) - list reactions with users

Frontend:
- CommentBox.vue - thumbs up button with count and user tooltip
- Highlights button when current user has reacted
- Real-time update via publish_event

(cherry picked from commit d8c1f8ca19)
2026-02-19 07:06:44 +00:00
Ritvik Sardana
39f89f16ff fix: type check for ticket doctype with int | str
(cherry picked from commit edc3d29d74)

# Conflicts:
#	helpdesk/api/doc.py
#	helpdesk/api/saved_replies.py
#	helpdesk/helpdesk/doctype/hd_ticket/api.py
2026-02-17 15:54:26 +00:00
RitvikSardana
c4f32eda16 Merge pull request #3023 from frappe/mergify/bp/main-hotfix/pr-2623
fix: ignore automated system notifications in ticket communication from automatically reopens the ticket. (backport #2623)
2026-02-17 20:08:14 +05:30
MostafaKadry
f3a701bfab fix: ignore automated system notifications in ticket communication handling
(cherry picked from commit ee86eb6a0e)
2026-02-17 14:37:04 +00:00
RitvikSardana
cec8db5626 Merge pull request #3021 from frappe/mergify/bp/main-hotfix/pr-3020
fix: filter personal replies from list (backport #3020)
2026-02-17 20:06:54 +05:30
Ritvik Sardana
1cadd07155 fix: revert CP changes
(cherry picked from commit 60584fcd4d)
2026-02-17 14:36:51 +00:00
Ritvik Sardana
894a588928 fix: order_by in Ticket Summary report
(cherry picked from commit a096e1b19f)
2026-02-17 14:36:51 +00:00
Ritvik Sardana
280ef71fc1 fix: dont send notification if agent is same as session.user
(cherry picked from commit d6d4c4dfe9)
2026-02-17 14:36:50 +00:00
Ritvik Sardana
51b0bad8c8 fix: redisearch syntax error
(cherry picked from commit adb3ee3b0d)
2026-02-17 14:36:50 +00:00
Ritvik Sardana
9ec01333d3 fix: redisearch syntax error
(cherry picked from commit 93bc04605e)
2026-02-17 14:36:50 +00:00
Ritvik Sardana
b0f275487a fix: CP styles
(cherry picked from commit 29ad7da211)
2026-02-17 14:36:49 +00:00
Ritvik Sardana
0124948ed8 fix: append saved reply to email content instead of replacing it
(cherry picked from commit ea60812f81)
2026-02-17 14:36:49 +00:00
Ritvik Sardana
c1aa15145f fix: socket and saved reply
(cherry picked from commit 69e047f69e)

# Conflicts:
#	desk/src/pages/ticket/TicketCustomer.vue
2026-02-17 14:36:49 +00:00
Pratik
49af2e1fe9 fix: saved reply admin test
(cherry picked from commit 576432d380)
2026-02-17 12:34:42 +00:00
Pratik
981515387f fix: filter personal replies from list
(cherry picked from commit c13aabdbdc)
2026-02-17 12:34:42 +00:00
RitvikSardana
1f5ffe5084 Merge pull request #3019 from frappe/mergify/bp/main-hotfix/pr-3018
chore: project URLs (backport #3018)
2026-02-17 17:31:43 +05:30
Ankush Menat
6d5f8535b5 chore: project URLs (#3018)
(cherry picked from commit d6be9938ad)
2026-02-17 10:20:53 +00:00
RitvikSardana
2cc2987d94 Merge pull request #2998 from frappe/mergify/bp/main-hotfix/pr-2811
fix: add DatePicker support for custom Date/Datetime fields in UniInput (backport #2811)
2026-02-09 15:28:16 +05:30
RitvikSardana
d95d3ee878 Merge pull request #2997 from frappe/mergify/bp/main-hotfix/pr-2996
fix: add login endpoints in auth (backport #2996)
2026-02-09 15:27:57 +05:30
RitvikSardana
5b7dc536df Merge pull request #2995 from frappe/mergify/bp/main-hotfix/pr-2991
chore: update POT file (backport #2991)
2026-02-09 15:27:47 +05:30
Ritvik Sardana
8b5cde9bbd fix: add support in ticket creation form
(cherry picked from commit 8e64cf9cca)
2026-02-09 09:51:38 +00:00
Ritvik Sardana
ad52394ce6 fix: add date/datetime support in agent and customer ticket view
(cherry picked from commit df7deec952)
2026-02-09 09:51:38 +00:00
samarth93
f9c10d3d8b fix: prettier formatting
(cherry picked from commit 5e3173ac5a)
2026-02-09 09:51:38 +00:00
samarth93
4e305315c2 fix: add DatePicker support for custom Date/Datetime fields in UniInput
Fixes #2669

Custom Date and Datetime fields on the new ticket form were rendering
as plain text inputs instead of proper DatePicker/DateTimePicker
components.

Changes:
- Import DatePicker and DateTimePicker from frappe-ui
- Add handling for 'Date' fieldtype to render DatePicker component
- Add handling for 'Datetime' fieldtype to render DateTimePicker component
- Add date formatting in transValue for proper display

(cherry picked from commit d42af58d88)
2026-02-09 09:51:37 +00:00
Ritvik Sardana
c56fc87826 fix: add login endpoints in auth
(cherry picked from commit 8478892383)
2026-02-09 06:40:57 +00:00
frappe-pr-bot
7b2d73dea2 chore: update POT file
(cherry picked from commit c47a44096c)
2026-02-09 06:01:59 +00:00
RitvikSardana
f8ea7765a0 Merge pull request #2989 from frappe/main-hotfix
chore(release): hotfix to main
2026-02-08 01:05:11 +05:30
RitvikSardana
a931adcb3d Merge pull request #2985 from frappe/mergify/bp/main-hotfix/pr-2973
fix: added support for mail with display names and latin characters (backport #2973)
2026-02-07 19:46:49 +05:30
RitvikSardana
101f5214f3 Merge pull request #2984 from frappe/mergify/bp/main-hotfix/pr-2977
chore: sync translations from crowdin (backport #2977)
2026-02-07 19:46:41 +05:30
RitvikSardana
2f32852840 chore: bump version 2026-02-07 19:38:39 +05:30
RitvikSardana
1efeb5f7f9 fix: remove canned response from sidebar 2026-02-07 19:36:52 +05:30
Sydney
42fce2b60e fix: add deboubnce and use zod validation for email
(cherry picked from commit 3b5b2ce9c6)
2026-02-06 09:08:13 +00:00
Sydney
ba8f819eb4 fix: fixed mail backspace bug and added support for multiinput for normalization
(cherry picked from commit d00431f51c)
2026-02-06 09:08:12 +00:00
Sydney
14a2dff554 fix: add regex support for latin characters and input support for MultiInput for mail ids
(cherry picked from commit 257c12e79f)
2026-02-06 09:08:12 +00:00
Sydney
5fcdd736f1 fix: add support for display names in mail
(cherry picked from commit 233b935393)
2026-02-06 09:08:12 +00:00
Jannat Patel
f37a70fab3 chore: Persian translations
(cherry picked from commit e6c267338c)
2026-02-06 09:03:42 +00:00
Jannat Patel
a385e9e05b chore: Portuguese, Brazilian translations
(cherry picked from commit 85a0644593)
2026-02-06 09:03:42 +00:00
Jannat Patel
1724565f7f chore: Swedish translations
(cherry picked from commit a91f4867c4)
2026-02-06 09:03:42 +00:00
Jannat Patel
e18bbd2eeb chore: Dutch translations
(cherry picked from commit 420ef47b66)
2026-02-06 09:03:41 +00:00
Jannat Patel
1ecac6270a chore: Italian translations
(cherry picked from commit cc665c838f)
2026-02-06 09:03:41 +00:00
Jannat Patel
60eb1e39fb chore: Spanish translations
(cherry picked from commit 22901fd402)
2026-02-06 09:03:41 +00:00
RitvikSardana
7ec09103da Merge pull request #2983 from frappe/mergify/bp/main-hotfix/pr-2972
fix: hide captions in text editor (backport #2972)
2026-02-06 14:32:41 +05:30
RitvikSardana
0c8704b08b Merge pull request #2982 from frappe/mergify/bp/main-hotfix/pr-2981
fix: sprint fixes-1 (backport #2981)
2026-02-06 14:32:32 +05:30
RitvikSardana
b05cd37cd3 Merge pull request #2968 from frappe/mergify/bp/main-hotfix/pr-2939
chore: sync translations from crowdin (backport #2939)
2026-02-06 14:25:54 +05:30
RitvikSardana
abc20dd161 Merge pull request #2976 from frappe/mergify/bp/main-hotfix/pr-2956
chore(setup): Add build info in pyproject (backport #2956)
2026-02-06 14:25:01 +05:30
RitvikSardana
39f0545c8f chore: fix merge conflicts 2026-02-06 14:17:59 +05:30
Sydney
4565a76e7c chore: disable image captions all over
(cherry picked from commit 64f94848ea)
2026-02-06 08:44:31 +00:00
Sydney
5dea5e3497 fix: disable input for image captions in textinput
(cherry picked from commit 23571113f6)
2026-02-06 08:44:31 +00:00
Ritvik Sardana
933fe94eac chore: add type hints to api
(cherry picked from commit 4c73593c8a)
2026-02-06 08:44:19 +00:00
Ritvik Sardana
cd6050f5f1 fix: persist count in LV
(cherry picked from commit 4c594535a6)
2026-02-06 08:44:19 +00:00
Ritvik Sardana
81322323c4 fix: add seen functionality in list view
(cherry picked from commit 5a4f152d52)
2026-02-06 08:44:18 +00:00
Ritvik Sardana
54414613ee fix(search): prepare doc if field exists
(cherry picked from commit a7135bc17b)
2026-02-06 08:44:18 +00:00
Ritvik Sardana
3713cd6b2c fix: persist rows count in list view
(cherry picked from commit e92963357f)
2026-02-06 08:44:18 +00:00
Aradhya-Tripathi
3d44b09851 chore(build): Setup out dir and index from project root
(cherry picked from commit a76ff09d6e)

# Conflicts:
#	pyproject.toml
2026-02-05 05:59:27 +00:00
Aradhya-Tripathi
6de40f928b chore(setup): Add build info in pyproject
(cherry picked from commit ce4c738898)

# Conflicts:
#	pyproject.toml
2026-02-05 05:59:26 +00:00
RitvikSardana
b90f20ee21 chore: Arabic translations
(cherry picked from commit 29ca9701c2)
2026-02-02 16:14:56 +00:00
RitvikSardana
f112dc08df chore: Dutch translations
(cherry picked from commit 09552d7e90)
2026-02-02 16:14:55 +00:00
RitvikSardana
637f3879db Merge pull request #2965 from frappe/main-hotfix
chore(release): hotfix to main
2026-02-02 14:07:51 +05:30
RitvikSardana
e156154855 Merge pull request #2962 from frappe/mergify/bp/main-hotfix/pr-2961
fix: add signup auth and redirect route perm (backport #2961)
2026-02-02 13:56:11 +05:30
RitvikSardana
18a2e02525 Merge branch 'main-hotfix' into mergify/bp/main-hotfix/pr-2961 2026-02-02 13:49:58 +05:30
RitvikSardana
bd56224691 Merge pull request #2944 from frappe/mergify/bp/main-hotfix/pr-2943
fix: add OAuth2 paths (backport #2943)
2026-02-02 13:49:33 +05:30
RitvikSardana
ed3e27c8c5 Merge branch 'main-hotfix' into mergify/bp/main-hotfix/pr-2943 2026-02-02 13:43:13 +05:30
RitvikSardana
fa3bcf27ae Merge pull request #2964 from frappe/mergify/bp/main-hotfix/pr-2941
fix: custom login auth path (backport #2941)
2026-02-02 13:41:36 +05:30
Ritvik Sardana
bead00ad68 fix: custom login auth path
(cherry picked from commit 2dc26b378d)
2026-02-02 08:09:46 +00:00
RitvikSardana
83f4d35ad0 Merge pull request #2963 from frappe/mergify/bp/main-hotfix/pr-2933
fix(security): limit auth hooks (backport #2933)
2026-02-02 13:38:57 +05:30
Ritvik Sardana
4434c20716 fix(security): limit auth hooks
(cherry picked from commit a7596090c4)
2026-02-02 08:08:17 +00:00
Ritvik Sardana
d6d7c1f5dd fix: version bump
(cherry picked from commit a3116603c7)
2026-02-02 08:05:23 +00:00
Ritvik Sardana
94ce44ad02 fix: version bump
(cherry picked from commit 1ce95fcab5)
2026-02-02 08:05:23 +00:00
Ritvik Sardana
2aa9533d26 fix: add signup auth and redirect route perm
(cherry picked from commit b625a95e22)

# Conflicts:
#	helpdesk/auth.py
2026-02-02 08:05:22 +00:00
Shariq Ansari
c9b2fc1291 Merge pull request #2953 from frappe/mergify/bp/main/pr-2951
fix: posthog optional chaining added to fix delete button bug (backport #2951)
2026-01-28 21:01:21 +05:30
Shariq Ansari
862bb94cbc Merge pull request #2952 from frappe/mergify/bp/main-hotfix/pr-2951
fix: posthog optional chaining added to fix delete button bug (backport #2951)
2026-01-28 20:58:33 +05:30
Sydney
ac504d84ff fix: posthog optional chaining added to fix close button bug
(cherry picked from commit 82d3751f80)
2026-01-28 15:27:01 +00:00
Sydney
6e4545a058 fix: posthog optional chaining added to fix close button bug
(cherry picked from commit 82d3751f80)
2026-01-28 15:24:24 +00:00
Ritvik Sardana
060338d3c4 fix: add OAuth2 paths
(cherry picked from commit a94013e8d6)

# Conflicts:
#	helpdesk/auth.py
2026-01-26 07:46:10 +00:00
RitvikSardana
41abffdbbd Merge pull request #2937 from frappe/main-hotfix
chore(release): hotfix to main
2026-01-23 16:57:44 +05:30
RitvikSardana
95825dc9f6 chore: version bump 2026-01-23 16:57:20 +05:30
RitvikSardana
3974b153a8 Merge pull request #2935 from frappe/mergify/bp/main-hotfix/pr-2934
fix: fail install (backport #2934)
2026-01-23 16:56:06 +05:30
RitvikSardana
45273dabe8 Merge pull request #2936 from RitvikSardana/email-box-width
fix: email box height
2026-01-23 16:54:46 +05:30
Ritvik Sardana
e33e9203ed fix: email box height 2026-01-23 16:54:02 +05:30
Ritvik Sardana
c07d5dc043 chore: code cleanup
(cherry picked from commit 402dd042ae)
2026-01-23 11:20:07 +00:00
Ritvik Sardana
ba67d869bc fix: add agent_name field while installing
(cherry picked from commit 012b6b91ea)
2026-01-23 11:20:07 +00:00
RitvikSardana
28e909a9e0 Merge pull request #2931 from frappe/main-hotfix
chore(release): hotfix to main
2026-01-23 13:00:11 +05:30
RitvikSardana
1ebe1503c4 Merge pull request #2920 from frappe/mergify/bp/main-hotfix/pr-2880
chore: sync translations from crowdin (backport #2880)
2026-01-23 12:48:53 +05:30
RitvikSardana
4859978e0a Merge branch 'main-hotfix' into mergify/bp/main-hotfix/pr-2880 2026-01-23 12:48:44 +05:30
RitvikSardana
dc376d7e09 chore: version bump 2026-01-23 12:45:08 +05:30
RitvikSardana
eb605fd7b6 Merge pull request #2928 from frappe/mergify/bp/main-hotfix/pr-2922
chore: sync translations from crowdin (backport #2922)
2026-01-23 12:16:12 +05:30
RitvikSardana
22ce271aa1 chore: Bosnian translations
(cherry picked from commit e4372f72cf)
2026-01-22 18:11:20 +00:00
RitvikSardana
cc64bc1723 chore: Swedish translations
(cherry picked from commit aa70598d7a)
2026-01-22 18:11:20 +00:00
RitvikSardana
3d5692cdc6 chore: Dutch translations
(cherry picked from commit 2c4ec37fb1)
2026-01-22 18:11:20 +00:00
RitvikSardana
a989dc1af4 chore: Norwegian Bokmal translations
(cherry picked from commit 774b9073a1)
2026-01-22 18:11:20 +00:00
RitvikSardana
d61b38c674 chore: Bosnian translations
(cherry picked from commit 41fd854f2d)
2026-01-22 18:11:19 +00:00
RitvikSardana
5d51ccd525 chore: Croatian translations
(cherry picked from commit 78282416d1)
2026-01-22 18:11:19 +00:00
RitvikSardana
0ad7fdaa8d chore: Portuguese, Brazilian translations
(cherry picked from commit 3da40a1fed)
2026-01-22 18:11:19 +00:00
RitvikSardana
3aa0ce46ef chore: Vietnamese translations
(cherry picked from commit c968fdf0f3)
2026-01-22 18:11:19 +00:00
RitvikSardana
5032dc611a chore: Chinese Simplified translations
(cherry picked from commit 52c01e93e9)
2026-01-22 18:11:18 +00:00
RitvikSardana
244838fcef chore: Turkish translations
(cherry picked from commit 4b7a065bae)
2026-01-22 18:11:18 +00:00
RitvikSardana
7eecb4c173 chore: Swedish translations
(cherry picked from commit 7932b40420)
2026-01-22 18:11:18 +00:00
RitvikSardana
488956db07 chore: Slovenian translations
(cherry picked from commit 66b50e3799)
2026-01-22 18:11:18 +00:00
RitvikSardana
9367660af3 chore: Portuguese translations
(cherry picked from commit 71780d5e04)
2026-01-22 18:11:17 +00:00
RitvikSardana
a878780786 chore: Polish translations
(cherry picked from commit 45bf04d592)
2026-01-22 18:11:17 +00:00
RitvikSardana
bac49e41a3 chore: Italian translations
(cherry picked from commit 6f161fd717)
2026-01-22 18:11:17 +00:00
RitvikSardana
84ac4c2f48 chore: German translations
(cherry picked from commit 0ca91888d2)
2026-01-22 18:11:17 +00:00
RitvikSardana
cce5a30496 chore: Arabic translations
(cherry picked from commit c18eb9f361)
2026-01-22 18:11:16 +00:00
RitvikSardana
d44ffe4b24 chore: Spanish translations
(cherry picked from commit f9b2b423af)
2026-01-22 18:11:16 +00:00
RitvikSardana
8b34a4a9e2 chore: French translations
(cherry picked from commit 57d00bb726)

# Conflicts:
#	helpdesk/locale/fr.po
2026-01-22 18:11:16 +00:00
RitvikSardana
8b8c92f5bb chore: Indonesian translations
(cherry picked from commit e60cedd170)
2026-01-22 18:11:15 +00:00
RitvikSardana
e124cb2dcf chore: Russian translations
(cherry picked from commit 1dbec24253)
2026-01-22 18:11:15 +00:00
RitvikSardana
95355c67c4 chore: Persian translations
(cherry picked from commit dc1bb0596a)
2026-01-22 18:11:15 +00:00
RitvikSardana
e945f118a7 chore: Dutch translations
(cherry picked from commit cc9a1638f6)
2026-01-22 18:11:15 +00:00
RitvikSardana
7f8d3be345 chore: Hungarian translations
(cherry picked from commit 9447c8ccd4)
2026-01-22 18:11:14 +00:00
RitvikSardana
93cef0c509 Merge pull request #2924 from frappe/mergify/bp/main-hotfix/pr-2923
fix(patch): rename canned response (backport #2923)
2026-01-22 23:29:27 +05:30
Pratik
c23e8b001e fix: rename canned response patch
(cherry picked from commit 1888f24f46)
2026-01-22 10:14:39 +00:00
RitvikSardana
ca6ae4cdf4 chore: French translations
(cherry picked from commit 79943278e9)
2026-01-20 11:37:59 +00:00
RitvikSardana
54261e3c3e Merge pull request #2919 from frappe/mergify/bp/main-hotfix/pr-2914
fix(HD Agent): make fields mandatory (backport #2914)
2026-01-20 10:42:04 +05:30
Ritvik Sardana
76edb52a1d chore: code cleanup
(cherry picked from commit 8b765ba34d)
2026-01-20 04:51:39 +00:00
Ritvik Sardana
e9aa895159 test: add agent_name field in test utils
(cherry picked from commit 6944796c8e)
2026-01-20 04:51:39 +00:00
Ritvik Sardana
42b1a7862c test: add agent_name field in test utils
(cherry picked from commit 04d289bb95)
2026-01-20 04:51:39 +00:00
Ritvik Sardana
67c59d26de fix(HD Agent): make fields mandatory
(cherry picked from commit c34dfc18ac)
2026-01-20 04:51:39 +00:00
RitvikSardana
07fa11fa87 Merge pull request #2917 from frappe/mergify/bp/main-hotfix/pr-2913
fix: update yarn lock in frontend folder (backport #2913)
2026-01-20 00:41:22 +05:30
RitvikSardana
8b1fb35730 chore: resolve conflicts 2026-01-20 00:32:39 +05:30
Ritvik Sardana
346275d1b1 fix: update yarn lock in frontend folder
(cherry picked from commit b784ea807f)

# Conflicts:
#	desk/src/components/notifications/Notifications.vue
2026-01-19 18:59:28 +00:00
RitvikSardana
5a271df560 Merge pull request #2916 from frappe/mergify/bp/main-hotfix/pr-2912
fix: update lock file (backport #2912)
2026-01-20 00:28:13 +05:30
Ritvik Sardana
beefbdce11 fix: update lock file
(cherry picked from commit 6d6d3498cf)
2026-01-19 18:57:24 +00:00
RitvikSardana
1770545fc0 Merge pull request #2915 from frappe/mergify/bp/main-hotfix/pr-2910
fix(reactivity): mentions dropdown (backport #2910)
2026-01-20 00:24:00 +05:30
Ritvik Sardana
9336363968 fix(reactivity): mentions dropdown
(cherry picked from commit 53fe99dc8a)
2026-01-19 18:53:24 +00:00
RitvikSardana
8241dc83e7 Merge pull request #2909 from frappe/revert-2906-mergify/bp/main-hotfix/pr-2905
Revert "fix: email scroll & notifications (backport #2905)"
2026-01-19 15:18:51 +05:30
RitvikSardana
ab9f3bc818 Revert "fix: email scroll & notifications (backport #2905)" 2026-01-19 14:03:47 +05:30
Ritvik Sardana
10cd71be8e fix: notify only when comment is updated
(cherry picked from commit 07ea05aa37)

# Conflicts:
#	helpdesk/helpdesk/doctype/hd_ticket_comment/hd_ticket_comment.py
2026-01-19 08:32:15 +00:00
Ritvik Sardana
a3959a6da9 fix: duplicate mention notification
(cherry picked from commit 67a753e5fb)

# Conflicts:
#	helpdesk/helpdesk/doctype/hd_ticket_comment/hd_ticket_comment.py
2026-01-19 08:32:15 +00:00
RitvikSardana
8d3b676c03 Merge pull request #2906 from frappe/mergify/bp/main-hotfix/pr-2905
fix: email scroll & notifications (backport #2905)
2026-01-19 13:06:40 +05:30
Ritvik Sardana
96911c65d3 fix: render notifications properly
(cherry picked from commit c696a595dd)

# Conflicts:
#	desk/src/components/notifications/Notifications.vue
2026-01-19 05:33:06 +00:00
Ritvik Sardana
b43107add2 fix(EmailBox): load content properly
(cherry picked from commit f4339b51e1)
2026-01-19 05:33:06 +00:00
RitvikSardana
0f62199ae7 Merge pull request #2899 from frappe/main-hotfix
chore(release): hotfix to main
2026-01-16 12:25:09 +05:30
RitvikSardana
aad1a0705d Merge branch 'main' into main-hotfix 2026-01-16 12:12:53 +05:30
RitvikSardana
db8ac693e2 Merge pull request #2889 from frappe/mergify/bp/main-hotfix/pr-2854
fix: saved reply renaming (backport #2854)
2026-01-16 12:11:36 +05:30
RitvikSardana
0408360716 Merge pull request #2898 from frappe/mergify/bp/main-hotfix/pr-2897
test(saved-reply): revert user to admin (backport #2897)
2026-01-16 12:11:19 +05:30
Ritvik Sardana
7ab0cabc1e test(saved-reply): revert user to admin
(cherry picked from commit 6c9d66e06b)
2026-01-16 06:41:02 +00:00
RitvikSardana
25f5c06b70 chore: version bump 2026-01-16 11:54:32 +05:30
RitvikSardana
5dd7bd9513 Merge branch 'main-hotfix' into mergify/bp/main-hotfix/pr-2854 2026-01-16 11:52:41 +05:30
RitvikSardana
bc9d51960c chore: handle versioning properly 2026-01-16 10:47:00 +05:30
RitvikSardana
29a3d410b5 Merge pull request #2896 from RitvikSardana/fix-tests
fix: test cases for holidays
2026-01-16 10:22:48 +05:30
RitvikSardana
b4f4078427 Merge pull request #2888 from pratikb64/backport-2708
refactor: move canned responses into settings modal (backport #2708)
2026-01-16 10:22:33 +05:30
Ritvik Sardana
890f27cbb9 fix: test cases for holidays 2026-01-16 10:17:26 +05:30
RitvikSardana
bbd95dafa1 Merge pull request #2892 from frappe/mergify/bp/main-hotfix/pr-2891
fix(dashboard): order by count (backport #2891)
2026-01-15 15:37:21 +05:30
Ritvik Sardana
286c196ba7 fix(dashboard): order by count
(cherry picked from commit 44877bd0e8)
2026-01-15 10:06:55 +00:00
Pratik
eac1280adc fix: saved reply renaming
(cherry picked from commit 819c28a805)

# Conflicts:
#	desk/src/components/Settings/SavedReplies/SavedReplyView.vue
#	helpdesk/helpdesk/doctype/hd_saved_reply/hd_saved_reply.json
2026-01-15 05:43:17 +00:00
Pratik
be7e4f417c fix: CI fix 2026-01-15 04:18:32 +00:00
Pratik
c4d9a25c03 fix: ci lint error 2026-01-14 17:27:01 +00:00
Ritvik Sardana
2e749fc76a fix: add list count 2026-01-14 17:26:42 +00:00
Pratik
e65507e1b9 chore: add translation 2026-01-14 17:24:50 +00:00
Pratik
5042fc718d chore: add translation 2026-01-14 17:24:50 +00:00
Pratik
696802e65b fix: avatar label & loading state in reply selector modal 2026-01-14 17:24:50 +00:00
Ritvik Sardana
857fd3df32 fix(naming): use title field for naming in Saved Reply 2026-01-14 17:24:50 +00:00
Pratik
d7f4fa7711 fix: focus on reply selector modal open 2026-01-14 17:24:48 +00:00
Pratik
81b3757a17 fix: tiptap extension suggestion search 2026-01-14 17:24:12 +00:00
Pratik
0fd4178ef3 test: add test for editing personal reply 2026-01-14 17:23:35 +00:00
Pratik
73377712d3 test: add tests 2026-01-14 17:23:32 +00:00
Pratik
07737b1609 fix: loading indicator fix 2026-01-14 17:22:55 +00:00
Pratik
3effc56d84 fix: minor conditional logic fix 2026-01-14 17:22:55 +00:00
Pratik
1ca7e5c41b refactor: rename canned response to saved reply 2026-01-14 17:22:52 +00:00
Pratik
7414b40d0f fix: bug in saved reply select modal 2026-01-14 17:21:21 +00:00
Pratik
975fea9f93 fix: code cleanup & refactor patches 2026-01-14 17:21:20 +00:00
Pratik
3ac62b1583 refactor: add & use HD Saved Reply doctype 2026-01-14 17:19:55 +00:00
Pratik
5695f86e16 refactor: change file name 2026-01-14 17:19:55 +00:00
Pratik
62b51d8383 fix: add icons in scope select 2026-01-14 17:19:55 +00:00
Pratik
674fdc1194 fix: minor enhancements 2026-01-14 17:19:55 +00:00
Pratik
4252657d17 refactor: rename canned response to saved reply 2026-01-14 17:19:53 +00:00
Pratik
9dccf0c352 fix: improve toast error message in saved replies preview dialog 2026-01-14 17:19:11 +00:00
Pratik
1d2e4bdaa2 fix: improve patch logic 2026-01-14 17:19:11 +00:00
Pratik
9b2c988162 fix: owner field not getting set in patch 2026-01-14 17:19:11 +00:00
Pratik
31ef62dd96 fix: patch order 2026-01-14 17:19:08 +00:00
Pratik
7fa910dee6 fix: add patch for email template fields 2026-01-14 17:18:11 +00:00
Pratik
756618a23b fix: code cleanup & enhancements 2026-01-14 17:18:09 +00:00
Pratik
7fe8d62a6c fix: code cleanup 2026-01-14 17:17:39 +00:00
Pratik
c9d6574acf refactor: move tiptap extension 2026-01-14 17:17:39 +00:00
Pratik
8550ddb52c fix: modal permission & small code cleanup 2026-01-14 17:17:37 +00:00
Pratik
1f54124b45 feat: add ticket based restriction logic 2026-01-14 17:15:01 +00:00
Pratik Badhe
562e34e38b chore: code cleanup 2026-01-14 17:13:08 +00:00
Pratik Badhe
1fd8a17305 feat: add load more button 2026-01-14 17:12:34 +00:00
Pratik Badhe
ee9b70260b fix: handle case when user does not have team assigned 2026-01-14 17:12:34 +00:00
Pratik
6b91cc456e feat: add scope & improve UI 2026-01-14 17:12:32 +00:00
Pratik Badhe
aa214a752a fix: remove subject & add toolbar for response editor 2026-01-14 17:11:55 +00:00
Pratik Badhe
377582a48a chore: add i18n 2026-01-14 17:11:55 +00:00
Pratik Badhe
6dd1779049 refactor: move canned responses into settings modal 2026-01-14 17:11:47 +00:00
Ritvik Sardana
eb69aef769 fix: support frappe v16 2026-01-14 18:27:04 +05:30
RitvikSardana
b414902d7e Merge pull request #2885 from frappe/mergify/bp/main-hotfix/pr-2884
fix: sanitize search query (backport #2884)
2026-01-14 17:09:05 +05:30
RitvikSardana
4eb2d9fe49 Merge pull request #2887 from frappe/mergify/bp/main-hotfix/pr-2886
fix: better support for v16 (backport #2886)
2026-01-14 17:08:55 +05:30
RitvikSardana
27fcf2f0da chore: code cleanup 2026-01-14 17:07:33 +05:30
RitvikSardana
591092e3ed chore: code cleanup 2026-01-14 17:05:09 +05:30
Ritvik Sardana
2a9c9f457e fix: better support for v16
(cherry picked from commit 3b85a3b269)

# Conflicts:
#	helpdesk/test_utils.py
2026-01-14 11:28:31 +00:00
Ritvik Sardana
fae2f361a9 fix: sanitize search query
(cherry picked from commit 5182126876)
2026-01-14 11:14:18 +00:00
RitvikSardana
b02e9a3849 Merge pull request #2883 from frappe/mergify/bp/main-hotfix/pr-2878
test: add tests for ticket split and merge (backport #2878)
2026-01-14 16:41:52 +05:30
RitvikSardana
8ac3f805a5 Merge pull request #2882 from frappe/mergify/bp/main-hotfix/pr-2881
fix: minor UI fixes (backport #2881)
2026-01-14 16:41:39 +05:30
Ritvik Sardana
8ab6848f48 chore: formatting 2026-01-14 16:30:41 +05:30
RitvikSardana
21da9cb643 chore: merge conflict 2026-01-14 16:28:06 +05:30
RitvikSardana
9606e343c4 chore: formatting 2026-01-14 16:25:09 +05:30
RitvikSardana
a7f62a23fb fix: merge conflict 2026-01-14 13:55:56 +05:30
RitvikSardana
e762652860 Merge pull request #2876 from frappe/mergify/bp/main-hotfix/pr-2859
chore: sync translations from crowdin (backport #2859)
2026-01-14 13:52:31 +05:30
Ritvik Sardana
5ccfd82895 fix(tests): add email domain
(cherry picked from commit 1515970c39)
2026-01-14 07:32:00 +00:00
Ritvik Sardana
95d5ad1784 test: add tests for ticket split and merge
(cherry picked from commit b652cb9c65)

# Conflicts:
#	helpdesk/test_utils.py
2026-01-14 07:32:00 +00:00
Ritvik Sardana
09feebce83 chore: code cleanup
(cherry picked from commit 1ce75aa717)
2026-01-14 07:31:59 +00:00
Ritvik Sardana
8a394aeec5 fix: loading state in editor
(cherry picked from commit 6bd424ff83)

# Conflicts:
#	desk/src/components/EmailEditor.vue
2026-01-14 07:31:59 +00:00
Ritvik Sardana
a7af289133 fix: minor style changes
(cherry picked from commit 9602681745)
2026-01-14 07:31:58 +00:00
Ritvik Sardana
eb341e9f58 fix: order_by in ticket_summary report
(cherry picked from commit b5ff021b86)
2026-01-14 07:31:58 +00:00
RitvikSardana
defe28fdc0 Merge pull request #2879 from RitvikSardana/dayjs-import
fix: add remaining imports
2026-01-14 12:15:29 +05:30
Ritvik Sardana
fafd0d0bcd fix: add remaining imports 2026-01-13 19:20:34 +05:30
RitvikSardana
36b359326e chore: Indonesian translations
(cherry picked from commit f2f195e855)
2026-01-13 10:43:06 +00:00
RitvikSardana
543a3fae67 chore: Russian translations
(cherry picked from commit 3fe45bcf7e)
2026-01-13 10:43:05 +00:00
RitvikSardana
e3afef5dcd chore: Hungarian translations
(cherry picked from commit b8a4803824)
2026-01-13 10:43:05 +00:00
RitvikSardana
cc5b4e35fe chore: Dutch translations
(cherry picked from commit 5d8a7ba05c)
2026-01-13 10:43:05 +00:00
RitvikSardana
8727f3075b chore: Hungarian translations
(cherry picked from commit 4004daf191)
2026-01-13 10:43:05 +00:00
RitvikSardana
8304de0e69 Merge pull request #2875 from frappe/mergify/bp/main-hotfix/pr-2874
chore: update readme (backport #2874)
2026-01-13 10:44:36 +05:30
Ritvik Sardana
b780ad4253 chore: update readme
(cherry picked from commit 03fe225df7)
2026-01-13 05:07:55 +00:00
RitvikSardana
d2aa02d0d0 Merge pull request #2868 from frappe/mergify/bp/main-hotfix/pr-2867
fix: rendering @mention in comments (backport #2867)
2026-01-13 09:52:20 +05:30
Vivek Agrawal
34e07f907b fix: rendering @mention in comments
(cherry picked from commit d8228382b0)
2026-01-09 12:12:19 +00:00
RitvikSardana
a3b8bf26c2 Merge pull request #2864 from frappe/mergify/bp/main-hotfix/pr-2863
fix: dont run onClick twice (backport #2863)
2026-01-08 00:06:22 +05:30
RitvikSardana
b008091137 fix: revert translation changes
(cherry picked from commit ec82ee91a9)
2026-01-06 18:54:36 +00:00
Ritvik Sardana
e3587c09e7 fix: dont run onClick twice
(cherry picked from commit 4e1e261a51)
2026-01-06 18:54:36 +00:00
RitvikSardana
09a174f190 chore: Bump version to 1.18.1 2026-01-02 13:05:12 +05:30
RitvikSardana
e09116a523 chore: Update frappe dependency version range 2026-01-02 12:46:13 +05:30
RitvikSardana
f77349faea Merge pull request #2855 from frappe/main-hotfix
chore(release): hotfix to main
2026-01-01 23:44:26 +05:30
RitvikSardana
29d503090f chore: replace IntegrationTestCase with FrappeTestCase 2026-01-01 23:38:36 +05:30
RitvikSardana
b850d733f7 chore: update Frappe branch in install script 2026-01-01 21:49:33 +05:30
RitvikSardana
185442d153 chore: Bump version from 1.17.4 to 1.18.0 2026-01-01 21:26:41 +05:30
RitvikSardana
c56de5904b Merge pull request #2849 from frappe/mergify/bp/main-hotfix/pr-2836
feat(i18n): Add translation wrappers to Vue components (backport #2836)
2026-01-01 21:24:30 +05:30
RitvikSardana
88afe2f413 fix: add translation strings for sidebar label
(cherry picked from commit 4532c42f64)
2025-12-30 21:53:33 +00:00
Jérémy Christillin
6a8447a882 style: apply prettier formatting
(cherry picked from commit 58dfc6d95d)
2025-12-30 21:53:33 +00:00
Jérémy Christillin
253afdc16c feat(i18n): Add French translations for new i18n strings
Add 40+ French translations for settings, SLA, and workflow strings.

(cherry picked from commit 838ffcdf74)
2025-12-30 21:53:32 +00:00
Jérémy Christillin
ce17e05a70 feat(i18n): Add translation wrappers to Vue components
Add __() translation function wrappers to hardcoded strings in Vue/TypeScript
components to enable internationalization support.

Files modified:
- ListViewBuilder, SearchMultiSelect, FilterPopover components
- Settings: NewTeamModal, ExportModal
- Ticket views: TicketAgent, MobileTicketAgent, TicketCustomer, TicketAgentSidebar
- Knowledge Base: Article, NewArticle, KnowledgeBase views
- Contact: ContactDialog, SetContactPhoneModal
- Notifications: MobileNotifications
- Activity: ActivityHeader, CommunicationArea
- Customer: NewCustomerDialog

This enables proper translation of UI strings through PO files.

(cherry picked from commit f6db2f72d7)
2025-12-30 21:53:32 +00:00
RitvikSardana
1b52048b8f Merge pull request #2848 from frappe/mergify/bp/main-hotfix/pr-2839
fix(workspace): helpdesk reports routing (backport #2839)
2025-12-31 03:05:53 +05:30
RitvikSardana
010938804a Merge pull request #2847 from frappe/mergify/bp/main-hotfix/pr-2842
fix: last_synced_at to last_received_at in email sync (backport #2842)
2025-12-31 03:05:39 +05:30
KerollesFathy
1cda760798 fix(workspace): helpdesk reports routing
(cherry picked from commit c395c8b67a)
2025-12-30 21:34:28 +00:00
KerollesFathy
4e5ca82963 revert: helpdesk reports routing"
This reverts commit 7f785be3b8.

(cherry picked from commit ae97eafff5)
2025-12-30 21:34:27 +00:00
KerollesFathy
2854c573dd fix(workspace): helpdesk reports routing
(cherry picked from commit 7f785be3b8)
2025-12-30 21:34:27 +00:00
Elnegren
ddd380d2b4 fix: last_synced_at to last_received_at in email sync
(cherry picked from commit 7432d3e9d3)
2025-12-30 21:33:34 +00:00
RitvikSardana
6f381d745e Merge pull request #2845 from frappe/mergify/bp/main-hotfix/pr-2837
chore: update POT file (backport #2837)
2025-12-30 12:59:56 +05:30
RitvikSardana
b18b81c22e Merge pull request #2844 from frappe/mergify/bp/main-hotfix/pr-2833
chore: sync translations from crowdin (backport #2833)
2025-12-30 12:59:46 +05:30
frappe-pr-bot
3bdda78513 chore: update POT file
(cherry picked from commit 63d4442a54)
2025-12-30 07:25:09 +00:00
RitvikSardana
f007a1be29 chore: Persian translations
(cherry picked from commit 1218e9219a)
2025-12-30 07:15:49 +00:00
RitvikSardana
ee387164d4 chore: Spanish translations
(cherry picked from commit 930e8ec184)
2025-12-30 07:15:49 +00:00
RitvikSardana
65ce2c1333 chore: Persian translations
(cherry picked from commit 847e485fb4)
2025-12-30 07:15:49 +00:00
RitvikSardana
65467272a8 chore: Hungarian translations
(cherry picked from commit 2adbe1cdba)
2025-12-30 07:15:49 +00:00
RitvikSardana
6410ced280 chore: Hungarian translations
(cherry picked from commit 5eddc89075)
2025-12-30 07:15:48 +00:00
RitvikSardana
cc8bde3091 chore: Spanish translations
(cherry picked from commit d0c6e5167a)
2025-12-30 07:15:48 +00:00
RitvikSardana
e4316de66e Merge pull request #2801 from frappe/mergify/bp/main-hotfix/pr-2794
fix: bugs related to frappe-ui update (backport #2794)
2025-12-18 17:25:50 +05:30
Pratik Badhe
7930000998 Merge branch 'main-hotfix' into mergify/bp/main-hotfix/pr-2794 2025-12-18 11:32:23 +05:30
RitvikSardana
f3725e53ac Merge pull request #2832 from pratikb64/backport-2664
feat: add profile, general settings page & search bars for lists (backport #2664)
2025-12-17 13:41:06 +05:30
Ritvik Sardana
0ceda51542 chore(list-view): dont show border-b for last element 2025-12-15 11:18:12 +00:00
Pratik
669812d6f9 fix: hover state 2025-12-15 11:18:12 +00:00
Pratik
c19b54df7f fix: agents list filter hover state 2025-12-15 11:18:12 +00:00
Pratik
378214e22c chore: code cleanup 2025-12-15 11:17:37 +00:00
Pratik
5bd3ff389f chore: fix description 2025-12-15 11:17:37 +00:00
Pratik
451772506d fix: dropdown bug & labels 2025-12-15 11:17:37 +00:00
Pratik
8c4b10f567 fix: spacing in agents list view dropdowns 2025-12-15 11:17:37 +00:00
Pratik
1e16241217 chore: add Dropdown component imports 2025-12-15 11:17:37 +00:00
Pratik
399c3f89cb fix: button label & use symbol for inject/provide 2025-12-15 11:17:34 +00:00
Pratik
24089711d2 fix: assignee search bug 2025-12-15 11:16:42 +00:00
Pratik
d079147540 feat: add language setting 2025-12-15 11:15:56 +00:00
Pratik
03a7b5199c fix: ui cleanup & move SettingsLayoutBase component 2025-12-15 11:10:35 +00:00
Pratik Badhe
d8c95bb39a fix: remove i18n for week days 2025-12-15 11:10:35 +00:00
Pratik Badhe
c9300824f0 fix: ui alignment 2025-12-15 11:10:35 +00:00
Pratik Badhe
8c1777f512 fix: order list view's by modified desc 2025-12-15 11:10:35 +00:00
Pratik Badhe
9ad9bea8ac feat: add teams agents selector 2025-12-15 11:10:35 +00:00
Pratik Badhe
b6e480501e ci: remove frappe db commit 2025-12-15 11:10:35 +00:00
Pratik Badhe
cc18255dc9 fix: CI lint error 2025-12-15 11:10:35 +00:00
Pratik Badhe
4f482faf58 refactor: add common settings layout base component 2025-12-15 11:10:32 +00:00
Pratik Badhe
3478361dcb chore: add i18n and code cleanup 2025-12-15 10:58:27 +00:00
Pratik Badhe
cbcd1d96ff fix: improve telephony dirty state logic 2025-12-15 10:55:45 +00:00
Pratik Badhe
f79cd726be fix: favicon icon 2025-12-15 10:55:45 +00:00
Pratik Badhe
950e23983c refactor: remove some setting options & add i18n 2025-12-15 10:55:45 +00:00
Pratik Badhe
e2bbd830ed fix: semgrep lint fix 2025-12-15 10:55:45 +00:00
Pratik Badhe
457d6e1f9c fix: semgrep lint fix 2025-12-15 10:55:45 +00:00
Pratik Badhe
6c54da1d1e refactor: improve assignment rule invite agent handling 2025-12-15 10:55:37 +00:00
Pratik Badhe
5f73ea65c7 fix: internationalization & state re-rendering 2025-12-15 10:52:18 +00:00
Pratik Badhe
a7e5f65422 fix: agent flow test 2025-12-15 10:52:18 +00:00
Pratik Badhe
f05afc8465 fix: improve team edit 2025-12-15 10:52:18 +00:00
Pratik Badhe
a57e2b5faf fix: add empty state for team edit page 2025-12-15 10:52:18 +00:00
Pratik Badhe
3baff61473 fix: semgrep CI error 2025-12-15 10:52:18 +00:00
Pratik Badhe
6ff72d7c33 fix: horizontal line conditional rendering in general settings 2025-12-15 10:52:18 +00:00
Pratik Badhe
afd6b97dd5 fix: import paths 2025-12-15 10:52:18 +00:00
Pratik Badhe
748fef89af fix: layouts & alignments 2025-12-15 10:51:41 +00:00
Pratik Badhe
daeb72b474 fix: improve logo upload functionality 2025-12-15 10:51:22 +00:00
Pratik Badhe
ce8fce52d9 fix: add unsaved changes badge in profile 2025-12-15 10:51:22 +00:00
Pratik Badhe
b2126a4606 fix: handle roles for settings modal tabs 2025-12-15 10:51:22 +00:00
Pratik Badhe
f1663e1edc fix: profile image upload loading state 2025-12-15 10:51:22 +00:00
Pratik Badhe
b7c894cea3 fix: hide search bar when items are less than 10 2025-12-15 10:51:17 +00:00
Pratik Badhe
82b14dd378 fix: assignment rule new button label 2025-12-15 10:47:12 +00:00
Pratik Badhe
97c55258d3 fix: logo upload disable state 2025-12-15 10:47:12 +00:00
Pratik Badhe
c3d411a854 fix: empty state icon alignment & brand logo, favicon edge case 2025-12-15 10:47:12 +00:00
Pratik Badhe
b78c0a63d6 fix: agents dropdown placement 2025-12-15 10:47:12 +00:00
Pratik Badhe
434a5fee9f fix: padding & spacing 2025-12-15 10:47:12 +00:00
Pratik Badhe
d53bb65e3e fix: agent name while creating new agent 2025-12-15 10:47:12 +00:00
Pratik Badhe
d1f399f7d7 fix: add email account empty state & fix agent before_save hook 2025-12-15 10:47:12 +00:00
Pratik Badhe
49a66176a2 fix: handle case where agent_name is not available 2025-12-15 10:47:12 +00:00
Pratik Badhe
804b04c17b feat: add profile, general settings page & search bars for lists 2025-12-15 10:47:06 +00:00
RitvikSardana
6d3da9def5 Merge pull request #2831 from frappe/mergify/bp/main-hotfix/pr-2823
chore: update POT file (backport #2823)
2025-12-15 13:17:26 +05:30
RitvikSardana
760d6f49ad Merge pull request #2830 from frappe/mergify/bp/main-hotfix/pr-2816
chore: sync translations from crowdin (backport #2816)
2025-12-15 13:17:19 +05:30
RitvikSardana
58ffcf76f6 Merge pull request #2829 from frappe/mergify/bp/main-hotfix/pr-2798
fix: preserve query parameters when switching tabs (#2790) (backport #2798)
2025-12-15 13:17:09 +05:30
frappe-pr-bot
4e66acaab8 chore: update POT file
(cherry picked from commit c5b6ab3569)
2025-12-15 07:22:30 +00:00
RitvikSardana
655229ff9c chore: Russian translations
(cherry picked from commit 6cd0163e2d)
2025-12-15 07:21:38 +00:00
RitvikSardana
18bdf0791a chore: Hungarian translations
(cherry picked from commit 3189db9884)
2025-12-15 07:21:38 +00:00
RitvikSardana
0806083ed8 chore: Hungarian translations
(cherry picked from commit f2bacb6200)
2025-12-15 07:21:37 +00:00
RitvikSardana
9057611f8e chore: Hungarian translations
(cherry picked from commit 032e1b0bbe)
2025-12-15 07:21:37 +00:00
RitvikSardana
49be94bb61 chore: Serbian (Latin) translations
(cherry picked from commit a1fd77f1f3)
2025-12-15 07:21:37 +00:00
RitvikSardana
066eb8b72d chore: Serbian (Cyrillic) translations
(cherry picked from commit 39e38c27ec)
2025-12-15 07:21:37 +00:00
RitvikSardana
aff7049d2d chore: Esperanto translations
(cherry picked from commit 09e6d637dd)
2025-12-15 07:21:36 +00:00
RitvikSardana
2ddc720723 chore: Slovenian translations
(cherry picked from commit fee0b713c9)
2025-12-15 07:21:36 +00:00
RitvikSardana
b790f63bb3 chore: French translations
(cherry picked from commit d492740475)
2025-12-15 07:21:36 +00:00
RitvikSardana
653b9044b8 chore: Serbian (Latin) translations
(cherry picked from commit 211781be1c)
2025-12-15 07:21:36 +00:00
RitvikSardana
9e825f5452 chore: Norwegian Bokmal translations
(cherry picked from commit 2fc900c02d)
2025-12-15 07:21:35 +00:00
RitvikSardana
a6bd06db43 chore: Bosnian translations
(cherry picked from commit 0744eb5d03)
2025-12-15 07:21:35 +00:00
RitvikSardana
21ad46f59d chore: Burmese translations
(cherry picked from commit e3661e9836)
2025-12-15 07:21:35 +00:00
RitvikSardana
29aa40de27 chore: Croatian translations
(cherry picked from commit 13aab390b0)
2025-12-15 07:21:35 +00:00
RitvikSardana
3a77ffb593 chore: Thai translations
(cherry picked from commit c64dcea9b8)
2025-12-15 07:21:34 +00:00
RitvikSardana
d7491a72ed chore: Tamil translations
(cherry picked from commit ecb076eec8)
2025-12-15 07:21:34 +00:00
RitvikSardana
cd9a429270 chore: Persian translations
(cherry picked from commit b51a22c2b6)
2025-12-15 07:21:34 +00:00
RitvikSardana
bac9e5aaa2 chore: Indonesian translations
(cherry picked from commit 50fb1c20fc)
2025-12-15 07:21:34 +00:00
RitvikSardana
126c9c1f14 chore: Portuguese, Brazilian translations
(cherry picked from commit abd6d46963)
2025-12-15 07:21:33 +00:00
RitvikSardana
ddca7c4146 chore: Vietnamese translations
(cherry picked from commit da338ef7b0)
2025-12-15 07:21:33 +00:00
RitvikSardana
6ae0023cd8 chore: Chinese Simplified translations
(cherry picked from commit b5cee665b9)
2025-12-15 07:21:33 +00:00
RitvikSardana
c2e3551e4f chore: Turkish translations
(cherry picked from commit e3a7ea1516)
2025-12-15 07:21:33 +00:00
RitvikSardana
f308079f59 chore: Swedish translations
(cherry picked from commit 68ad2efdf9)
2025-12-15 07:21:32 +00:00
RitvikSardana
470fe5949d chore: Serbian (Cyrillic) translations
(cherry picked from commit 8acff3fc51)
2025-12-15 07:21:32 +00:00
RitvikSardana
d53412258b chore: Russian translations
(cherry picked from commit 420c33787e)
2025-12-15 07:21:32 +00:00
RitvikSardana
2f0aaa7188 chore: Portuguese translations
(cherry picked from commit 93f3504009)
2025-12-15 07:21:32 +00:00
RitvikSardana
728ec2fb33 chore: Polish translations
(cherry picked from commit 7b9ff2497f)
2025-12-15 07:21:31 +00:00
RitvikSardana
20579acf55 chore: Dutch translations
(cherry picked from commit f1ad5b8e03)
2025-12-15 07:21:31 +00:00
RitvikSardana
ba7720ff2c chore: Italian translations
(cherry picked from commit 393ad9073b)
2025-12-15 07:21:31 +00:00
RitvikSardana
c2b0e9fa59 chore: Hungarian translations
(cherry picked from commit ecc17e12e7)
2025-12-15 07:21:31 +00:00
RitvikSardana
10d3c9651a chore: German translations
(cherry picked from commit 4357bd544f)
2025-12-15 07:21:30 +00:00
RitvikSardana
2221f8c33d chore: Danish translations
(cherry picked from commit 8c74a69625)
2025-12-15 07:21:30 +00:00
RitvikSardana
47416cdf3c chore: Czech translations
(cherry picked from commit 61b971c0d1)
2025-12-15 07:21:30 +00:00
RitvikSardana
dafd1d7066 chore: Arabic translations
(cherry picked from commit b2776805f6)
2025-12-15 07:21:30 +00:00
RitvikSardana
b6893210b7 chore: Spanish translations
(cherry picked from commit 97e424c56b)
2025-12-15 07:21:29 +00:00
samarth
937d8a0909 fix: preserve query parameters when switching tabs (#2790)
Fixes #2790 - Active View is removed from the query params when the page is reloaded

When navigating to a ticket from an Active View and switching between tabs,
the query parameters (including view parameter) were being removed from the URL.

Changes:
- Updated router.replace() calls in useActiveTabManager.ts to preserve
  route.query alongside route.path
- Ensures view context is maintained during tab navigation
- Applies to changeTabTo(), setActiveTab(), and hash watch handler

This fix ensures that when users navigate to a ticket from an Active View
and switch between tabs, the view parameter remains in the URL for proper
navigation context.

(cherry picked from commit 3f01c575fb)
2025-12-15 07:18:26 +00:00
RitvikSardana
5991711a60 Merge pull request #2828 from frappe/mergify/bp/main-hotfix/pr-2827
fix: use get_list to get count (backport #2827)
2025-12-15 12:47:49 +05:30
Ritvik Sardana
0afd392c53 fix: add fallback value
(cherry picked from commit 8d847962f3)
2025-12-15 06:34:21 +00:00
Ritvik Sardana
71d517fbda chore: code cleanup
(cherry picked from commit 698659f7c4)
2025-12-15 06:34:21 +00:00
Ritvik Sardana
981bb6f4a5 fix: use get_list to get count
(cherry picked from commit 28947034ba)
2025-12-15 06:34:20 +00:00
RitvikSardana
cada6fc48f Merge pull request #2815 from frappe/mergify/bp/main-hotfix/pr-2809
chore: update POT file (backport #2809)
2025-12-09 15:55:08 +05:30
RitvikSardana
0b115a925b Merge pull request #2814 from frappe/mergify/bp/main-hotfix/pr-2805
chore: sync translations from crowdin (backport #2805)
2025-12-09 15:54:50 +05:30
frappe-pr-bot
b056b87c6d chore: update POT file
(cherry picked from commit 0d5d0e2b1d)
2025-12-09 10:21:39 +00:00
RitvikSardana
f8650059d7 chore: Russian translations
(cherry picked from commit a9e35f9b9b)
2025-12-09 10:20:33 +00:00
RitvikSardana
942fb17cec chore: Hungarian translations
(cherry picked from commit 6b44eac9d1)
2025-12-09 10:20:33 +00:00
RitvikSardana
f87cfa33b7 chore: Russian translations
(cherry picked from commit 20fb1b7e42)
2025-12-09 10:20:33 +00:00
RitvikSardana
f4e081850a chore: Hungarian translations
(cherry picked from commit bdce05270a)
2025-12-09 10:20:33 +00:00
RitvikSardana
8983e0b4bd Merge pull request #2802 from frappe/mergify/bp/main-hotfix/pr-2797
chore: sync translations from crowdin (backport #2797)
2025-12-09 15:50:02 +05:30
RitvikSardana
24d64897dc Merge pull request #2804 from frappe/mergify/bp/main-hotfix/pr-2803
fix: add support for button variables in custom buttons (backport #2803)
2025-12-05 22:51:20 +05:30
Ritvik Sardana
6289d66c59 fix: add support for button variables in custom buttons
(cherry picked from commit 7f4ad4387a)
2025-12-05 17:18:06 +00:00
RitvikSardana
1281b54d7d chore: Slovenian translations
(cherry picked from commit 6f13958974)
2025-12-05 15:50:36 +00:00
RitvikSardana
c6aa12a2aa chore: Bosnian translations
(cherry picked from commit c9b969f3fd)
2025-12-05 15:50:36 +00:00
RitvikSardana
9a72503b39 chore: Croatian translations
(cherry picked from commit fa44401f6e)
2025-12-05 15:50:36 +00:00
RitvikSardana
f787395865 chore: Russian translations
(cherry picked from commit b927731bcf)
2025-12-05 15:50:36 +00:00
RitvikSardana
45dae2eb4d chore: Esperanto translations
(cherry picked from commit 39d49bba6d)
2025-12-05 15:50:35 +00:00
RitvikSardana
4899a9e9d5 chore: Slovenian translations
(cherry picked from commit 5908ac8cd1)
2025-12-05 15:50:35 +00:00
RitvikSardana
aebf2caecc chore: French translations
(cherry picked from commit 3d61f226ff)
2025-12-05 15:50:35 +00:00
RitvikSardana
e8b3fe6052 chore: Serbian (Latin) translations
(cherry picked from commit 526828ca87)
2025-12-05 15:50:35 +00:00
RitvikSardana
6c2858102a chore: Norwegian Bokmal translations
(cherry picked from commit 918aa7582f)
2025-12-05 15:50:34 +00:00
RitvikSardana
b17ea62f95 chore: Bosnian translations
(cherry picked from commit ab12cc4017)
2025-12-05 15:50:34 +00:00
RitvikSardana
2ca7d118fc chore: Burmese translations
(cherry picked from commit bb2db66f81)
2025-12-05 15:50:34 +00:00
RitvikSardana
fae8492cf3 chore: Croatian translations
(cherry picked from commit 1398427e65)
2025-12-05 15:50:34 +00:00
RitvikSardana
56461a3428 chore: Thai translations
(cherry picked from commit d329acb0d7)
2025-12-05 15:50:33 +00:00
RitvikSardana
df9c505961 chore: Tamil translations
(cherry picked from commit f39db539e7)
2025-12-05 15:50:33 +00:00
RitvikSardana
6482524705 chore: Persian translations
(cherry picked from commit 6b694352b1)
2025-12-05 15:50:33 +00:00
RitvikSardana
f4c2c12b9d chore: Indonesian translations
(cherry picked from commit 6c356d3a73)
2025-12-05 15:50:33 +00:00
RitvikSardana
299e16f1e2 chore: Portuguese, Brazilian translations
(cherry picked from commit 7c6311eeb1)
2025-12-05 15:50:32 +00:00
RitvikSardana
b099a6658b chore: Vietnamese translations
(cherry picked from commit 9a6e74f23c)
2025-12-05 15:50:32 +00:00
RitvikSardana
7f1d06588e chore: Chinese Simplified translations
(cherry picked from commit d6a96a4c6b)
2025-12-05 15:50:32 +00:00
RitvikSardana
b970d9ed82 chore: Turkish translations
(cherry picked from commit 90e1b75793)
2025-12-05 15:50:32 +00:00
RitvikSardana
712c1b6af7 chore: Swedish translations
(cherry picked from commit 9d6488ac7b)
2025-12-05 15:50:31 +00:00
RitvikSardana
5eb8bb8c05 chore: Serbian (Cyrillic) translations
(cherry picked from commit 38d326294f)
2025-12-05 15:50:31 +00:00
RitvikSardana
47dcb01852 chore: Russian translations
(cherry picked from commit 2c8d353105)
2025-12-05 15:50:31 +00:00
RitvikSardana
7c16051cd3 chore: Portuguese translations
(cherry picked from commit cb80db8bb6)
2025-12-05 15:50:31 +00:00
RitvikSardana
651a3d67e9 chore: Polish translations
(cherry picked from commit fb02488cc2)
2025-12-05 15:50:30 +00:00
RitvikSardana
678df4256e chore: Dutch translations
(cherry picked from commit bdb401cea8)
2025-12-05 15:50:30 +00:00
RitvikSardana
57b077f648 chore: Italian translations
(cherry picked from commit cec8e1c963)
2025-12-05 15:50:30 +00:00
RitvikSardana
0258be7a05 chore: Hungarian translations
(cherry picked from commit 4184f067f7)
2025-12-05 15:50:30 +00:00
RitvikSardana
1f417d0ddc chore: German translations
(cherry picked from commit 07764582bc)
2025-12-05 15:50:29 +00:00
RitvikSardana
bb3983b35d chore: Danish translations
(cherry picked from commit cb5ffcc299)
2025-12-05 15:50:29 +00:00
RitvikSardana
bdad810b4b chore: Czech translations
(cherry picked from commit 1c4b5eb4f5)
2025-12-05 15:50:29 +00:00
RitvikSardana
81c8d24495 chore: Arabic translations
(cherry picked from commit 6126dbef15)
2025-12-05 15:50:29 +00:00
RitvikSardana
09eef74ccb chore: Spanish translations
(cherry picked from commit 9a43e789a3)
2025-12-05 15:50:28 +00:00
Pratik
c80a6c1d12 fix: ticket view tabs alignment
(cherry picked from commit 5171c3bf22)
2025-12-05 15:48:27 +00:00
Pratik
d11258e90b fix: revert select element in gemeral settings
(cherry picked from commit cc42501517)
2025-12-05 15:48:27 +00:00
Pratik
b9457b7448 fix: popover width
(cherry picked from commit 2c2039faa6)

# Conflicts:
#	desk/src/components/Settings/Assignment Rules/AssignmentRuleView.vue
2025-12-05 15:48:27 +00:00
Pratik
5b2b96c5b6 fix: select options width & assigmnent rule bugs
(cherry picked from commit 4b43b6d01f)

# Conflicts:
#	desk/src/components/Settings/Assignment Rules/AssignmentRuleView.vue
2025-12-05 15:48:26 +00:00
Pratik
a94fe5ed1b fix: bugs introduced by frappe-ui update
(cherry picked from commit 8e6848dc23)
2025-12-05 15:48:26 +00:00
Pratik
461edc93aa fix: bugs related to frappe-ui update
(cherry picked from commit e2a2d29b84)

# Conflicts:
#	desk/src/components/SelectDropdown.vue
#	desk/src/components/Settings/General/components/TicketSettings.vue
#	desk/src/components/Settings/Sla/SlaPriorityListItem.vue
#	desk/src/components/Settings/Sla/SlaWorkDaysListItem.vue
2025-12-05 15:48:26 +00:00
RitvikSardana
1a427ef047 Merge pull request #2800 from frappe/mergify/bp/main-hotfix/pr-2795
fix(security): dashboard APIs & realtime events (backport #2795)
2025-12-05 18:27:04 +05:30
RitvikSardana
0ed1d38b37 chore: update dashboard file 2025-12-05 17:00:40 +05:30
RitvikSardana
a653ada9b5 chore: update dashboard file 2025-12-05 16:48:58 +05:30
RitvikSardana
54da393df7 chore: update dashboard file 2025-12-05 16:24:16 +05:30
Ritvik Sardana
7c78e5ed58 fix: dont bombard socket events
(cherry picked from commit b2f7e029be)
2025-12-05 10:36:37 +00:00
Ritvik Sardana
3539979ecc refactor: convert dashboard api to class and add QB support
(cherry picked from commit 1e1cd602d6)

# Conflicts:
#	helpdesk/api/dashboard.py
2025-12-05 10:36:37 +00:00
RitvikSardana
e8f53b9063 Merge pull request #2792 from frappe/mergify/bp/main-hotfix/pr-2788
chore: update POT file (backport #2788)
2025-12-03 14:29:46 +05:30
RitvikSardana
08156fda53 Merge pull request #2793 from frappe/mergify/bp/main-hotfix/pr-2786
chore: sync translations from crowdin (backport #2786)
2025-12-03 14:29:38 +05:30
RitvikSardana
91c9aca479 chore: Persian translations
(cherry picked from commit cf5be1ea67)
2025-12-03 08:58:35 +00:00
RitvikSardana
452aff7ba8 chore: Hungarian translations
(cherry picked from commit 2ed447646d)
2025-12-03 08:58:35 +00:00
RitvikSardana
012fa5e56f chore: Spanish translations
(cherry picked from commit 8a87142618)
2025-12-03 08:58:35 +00:00
RitvikSardana
08e638d598 chore: Persian translations
(cherry picked from commit 12b9fe46ef)
2025-12-03 08:58:35 +00:00
RitvikSardana
6cff520fab chore: Slovenian translations
(cherry picked from commit bca072eb23)
2025-12-03 08:58:34 +00:00
RitvikSardana
8e136a2873 chore: Slovenian translations
(cherry picked from commit 3b2b3a194f)
2025-12-03 08:58:34 +00:00
RitvikSardana
944008b176 chore: Serbian (Latin) translations
(cherry picked from commit 3960d96377)
2025-12-03 08:58:34 +00:00
RitvikSardana
26fc1648ed chore: Norwegian Bokmal translations
(cherry picked from commit b04b4b1aa3)
2025-12-03 08:58:34 +00:00
RitvikSardana
75783677ea chore: Bosnian translations
(cherry picked from commit 11de025c42)
2025-12-03 08:58:33 +00:00
RitvikSardana
55cc6f2640 chore: Croatian translations
(cherry picked from commit 401ee26e3e)
2025-12-03 08:58:33 +00:00
RitvikSardana
2db40ba4f7 chore: Thai translations
(cherry picked from commit 35ae4af61a)
2025-12-03 08:58:33 +00:00
RitvikSardana
a43718427e chore: Tamil translations
(cherry picked from commit 6dee7bf2e2)
2025-12-03 08:58:33 +00:00
RitvikSardana
b5169d0d15 chore: Persian translations
(cherry picked from commit d615d7ae3e)
2025-12-03 08:58:32 +00:00
RitvikSardana
dcdda3b770 chore: Indonesian translations
(cherry picked from commit 9cb6df0bee)
2025-12-03 08:58:32 +00:00
RitvikSardana
227ff783f6 chore: Portuguese, Brazilian translations
(cherry picked from commit 13aff48429)
2025-12-03 08:58:32 +00:00
RitvikSardana
33ffc0abe5 chore: Vietnamese translations
(cherry picked from commit c413ef2e48)
2025-12-03 08:58:32 +00:00
RitvikSardana
561e4ab441 chore: Chinese Simplified translations
(cherry picked from commit b367cdc828)
2025-12-03 08:58:31 +00:00
RitvikSardana
4b67c5f2f5 chore: Turkish translations
(cherry picked from commit 5c7efb6372)
2025-12-03 08:58:31 +00:00
RitvikSardana
29d159dd11 chore: Swedish translations
(cherry picked from commit e3aacdbcdc)
2025-12-03 08:58:31 +00:00
RitvikSardana
7adeed96fe chore: Serbian (Cyrillic) translations
(cherry picked from commit 91dd2f4a54)
2025-12-03 08:58:31 +00:00
RitvikSardana
93362f939b chore: Russian translations
(cherry picked from commit cf629ebd21)
2025-12-03 08:58:31 +00:00
RitvikSardana
a16b701032 chore: Portuguese translations
(cherry picked from commit ce62f05c25)
2025-12-03 08:58:30 +00:00
RitvikSardana
e3a09004c6 chore: Polish translations
(cherry picked from commit 5150c85284)
2025-12-03 08:58:30 +00:00
RitvikSardana
68faaebb37 chore: Dutch translations
(cherry picked from commit bff28f2642)
2025-12-03 08:58:30 +00:00
RitvikSardana
4d72882d40 chore: Italian translations
(cherry picked from commit 70da538f78)
2025-12-03 08:58:30 +00:00
RitvikSardana
f05e66b039 chore: Hungarian translations
(cherry picked from commit a2827630b1)
2025-12-03 08:58:29 +00:00
RitvikSardana
28f44bfe61 chore: German translations
(cherry picked from commit d527448d5b)
2025-12-03 08:58:29 +00:00
RitvikSardana
1e3fc96adc chore: Danish translations
(cherry picked from commit 3cf62a9a2e)
2025-12-03 08:58:29 +00:00
RitvikSardana
4e8ecc5447 chore: Czech translations
(cherry picked from commit e86ee3f5e8)
2025-12-03 08:58:29 +00:00
RitvikSardana
14aefb9b23 chore: Arabic translations
(cherry picked from commit 6789a25986)
2025-12-03 08:58:28 +00:00
frappe-pr-bot
4cb3c57865 chore: update POT file
(cherry picked from commit a27001e934)
2025-12-03 08:57:28 +00:00
RitvikSardana
105da6be52 Merge pull request #2791 from frappe/mergify/bp/main-hotfix/pr-2789
chore: V16 support (backport #2789)
2025-12-03 14:26:25 +05:30
RitvikSardana
994c14e70d Merge branch 'main-hotfix' into mergify/bp/main-hotfix/pr-2789 2025-12-03 14:10:46 +05:30
RitvikSardana
284531ab56 Merge pull request #2774 from frappe/mergify/bp/main-hotfix/pr-2719
refactor: reduce bundle size (backport #2719)
2025-12-03 14:10:08 +05:30
RitvikSardana
484d00e06d chore: solvemerge conflicts 2025-12-03 14:05:19 +05:30
Ritvik Sardana
350275ece1 chore: code cleanup
(cherry picked from commit b800ee03c2)
2025-12-03 08:27:22 +00:00
Ritvik Sardana
c00da37443 fix: add util to check version
(cherry picked from commit d016312f86)
2025-12-03 08:27:21 +00:00
Ritvik Sardana
d2acd5f7e9 fix: better way to check version
(cherry picked from commit 7b9dbe748e)
2025-12-03 08:27:21 +00:00
Ritvik Sardana
98491bb277 chore: revert py project changes
(cherry picked from commit 246462901e)

# Conflicts:
#	pyproject.toml
2025-12-03 08:27:21 +00:00
Ritvik Sardana
8e3189d9a0 fix: add version change for testing in v15
(cherry picked from commit 2309dd9c9d)

# Conflicts:
#	pyproject.toml
2025-12-03 08:27:21 +00:00
Ritvik Sardana
be58389888 fix: add conditional version support
(cherry picked from commit a36e377771)
2025-12-03 08:27:21 +00:00
Ritvik Sardana
3f1299d6ed chore: add v16 support
(cherry picked from commit 825ec55d80)

# Conflicts:
#	desk/src/pages/dashboard/Dashboard.vue
#	desk/tsconfig.json
#	helpdesk/api/dashboard.py
2025-12-03 08:27:20 +00:00
RitvikSardana
d0bc2f5250 chore: code cleanup 2025-12-03 12:11:30 +05:30
RitvikSardana
f8d9828f85 Merge branch 'main-hotfix' into mergify/bp/main-hotfix/pr-2719 2025-12-03 11:53:22 +05:30
RitvikSardana
99682ad5fd Merge pull request #2785 from frappe/main-hotfix
chore(release): hotfix to main
2025-11-28 14:59:18 +05:30
RitvikSardana
8cea4bcc45 Merge pull request #2784 from frappe/mergify/bp/main-hotfix/pr-2783
chore: bump version (backport #2783)
2025-11-28 11:32:37 +05:30
Ritvik Sardana
d9f6fdf492 chore: bump version
(cherry picked from commit 8fb56bad25)
2025-11-28 06:01:59 +00:00
RitvikSardana
bb77ed8673 Merge pull request #2782 from frappe/mergify/bp/main-hotfix/pr-2779
chore: sync translations from crowdin (backport #2779)
2025-11-28 11:31:29 +05:30
RitvikSardana
508d6dc5c3 chore: Slovenian translations
(cherry picked from commit c1781bd8b4)
2025-11-28 05:59:50 +00:00
RitvikSardana
9fd72ba073 chore: Burmese translations
(cherry picked from commit 5c4a7ac43c)
2025-11-28 05:59:50 +00:00
RitvikSardana
c24477f90f chore: Esperanto translations
(cherry picked from commit 4ea804b0d0)
2025-11-28 05:59:49 +00:00
RitvikSardana
3555ef8f69 chore: Slovenian translations
(cherry picked from commit a546403f1c)
2025-11-28 05:59:49 +00:00
RitvikSardana
526b030305 chore: French translations
(cherry picked from commit 5947c38d30)
2025-11-28 05:59:49 +00:00
RitvikSardana
caef4a6670 chore: Spanish translations
(cherry picked from commit 863b543e28)
2025-11-28 05:59:49 +00:00
RitvikSardana
e48b138baa Merge pull request #2778 from frappe/mergify/bp/main-hotfix/pr-2761
fix: mandatory feedback bug (backport #2761)
2025-11-27 00:35:41 +05:30
RitvikSardana
ecffab176c Merge pull request #2777 from frappe/mergify/bp/main-hotfix/pr-2765
fix: auto closing bug in reply & comment section (backport #2765)
2025-11-27 00:33:37 +05:30
RitvikSardana
2d9ce87d9c Merge pull request #2776 from frappe/mergify/bp/main-hotfix/pr-2768
fix: Validate that published HD articles contain content (backport #2768)
2025-11-27 00:31:09 +05:30
RitvikSardana
f2e4482c2b Merge pull request #2775 from frappe/mergify/bp/main-hotfix/pr-2758
chore: update POT file (backport #2758)
2025-11-27 00:30:34 +05:30
RitvikSardana
cab852c4d0 Merge branch 'main-hotfix' into mergify/bp/main-hotfix/pr-2758 2025-11-27 00:30:27 +05:30
Pratik
8f631a9e33 fix: remove feedback field in validation
(cherry picked from commit 015bb01599)
2025-11-26 19:00:23 +00:00
Pratik
6fef06be3a fix: mandatory feedback bug
(cherry picked from commit 86b4440149)
2025-11-26 19:00:23 +00:00
RitvikSardana
b5a0dca8c5 Merge pull request #2773 from frappe/mergify/bp/main-hotfix/pr-2751
chore: sync translations from crowdin (backport #2751)
2025-11-27 00:30:02 +05:30
RitvikSardana
5521e46696 Merge pull request #2772 from frappe/mergify/bp/main-hotfix/pr-2766
chore: update POT file (backport #2766)
2025-11-27 00:29:53 +05:30
Pratik
b006403eff fix: revert changes & add ignore args
(cherry picked from commit 77eaa45ee7)
2025-11-26 18:58:23 +00:00
Pratik
794303795d fix: auto closing bug in reply & comment section
(cherry picked from commit e197993dbf)
2025-11-26 18:58:23 +00:00
KerollesFathy
00d7cad822 fix: validate published articles have content
(cherry picked from commit 356c88bc1f)
2025-11-26 18:44:36 +00:00
frappe-pr-bot
4a9260ad37 chore: update POT file
(cherry picked from commit 75647b121d)
2025-11-26 18:41:32 +00:00
Ritvik Sardana
62c56faec0 fix: update frappe-ui version
(cherry picked from commit f386c33a09)
2025-11-26 18:40:31 +00:00
Ritvik Sardana
2bce281c7d fix: change PWA version
(cherry picked from commit b457646087)
2025-11-26 18:40:31 +00:00
Ritvik Sardana
98f0460c24 fix: resolve for node 18
(cherry picked from commit d14fc7dd5f)
2025-11-26 18:40:31 +00:00
Ritvik Sardana
8a1cf06df3 chore: update frappe-ui version
(cherry picked from commit 88acdd0a4f)
2025-11-26 18:40:31 +00:00
Ritvik Sardana
da4d1810b7 chore: code cleanup
(cherry picked from commit 09ef6a1d18)
2025-11-26 18:40:30 +00:00
Ritvik Sardana
8d23efeb0c fix: update frappe-ui version
(cherry picked from commit 98c8eb7445)
2025-11-26 18:40:30 +00:00
Ritvik Sardana
03329051a9 fix: frappe-ui changes in sidebar
(cherry picked from commit 15fdea2cd1)
2025-11-26 18:40:30 +00:00
Ritvik Sardana
4e11103806 fix: change frappe-ui commit hash
(cherry picked from commit 97a3be2fc7)
2025-11-26 18:40:30 +00:00
Ritvik Sardana
636607df99 fix: change frappe-ui commit hash
(cherry picked from commit 538674f68b)
2025-11-26 18:40:30 +00:00
Ritvik Sardana
8260debc30 fix: incorporate new changes
(cherry picked from commit c9a6a28af7)

# Conflicts:
#	desk/src/components/ticket-agent/TicketSLA.vue
2025-11-26 18:40:29 +00:00
Ritvik Sardana
0104750c59 chore: update git ignore file
(cherry picked from commit 0e84f92d32)
2025-11-26 18:40:29 +00:00
Ritvik Sardana
cbffb8304b fix: frappe-ui tree shaking compatible
(cherry picked from commit 6f02b27ff6)
2025-11-26 18:40:29 +00:00
Ritvik Sardana
2233c7ed37 chore: bump frappe-ui version
(cherry picked from commit 580ac33487)
2025-11-26 18:40:28 +00:00
Ritvik Sardana
2d2f0cbe68 chore: update yarn.lock
(cherry picked from commit 020bd77358)
2025-11-26 18:40:28 +00:00
Ritvik Sardana
14251eaa61 fix: remove visualizer
(cherry picked from commit 511fa074b4)
2025-11-26 18:40:28 +00:00
Ritvik Sardana
edf3f88136 refactor: reduce bundle size
(cherry picked from commit 01175b0fc8)

# Conflicts:
#	desk/src/components/ticket-agent/TicketActivityPanel.vue
2025-11-26 18:40:28 +00:00
RitvikSardana
0db3a26557 chore: Slovenian translations
(cherry picked from commit 660fd178b9)
2025-11-26 18:39:47 +00:00
RitvikSardana
c72f8c5923 chore: Portuguese, Brazilian translations
(cherry picked from commit 6c29b677cb)
2025-11-26 18:39:47 +00:00
RitvikSardana
0a2ba097df chore: Slovenian translations
(cherry picked from commit 530340a01f)
2025-11-26 18:39:46 +00:00
RitvikSardana
4fe3a05f55 chore: French translations
(cherry picked from commit 6f104d56f4)
2025-11-26 18:39:46 +00:00
RitvikSardana
685fb6d770 chore: Slovenian translations
(cherry picked from commit 9e66c34d99)
2025-11-26 18:39:46 +00:00
RitvikSardana
42347b4114 chore: Slovenian translations
(cherry picked from commit 144f1b9f6a)
2025-11-26 18:39:44 +00:00
RitvikSardana
b68653fc32 chore: Slovenian translations
(cherry picked from commit e93b3d3912)
2025-11-26 18:39:43 +00:00
RitvikSardana
74eb4093c3 chore: Slovenian translations
(cherry picked from commit b922219bb6)
2025-11-26 18:39:43 +00:00
RitvikSardana
be40fbfb53 chore: Indonesian translations
(cherry picked from commit 73adb17b98)
2025-11-26 18:39:43 +00:00
RitvikSardana
190f9801a8 chore: Portuguese, Brazilian translations
(cherry picked from commit 2157d27cbe)
2025-11-26 18:39:43 +00:00
RitvikSardana
9ac3d812ac chore: Spanish translations
(cherry picked from commit 4b0c61fa16)
2025-11-26 18:39:41 +00:00
RitvikSardana
9e87c2526a chore: Persian translations
(cherry picked from commit f4670c5fb2)
2025-11-26 18:39:40 +00:00
RitvikSardana
7f0e7fe4b2 chore: French translations
(cherry picked from commit ce7ccf1730)
2025-11-26 18:39:40 +00:00
RitvikSardana
df185cef71 chore: Serbian (Latin) translations
(cherry picked from commit 4d7601a527)
2025-11-26 18:39:40 +00:00
RitvikSardana
28574f6203 chore: Norwegian Bokmal translations
(cherry picked from commit 6be1784277)
2025-11-26 18:39:38 +00:00
RitvikSardana
f34dcb5974 chore: Bosnian translations
(cherry picked from commit c177472a42)
2025-11-26 18:39:38 +00:00
RitvikSardana
e3ab99bb36 chore: Croatian translations
(cherry picked from commit 7f80b00860)
2025-11-26 18:39:37 +00:00
RitvikSardana
e4a66d68d4 chore: Persian translations
(cherry picked from commit fd74e6311b)
2025-11-26 18:39:36 +00:00
RitvikSardana
090ee1b021 chore: Indonesian translations
(cherry picked from commit 64b8991408)
2025-11-26 18:39:35 +00:00
RitvikSardana
2501bafc46 chore: Chinese Simplified translations
(cherry picked from commit ea37dcfc3a)
2025-11-26 18:39:35 +00:00
RitvikSardana
37161a79e8 chore: Turkish translations
(cherry picked from commit 6be74cad34)
2025-11-26 18:39:35 +00:00
RitvikSardana
fb0edce5b0 chore: Swedish translations
(cherry picked from commit 03556b02b5)
2025-11-26 18:39:34 +00:00
RitvikSardana
fe13c7e383 chore: Serbian (Cyrillic) translations
(cherry picked from commit a7f42d9d14)
2025-11-26 18:39:34 +00:00
RitvikSardana
910f753c61 chore: Polish translations
(cherry picked from commit a83e75a4d3)
2025-11-26 18:39:32 +00:00
RitvikSardana
dcd9361a45 chore: German translations
(cherry picked from commit afb5f2cb34)
2025-11-26 18:39:32 +00:00
RitvikSardana
58638f67e8 chore: Arabic translations
(cherry picked from commit ff30d7d318)
2025-11-26 18:39:31 +00:00
RitvikSardana
423f01c27f chore: Spanish translations
(cherry picked from commit 952fe5daa0)
2025-11-26 18:39:31 +00:00
RitvikSardana
8350870406 chore: German translations
(cherry picked from commit caaf65d63b)
2025-11-26 18:39:31 +00:00
RitvikSardana
737ad7e807 chore: Persian translations
(cherry picked from commit c813319260)
2025-11-26 18:39:30 +00:00
frappe-pr-bot
d03120778a chore: update POT file
(cherry picked from commit 6fcae817d4)
2025-11-26 18:39:24 +00:00
RitvikSardana
0dd85bae82 Merge pull request #2749 from frappe/mergify/bp/main-hotfix/pr-2746
chore: sync translations from crowdin (backport #2746)
2025-11-12 02:30:47 +05:30
RitvikSardana
332a03230a chore: Bosnian translations
(cherry picked from commit c60636e65d)
2025-11-11 20:59:53 +00:00
RitvikSardana
f3122c7001 chore: Croatian translations
(cherry picked from commit 64876b97b3)
2025-11-11 20:59:53 +00:00
RitvikSardana
c46e97c990 chore: Swedish translations
(cherry picked from commit 6544352f17)
2025-11-11 20:59:53 +00:00
RitvikSardana
2a843ea14e chore: French translations
(cherry picked from commit 5d3155301e)
2025-11-11 20:59:53 +00:00
RitvikSardana
c82485520e chore: Serbian (Latin) translations
(cherry picked from commit 8eae98f9fb)
2025-11-11 20:59:52 +00:00
RitvikSardana
b44d833656 chore: Norwegian Bokmal translations
(cherry picked from commit 64730f9c10)
2025-11-11 20:59:52 +00:00
RitvikSardana
58e4314856 chore: Bosnian translations
(cherry picked from commit 4697af4d7b)
2025-11-11 20:59:52 +00:00
RitvikSardana
d9bf8b3787 chore: Croatian translations
(cherry picked from commit 76f45d5ac0)
2025-11-11 20:59:52 +00:00
RitvikSardana
fd49c2d34d chore: Persian translations
(cherry picked from commit 347205c866)
2025-11-11 20:59:51 +00:00
RitvikSardana
9f08a80a25 chore: Indonesian translations
(cherry picked from commit 13ea1ffc8c)
2025-11-11 20:59:51 +00:00
RitvikSardana
522b84e0ec chore: Portuguese, Brazilian translations
(cherry picked from commit 928a9391d0)
2025-11-11 20:59:51 +00:00
RitvikSardana
f8970a6693 chore: Chinese Simplified translations
(cherry picked from commit 240651564a)
2025-11-11 20:59:51 +00:00
RitvikSardana
91b7e98776 chore: Turkish translations
(cherry picked from commit c2a68b6a6b)
2025-11-11 20:59:51 +00:00
RitvikSardana
2eb6e479e6 chore: Swedish translations
(cherry picked from commit 5df19be765)
2025-11-11 20:59:50 +00:00
RitvikSardana
7c5973d56d chore: Serbian (Cyrillic) translations
(cherry picked from commit df85bb2111)
2025-11-11 20:59:50 +00:00
RitvikSardana
dda0438d82 chore: Portuguese translations
(cherry picked from commit df1adc6c6a)
2025-11-11 20:59:50 +00:00
RitvikSardana
1bbbcd0c8e chore: Polish translations
(cherry picked from commit 601b674f8d)
2025-11-11 20:59:50 +00:00
RitvikSardana
77f77073b2 chore: Dutch translations
(cherry picked from commit 79100fe489)
2025-11-11 20:59:49 +00:00
RitvikSardana
506fbca15d chore: Italian translations
(cherry picked from commit b0a8f48dae)
2025-11-11 20:59:49 +00:00
RitvikSardana
d7f5769ead chore: German translations
(cherry picked from commit 2a713fa2a4)
2025-11-11 20:59:49 +00:00
RitvikSardana
160dd3d1e8 chore: Danish translations
(cherry picked from commit abb2c8b8df)
2025-11-11 20:59:49 +00:00
RitvikSardana
de41ce2135 chore: Arabic translations
(cherry picked from commit b016726247)
2025-11-11 20:59:48 +00:00
RitvikSardana
e0f97a9bdb chore: Spanish translations
(cherry picked from commit b019883b91)
2025-11-11 20:59:48 +00:00
RitvikSardana
5f1eaae00b Merge pull request #2748 from frappe/mergify/bp/main-hotfix/pr-2747
fix: parse API Options correctly while creating tickets (backport #2747)
2025-11-12 02:28:43 +05:30
Ritvik Sardana
721866b782 fix: parse API Options correctly while creating tickets
(cherry picked from commit bf144300ba)
2025-11-11 07:03:21 +00:00
RitvikSardana
bfd01b0549 Merge pull request #2745 from frappe/main-hotfix
chore(release): hotfix to main
2025-11-10 15:59:34 +05:30
RitvikSardana
a0ca9daa97 Merge pull request #2742 from frappe/mergify/bp/main-hotfix/pr-2741
fix: validation error when replying on a ticket (backport #2741)
2025-11-10 15:50:58 +05:30
RitvikSardana
129dbb3cd2 Merge pull request #2744 from frappe/mergify/bp/main-hotfix/pr-2743
fix: filter out null/undefined values in apiOptions (backport #2743)
2025-11-10 15:50:42 +05:30
Ritvik Sardana
d06df8aafb chore: code cleanup
(cherry picked from commit 03583e44d5)
2025-11-10 10:19:03 +00:00
Ritvik Sardana
bf46380aae fix: filter out null/undefined values in apiOptions
(cherry picked from commit 4bb8b7695c)
2025-11-10 10:19:03 +00:00
Ritvik Sardana
73b608d133 fix: validation error when replying on a ticket
(cherry picked from commit 643155e4ec)
2025-11-10 10:02:00 +00:00
RitvikSardana
06ce05bcb0 Merge pull request #2739 from frappe/mergify/bp/main-hotfix/pr-2715
refactor: update apiOptions transform to map object labels and values (backport #2715)
2025-11-10 12:29:03 +05:30
KerollesFathy
62d35686b3 refactor: update apiOptions transform to handle object labels and values
(cherry picked from commit f06862057f)
2025-11-09 16:04:57 +00:00
RitvikSardana
7182665584 Merge pull request #2738 from frappe/mergify/bp/main-hotfix/pr-2737
chore: sync translations from crowdin (backport #2737)
2025-11-09 21:34:21 +05:30
RitvikSardana
a42f700154 chore: French translations
(cherry picked from commit 3d22970159)
2025-11-09 15:20:58 +00:00
RitvikSardana
dc41f10fb7 chore: Esperanto translations
(cherry picked from commit 4d39b43f15)
2025-11-09 15:20:58 +00:00
RitvikSardana
6a8cd912bd chore: Serbian (Latin) translations
(cherry picked from commit 5489209a0d)
2025-11-09 15:20:57 +00:00
RitvikSardana
dc2505c1ff chore: Norwegian Bokmal translations
(cherry picked from commit 4845183691)
2025-11-09 15:20:57 +00:00
RitvikSardana
d6a8c17860 chore: Bosnian translations
(cherry picked from commit e17d9f0123)
2025-11-09 15:20:57 +00:00
RitvikSardana
2fc428c25b chore: Burmese translations
(cherry picked from commit 30f4654d0f)
2025-11-09 15:20:57 +00:00
RitvikSardana
32831f9e6c chore: Croatian translations
(cherry picked from commit 6b6dacea76)
2025-11-09 15:20:56 +00:00
RitvikSardana
f74dc38917 chore: Thai translations
(cherry picked from commit 0594cba992)
2025-11-09 15:20:56 +00:00
RitvikSardana
cf09a7e922 chore: Tamil translations
(cherry picked from commit 1cfcbd964b)
2025-11-09 15:20:56 +00:00
RitvikSardana
7ed9d4e13b chore: Persian translations
(cherry picked from commit cffd32dda9)
2025-11-09 15:20:56 +00:00
RitvikSardana
e18e37752e chore: Indonesian translations
(cherry picked from commit 7e8071f33c)
2025-11-09 15:20:56 +00:00
RitvikSardana
6e6ea85c31 chore: Portuguese, Brazilian translations
(cherry picked from commit 926e21d258)
2025-11-09 15:20:55 +00:00
RitvikSardana
e85451d2d6 chore: Vietnamese translations
(cherry picked from commit 8af08fe0fa)
2025-11-09 15:20:55 +00:00
RitvikSardana
a4cc6f59fc chore: Chinese Simplified translations
(cherry picked from commit 0826769b62)
2025-11-09 15:20:55 +00:00
RitvikSardana
d9f3fc8a5c chore: Turkish translations
(cherry picked from commit f35457bdb0)
2025-11-09 15:20:55 +00:00
RitvikSardana
a18a544f2f chore: Swedish translations
(cherry picked from commit 6bc303f434)
2025-11-09 15:20:54 +00:00
RitvikSardana
a973a10297 chore: Serbian (Cyrillic) translations
(cherry picked from commit 12050328a2)
2025-11-09 15:20:54 +00:00
RitvikSardana
5bfd9ea9f8 chore: Russian translations
(cherry picked from commit 5ec5c53024)
2025-11-09 15:20:54 +00:00
RitvikSardana
f5b4e536b4 chore: Portuguese translations
(cherry picked from commit 0388bcaf45)
2025-11-09 15:20:54 +00:00
RitvikSardana
693b88df22 chore: Polish translations
(cherry picked from commit 50faed905e)
2025-11-09 15:20:53 +00:00
RitvikSardana
aff88c6078 chore: Dutch translations
(cherry picked from commit b97d1e8edc)
2025-11-09 15:20:53 +00:00
RitvikSardana
6754511b2a chore: Italian translations
(cherry picked from commit 699ce06906)
2025-11-09 15:20:53 +00:00
RitvikSardana
68272b43e0 chore: Hungarian translations
(cherry picked from commit 28bf477422)
2025-11-09 15:20:53 +00:00
RitvikSardana
a88f68564a chore: German translations
(cherry picked from commit 10c206c37f)
2025-11-09 15:20:53 +00:00
RitvikSardana
0d52ce1a3b chore: Danish translations
(cherry picked from commit 506a5619cb)
2025-11-09 15:20:52 +00:00
RitvikSardana
ca5a9f46dd chore: Czech translations
(cherry picked from commit 56e4a8fa27)
2025-11-09 15:20:52 +00:00
RitvikSardana
b0346cb7d8 chore: Arabic translations
(cherry picked from commit 387e6f65ea)
2025-11-09 15:20:52 +00:00
RitvikSardana
f154f26e39 chore: Spanish translations
(cherry picked from commit 6e94d7668e)
2025-11-09 15:20:52 +00:00
RitvikSardana
220d037088 Merge pull request #2736 from frappe/mergify/bp/main-hotfix/pr-2733
chore: sync translations from crowdin (backport #2733)
2025-11-09 20:49:32 +05:30
RitvikSardana
2ca10d4c75 Merge pull request #2735 from frappe/mergify/bp/main-hotfix/pr-2734
chore: update POT file (backport #2734)
2025-11-09 20:49:22 +05:30
RitvikSardana
7bd6442fb6 chore: Esperanto translations
(cherry picked from commit fbf5bed567)
2025-11-09 12:25:32 +00:00
RitvikSardana
57fa5106cf chore: Serbian (Latin) translations
(cherry picked from commit b7dcf6324c)
2025-11-09 12:25:32 +00:00
RitvikSardana
72c8dbccd7 chore: Norwegian Bokmal translations
(cherry picked from commit fe25d084d9)
2025-11-09 12:25:31 +00:00
RitvikSardana
b5f52079ed chore: Bosnian translations
(cherry picked from commit cb329e9747)
2025-11-09 12:25:31 +00:00
RitvikSardana
7649a9189a chore: Burmese translations
(cherry picked from commit f5720fba05)
2025-11-09 12:25:31 +00:00
RitvikSardana
247a866f3a chore: Croatian translations
(cherry picked from commit 0745ddf8cd)
2025-11-09 12:25:31 +00:00
RitvikSardana
58f34cae64 chore: Thai translations
(cherry picked from commit 4a6ce11692)
2025-11-09 12:25:31 +00:00
RitvikSardana
65573e904c chore: Tamil translations
(cherry picked from commit bed330a7db)
2025-11-09 12:25:30 +00:00
RitvikSardana
2f5c21c45d chore: Persian translations
(cherry picked from commit b939caaf68)
2025-11-09 12:25:30 +00:00
RitvikSardana
fdb2493ae4 chore: Indonesian translations
(cherry picked from commit dae531dd26)
2025-11-09 12:25:30 +00:00
RitvikSardana
f4b4dea414 chore: Portuguese, Brazilian translations
(cherry picked from commit 84af9ba07f)
2025-11-09 12:25:30 +00:00
RitvikSardana
334f9b11ca chore: Vietnamese translations
(cherry picked from commit d32244a877)
2025-11-09 12:25:29 +00:00
RitvikSardana
b794cff536 chore: Chinese Simplified translations
(cherry picked from commit f2b5213e6e)
2025-11-09 12:25:29 +00:00
RitvikSardana
08d830e0bd chore: Turkish translations
(cherry picked from commit 487ea74b51)
2025-11-09 12:25:29 +00:00
RitvikSardana
7d0c147e08 chore: Swedish translations
(cherry picked from commit 124a1a6911)
2025-11-09 12:25:29 +00:00
RitvikSardana
e8e672efcb chore: Serbian (Cyrillic) translations
(cherry picked from commit 2e85998e72)
2025-11-09 12:25:28 +00:00
RitvikSardana
631b53773c chore: Russian translations
(cherry picked from commit 83cefc54a1)
2025-11-09 12:25:28 +00:00
RitvikSardana
abc0ac26d1 chore: Portuguese translations
(cherry picked from commit fb42f359a1)
2025-11-09 12:25:28 +00:00
RitvikSardana
407c259aa7 chore: Polish translations
(cherry picked from commit 0334db5ef9)
2025-11-09 12:25:28 +00:00
RitvikSardana
736e1c404c chore: Dutch translations
(cherry picked from commit 305ef5e560)
2025-11-09 12:25:27 +00:00
RitvikSardana
05c2ccd29e chore: Italian translations
(cherry picked from commit a4f3d1d5b4)
2025-11-09 12:25:27 +00:00
RitvikSardana
32aa3fa9e0 chore: Hungarian translations
(cherry picked from commit 16f72e287a)
2025-11-09 12:25:27 +00:00
RitvikSardana
f2cf5ce054 chore: German translations
(cherry picked from commit de04086da7)
2025-11-09 12:25:27 +00:00
frappe-pr-bot
6d1758c7b7 chore: update POT file
(cherry picked from commit ce4f422335)
2025-11-09 12:25:26 +00:00
RitvikSardana
02f4336b8b chore: Danish translations
(cherry picked from commit 557bd6a498)
2025-11-09 12:25:26 +00:00
RitvikSardana
9279cb567b chore: Czech translations
(cherry picked from commit 4b0704060b)
2025-11-09 12:25:26 +00:00
RitvikSardana
70358a6e3a chore: Arabic translations
(cherry picked from commit 30debfc42b)
2025-11-09 12:25:26 +00:00
RitvikSardana
2498a20a2e chore: Spanish translations
(cherry picked from commit 23568e9b97)
2025-11-09 12:25:26 +00:00
RitvikSardana
0ea469f796 Merge pull request #2732 from frappe/main-hotfix
chore(release): hotfix to main
2025-11-07 17:33:54 +05:30
RitvikSardana
c961f3db39 Merge pull request #2731 from frappe/mergify/bp/main-hotfix/pr-2730
chore: bump version (backport #2730)
2025-11-07 17:04:58 +05:30
Ritvik Sardana
4b6cd0d6df chore: bump version
(cherry picked from commit 260d15de65)
2025-11-07 11:31:23 +00:00
RitvikSardana
42c4d0c0fc Merge pull request #2729 from frappe/mergify/bp/main-hotfix/pr-2705
chore: sync translations from crowdin (backport #2705)
2025-11-07 16:54:29 +05:30
RitvikSardana
bac4d39f51 Merge pull request #2728 from frappe/mergify/bp/main-hotfix/pr-2721
chore: update POT file (backport #2721)
2025-11-07 16:54:16 +05:30
RitvikSardana
12f99c0451 Merge pull request #2727 from frappe/mergify/bp/main-hotfix/pr-2726
fix: remove unnecessary validation while giving feedback for email tickets (backport #2726)
2025-11-07 16:53:52 +05:30
RitvikSardana
3daf50e765 chore: Chinese Simplified translations
(cherry picked from commit 01dd4fb42c)
2025-11-07 11:23:15 +00:00
RitvikSardana
b5576df9a7 chore: Serbian (Latin) translations
(cherry picked from commit 75799fa4a2)
2025-11-07 11:23:15 +00:00
RitvikSardana
a14f3c9e7d chore: Serbian (Cyrillic) translations
(cherry picked from commit 7fdcc42626)
2025-11-07 11:23:15 +00:00
RitvikSardana
b68a9f8be1 chore: Esperanto translations
(cherry picked from commit 2a15bfb7e2)
2025-11-07 11:23:14 +00:00
RitvikSardana
6cd27f5444 chore: Burmese translations
(cherry picked from commit 0722e819c3)
2025-11-07 11:23:14 +00:00
RitvikSardana
18d6eeff1a chore: Tamil translations
(cherry picked from commit 5f49a5afd1)
2025-11-07 11:23:14 +00:00
RitvikSardana
a238dcb20c chore: Serbian (Latin) translations
(cherry picked from commit a3254586e5)
2025-11-07 11:23:14 +00:00
RitvikSardana
66b0632584 chore: Norwegian Bokmal translations
(cherry picked from commit 04c4a57141)
2025-11-07 11:23:13 +00:00
RitvikSardana
5d8928e3b6 chore: Bosnian translations
(cherry picked from commit d7fd5cda70)
2025-11-07 11:23:13 +00:00
RitvikSardana
46ddee1111 chore: Croatian translations
(cherry picked from commit 9850e2da85)
2025-11-07 11:23:13 +00:00
RitvikSardana
21fbb8fe47 chore: Thai translations
(cherry picked from commit a0b7fab8da)
2025-11-07 11:23:13 +00:00
RitvikSardana
1da7dce716 chore: Persian translations
(cherry picked from commit 96fbb18677)
2025-11-07 11:23:12 +00:00
RitvikSardana
b7a38821f3 chore: Indonesian translations
(cherry picked from commit 9b10275f36)
2025-11-07 11:23:12 +00:00
RitvikSardana
fddc8b9b59 chore: Portuguese, Brazilian translations
(cherry picked from commit cb1000f32d)
2025-11-07 11:23:12 +00:00
RitvikSardana
c88310a2d3 chore: Vietnamese translations
(cherry picked from commit c0c9bf2cae)
2025-11-07 11:23:12 +00:00
RitvikSardana
cfcc08fe67 chore: Chinese Simplified translations
(cherry picked from commit 1b64db4792)
2025-11-07 11:23:11 +00:00
RitvikSardana
33f6aa0316 chore: Turkish translations
(cherry picked from commit 7631e7f9a4)
2025-11-07 11:23:11 +00:00
RitvikSardana
eab198c78b chore: Swedish translations
(cherry picked from commit 39f26f0050)
2025-11-07 11:23:11 +00:00
RitvikSardana
485cb2d678 chore: Serbian (Cyrillic) translations
(cherry picked from commit 2c67d72e4f)
2025-11-07 11:23:11 +00:00
RitvikSardana
3f76cf27d0 chore: Russian translations
(cherry picked from commit 006ead4074)
2025-11-07 11:23:10 +00:00
RitvikSardana
9d56115ac8 chore: Portuguese translations
(cherry picked from commit ee57aa5fb0)
2025-11-07 11:23:10 +00:00
RitvikSardana
4b3fdcab54 chore: Polish translations
(cherry picked from commit aec5d229eb)
2025-11-07 11:23:10 +00:00
RitvikSardana
0132e6129b chore: Dutch translations
(cherry picked from commit 3ecc905ae8)
2025-11-07 11:23:10 +00:00
RitvikSardana
712c456527 chore: Italian translations
(cherry picked from commit e1bb325c03)
2025-11-07 11:23:09 +00:00
RitvikSardana
a2fe7a53cc chore: Hungarian translations
(cherry picked from commit 037ae628a1)
2025-11-07 11:23:09 +00:00
RitvikSardana
beeec49ccf chore: German translations
(cherry picked from commit 8af498aa8b)
2025-11-07 11:23:09 +00:00
RitvikSardana
eda0ce2cfd chore: Danish translations
(cherry picked from commit 3adddec261)
2025-11-07 11:23:09 +00:00
RitvikSardana
34f9e1a2e4 chore: Czech translations
(cherry picked from commit 4225f50f0c)
2025-11-07 11:23:08 +00:00
RitvikSardana
2ee895491f chore: Arabic translations
(cherry picked from commit ef8b183c88)
2025-11-07 11:23:08 +00:00
RitvikSardana
e8948ce2f1 chore: Spanish translations
(cherry picked from commit 682a25a677)
2025-11-07 11:23:08 +00:00
RitvikSardana
2d9561796f chore: French translations
(cherry picked from commit 21c3a00c78)
2025-11-07 11:23:08 +00:00
RitvikSardana
543bf922a6 Merge pull request #2707 from frappe/mergify/bp/main-hotfix/pr-2706
fix(perm): agent should see the assigned tickets (backport #2706)
2025-11-07 16:52:30 +05:30
frappe-pr-bot
a270cf565c chore: update POT file
(cherry picked from commit 7c29161b3b)
2025-11-07 11:22:18 +00:00
RitvikSardana
e72c64b1a9 Merge pull request #2717 from frappe/mergify/bp/main-hotfix/pr-2716
fix: remove index delete from hooks (backport #2716)
2025-11-07 16:52:06 +05:30
Ritvik Sardana
87cf42ddea fix: remove unnecessary validation while giving feedback for email tickets
(cherry picked from commit f054d9e209)
2025-11-07 11:22:05 +00:00
Ritvik Sardana
2f1c2de00c fix: remove index delete from hooks
(cherry picked from commit 84fce9936e)
2025-10-31 07:32:29 +00:00
RitvikSardana
6857d2be4e Merge pull request #2713 from frappe/main-hotfix
chore(release): hotfix to main
2025-10-30 10:45:05 +05:30
RitvikSardana
b91a82eecb Bump version to 1.17.1 2025-10-30 10:43:22 +05:30
RitvikSardana
e139fa12df Merge pull request #2711 from frappe/mergify/bp/main-hotfix/pr-2710 2025-10-30 10:40:39 +05:30
Pratik Badhe
8a6568dcce fix: undefined ref
(cherry picked from commit 7a1545ef1b)
2025-10-30 04:59:03 +00:00
Ritvik Sardana
3d5f93dc4e fix(search): add ref ticket only if doc is HD Ticket
(cherry picked from commit 38d0a0b76e)
2025-10-29 11:35:20 +00:00
Ritvik Sardana
15ab7e2adc fix: type coercion while setting value
(cherry picked from commit 40f0032380)
2025-10-29 11:35:20 +00:00
Ritvik Sardana
26cf3ffd90 fix: show ticket to agent is they are assigned to it
(cherry picked from commit f564284d96)
2025-10-29 11:35:20 +00:00
RitvikSardana
3fe5020aa4 Merge pull request #2704 from frappe/main-hotfix
chore(release): hotfix to main
2025-10-29 13:30:31 +05:30
RitvikSardana
27dc26b81a Merge pull request #2703 from frappe/mergify/bp/main-hotfix/pr-2699
chore: bump version (backport #2699)
2025-10-29 12:59:54 +05:30
RitvikSardana
5efea5e456 chore: code cleanup 2025-10-29 12:58:40 +05:30
Ritvik Sardana
af5f937c6d chore: update yarn.lock
(cherry picked from commit c583974b74)
2025-10-29 07:24:21 +00:00
Ritvik Sardana
2f2055d760 chore: bump version
(cherry picked from commit 295c1fded4)
2025-10-29 07:24:21 +00:00
RitvikSardana
9331955bcb Merge pull request #2702 from RitvikSardana/url-hash-hotfix
fix: tab url hash & make a call button (backport #2576)
2025-10-29 12:53:19 +05:30
Pratik Badhe
7114e80e9f refactor: change loading state handling 2025-10-29 12:44:29 +05:30
Pratik Badhe
463026c2ac fix: edge case where tab wont change if call is disabled 2025-10-29 12:44:29 +05:30
Pratik Badhe
7f46ba1191 fix: reset tab state on navigation 2025-10-29 12:44:29 +05:30
Pratik Badhe
60686f151e fix: use correct variable 2025-10-29 12:44:26 +05:30
Pratik Badhe
ca4c6a7128 fix: url bug for custom view 2025-10-29 12:43:53 +05:30
Pratik
5f73663797 fix: tab url hash & make a call button 2025-10-29 12:43:39 +05:30
RitvikSardana
f7e1100d75 Merge pull request #2701 from frappe/mergify/bp/main-hotfix/pr-2689
fix: handle edge case for cc & to field (backport #2689)
2025-10-29 12:28:54 +05:30
Pratik Badhe
13cda63eb6 fix: handle edge case for cc & to field
(cherry picked from commit ffbb1c5e8f)
2025-10-29 06:42:20 +00:00
RitvikSardana
ea9f190683 Merge pull request #2691 from frappe/mergify/bp/main-hotfix/pr-2690
fix: minor fixes (backport #2690)
2025-10-29 10:45:51 +05:30
RitvikSardana
8511d032eb Merge branch 'main-hotfix' into mergify/bp/main-hotfix/pr-2690 2025-10-28 19:34:49 +05:30
RitvikSardana
02b32388dc Merge pull request #2698 from frappe/mergify/bp/main-hotfix/pr-2636
fix: assign history message (backport #2636)
2025-10-28 19:30:28 +05:30
Ritvik Sardana
e2171096b5 fix: reload activities
(cherry picked from commit 046aa8e085)
2025-10-28 13:59:38 +00:00
Ritvik Sardana
3ce3d85ef1 fix: assign history message
(cherry picked from commit 46f0faca0b)
2025-10-28 13:59:38 +00:00
RitvikSardana
35ef3c51dc Merge pull request #2697 from RitvikSardana/shortcuts-hotfix
feat: Shortcuts (backport #2676)
2025-10-28 19:18:35 +05:30
Ritvik Sardana
6e162b95fc fix: delete search index when a ticket is deleted 2025-10-28 19:03:01 +05:30
Ritvik Sardana
b475380508 fix: add shortcuts only in Agent Portal 2025-10-28 19:03:01 +05:30
Ritvik Sardana
20391a7d93 chore: code cleanup 2025-10-28 19:02:59 +05:30
Ritvik Sardana
fe3973c376 chore: code cleanup 2025-10-28 19:02:27 +05:30
Ritvik Sardana
650ca7035e fix: add shortcut for showing help panel 2025-10-28 19:02:27 +05:30
Ritvik Sardana
9e15c94d5e fix: handle special cases in shortcuts 2025-10-28 19:02:27 +05:30
Ritvik Sardana
5a3462f9d5 fix: persist redirect URL 2025-10-28 19:02:27 +05:30
Ritvik Sardana
4bf4ac05a4 chore: UI cleanup 2025-10-28 19:02:27 +05:30
Ritvik Sardana
7f7a934382 chore: code cleanup 2025-10-28 19:02:27 +05:30
Ritvik Sardana
0cafac8f38 refactor: shortcut composable 2025-10-28 19:02:27 +05:30
Ritvik Sardana
38cbb7c717 fix: UI for shortcuts 2025-10-28 19:02:27 +05:30
Ritvik Sardana
90d0303b3b fix: add proper handling to remove key bindings 2025-10-28 19:02:27 +05:30
Ritvik Sardana
62168f7d4f refactor: shortcut handling 2025-10-28 19:02:27 +05:30
Ritvik Sardana
6892132128 fix: handle delete_doc in sqlite search 2025-10-28 19:02:27 +05:30
Ritvik Sardana
cb715e8a2a fix: replace old shortcuts with new API 2025-10-28 19:02:25 +05:30
Ritvik Sardana
64fe77005e fix: add shortcuts for ticket navigation 2025-10-28 19:01:53 +05:30
Ritvik Sardana
33089a6a0c fix: add shortcuts for reply&comment 2025-10-28 19:01:53 +05:30
Ritvik Sardana
79f04ff750 fix: add shortcuts for core fields 2025-10-28 19:01:53 +05:30
Ritvik Sardana
59e57b8d56 fix: better way to disable shortcuts 2025-10-28 19:01:53 +05:30
Ritvik Sardana
46b74ae70d feat: key bindings 2025-10-28 19:01:21 +05:30
RitvikSardana
a6cbabbaba Merge pull request #2696 from frappe/mergify/bp/main-hotfix/pr-2678
chore: update POT file (backport #2678)
2025-10-28 18:46:39 +05:30
RitvikSardana
ece2092932 Merge pull request #2695 from frappe/mergify/bp/main-hotfix/pr-2679
chore: sync translations from crowdin (backport #2679)
2025-10-28 18:46:35 +05:30
RitvikSardana
a0bd028496 Merge branch 'main-hotfix' into mergify/bp/main-hotfix/pr-2678 2025-10-28 18:37:38 +05:30
RitvikSardana
f214c73b02 Merge pull request #2694 from frappe/mergify/bp/main-hotfix/pr-2687
chore: update POT file (backport #2687)
2025-10-28 18:36:50 +05:30
RitvikSardana
99d43706cc Merge pull request #2693 from frappe/mergify/bp/main-hotfix/pr-2657
fix: handle json parse error & json validation on doctype save (backport #2657)
2025-10-28 18:36:42 +05:30
RitvikSardana
0845564356 Merge pull request #2683 from efeone/main-hotfix
fix: update required_apps to include frappe/telephony
2025-10-28 18:35:20 +05:30
frappe-pr-bot
955dc75078 chore: update POT file
(cherry picked from commit 012cfd179b)
2025-10-28 13:02:14 +00:00
RitvikSardana
3b48f660b2 Merge pull request #2692 from frappe/mergify/bp/main-hotfix/pr-2688
fix: prevent usermenu button overflow in sidebar (backport #2688)
2025-10-28 18:31:42 +05:30
RitvikSardana
8e5986b6b9 chore: Polish translations
(cherry picked from commit 5300f24b10)
2025-10-28 13:01:14 +00:00
RitvikSardana
040c4569d5 chore: Polish translations
(cherry picked from commit 03bf47d082)
2025-10-28 13:01:14 +00:00
RitvikSardana
8b052f2764 chore: Persian translations
(cherry picked from commit e2ed80369c)
2025-10-28 13:01:14 +00:00
frappe-pr-bot
eafd4ee634 chore: update POT file
(cherry picked from commit da4008d6ab)
2025-10-28 13:00:10 +00:00
Ritvik Sardana
e53d52c2b7 chore: format error message in assignment rule
(cherry picked from commit 2b62a32f55)
2025-10-28 12:58:06 +00:00
Pratik Badhe
d3fbfb5169 fix: handle long email and name in assignee search
(cherry picked from commit aa0c887504)
2025-10-28 12:58:06 +00:00
Pratik Badhe
34f64f2d33 fix: bug in assignment rule overwrite handling
(cherry picked from commit 4fd9a38860)
2025-10-28 12:58:06 +00:00
Pratik Badhe
0d39e36a46 fix: assignment rule conditions
(cherry picked from commit 22d06eea8a)
2025-10-28 12:58:06 +00:00
Pratik Badhe
bc70ca90d5 fix: show toast if conditions are invalid
(cherry picked from commit 5cce62efef)
2025-10-28 12:58:05 +00:00
Pratik Badhe
b66717731c fix: handle json parse error & json validation on doctype save
(cherry picked from commit 746fb39d1c)
2025-10-28 12:58:05 +00:00
siduck
76ee72c0ea fix: prevent usermenu button overflow in sidebar
Related to https://github.com/frappe/frappe-ui/issues/298

(cherry picked from commit 856a161164)
2025-10-28 12:49:02 +00:00
Ritvik Sardana
e31833a486 fix(sqlite_search): convert to int only when doctype is HD Ticket
(cherry picked from commit 652188cc64)
2025-10-28 10:53:12 +00:00
Ritvik Sardana
0ec14e4ed6 fix: add handling bad_emails in process_mail
(cherry picked from commit 943da1be93)
2025-10-28 10:53:12 +00:00
Ritvik Sardana
bd57310ee6 fix: decoding the receiving email properly with try except
(cherry picked from commit d7225a82c0)
2025-10-28 10:53:11 +00:00
Ritvik Sardana
2c3b1d3a22 fix: dont add build_index function in hooks.py of helpdesk
(cherry picked from commit a25c9c0a8a)
2025-10-28 10:53:11 +00:00
Ritvik Sardana
c6b23de4f1 chore: cleanup
(cherry picked from commit e64fe01ed8)
2025-10-28 10:53:11 +00:00
Ritvik Sardana
998449b71c fix: add support for numberFields in side panel
(cherry picked from commit 9e1d493ef5)
2025-10-28 10:53:11 +00:00
Ritvik Sardana
5c79767406 fix: remove unwanted imports
(cherry picked from commit 8b1bd75348)

# Conflicts:
#	desk/src/components/ticket-agent/AssignTo.vue
#	desk/src/components/ticket-agent/TicketDetailsTab.vue
#	desk/src/components/ticket-agent/TicketNavigation.vue
#	desk/src/pages/SearchAgent.vue
2025-10-28 10:53:11 +00:00
MochaMind
b29bc60aa9 Merge pull request #2685 from frappe/main-hotfix
chore: Merge hotfix into main
2025-10-24 02:53:48 -07:00
Sherin KR
81af8b5e98 fix: update required_apps to include frappe/telephony 2025-10-24 10:00:23 +05:30
RitvikSardana
7b1c9152fa Merge pull request #2674 from frappe/mergify/bp/main-hotfix/pr-2667
chore: update POT file (backport #2667)
2025-10-15 15:28:11 +05:30
RitvikSardana
f432260f65 Merge pull request #2673 from frappe/mergify/bp/main-hotfix/pr-2652
chore: sync translations from crowdin (backport #2652)
2025-10-15 15:28:05 +05:30
frappe-pr-bot
a1a37e2102 chore: update POT file
(cherry picked from commit f6eec48671)
2025-10-15 09:51:18 +00:00
RitvikSardana
b85c38fc5d chore: Serbian (Latin) translations
(cherry picked from commit f9158f4bcf)
2025-10-15 09:50:22 +00:00
RitvikSardana
7623835cd0 chore: Serbian (Cyrillic) translations
(cherry picked from commit 246044776f)
2025-10-15 09:50:22 +00:00
RitvikSardana
c1eeaf3748 chore: Polish translations
(cherry picked from commit 25f33001ae)
2025-10-15 09:50:21 +00:00
RitvikSardana
f94c0fa609 chore: Polish translations
(cherry picked from commit de096bf1bc)
2025-10-15 09:50:21 +00:00
RitvikSardana
a8807155d7 chore: Burmese translations
(cherry picked from commit aac3b105d9)
2025-10-15 09:50:21 +00:00
RitvikSardana
d740c208e7 chore: Tamil translations
(cherry picked from commit 98e4852f43)
2025-10-15 09:50:21 +00:00
RitvikSardana
e951f5df1a chore: Esperanto translations
(cherry picked from commit f7ede8edb0)
2025-10-15 09:50:20 +00:00
RitvikSardana
8012c5c3a7 chore: Serbian (Latin) translations
(cherry picked from commit 76dc90c563)
2025-10-15 09:50:20 +00:00
RitvikSardana
ee13da2bb3 chore: Norwegian Bokmal translations
(cherry picked from commit 24ab3d735b)
2025-10-15 09:50:20 +00:00
RitvikSardana
70b08d2f0a chore: Bosnian translations
(cherry picked from commit 75348d5266)
2025-10-15 09:50:19 +00:00
RitvikSardana
8b57956505 chore: Croatian translations
(cherry picked from commit 037742eacb)
2025-10-15 09:50:19 +00:00
RitvikSardana
1aacf5b75f chore: Thai translations
(cherry picked from commit 31ac3b4bbb)
2025-10-15 09:50:19 +00:00
RitvikSardana
240b1b0a64 chore: Persian translations
(cherry picked from commit 3afcd2f43c)
2025-10-15 09:50:19 +00:00
RitvikSardana
9fef721e60 chore: Indonesian translations
(cherry picked from commit db71ab4744)
2025-10-15 09:50:18 +00:00
RitvikSardana
cabfd3499d chore: Portuguese, Brazilian translations
(cherry picked from commit b6fb4a1024)
2025-10-15 09:50:18 +00:00
RitvikSardana
be8a78a795 chore: Vietnamese translations
(cherry picked from commit 11da05c81e)
2025-10-15 09:50:18 +00:00
RitvikSardana
2e6f00cc1f chore: Chinese Simplified translations
(cherry picked from commit 95dcd882db)
2025-10-15 09:50:18 +00:00
RitvikSardana
b872bbab30 chore: Turkish translations
(cherry picked from commit 6b010d34d4)
2025-10-15 09:50:17 +00:00
RitvikSardana
ccfa7c4c72 chore: Swedish translations
(cherry picked from commit e4f0f7ace0)
2025-10-15 09:50:17 +00:00
RitvikSardana
df544c114e chore: Serbian (Cyrillic) translations
(cherry picked from commit 42b89e65cf)
2025-10-15 09:50:17 +00:00
RitvikSardana
2f21abd777 chore: Russian translations
(cherry picked from commit 131f03a0f6)
2025-10-15 09:50:17 +00:00
RitvikSardana
1581970179 chore: Portuguese translations
(cherry picked from commit d667d15ee9)
2025-10-15 09:50:16 +00:00
RitvikSardana
48164ca420 chore: Polish translations
(cherry picked from commit f3cc7920bd)
2025-10-15 09:50:16 +00:00
RitvikSardana
989ff6b2ab chore: Dutch translations
(cherry picked from commit 790bbcd772)
2025-10-15 09:50:16 +00:00
RitvikSardana
39391ab607 chore: Italian translations
(cherry picked from commit 11a608ead6)
2025-10-15 09:50:15 +00:00
RitvikSardana
ca48068aa4 chore: Hungarian translations
(cherry picked from commit 785e087e95)
2025-10-15 09:50:15 +00:00
RitvikSardana
4496bbdbed chore: German translations
(cherry picked from commit 0c1ad5e944)
2025-10-15 09:50:15 +00:00
RitvikSardana
4bbfe8e792 chore: Danish translations
(cherry picked from commit 29f6a71881)
2025-10-15 09:50:15 +00:00
RitvikSardana
13a29cae8a chore: Czech translations
(cherry picked from commit 04a05dd50b)
2025-10-15 09:50:14 +00:00
RitvikSardana
81314c422a chore: Arabic translations
(cherry picked from commit 2e2ae7e7db)
2025-10-15 09:50:14 +00:00
RitvikSardana
0b5f733c55 chore: Spanish translations
(cherry picked from commit 23cfb9afd8)
2025-10-15 09:50:14 +00:00
RitvikSardana
0ab6c17ef2 chore: French translations
(cherry picked from commit ee3d1e2dea)
2025-10-15 09:50:14 +00:00
RitvikSardana
f09e519b47 chore: Burmese translations
(cherry picked from commit 23260de0d7)
2025-10-15 09:50:13 +00:00
RitvikSardana
5276814156 chore: Portuguese, Brazilian translations
(cherry picked from commit 5959048cae)
2025-10-15 09:50:13 +00:00
RitvikSardana
c5b34bda25 Merge pull request #2663 from frappe/mergify/bp/main-hotfix/pr-2656
fix: reply all 'To' email bug (backport #2656)
2025-10-15 15:19:50 +05:30
RitvikSardana
ab34ac8fff Merge pull request #2662 from frappe/mergify/bp/main-hotfix/pr-2649
chore: update POT file (backport #2649)
2025-10-15 15:19:43 +05:30
Pratik Badhe
56b85aada5 fix: reply all 'To' email bug
(cherry picked from commit 4636ffab67)
2025-10-10 07:15:51 +00:00
RitvikSardana
07e79e2572 Merge pull request #2661 from frappe/mergify/bp/main-hotfix/pr-2647
fix: docker bash file (backport #2647)
2025-10-10 12:41:58 +05:30
frappe-pr-bot
bb9927d252 chore: update POT file
(cherry picked from commit dee4cdf688)
2025-10-10 07:11:51 +00:00
Pratik Badhe
e08e1c94fd fix: docker bash file
(cherry picked from commit 043780c85d)
2025-10-10 07:01:19 +00:00
RitvikSardana
b2934885b1 Merge pull request #2660 from frappe/mergify/bp/main-hotfix/pr-2659
fix: bump vueuse to fix builds (backport #2659)
2025-10-10 12:14:44 +05:30
18alantom
b2fac92338 fix: bump vueuse to fix builds
(cherry picked from commit 4099373b62)
2025-10-10 06:08:32 +00:00
RitvikSardana
52bfc91781 Merge pull request #2645 from frappe/mergify/bp/main-hotfix/pr-2641
chore: sync translations from crowdin (backport #2641)
2025-10-03 12:28:03 +05:30
RitvikSardana
5507ee420d Merge pull request #2644 from frappe/mergify/bp/main-hotfix/pr-2639
fix: disable command palette when text editor is enabled (backport #2639)
2025-10-03 12:27:44 +05:30
RitvikSardana
8d7201c477 chore: Tamil translations
(cherry picked from commit 9afc83e633)
2025-10-03 06:04:57 +00:00
RitvikSardana
0b3174be90 chore: Esperanto translations
(cherry picked from commit 9f017522f0)
2025-10-03 06:04:57 +00:00
RitvikSardana
b3eeba27b0 chore: Serbian (Latin) translations
(cherry picked from commit 4bddc7f0ef)
2025-10-03 06:04:56 +00:00
RitvikSardana
35b5a2e82d chore: Norwegian Bokmal translations
(cherry picked from commit b470a17913)
2025-10-03 06:04:56 +00:00
RitvikSardana
4a56f45da9 chore: Bosnian translations
(cherry picked from commit 00a2efbfbb)
2025-10-03 06:04:56 +00:00
RitvikSardana
2443223a91 chore: Croatian translations
(cherry picked from commit 54b1854bdf)
2025-10-03 06:04:55 +00:00
RitvikSardana
9cc28b6789 chore: Thai translations
(cherry picked from commit dbe03e6fd0)
2025-10-03 06:04:55 +00:00
RitvikSardana
36c3dd6509 chore: Persian translations
(cherry picked from commit 309c084222)
2025-10-03 06:04:55 +00:00
RitvikSardana
abf2248d3e chore: Indonesian translations
(cherry picked from commit 51f2a5e428)
2025-10-03 06:04:55 +00:00
RitvikSardana
ac9e854b34 chore: Portuguese, Brazilian translations
(cherry picked from commit 5343a006ef)
2025-10-03 06:04:54 +00:00
RitvikSardana
6a943f0000 chore: Vietnamese translations
(cherry picked from commit 2caf0e94b8)
2025-10-03 06:04:54 +00:00
RitvikSardana
1cf28aab92 chore: Chinese Simplified translations
(cherry picked from commit 8c9eab3d71)
2025-10-03 06:04:54 +00:00
RitvikSardana
7f9ab5eb96 chore: Turkish translations
(cherry picked from commit 8790567a50)
2025-10-03 06:04:53 +00:00
RitvikSardana
d40f71ff5c chore: Swedish translations
(cherry picked from commit 7a75306222)
2025-10-03 06:04:52 +00:00
RitvikSardana
7936c1243d chore: Serbian (Cyrillic) translations
(cherry picked from commit a1e4bb2555)
2025-10-03 06:04:52 +00:00
RitvikSardana
dba45334c0 chore: Russian translations
(cherry picked from commit 0a0fc03f70)
2025-10-03 06:04:52 +00:00
RitvikSardana
51e35a5838 chore: Portuguese translations
(cherry picked from commit 24b30fb9cb)
2025-10-03 06:04:52 +00:00
RitvikSardana
a9d3a39c56 chore: Polish translations
(cherry picked from commit 6c40f9b2a5)
2025-10-03 06:04:51 +00:00
RitvikSardana
f490014415 chore: Dutch translations
(cherry picked from commit 6e59e71c7c)
2025-10-03 06:04:51 +00:00
RitvikSardana
5733c5fff1 chore: Italian translations
(cherry picked from commit 95e10e43a8)
2025-10-03 06:04:51 +00:00
RitvikSardana
8e395cdeab chore: Hungarian translations
(cherry picked from commit 88396d22a9)
2025-10-03 06:04:50 +00:00
RitvikSardana
3f97ae78b3 chore: German translations
(cherry picked from commit 207b8efcc5)
2025-10-03 06:04:50 +00:00
RitvikSardana
eef3ea7a6f chore: Danish translations
(cherry picked from commit 309cd9e417)
2025-10-03 06:04:50 +00:00
RitvikSardana
325d6ec506 chore: Czech translations
(cherry picked from commit 69fd0d17ac)
2025-10-03 06:04:50 +00:00
RitvikSardana
69ae56d923 chore: Arabic translations
(cherry picked from commit 02cf1d1375)
2025-10-03 06:04:49 +00:00
RitvikSardana
ef830ebbb6 chore: Spanish translations
(cherry picked from commit faade64fb5)
2025-10-03 06:04:49 +00:00
RitvikSardana
6591d5aec5 chore: French translations
(cherry picked from commit 9deb301619)
2025-10-03 06:04:49 +00:00
Ritvik Sardana
5027b876a3 fix: disable command palette when text editor is enabled
(cherry picked from commit 105e8daff6)
2025-10-03 06:04:37 +00:00
RitvikSardana
f34d744f36 Merge pull request #2640 from frappe/mergify/bp/main-hotfix/pr-2625
chore: update POT file (backport #2625)
2025-10-03 11:32:46 +05:30
frappe-pr-bot
e61525de50 chore: update POT file
(cherry picked from commit 5bbfeaff35)
2025-10-01 15:47:14 +00:00
RitvikSardana
1fcc8f7a28 Merge pull request #2638 from frappe/mergify/bp/main-hotfix/pr-2624
chore: sync translations from crowdin (backport #2624)
2025-10-01 21:16:59 +05:30
RitvikSardana
a0fe934e36 chore: Tamil translations
(cherry picked from commit 5d9bdedb22)
2025-10-01 15:37:01 +00:00
RitvikSardana
0bd667223b chore: Persian translations
(cherry picked from commit add112ff9a)
2025-10-01 15:37:01 +00:00
RitvikSardana
62f1d6a3f8 chore: Portuguese, Brazilian translations
(cherry picked from commit 9bc28bec9e)
2025-10-01 15:36:59 +00:00
RitvikSardana
a69b1259ca chore: Vietnamese translations
(cherry picked from commit 5b768c0e4f)
2025-10-01 15:36:58 +00:00
RitvikSardana
36a9252ce3 chore: Chinese Simplified translations
(cherry picked from commit 9d7bcfcbec)
2025-10-01 15:36:58 +00:00
RitvikSardana
48f8c79898 chore: Polish translations
(cherry picked from commit f658054549)
2025-10-01 15:36:57 +00:00
RitvikSardana
ce7b2ec996 chore: Hungarian translations
(cherry picked from commit 1919abfcea)
2025-10-01 15:36:57 +00:00
RitvikSardana
8b548d699e chore: Arabic translations
(cherry picked from commit d058962498)
2025-10-01 15:36:57 +00:00
RitvikSardana
c8971ed41f chore: Spanish translations
(cherry picked from commit 0434986a00)
2025-10-01 15:36:55 +00:00
RitvikSardana
44d28502f4 chore: French translations
(cherry picked from commit 6c6941d53c)
2025-10-01 15:36:54 +00:00
RitvikSardana
8bd6b02233 chore: Norwegian Bokmal translations
(cherry picked from commit 32447b2e77)
2025-10-01 15:36:54 +00:00
RitvikSardana
04ebf1c056 chore: Hungarian translations
(cherry picked from commit 557e0c1d61)
2025-10-01 15:36:54 +00:00
RitvikSardana
fe508b6114 chore: Norwegian Bokmal translations
(cherry picked from commit 6ea1fb316a)
2025-10-01 15:36:53 +00:00
RitvikSardana
b5793d0f2c Merge pull request #2637 from frappe/mergify/bp/main-hotfix/pr-2594
feat: Full Text Search using SQLite (backport #2594)
2025-10-01 21:05:11 +05:30
RitvikSardana
019ca9c58f chore: bump version 2025-10-01 16:30:18 +05:30
Ritvik Sardana
923241e450 chore: version bump
(cherry picked from commit 74a434acac)

# Conflicts:
#	helpdesk/__init__.py
2025-10-01 07:07:10 +00:00
Ritvik Sardana
32527cbf59 fix: search icon and placeholder
(cherry picked from commit ecabb8d55d)
2025-10-01 07:07:10 +00:00
Ritvik Sardana
aca4a01aed fix: persist filters and remove dump code from hooks and search_sqlite
(cherry picked from commit e9e5a58154)
2025-10-01 07:07:09 +00:00
Ritvik Sardana
b78d2e0b1b fix: dont index same doc thrice
(cherry picked from commit 741200e217)
2025-10-01 07:07:09 +00:00
Ritvik Sardana
d794ecc8b9 fix: hide dialog after deleting a comment
(cherry picked from commit 5029510766)
2025-10-01 07:07:08 +00:00
Ritvik Sardana
9ecdd96ee4 fix: add shortcut to focus on search bar
(cherry picked from commit 16b358b599)
2025-10-01 07:07:08 +00:00
Ritvik Sardana
09446a7ec7 fix: show white icon for online and offline
(cherry picked from commit 0248fcfc48)
2025-10-01 07:07:08 +00:00
Ritvik Sardana
9ea3ea71d9 chore: update yarn.lock
(cherry picked from commit 232b30ebdd)
2025-10-01 07:07:08 +00:00
Ritvik Sardana
c094193b59 fix: linters
(cherry picked from commit 7ade7b602b)
2025-10-01 07:07:07 +00:00
Ritvik Sardana
ca0d59f7e6 fix: add scrollbar in custom fields of customer portal
(cherry picked from commit da7bf3d861)
2025-10-01 07:07:07 +00:00
Ritvik Sardana
a0cf892ea8 fix: dont show count
(cherry picked from commit f8280ac203)
2025-10-01 07:07:07 +00:00
Ritvik Sardana
7aed2a563f fix: convert reference_ticket value to int
(cherry picked from commit aad177fc73)
2025-10-01 07:07:07 +00:00
Ritvik Sardana
7640087fb5 fix: search results with permission query filters
(cherry picked from commit ed06002cfc)
2025-10-01 07:07:06 +00:00
Ritvik Sardana
26e547aa36 fix: ticket not found error
(cherry picked from commit 063c8aeea4)
2025-10-01 07:07:06 +00:00
Ritvik Sardana
88b9b9a28b fix: convert command pallete to composition API from options API
(cherry picked from commit efa9ca438e)
2025-10-01 07:07:06 +00:00
Ritvik Sardana
c0b661d9a8 fix: ticket agent scroll
(cherry picked from commit 02080dd4c0)
2025-10-01 07:07:05 +00:00
Faris Ansari
fa2c323ee0 feat: Full Text Search using SQLite
- dedicated search page
- route to ticket and scroll to relevant comment or email
- wip

(cherry picked from commit 0c2967f503)
2025-10-01 07:07:05 +00:00
RitvikSardana
bebcde4144 Merge pull request #2622 from frappe/mergify/bp/main-hotfix/pr-2621
fix: respect read_only fields (backport #2621)
2025-09-29 23:17:01 +05:30
Ritvik Sardana
a071cd7a67 fix: respect read_only fields
(cherry picked from commit 3317f1446b)
2025-09-26 10:43:01 +00:00
RitvikSardana
4ec1299d74 Merge pull request #2620 from frappe/mergify/bp/main-hotfix/pr-2617
fix: add disable field to Feedback Option (backport #2617)
2025-09-26 16:11:28 +05:30
RitvikSardana
fc4a9ac96b Merge pull request #2619 from frappe/mergify/bp/main-hotfix/pr-2618
fix: fetch notifications after the user is fetched (backport #2618)
2025-09-26 16:11:18 +05:30
Ritvik Sardana
abcab05fbe fix: validate for old options only
(cherry picked from commit 0bf79c7be8)
2025-09-26 10:29:35 +00:00
Ritvik Sardana
aed4198add fix: fetch notifications after the user is fetched
(cherry picked from commit 916f039ed3)
2025-09-26 10:29:34 +00:00
Ritvik Sardana
315ae1dd34 fix: add disable field to Feedback Option
(cherry picked from commit 8520a225d1)
2025-09-26 10:29:34 +00:00
RitvikSardana
868304ffc8 Merge pull request #2616 from frappe/main-hotfix
chore: merge hotfix to main
2025-09-26 13:46:27 +05:30
RitvikSardana
0c5c96c3fe Merge pull request #2613 from frappe/mergify/bp/main-hotfix/pr-2610
fix: search in Canned responses  (backport #2610)
2025-09-25 21:06:29 +05:30
RitvikSardana
1a408be504 Merge pull request #2612 from frappe/mergify/bp/main-hotfix/pr-2595
chore: sync translations from crowdin (backport #2595)
2025-09-25 20:37:52 +05:30
Ritvik Sardana
fff8e5346b fix: add debounce in search
(cherry picked from commit f0060c24c2)
2025-09-25 15:07:32 +00:00
MhmdSinanKT
deee7efbce feat: enhance search with or filter
(cherry picked from commit 2b6e54a941)
2025-09-25 15:07:32 +00:00
MhmdSinanKT
cd5f05c059 feat: search for canned responses in hd view
(cherry picked from commit 85e8d9d2e9)
2025-09-25 15:07:32 +00:00
RitvikSardana
3ecbd4a555 Merge pull request #2611 from frappe/mergify/bp/main-hotfix/pr-2604
chore: update POT file (backport #2604)
2025-09-25 20:37:12 +05:30
RitvikSardana
6b76acbaa2 chore: Norwegian Bokmal translations
(cherry picked from commit d67ad04e89)
2025-09-25 15:02:43 +00:00
RitvikSardana
a22f73b93d chore: Norwegian Bokmal translations
(cherry picked from commit 5ea83dccdd)
2025-09-25 15:02:42 +00:00
RitvikSardana
c05b9a3aac chore: Persian translations
(cherry picked from commit db9426279e)
2025-09-25 15:02:42 +00:00
RitvikSardana
a33e34d2fa chore: Norwegian Bokmal translations
(cherry picked from commit f64e305f91)
2025-09-25 15:02:42 +00:00
RitvikSardana
2e8b172dcc chore: Norwegian Bokmal translations
(cherry picked from commit a55a148a78)
2025-09-25 15:02:41 +00:00
RitvikSardana
773ae4c476 chore: Norwegian Bokmal translations
(cherry picked from commit b93128d390)
2025-09-25 15:02:41 +00:00
RitvikSardana
229bf8a2a7 chore: Serbian (Latin) translations
(cherry picked from commit d4936a833f)
2025-09-25 15:02:41 +00:00
RitvikSardana
7566c761ef chore: Serbian (Cyrillic) translations
(cherry picked from commit 781fa723e4)
2025-09-25 15:02:40 +00:00
RitvikSardana
1f4b565bb7 chore: Esperanto translations
(cherry picked from commit d07a8765ed)
2025-09-25 15:02:40 +00:00
RitvikSardana
fe61cb822d chore: Serbian (Latin) translations
(cherry picked from commit f513485016)
2025-09-25 15:02:40 +00:00
RitvikSardana
df1ba3bb7f chore: Norwegian Bokmal translations
(cherry picked from commit e866951197)
2025-09-25 15:02:39 +00:00
RitvikSardana
7e70bef84e chore: Bosnian translations
(cherry picked from commit 7bc623051c)
2025-09-25 15:02:39 +00:00
RitvikSardana
536201602e chore: Croatian translations
(cherry picked from commit 998b277216)
2025-09-25 15:02:39 +00:00
RitvikSardana
61c1c58c41 chore: Thai translations
(cherry picked from commit dbcf6fe866)
2025-09-25 15:02:38 +00:00
RitvikSardana
a2e1fe50b1 chore: Persian translations
(cherry picked from commit 0bd75cec41)
2025-09-25 15:02:38 +00:00
RitvikSardana
7b67a03b90 chore: Indonesian translations
(cherry picked from commit 4e37c4c1d5)
2025-09-25 15:02:38 +00:00
RitvikSardana
168d296d73 chore: Portuguese, Brazilian translations
(cherry picked from commit 6f6b04e6a9)
2025-09-25 15:02:38 +00:00
RitvikSardana
c1c183f2fd chore: Vietnamese translations
(cherry picked from commit 1410bd82cf)
2025-09-25 15:02:37 +00:00
RitvikSardana
1a03488849 chore: Chinese Simplified translations
(cherry picked from commit 6eecc8d8aa)
2025-09-25 15:02:37 +00:00
RitvikSardana
ee48296c16 chore: Turkish translations
(cherry picked from commit 58b27e0261)
2025-09-25 15:02:37 +00:00
RitvikSardana
9b0620b5cd chore: Swedish translations
(cherry picked from commit 4e6a00823f)
2025-09-25 15:02:36 +00:00
RitvikSardana
81674811d8 chore: Serbian (Cyrillic) translations
(cherry picked from commit e599fd2e5a)
2025-09-25 15:02:36 +00:00
RitvikSardana
a985f72651 chore: Russian translations
(cherry picked from commit cee68f1b0d)
2025-09-25 15:02:36 +00:00
RitvikSardana
2264700c53 chore: Portuguese translations
(cherry picked from commit 6358533179)
2025-09-25 15:02:35 +00:00
RitvikSardana
e2fabb1a15 chore: Polish translations
(cherry picked from commit 117aa24a0a)
2025-09-25 15:02:35 +00:00
RitvikSardana
71a0628dab chore: Dutch translations
(cherry picked from commit ff91bd0c15)
2025-09-25 15:02:35 +00:00
RitvikSardana
aa25a2c521 chore: Italian translations
(cherry picked from commit 647fa443fc)
2025-09-25 15:02:34 +00:00
RitvikSardana
db95c35cbb chore: Hungarian translations
(cherry picked from commit 5be3593a13)
2025-09-25 15:02:34 +00:00
RitvikSardana
5cbefdb710 chore: German translations
(cherry picked from commit 93dd13deaf)
2025-09-25 15:02:34 +00:00
RitvikSardana
7535a2d6a6 chore: Danish translations
(cherry picked from commit d86fdba523)
2025-09-25 15:02:34 +00:00
RitvikSardana
9fce60e6fe chore: Czech translations
(cherry picked from commit a53450f740)
2025-09-25 15:02:33 +00:00
RitvikSardana
51c81d8111 chore: Arabic translations
(cherry picked from commit f7929ca621)
2025-09-25 15:02:33 +00:00
RitvikSardana
214d04d69f chore: Spanish translations
(cherry picked from commit dab44e62d5)
2025-09-25 15:02:33 +00:00
frappe-pr-bot
6163562235 chore: update POT file
(cherry picked from commit b125c63d7b)
2025-09-25 15:02:32 +00:00
RitvikSardana
5699356dba chore: French translations
(cherry picked from commit dd81a4cdad)
2025-09-25 15:02:32 +00:00
RitvikSardana
5d1bcef3c2 Merge pull request #2609 from frappe/mergify/bp/main-hotfix/pr-2608
fix: email reply all bug (backport #2608)
2025-09-25 20:31:30 +05:30
Pratik Badhe
1d9c75119b fix: email reply all bug
(cherry picked from commit 14f1acea19)
2025-09-25 14:35:37 +00:00
RitvikSardana
6bc673302f Merge pull request #2597 from frappe/mergify/bp/main-hotfix/pr-2596
fix(desk): don't call mark seen api on new ticket (backport #2596)
2025-09-21 15:31:39 +05:30
RitvikSardana
e8a384dacd chore: Bump version to 1.15.1 2025-09-20 17:47:07 +05:30
RitvikSardana
5f16f0f49e Merge pull request #2603 from frappe/mergify/bp/main-hotfix/pr-2602
fix: add telephony in easy install script (backport #2602)
2025-09-20 17:38:50 +05:30
Ritvik Sardana
705820ffad fix: add telephony in easy install script
(cherry picked from commit 096381bb5c)
2025-09-20 12:07:09 +00:00
Ritvik Sardana
283fc81091 fix(desk): dont call mark seen api on new ticket
(cherry picked from commit 96efa8624f)
2025-09-18 09:52:19 +00:00
RitvikSardana
83b7a94756 Merge pull request #2589 from frappe/main-hotfix
chore(release): hotfix to main
2025-09-17 00:24:06 +05:30
RitvikSardana
bf6372b570 Merge pull request #2588 from frappe/mergify/bp/main-hotfix/pr-2587
fix: update portal url param (backport #2587)
2025-09-17 00:22:31 +05:30
Ritvik Sardana
7a34ac4423 chore: bump version
(cherry picked from commit ee4f111f05)
2025-09-16 18:52:06 +00:00
Ritvik Sardana
a83dc0417d fix: update portal url param
(cherry picked from commit f671d05ba2)
2025-09-16 18:52:06 +00:00
RitvikSardana
efb7c6e21e chore: update frappe version 2025-09-16 17:15:37 +05:30
470 changed files with 14206 additions and 21926 deletions

View File

@@ -9,7 +9,7 @@ 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
git clone "https://github.com/frappe/frappe" --branch "version-15" --depth 1
bench init --skip-assets --frappe-path ~/frappe --python "$(which python)" frappe-bench
mkdir ~/frappe-bench/sites/test_site
@@ -40,7 +40,7 @@ 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 erpnext --branch "develop"
bench get-app erpnext --branch "version-15"
bench get-app telephony
bench get-app helpdesk "${GITHUB_WORKSPACE}"
bench setup requirements --dev

View File

@@ -1,15 +0,0 @@
name: Pre-build assets
on:
push:
branches: [develop, main]
jobs:
assets:
name: Pre-build assets
uses: frappe/pilot/.github/workflows/app-assets.yml@develop
with:
# main supports Frappe v15 and v16; Pilot benches run v16 or later.
frappe-branch: ${{ github.ref_name == 'main' && 'version-16' || 'develop' }}
permissions:
contents: write

View File

@@ -13,15 +13,21 @@ jobs:
runs-on: ubuntu-latest
permissions:
packages: write
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
@@ -32,7 +38,8 @@ jobs:
- name: Set Branch
run: |
echo '[{"url": "https://github.com/frappe/telephony","branch": "develop"},{"url": "https://github.com/frappe/helpdesk","branch": "main"}]' > apps.json
export APPS_JSON='[{"url": "https://github.com/frappe/telephony","branch": "develop"},{"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
@@ -44,10 +51,10 @@ jobs:
repository: frappe/frappe_docker
path: builds
- name: Build
- name: Build and push
uses: docker/build-push-action@v6
with:
load: true
push: true
context: builds
file: builds/images/layered/Containerfile
tags: >
@@ -55,14 +62,4 @@ jobs:
ghcr.io/${{ github.repository }}:${{ env.IMAGE_TAG }}
build-args: |
"FRAPPE_BRANCH=${{ env.FRAPPE_BRANCH }}"
secret-files: |
apps_json=apps.json
- name: Verify apps are installed
run: |
apps=$(docker run --rm --entrypoint ls ghcr.io/${{ github.repository }}:${{ env.IMAGE_TAG }} apps)
echo "$apps"
grep -qx helpdesk <<< "$apps" && grep -qx telephony <<< "$apps"
- name: Push
run: docker push --all-tags ghcr.io/${{ github.repository }}
"APPS_JSON_BASE64=${{ env.APPS_JSON_BASE64 }}"

View File

@@ -25,12 +25,7 @@ jobs:
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: "3.14"
- name: Setup Node
uses: actions/setup-node@v6
with:
node-version: 24
python-version: "3.12"
- name: Run script to update POT file
run: |

View File

@@ -35,7 +35,7 @@ jobs:
- name: Set up Python 3.10
uses: actions/setup-python@v2
with:
python-version: '3.14'
python-version: '3.10'
- name: Install and Run Pre-commit
uses: pre-commit/action@v3.0.1

View File

@@ -40,7 +40,7 @@ jobs:
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.14'
python-version: '3.12'
- name: Check for valid Python & Merge Conflicts
if: github.event.pull_request.base.ref == 'develop'
@@ -104,32 +104,7 @@ jobs:
FRAPPE_BRANCH: ${{ github.event.inputs.branch }}
- name: Run Tests
run: 'cd ~/frappe-bench/ && bench --site test_site run-tests --app helpdesk --coverage'
run: 'cd ~/frappe-bench/ && bench --site test_site run-tests --app helpdesk'
env:
TYPE: server
CI_BUILD_ID: ${{ github.run_id }}
- name: Upload coverage data
uses: actions/upload-artifact@v4
with:
name: coverage-${{ matrix.container }}
path: /home/runner/frappe-bench/sites/coverage.xml
coverage:
name: Coverage Wrap Up
needs: tests
runs-on: ubuntu-latest
steps:
- name: Clone
uses: actions/checkout@v6
- name: Download artifacts
uses: actions/download-artifact@v4
- name: Upload coverage data
uses: codecov/codecov-action@v4
with:
name: MariaDB
token: ${{ secrets.CODECOV_TOKEN }}
fail_ci_if_error: true
verbose: true

View File

@@ -1,187 +0,0 @@
name: UI Tests
on:
pull_request:
branches:
- develop
paths:
- "desk/**"
- "e2e/**"
- "playwright.config.ts"
- "package.json"
- "yarn.lock"
- ".github/workflows/ui-tests.yml"
workflow_dispatch:
concurrency:
group: ui-tests-helpdesk-${{ github.event.number || github.ref }}
cancel-in-progress: true
env:
FRAPPE_BRANCH: develop
SITE: helpdesk.test
jobs:
ui-tests:
name: Playwright E2E Tests (${{ matrix.shard }}/2)
runs-on: ubuntu-latest
timeout-minutes: 60
strategy:
fail-fast: false
matrix:
shard: [1, 2]
services:
redis-cache:
image: redis/redis-stack-server:latest
ports:
- 13000:6379
redis-queue:
image: redis:alpine
ports:
- 11000:6379
mariadb:
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@v4
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: "3.14"
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 24
check-latest: true
- name: Cache pip
uses: actions/cache@v4
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('**/pyproject.toml') }}
restore-keys: ${{ runner.os }}-pip-
- name: Cache yarn
uses: actions/cache@v4
with:
path: ~/.cache/yarn
key: ${{ runner.os }}-yarn-ui-${{ hashFiles('**/yarn.lock') }}
restore-keys: ${{ runner.os }}-yarn-ui-
- name: Cache Playwright browsers
uses: actions/cache@v4
with:
path: ~/.cache/ms-playwright
key: ${{ runner.os }}-playwright-${{ hashFiles('yarn.lock') }}
- name: Install MariaDB Client
run: |
sudo apt update
sudo apt install -y mariadb-client
- name: Setup Bench
run: |
pip install frappe-bench
bench init --skip-redis-config-generation --skip-assets --frappe-branch "$FRAPPE_BRANCH" --python "$(which python)" ~/frappe-bench
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'"
- name: Install Helpdesk
working-directory: /home/runner/frappe-bench
run: |
bench get-app telephony
bench get-app helpdesk $GITHUB_WORKSPACE
bench setup requirements --dev
bench new-site --db-root-password root --admin-password admin --install-app helpdesk $SITE
bench use $SITE
bench --site $SITE set-config host_name "http://localhost:8000"
bench build --apps frappe,helpdesk
env:
CI: "Yes"
- name: Start Frappe Server
working-directory: /home/runner/frappe-bench
run: |
sed -i 's/^watch:/# watch:/g' Procfile
sed -i 's/^schedule:/# schedule:/g' Procfile
bench start &> bench_start.log &
timeout 120 bash -c "until curl -s http://localhost:8000 > /dev/null; do sleep 2; done"
- name: Install Playwright
run: |
yarn install --frozen-lockfile --ignore-scripts
npx playwright install --with-deps chromium
- name: Run Playwright Tests
run: npx playwright test --shard=${{ matrix.shard }}/2
env:
# localhost is a secure context, which crypto.randomUUID in frappe/ui needs.
BASE_URL: http://localhost:8000
ADMIN_PASSWORD: admin
- name: Upload Blob Report
uses: actions/upload-artifact@v4
if: always()
with:
name: blob-report-${{ matrix.shard }}
path: blob-report/
retention-days: 1
- name: Upload Test Results
uses: actions/upload-artifact@v4
if: failure()
with:
name: test-results-${{ matrix.shard }}
path: test-results/
retention-days: 7
- name: Show Bench Logs on Failure
if: failure()
working-directory: /home/runner/frappe-bench
run: |
cat bench_start.log || true
cat logs/*.log || true
merge-reports:
name: Merge Playwright Reports
needs: ui-tests
if: always()
runs-on: ubuntu-latest
steps:
- name: Clone
uses: actions/checkout@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 24
- name: Install Playwright
run: yarn install --frozen-lockfile --ignore-scripts
- name: Download Blob Reports
uses: actions/download-artifact@v4
with:
path: all-blob-reports
pattern: blob-report-*
merge-multiple: true
- name: Merge Into HTML Report
run: npx playwright merge-reports --reporter html ./all-blob-reports
- name: Upload Playwright Report
uses: actions/upload-artifact@v4
with:
name: playwright-report
path: playwright-report/
retention-days: 7

6
.gitignore vendored
View File

@@ -42,8 +42,4 @@ helpdesk/public/frontend
helpdesk/public/node_modules
helpdesk/www/helpdesk/index.html
desk/components.d.ts
desk/stats.html
# Playwright
e2e/.auth
playwright-report
test-results
desk/stats.html

View File

@@ -4,19 +4,19 @@ fail_fast: false
repos:
- repo: https://github.com/psf/black
rev: 25.11.0
rev: 22.6.0
hooks:
- id: black
types_or: [python, pyi]
- repo: https://github.com/PyCQA/flake8
rev: 7.3.0
rev: 5.0.4
hooks:
- id: flake8
additional_dependencies:
- flake8-bugbear
- flake8-comprehensions
- flake8-simplify==0.30.0
- flake8-simplify
args: ['--config', '.github/helpers/.flake8_strict']
- repo: https://github.com/pre-commit/mirrors-prettier

View File

@@ -1,18 +1,5 @@
# Copilot Instructions for Frappe Helpdesk
## Skills
For Frappe development tasks, reference the frappe-dev skill:
- **Location**: `~/.agents/skills/frappe-dev/`
- **Usage**: When working on DocType, controllers, whitelisted APIs, background jobs, permissions, or frontend tasks, read the relevant skill reference files:
- `doctype.md` — Creating/modifying DocTypes and fields
- `controllers.md` — Document lifecycle and server logic
- `api.md` — REST endpoints with `@frappe.whitelist()`
- `database.md` — `frappe.db`, queries, raw SQL
- `background-jobs.md` — `frappe.enqueue`, scheduled jobs
- `permissions.md` — Roles, DocType permissions
- `frontend-desk.md`, `frontend-vue.md`, `frontend-portal.md` — Frontend references
## Project Overview
Frappe Helpdesk is an open-source ticket management tool built on the [Frappe Framework](https://github.com/frappe/frappe) (Python backend) and [Frappe UI](https://github.com/frappe/frappe-ui) (Vue.js frontend). It provides agent/customer portals, SLAs, assignment rules, a knowledge base, and saved replies.
@@ -215,9 +202,7 @@ apiCall.submit({ ticket_id: "<id>", agent_id: "<agent>" });
**Data Query Patterns**:
- Always prefer `frappe.get_list()` over `frappe.get_all()` for new code. It handles perms out of the box and is more flexible.
- `frappe.get_all()` is fine for child tables (e.g. `Has Role`, `HD Customer Member`), which have no permissions of their own.
- When `frappe.get_all()` is used on a parent DocType, make sure the caller may see the result some other way, for example a `frappe.has_permission(...)` check first, or `@agent_only` / `@agent_manager_only` (`helpdesk/utils.py`) on the endpoint.
- Always prefer `frappe.qb.get_query()` over `frappe.db.get_all()` for new code
- Use `frappe.qb.get_query(..., ignore_permissions=False)` when permission checks are needed
- Example query patterns from helpdesk context
@@ -267,7 +252,6 @@ class HDFoo(Document):
- Methods that mutate a related document (e.g. an Assignment Rule) receive that doc as an argument and mutate it in memory. The **caller** is responsible for the final `doc.save()` — this keeps saves to a minimum (one save per hook).
- Never fetch the same document twice in one hook. Fetch once, pass the doc through the call chain.
- `@staticmethod` is allowed for pure transformations (e.g. building a condition string) that don't touch `self` or any Frappe doc.
- If there is an issue in framework/ui or frappe-ui or frappe framework, dont do a workaround. Instead, raise a blocker in the spec and wait for a fix. Do not implement workarounds that will be removed later. If possible, raise a PR to fix the issue in the framework instead of implementing a workaround in helpdesk.
**Save discipline:**
@@ -374,7 +358,7 @@ const ticket = createDocumentResource({
- Use ESLint with Vue 3 recommended rules and Prettier for consistency
- Write meaningful commit messages and maintain clean git history
- Document complex logic with JSDoc/TSDoc comments
- Keep a comment to 2 lines at most. If it needs more to explain, simplify the code instead
- Only add comments that explain why something is done, not what is done
- Keep dependencies updated and audit for security vulnerabilities
## References

View File

@@ -21,13 +21,11 @@
"@tiptap/starter-kit": "^3.26.0",
"@twilio/voice-sdk": "^2.15.0",
"@vee-validate/zod": "^4.8.2",
"@vitejs/plugin-vue": "^4.6.2",
"@vueuse/core": "^14.1.0",
"@vueuse/integrations": "^14.1.0",
"@vitejs/plugin-vue": "^4.2.3",
"@vueuse/core": "^13.8.0",
"@vueuse/integrations": "^13.8.0",
"dayjs": "^1.11.7",
"echarts": "^6.1.0",
"grid-layout-plus": "^1.1.0",
"frappe-ui": "1.0.0-rc.1",
"frappe-ui": "1.0.0-beta.24",
"mime": "^3.0.0",
"pinia": "^2.0.33",
"sanitize-html": "^2.10.0",
@@ -39,7 +37,7 @@
"zod": "^3.21.4"
},
"devDependencies": {
"@vitejs/plugin-vue-jsx": "^3.1.0",
"@vitejs/plugin-vue-jsx": "^3.0.1",
"autoprefixer": "^10.4.13",
"patch-package": "^8.0.1",
"postcss": "^8.4.5",
@@ -47,15 +45,11 @@
"prettier": "2.8.4",
"tailwindcss": "^3.4.15",
"typescript": "^5.0.2",
"unplugin-icons": "^22.1.0",
"vite": "^5.4.21",
"vite-plugin-pwa": "0.17.5"
"vite": "^4.4.9",
"vite-plugin-pwa": "0.15.0"
},
"resolutions": {
"cheerio": "1.0.0-rc.12",
"prosemirror-model": "1.25.9",
"prosemirror-state": "1.4.4",
"prosemirror-view": "1.41.9",
"prosemirror-transform": "1.12.0"
"prosemirror-model": "1.25.4"
}
}
}

View File

@@ -0,0 +1,119 @@
diff --git a/node_modules/frappe-ui/src/components/MultiSelect/MultiSelect.vue b/node_modules/frappe-ui/src/components/MultiSelect/MultiSelect.vue
index b8d1d2b..56d6e3c 100644
--- a/node_modules/frappe-ui/src/components/MultiSelect/MultiSelect.vue
+++ b/node_modules/frappe-ui/src/components/MultiSelect/MultiSelect.vue
@@ -428,6 +428,7 @@ defineSlots<MultiSelectSlots>()
v-if="loading"
class="size-4 shrink-0 text-ink-gray-5"
/>
+ <slot name="suffix" v-bind="slotProps" />
</div>
<MultiSelectResults
diff --git a/node_modules/frappe-ui/src/molecules/editor/SuggestionExtension.ts b/node_modules/frappe-ui/src/molecules/editor/SuggestionExtension.ts
index 0b7069a..de2a3df 100644
--- a/node_modules/frappe-ui/src/molecules/editor/SuggestionExtension.ts
+++ b/node_modules/frappe-ui/src/molecules/editor/SuggestionExtension.ts
@@ -16,6 +16,7 @@ export type SuggestionExtensionOptions<TItem = any> = {
items: TItem[] | ((query: string) => TItem[] | Promise<TItem[]>)
component?: Component
floatingOptions?: SuggestionFloatingOptions
+ allowSpaces?: boolean
command: (props: { editor: Editor; item: TItem; range: SuggestionRange }) => void
}
@@ -26,6 +27,7 @@ function buildSuggestionExtension<TItem = any>(options: SuggestionExtensionOptio
return {
suggestion: {
char: options.trigger,
+ allowSpaces: options.allowSpaces,
pluginKey: new PluginKey(options.name),
items: ({ query }: { query: string }) =>
typeof options.items === 'function' ? options.items(query) : options.items,
diff --git a/node_modules/frappe-ui/src/molecules/editor/extensions/link/link-extension.ts b/node_modules/frappe-ui/src/molecules/editor/extensions/link/link-extension.ts
index 1447ba9..b6aad68 100644
--- a/node_modules/frappe-ui/src/molecules/editor/extensions/link/link-extension.ts
+++ b/node_modules/frappe-ui/src/molecules/editor/extensions/link/link-extension.ts
@@ -45,6 +45,14 @@ export const LinkExtension = Link.extend({
}
},
+ // tiptap's Link mark is inclusive whenever `autolink` is on, so typing right
+ // after a link extends the mark onto the new text. Keep autolink (URL
+ // detection as you type) but make the mark non-inclusive so the link stops at
+ // its boundary.
+ inclusive() {
+ return false
+ },
+
addCommands() {
return {
...this.parent?.(),
diff --git a/node_modules/frappe-ui/src/molecules/editor/extensions/shared/suggestion-renderer.ts b/node_modules/frappe-ui/src/molecules/editor/extensions/shared/suggestion-renderer.ts
index 8363502..07f4551 100644
--- a/node_modules/frappe-ui/src/molecules/editor/extensions/shared/suggestion-renderer.ts
+++ b/node_modules/frappe-ui/src/molecules/editor/extensions/shared/suggestion-renderer.ts
@@ -82,6 +82,25 @@ export function createSuggestionRenderer(
})
}
+ // Attach the VueRenderer's mount wrapper (`el`), not `renderer.element` —
+ // FocusScope-based popups have no synchronous first element child.
+ function getWrapper(): HTMLElement | null {
+ return (renderer as unknown as { el: HTMLElement | null } | null)?.el ?? null
+ }
+
+ function attach(props: SuggestionProps, token: number): void {
+ if (!isActive || token !== renderToken || !renderer) return
+ if (floatingEl) return
+ const wrapper = getWrapper()
+ if (!props.clientRect || !wrapper) return
+
+ floatingEl = wrapper
+ floatingEl.style.position = 'absolute'
+ document.body.appendChild(floatingEl)
+ getReferenceClientRect = props.clientRect as () => DOMRect | null
+ updatePosition()
+ }
+
return {
onStart(props: SuggestionProps) {
isActive = true
@@ -92,15 +111,7 @@ export function createSuggestionRenderer(
props,
})
- if (!props.clientRect || !renderer.element) return
- // A newer query already superseded this start before mount completed.
- if (token !== renderToken || !isActive) return
-
- floatingEl = renderer.element as HTMLElement
- floatingEl.style.position = 'absolute'
- document.body.appendChild(floatingEl)
- getReferenceClientRect = props.clientRect as () => DOMRect | null
- updatePosition()
+ attach(props, token)
},
onUpdate(props: SuggestionProps) {
@@ -108,14 +119,18 @@ export function createSuggestionRenderer(
if (!isActive || !renderer) return
const token = ++renderToken
- renderer.updateProps(props)
+ // Skip the plugin's transient `loading` dispatch (empty items) so the
+ // popover doesn't unmount/remount on every keystroke.
+ const loading = (props as SuggestionProps & { loading?: boolean }).loading
+ if (!loading) renderer.updateProps(props)
if (!props.clientRect) return
// Fix 2: a newer query bumped the token between updateProps and now.
if (token !== renderToken) return
getReferenceClientRect = props.clientRect as () => DOMRect | null
- updatePosition()
+ if (!floatingEl) attach(props, token)
+ else updatePosition()
},
onKeyDown(props: SuggestionKeyDownProps): boolean {

View File

@@ -1,70 +0,0 @@
diff --git a/node_modules/frappe-ui/src/molecules/editor/extensions/shared/suggestion-renderer.ts b/node_modules/frappe-ui/src/molecules/editor/extensions/shared/suggestion-renderer.ts
index 91c8dc4..2883b93 100644
--- a/node_modules/frappe-ui/src/molecules/editor/extensions/shared/suggestion-renderer.ts
+++ b/node_modules/frappe-ui/src/molecules/editor/extensions/shared/suggestion-renderer.ts
@@ -5,6 +5,7 @@ import type {
} from '@tiptap/suggestion'
import type { Component } from 'vue'
import {
+ autoUpdate,
computePosition,
flip,
offset,
@@ -40,6 +41,9 @@ export function createSuggestionRenderer(
let isActive = false
// Monotonic token; a stale onUpdate from a superseded query bails.
let renderToken = 0
+ // Monotonic token; a stale computePosition settling later bails.
+ let positionToken = 0
+ let cleanupAutoUpdate: (() => void) | null = null
function getListExpose(): SuggestionListExpose | null {
const ref = renderer?.ref as SuggestionListExpose | null | undefined
@@ -52,6 +56,7 @@ export function createSuggestionRenderer(
const rect = getReferenceClientRect()
if (!rect) return
const reference = { getBoundingClientRect: () => rect }
+ const token = ++positionToken
void computePosition(reference, floatingEl, {
placement: floatingOptions?.placement ?? 'bottom-start',
middleware: [
@@ -60,7 +65,7 @@ export function createSuggestionRenderer(
shift({ padding: 8 }),
],
}).then(({ x, y }) => {
- if (!floatingEl) return
+ if (!floatingEl || token !== positionToken) return
Object.assign(floatingEl.style, {
position: 'absolute',
left: `${x}px`,
@@ -93,7 +98,19 @@ export function createSuggestionRenderer(
floatingEl.style.position = 'absolute'
document.body.appendChild(floatingEl)
getReferenceClientRect = props.clientRect as () => DOMRect | null
- updatePosition()
+
+ // Positions once, then keeps the popup on the caret through scroll, window
+ // resize and its own height changes (`flip()` measures a height that async
+ // rows and late fonts change after the fact).
+ cleanupAutoUpdate = autoUpdate(
+ {
+ getBoundingClientRect: () =>
+ getReferenceClientRect?.() ?? new DOMRect(),
+ contextElement: props.editor?.view?.dom as HTMLElement | undefined,
+ },
+ floatingEl,
+ updatePosition,
+ )
}
return {
@@ -139,6 +156,9 @@ export function createSuggestionRenderer(
onExit() {
isActive = false
renderToken++
+ positionToken++
+ cleanupAutoUpdate?.()
+ cleanupAutoUpdate = null
floatingEl?.remove()
renderer?.destroy()
floatingEl = null

View File

@@ -9,13 +9,13 @@
import { Dialogs } from "@/components/dialogs";
import { useConfigStore } from "@/stores/config";
import { useFavicon } from "@vueuse/core";
import { FrappeUIProvider, setConfig, toast, useColorScheme } from "frappe-ui";
import { FrappeUIProvider, setConfig, toast, useTheme } from "frappe-ui";
import { storeToRefs } from "pinia";
import { h, onMounted } from "vue";
import Wifi from "~icons/lucide/wifi";
import WifiOff from "~icons/lucide/wifi-off";
import { __ } from "./translation";
import { isCustomerPortal } from "./utils";
import { isCustomerPortal, getBrowserTimezone } from "./utils";
const configStore = useConfigStore();
const { favicon } = storeToRefs(configStore);
@@ -25,18 +25,20 @@ useFavicon(favicon);
if (!localStorage.getItem("theme")) {
localStorage.setItem("theme", "light");
}
useColorScheme();
useTheme();
onMounted(() => {
window.addEventListener("online", () => {
toast(__("You are now online."), {
icon: () => h(Wifi, { class: "text-ink-base" }),
toast.create({
message: __("You are now online."),
icon: h(Wifi, { class: "text-ink-base" }),
});
});
window.addEventListener("offline", () => {
toast(__("You are now offline."), {
icon: () => h(WifiOff, { class: "text-ink-base" }),
toast.create({
message: __("You are now offline."),
icon: h(WifiOff, { class: "text-ink-base" }),
});
});
!isCustomerPortal.value && setConfig("localTimezone", window.timezone?.user);

View File

@@ -26,13 +26,13 @@
<img
v-if="preview === 'image'"
:src="url"
class="m-auto rounded-4 border"
class="m-auto rounded border"
/>
<video
v-if="preview === 'video'"
:src="url"
controls
class="m-auto max-h-[70vh] rounded-4 border"
class="m-auto max-h-[70vh] rounded border"
/>
</template>
</Dialog>

View File

@@ -9,7 +9,7 @@
<template #suffix>
<LucideX
class="size-3.5 cursor-pointer text-ink-gray-6 transition-colors hover:text-ink-gray-9"
@click.stop.prevent="emit('remove', attachment)"
@click.stop="emit('remove', attachment)"
/>
</template>
</AttachmentItem>

View File

@@ -0,0 +1,288 @@
<template>
<Combobox v-slot="{ open: isComboboxOpen }" v-model="selectedValue" nullable>
<Popover v-model:show="showOptions">
<template #target="{ open: openPopover, togglePopover }">
<slot name="target" v-bind="{ open: openPopover, togglePopover }">
<div class="w-full -ms-0.5">
<button
class="flex w-full items-center justify-between focus:outline-none"
:class="inputClasses"
@click="
() => {
!disabled && togglePopover();
}
"
>
<div class="flex items-center truncate">
<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-ink-gray-4">
{{ placeholder || "" }}
</span>
</div>
<FeatherIcon
name="chevron-down"
class="h-4 w-4 text-ink-gray-7"
aria-hidden="true"
/>
</button>
</div>
</slot>
</template>
<template #body="{ isOpen }">
<div v-show="isOpen">
<div
class="mt-1 rounded-lg bg-surface-base py-1 text-base shadow-2xl"
>
<div class="relative px-1.5 pt-0.5">
<ComboboxInput
ref="search"
class="form-input w-full pe-6 bg-transparent"
type="text"
:value="query"
autocomplete="off"
placeholder="Search"
@change="
(e) => {
query = e.target.value;
}
"
/>
<button
class="absolute inset-y-0 end-3 top-px flex items-center"
@click="selectedValue = null"
>
<FeatherIcon name="x" class="size-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-medium text-ink-gray-4"
>
{{ 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-surface-gray-2': 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-ink-gray-5"
>
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-ink-gray-5" : "text-ink-gray-8";
});
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-2xl 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-outline-gray-1 bg-surface-gray-2 placeholder-ink-gray-4 hover:border-outline-elevation-2 hover:bg-surface-gray-3 focus:bg-surface-base focus:border-outline-gray-4 focus:shadow-sm focus:ring-0 focus-visible:ring-2 focus-visible:ring-outline-gray-3",
outline:
"border border-outline-gray-2 bg-surface-base placeholder-ink-gray-4 hover:border-outline-gray-3 hover:shadow-sm focus:bg-surface-base focus:border-outline-gray-4 focus:shadow-sm focus:ring-0 focus-visible:ring-2 focus-visible:ring-outline-gray-3",
disabled: [
"border bg-surface-sidebar placeholder-ink-gray-3",
props.variant === "outline"
? "border-outline-gray-2"
: "border-transparent",
],
}[variant];
return [
sizeClasses,
paddingClasses,
variantClasses,
textColor.value,
"transition-colors w-full",
];
});
defineExpose({ query });
</script>

View File

@@ -6,10 +6,10 @@
variant="subtle"
@update:model-value="agentStatusStore.setMyStatus"
>
<template #item-prefix="{ item }">
<template #item-prefix="{ option }">
<div
class="size-2 rounded-full flex-shrink-0"
:class="agentStatusStore.statusColor(item.value)"
:class="agentStatusStore.statusColor(option.value)"
/>
</template>
</Select>

View File

@@ -76,8 +76,7 @@ const props = defineProps({
},
});
// the untranslated key: it is lowercased straight into the API period
const currentDuration = ref("Last month");
const currentDuration = ref(__("Last month"));
const chartData = computed(() => {
const isDataFetched = resource.fetched;

View File

@@ -5,7 +5,7 @@
alt="Brand Logo"
class="h-8 w-8 shrink-0 object-cover"
/>
<HDLogo v-else class="h-8 w-8 shrink-0 rounded-4" />
<HDLogo v-else class="h-8 w-8 shrink-0 rounded" />
</template>
<script setup lang="ts">

View File

@@ -26,7 +26,7 @@
</div>
<div
@click="showCallLogDetailModal = true"
class="flex flex-col gap-2 cursor-pointer border-transparent shadow rounded-5 bg-surface-elevation-1 px-3 py-2.5 text-ink-gray-9"
class="flex flex-col gap-2 cursor-pointer border-transparent shadow rounded-md bg-surface-elevation-1 px-3 py-2.5 text-ink-gray-9"
>
<div class="flex items-center justify-between">
<div class="inline-flex gap-2 items-center text-base-medium">

View File

@@ -1,6 +1,6 @@
<template>
<div
class="flex flex-col w-full h-full rounded-5 p-4"
class="flex flex-col w-full h-full rounded-md p-4"
:class="[orientation == 'horizontal' && 'pt-3']"
>
<slot name="title">
@@ -15,7 +15,7 @@
<div class="flex items-end w-full gap-2">
<slot name="text">
<div
class="text-2xl-medium text-center text-ink-gray-8 whitespace-nowrap"
class="text-3xl-medium text-center text-ink-gray-8 whitespace-nowrap"
>
{{ text }}
</div>
@@ -33,15 +33,14 @@
<div
class="flex items-center gap-0.5 text-ink-gray-5 hover:text-ink-gray-6 cursor-pointer shrink-0"
>
<div class="flex gap-1">
<span>vs</span>
<span>{{ __(currentDuration).toLowerCase() }}</span>
<div class="rtl:flex rtl:gap-1">
<span>vs</span> <span>{{ currentDuration.toLowerCase() }}</span>
</div>
<LucideChevronDown class="size-4" />
<FeatherIcon name="chevron-down" class="size-4" />
</div>
<template #item-label="{ item }">
<div
class="data-[disabled]:cursor-not-allowed group flex w-full items-center rounded-4 px-2 text-base focus:outline-none focus:bg-surface-gray-3 data-[highlighted]:bg-surface-gray-3 data-[state=open]:bg-surface-gray-3 whitespace-nowrap text-ink-gray-7 cursor-pointer justify-between"
class="data-[disabled]:cursor-not-allowed group flex w-full items-center rounded px-2 text-base focus:outline-none focus:bg-surface-gray-3 data-[highlighted]:bg-surface-gray-3 data-[state=open]:bg-surface-gray-3 whitespace-nowrap text-ink-gray-7 cursor-pointer justify-between"
>
<span>
{{ item.label }}
@@ -49,8 +48,9 @@
</div>
</template>
<template #item-suffix="{ item }">
<LucideCheck
<FeatherIcon
v-if="item.label == __(currentDuration)"
name="check"
class="size-4"
/>
</template>
@@ -67,7 +67,7 @@
<div class="flex items-end w-full gap-2 justify-between flex-1">
<slot name="text">
<span
class="text-2xl-medium text-center text-ink-gray-8 whitespace-nowrap"
class="text-3xl-medium text-center text-ink-gray-8 whitespace-nowrap"
>
{{ text }}
</span>
@@ -91,12 +91,12 @@
<div
class="flex items-center gap-0.5 text-ink-gray-5 hover:text-ink-gray-6 cursor-pointer shrink-0"
>
vs {{ __(currentDuration).toLowerCase() }}
<LucideChevronDown class="size-4" />
vs {{ currentDuration.toLowerCase() }}
<FeatherIcon name="chevron-down" class="size-4" />
</div>
<template #item-label="{ item }">
<div
class="data-[disabled]:cursor-not-allowed group flex w-full items-center rounded-4 px-2 text-base focus:outline-none focus:bg-surface-gray-3 data-[highlighted]:bg-surface-gray-3 data-[state=open]:bg-surface-gray-3 whitespace-nowrap text-ink-gray-7 cursor-pointer justify-between"
class="data-[disabled]:cursor-not-allowed group flex w-full items-center rounded px-2 text-base focus:outline-none focus:bg-surface-gray-3 data-[highlighted]:bg-surface-gray-3 data-[state=open]:bg-surface-gray-3 whitespace-nowrap text-ink-gray-7 cursor-pointer justify-between"
>
<span>
{{ item.label }}
@@ -104,8 +104,9 @@
</div>
</template>
<template #item-suffix="{ item }">
<LucideCheck
<FeatherIcon
v-if="item.label == __(currentDuration)"
name="check"
class="size-4"
/>
</template>
@@ -116,12 +117,9 @@
</template>
<script setup lang="ts">
import LucideCheck from "~icons/lucide/check";
import LucideChevronDown from "~icons/lucide/chevron-down";
import { __ } from "@/translation";
import { EChartsOption } from "echarts";
import { Dropdown } from "frappe-ui";
import { ECharts } from "frappe-ui/experimental";
import { Dropdown, ECharts, FeatherIcon } from "frappe-ui";
import { computed, type PropType } from "vue";
const props = defineProps({
@@ -160,14 +158,27 @@ const currentDuration = computed(() => props.currentDuration);
const emit = defineEmits(["changeDuration"]);
// the emitted value is the untranslated key: it travels to the API as the
// period, so only the label goes through __()
const DURATIONS = ["Last week", "Last month", "Last 3 months"];
const durationOptions = DURATIONS.map((duration) => ({
label: __(duration),
onClick: () => {
if (currentDuration.value !== duration) emit("changeDuration", duration);
const durationOptions = [
{
label: __("Last week"),
onClick: () => {
if (currentDuration.value == __("Last week")) return;
emit("changeDuration", __("Last week"));
},
},
}));
{
label: __("Last month"),
onClick: () => {
if (currentDuration.value == __("Last month")) return;
emit("changeDuration", __("Last month"));
},
},
{
label: __("Last 3 months"),
onClick: () => {
if (currentDuration.value == __("Last 3 months")) return;
emit("changeDuration", __("Last 3 months"));
},
},
];
</script>

View File

@@ -0,0 +1,351 @@
<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-ink-gray-5 flex items-center gap-2">
<Avatar
size="md"
:label="commenter"
:image="getUser(commentedBy).user_image"
/>
<p>
<span class="font-medium text-ink-gray-8">
{{ commenter }}
</span>
<span> {{ __(" commented") }}</span>
</p>
</div>
<div class="flex items-center gap-1">
<Tooltip :text="dateFormat(creation, dateTooltipFormat)">
<span class="ps-0.5 text-sm text-ink-gray-5">
{{ timeAgo(creation) }}
</span>
</Tooltip>
<div v-if="authStore.userId === commentedBy && !editable">
<Dropdown
:placement="'right'"
:options="dropdownOptions"
@click="isConfirmingDelete = false"
>
<Button
icon="lucide-more-horizontal"
class="text-ink-gray-5"
variant="ghost"
/>
</Dropdown>
</div>
</div>
</div>
<div
:id="`comment-${name}`"
class="rounded-md bg-surface-gray-1 transition-colors px-3 py-[6px] pt-1"
@keydown.ctrl.enter.capture.stop="handleSaveComment"
@keydown.meta.enter.capture.stop="handleSaveComment"
>
<Editor
:key="editable ? 'edit' : 'view'"
v-model="_content"
:extensions="extensions"
:editable="editable"
:upload-function="(file:any) => uploadFunction(file, 'HD Ticket', ticketId)"
>
<template #default>
<EditorBubbleMenu :items="fullToolbar" />
<EditorContent
:class="[
'prose-f shrink text-p-sm transition-all duration-300 ease-in-out block w-full content',
getFontFamily(_content),
]"
/>
</template>
</Editor>
<div v-if="editable" class="flex flex-row-reverse gap-2">
<div>
<Button
:label="
isMobileView ? 'Save' : isMac ? 'Save (⌘ + ⏎)' : 'Save (Ctrl + ⏎)'
"
@click="handleSaveComment"
variant="solid"
/>
</div>
<Button label="Discard" @click="handleDiscard" />
</div>
<div
class="flex flex-wrap gap-2"
v-if="!editable && Boolean(attachments.length)"
>
<AttachmentItem
v-for="a in attachments"
:key="a.file_url"
:label="a.file_name"
:url="a.file_url"
/>
</div>
<div
class="flex items-center gap-2 mt-2"
v-if="!editable && enableCommentReactions"
>
<Popover>
<template #target="{ togglePopover }">
<button
class="flex h-full items-center justify-center rounded-full bg-surface-gray-2 px-1 py-1 text-ink-gray-6 transition hover:bg-surface-gray-3"
@click="togglePopover()"
>
<ReactionIcon class="w-4 h-4" />
</button>
</template>
<template #body>
<div
class="bg-surface-base rounded-lg shadow-lg p-2 border border-outline-gray-2"
>
<div class="grid grid-cols-6 gap-2">
<button
v-for="emoji in emojiList"
:key="emoji"
class="size-6 flex items-center justify-center rounded hover:bg-surface-gray-2 text-lg transition-colors"
@click="handleReaction(emoji)"
>
{{ emoji }}
</button>
</div>
</div>
</template>
</Popover>
<template v-for="reaction in reactionsList" :key="reaction.emoji">
<Tooltip>
<template #body>
<div
class="bg-surface-gray-10 px-2 py-1 text-center text-p-xs text-ink-base shadow-xl rounded"
>
<span v-for="(user, idx) in reaction.users" :key="user.user"
>{{ user.full_name
}}<span v-if="idx < reaction.users.length - 1">, </span></span
>
</div>
</template>
<button
class="flex items-center gap-1 px-2 py-1 rounded-full text-sm transition-colors"
:class="
reaction.current_user_reacted
? 'bg-surface-blue-2 text-ink-blue-6 hover:bg-surface-blue-3'
: 'bg-surface-gray-3 text-ink-gray-6 hover:bg-surface-gray-4'
"
v-if="reaction.count !== 0"
@click="handleReaction(reaction.emoji)"
>
<span>{{ reaction.emoji }}</span>
<span class="font-medium">{{ reaction.count }}</span>
</button>
</Tooltip>
</template>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { AttachmentItem } from "@/components";
import ReactionIcon from "@/components/icons/ReactionIcon.vue";
import { useDevice } from "@/composables";
import { useScreenSize } from "@/composables/screen";
import { useAgentStore } from "@/stores/agent";
import { useAuthStore } from "@/stores/auth";
import { useConfigStore } from "@/stores/config";
import { updateRes as updateComment } from "@/stores/knowledgeBase";
import { useUserStore } from "@/stores/user";
import { __ } from "@/translation";
import { CommentActivity } from "@/types";
import {
ConfirmDelete,
dateFormat,
dateTooltipFormat,
getFontFamily,
isContentEmpty,
timeAgo,
uploadFunction,
} from "@/utils";
import { buildEditorExtensions, fullToolbar } from "@/components/editor/config";
import {
Avatar,
Dropdown,
Popover,
Tooltip,
createResource,
toast,
} from "frappe-ui";
import { Editor, EditorBubbleMenu, EditorContent } from "frappe-ui/editor";
import { PropType, computed, onMounted, ref } from "vue";
import { useRoute } from "vue-router";
const authStore = useAuthStore();
const ticketId = useRoute().params.ticketId as string;
const props = defineProps({
activity: {
type: Object as PropType<CommentActivity>,
required: true,
},
});
const { getUser } = useUserStore();
const { enableCommentReactions } = useConfigStore();
const { name, creation, content, commenter, commentedBy, attachments } =
props.activity;
const { isMac } = useDevice();
const { isMobileView } = useScreenSize();
const isTicketMergedComment = computed(() => {
const regex = /has been merged with ticket #\d+/;
return regex.test(content);
});
const agentStore = useAgentStore();
const extensions = buildEditorExtensions({
mentions: () =>
(agentStore.dropdown ?? []).map((a: { label: string; value: string }) => ({
id: a.value,
label: a.label,
})),
});
const emit = defineEmits(["update"]);
const isConfirmingDelete = ref(false);
const editable = ref(false);
const _content = ref(content);
const emojiList = ["👍", "👎", "❤️", "🎉", "👀", "✅"];
const dropdownOptions = computed(() => [
{
label: "Edit",
onClick: () => handleEditMode(),
icon: "lucide-edit-2",
condition: () => !isTicketMergedComment.value,
},
...ConfirmDelete({
onConfirmDelete: () => deleteComment.submit(),
isConfirmingDelete,
}),
]);
// editor.commands.focus('end')
const reactions = ref<
Array<{
emoji: string;
count: number;
users: Array<{ user: string; full_name: string }>;
current_user_reacted: boolean;
}>
>([]);
const reactionsList = computed(() => reactions.value || []);
const fetchReactions = createResource({
url: "helpdesk.helpdesk.doctype.hd_ticket_comment.hd_ticket_comment.get_reactions",
makeParams: () => ({ comment: name }),
auto: true,
onSuccess(data) {
reactions.value = data || [];
},
});
const toggleReaction = createResource({
url: "helpdesk.helpdesk.doctype.hd_ticket_comment.hd_ticket_comment.toggle_reaction",
makeParams: (emoji: string) => ({ comment: name, emoji }),
onSuccess() {
fetchReactions.reload();
},
});
function handleReaction(emoji: string) {
const previousReaction = reactions.value.find(
(r) => r.current_user_reacted && r.emoji !== emoji
);
if (previousReaction) {
previousReaction.count = Math.max(0, previousReaction.count - 1);
previousReaction.current_user_reacted = false;
}
const existingReaction = reactions.value.find((r) => r.emoji === emoji);
if (existingReaction) {
if (existingReaction.current_user_reacted) {
existingReaction.count = Math.max(0, existingReaction.count - 1);
existingReaction.current_user_reacted = false;
} else {
existingReaction.count += 1;
existingReaction.current_user_reacted = true;
}
} else {
reactions.value.push({
emoji,
count: 1,
current_user_reacted: true,
users: [
{
user: authStore.userId,
full_name: getUser(authStore.userId).full_name,
},
],
});
}
toggleReaction.submit(emoji);
}
const commentBoxRef = ref(null);
const lastSavedContent = ref(content);
const commentBoxState = ref(content);
function handleEditMode() {
editable.value = true;
commentBoxState.value = _content.value;
}
function handleDiscard() {
_content.value = commentBoxState.value;
editable.value = false;
}
const deleteComment = createResource({
url: "frappe.client.delete",
makeParams: () => ({
doctype: "HD Ticket Comment",
name: name,
}),
onSuccess() {
emit("update");
toast.success(__("Comment deleted successfully."));
},
});
function handleSaveComment() {
if (lastSavedContent.value === _content.value) {
editable.value = false;
return;
}
if (isContentEmpty(_content.value)) {
toast.error(__("Comment cannot be empty."));
return;
}
updateComment.submit(
{
doctype: "HD Ticket Comment",
name: name,
fieldname: "content",
value: _content.value,
},
{
onSuccess: () => {
editable.value = false;
lastSavedContent.value = _content.value;
emit("update");
toast.success(__("Comment updated successfully."));
},
}
);
}
onMounted(() => {
commentBoxRef.value.style.width = "0px";
});
</script>

View File

@@ -5,22 +5,17 @@
:extensions="extensions"
:editable="editable"
:placeholder="placeholder"
:upload-function="
(file: any, options: any) =>
track(uploadFunction(file, doctype, ticketId, true, options))
"
:upload-function="(file:any)=>uploadFunction(file, doctype, ticketId)"
>
<template #default="{ isEmpty }">
<!-- Scroll here so selected nodes aren't clipped. -->
<div :class="editable && 'max-h-[44vh] overflow-y-auto'">
<EditorContent
:class="[
'prose-sm max-w-none',
editable && 'min-h-[7rem] mx-5 border-t py-3',
getFontFamily(newComment),
]"
/>
</div>
<EditorContent
:class="[
'prose-sm max-w-none',
editable &&
'min-h-[7rem] mx-5 max-h-[44vh] overflow-y-auto border-t py-3',
getFontFamily(newComment),
]"
/>
<!-- Attachments -->
<AttachmentList
class="my-2 ms-5"
@@ -30,19 +25,21 @@
<div v-if="editable" class="flex flex-col gap-2 border-t">
<div class="px-4">
<!-- Fixed Menu -->
<div class="flex justify-between gap-2 overflow-hidden py-2.5">
<div class="flex min-w-0 flex-1 items-center overflow-x-auto">
<div class="flex justify-between overflow-hidden py-2.5">
<div class="flex items-center overflow-x-auto w-[60%]">
<div class="inline-flex items-center gap-1.5 p-1">
<FileUploader
:doctype="doctype"
:docname="ticketId"
private
:upload-args="{
doctype: doctype,
docname: ticketId,
private: true,
}"
@success="(f) => attachments.push(f)"
>
<template #default="{ openFileSelector, uploading }">
{{ void (loading = uploading) }}
<button
class="flex rounded-4 p-1 text-ink-gray-8 transition-colors focus-within:ring-0 hover:bg-surface-gray-3"
class="flex rounded p-1 text-ink-gray-8 transition-colors focus-within:ring-0 hover:bg-surface-gray-2"
@click="openFileSelector()"
:disabled="uploading"
>
@@ -55,38 +52,34 @@
</button>
</template>
</FileUploader>
<div class="h-4 w-[2px] border-s ml-1" />
<div class="h-4 w-[2px] border-s ms-1" />
</div>
<EditorFixedMenu :items="fullToolbar" />
<EditorTableMenu />
</div>
<div class="flex shrink-0 items-center justify-end gap-x-2">
<div class="flex items-center justify-end gap-x-2 w-[40%]">
<Button
label="Discard"
@click="
() => {
newComment = '';
attachments = [];
dropUnused(null);
emit('discard');
}
"
/>
<!-- A disabled button fires no pointer events, so the span
carries the hover for the tooltip -->
<Tooltip
:text="isUploading ? __('Please wait, media is uploading') : ''"
>
<span class="inline-flex">
<Button
variant="solid"
:label="label"
:disabled="isDisabled"
:loading="loading"
@click="submitComment()"
/>
</span>
</Tooltip>
<Button
variant="solid"
:label="label"
:disabled="isDisabled"
:loading="loading"
@click="
() => {
loading = true;
submitComment();
newComment = '';
}
"
/>
</div>
</div>
</div>
@@ -95,34 +88,17 @@
</Editor>
</template>
<script setup lang="ts">
import {
FileUploader,
LoadingIndicator,
Tooltip,
createResource,
dayjs,
toast,
} from "frappe-ui";
import {
Editor,
EditorContent,
EditorFixedMenu,
EditorTableMenu,
} from "frappe-ui/editor";
import { addPendingActivity } from "@framework/ui/ActivityTimeline";
import { useOnboarding } from "@framework/ui";
import { FileUploader, LoadingIndicator, createResource } from "frappe-ui";
import { Editor, EditorContent, EditorFixedMenu } from "frappe-ui/editor";
import { useOnboarding } from "frappe-ui/frappe";
import { computed, onBeforeUnmount, onMounted, ref, watch } from "vue";
import { AttachmentList } from "@/components/";
import { buildEditorExtensions, fullToolbar } from "@/components/editor/config";
import { AttachmentIcon } from "@/components/icons/";
import { useTyping } from "@/composables/realtime";
import { useUploadTracker } from "@/composables/useUploadTracker";
import { useAgentStore } from "@/stores/agent";
import { useAuthStore } from "@/stores/auth";
import { useUserStore } from "@/stores/user";
import { __ } from "@/translation";
import { capture } from "@/telemetry";
import {
getFontFamily,
isContentEmpty,
@@ -132,11 +108,9 @@ import {
import { useStorage } from "@vueuse/core";
import { storeToRefs } from "pinia";
const { updateOnboardingStep } = useOnboarding("helpdesk") ?? {};
const { updateOnboardingStep } = useOnboarding("helpdesk");
const { agents: agentsList, dropdown } = storeToRefs(useAgentStore());
const authStore = useAuthStore();
const { isManager } = authStore;
const { getUser } = useUserStore();
const { isManager } = useAuthStore();
const props = defineProps({
ticketId: {
@@ -161,22 +135,25 @@ const props = defineProps({
},
});
const emit = defineEmits(["submit", "discard", "sending", "restore"]);
const emit = defineEmits(["submit", "discard"]);
const newComment = useStorage("commentBoxContent" + props.ticketId, null);
// Mentions as a reactive getter so the `@` list stays in sync as agents load.
const extensions = buildEditorExtensions({
mentions: () => dropdown.value ?? [],
mentions: () =>
(dropdown.value ?? []).map((a: { label: string; value: string }) => ({
id: a.value,
label: a.label,
})),
});
// Initialize typing composable
const { onUserType, cleanup } = useTyping(props.ticketId);
const attachments = ref([]);
const { isUploading, track, dropUnused } = useUploadTracker();
const isDisabled = computed(() => {
return isContentEmpty(newComment.value) || loading.value || isUploading.value;
return isContentEmpty(newComment.value) || loading.value;
});
const loading = ref(false);
@@ -189,58 +166,28 @@ async function submitComment() {
if (isContentEmpty(newComment.value)) {
return false;
}
// The keyboard shortcut reaches here without passing the disabled button
if (isUploading.value || loading.value) return false;
const content = newComment.value;
const sentAttachments = attachments.value;
const pendingRow = addPendingActivity(props.doctype, props.ticketId, {
type: "comment",
timestamp: dayjs().format("YYYY-MM-DD HH:mm:ss"),
author: {
email: getUser(authStore.userId).email,
// the users list may still be a stub with a guessed name and no avatar
fullname: authStore.userName,
image: authStore.userImage,
},
data: { name: "", content, attachments: sentAttachments },
});
// drop before clearing, or an unmount mid-send deletes what the comment carries
dropUnused(content);
newComment.value = null;
attachments.value = [];
loading.value = true;
emit("sending");
const comment = createResource({
url: "run_doc_method",
makeParams: () => ({
dt: props.doctype,
dn: props.ticketId,
method: "new_comment",
args: { content, attachments: sentAttachments },
args: {
content: newComment.value,
attachments: attachments.value,
},
}),
onSuccess: (res: { message?: string } | string) => {
// run_doc_method answers with the whole body, since it always carries `docs`
const name = typeof res === "string" ? res : res?.message;
// the real row replaces the pending one the moment it arrives; unkeyed,
// it would outlive it
name ? pendingRow.resolve(`comment:${name}`) : pendingRow.drop();
capture("comment_added");
onSuccess: () => {
if (isManager) {
updateOnboardingStep?.("comment_on_ticket");
updateOnboardingStep("comment_on_ticket");
}
emit("submit");
loading.value = false;
attachments.value = [];
newComment.value = null;
},
onError: () => {
toast.error(__("Could not add the comment"));
pendingRow.drop();
newComment.value = content;
attachments.value = sentAttachments;
loading.value = false;
emit("restore");
},
});
@@ -270,8 +217,6 @@ onMounted(() => {
onBeforeUnmount(() => {
cleanup();
// the saved draft still references what it shows, so only what it dropped goes
dropUnused(newComment.value);
if (isContentEmpty(newComment.value)) {
localStorage.removeItem("commentBoxContent" + props.ticketId);
}

View File

@@ -1,5 +1,5 @@
<template>
<div class="comm-area" resizable="true">
<div class="comm-area">
<div
class="flex justify-between gap-3 border-t px-6 md:px-5 py-4 md:py-2.5"
>
@@ -51,15 +51,10 @@
:to-emails="toEmails"
:cc-emails="ccEmails"
:bcc-emails="bccEmails"
@sending="
@submit="
() => {
showEmailBox = false;
}
"
@submit="() => emit('update')"
@restore="
() => {
showEmailBox = true;
emit('update');
}
"
@discard="
@@ -93,15 +88,10 @@
:editable="showCommentBox"
:doctype="doctype"
placeholder="@John could you please look into this?"
@sending="
@submit="
() => {
showCommentBox = false;
}
"
@submit="() => emit('update')"
@restore="
() => {
showCommentBox = true;
emit('update');
}
"
@discard="
@@ -151,14 +141,16 @@ function toggleCommentBox() {
showCommentBox.value = !showCommentBox.value;
}
// the editors emit `submit` once the write lands; reloading here too would
// fetch twice, and the guards' `false` never reaches this side anyway
function submitEmail() {
emailEditorRef.value.submitMail();
if (emailEditorRef.value.submitMail()) {
emit("update");
}
}
function submitComment() {
commentTextEditorRef.value.submitComment();
if (commentTextEditorRef.value.submitComment()) {
emit("update");
}
}
function splitIfString(str: string | string[]) {

View File

@@ -10,17 +10,20 @@
<template #default>
<EditorBubbleMenu :items="commentToolbar" />
<div
class="flex items-center overflow-x-auto rounded-t-4 border border-b-0 border-outline-gray-1 bg-surface-gray-1 px-1 py-1"
class="flex items-center overflow-x-auto rounded-t border border-b-0 border-[--surface-gray-2] px-1 py-1"
>
<div
v-if="showAttachments"
class="inline-flex items-center gap-1.5 pe-1"
>
<FileUploader private @success="addAttachment">
<FileUploader
:upload-args="{ private: true }"
@success="addAttachment"
>
<template #default="{ openFileSelector, uploading }">
{{ syncUploadingState(uploading) }}
<button
class="flex rounded-4 p-1 text-ink-gray-8 transition-colors hover:bg-surface-gray-3 disabled:opacity-40"
class="flex rounded p-1 text-ink-gray-8 transition-colors hover:bg-surface-gray-3 disabled:opacity-40"
:disabled="uploading"
@click="openFileSelector()"
>
@@ -33,10 +36,9 @@
</button>
</template>
</FileUploader>
<div class="h-4 w-[2px] border-s ml-1" />
<div class="h-4 w-[2px] border-s ms-1" />
</div>
<EditorFixedMenu :items="fullToolbar" />
<EditorTableMenu />
</div>
<EditorContent :class="editorClass" />
</template>
@@ -66,7 +68,6 @@ import {
EditorBubbleMenu,
EditorContent,
EditorFixedMenu,
EditorTableMenu,
} from "frappe-ui/editor";
import { computed, nextTick, onMounted, ref, watch } from "vue";
@@ -79,6 +80,7 @@ const props = withDefaults(
maxHeight?: string;
extensions?: any[];
showSignature?: boolean;
type?: "Saved Reply" | "Email";
showAttachments?: boolean;
uploadFn?: UploadFunction;
}>(),
@@ -88,6 +90,7 @@ const props = withDefaults(
maxHeight: "max-h-80",
extensions: () => [],
showSignature: false,
type: "Saved Reply",
showAttachments: false,
}
);
@@ -102,14 +105,25 @@ const isUploading = ref(false);
const extensions = buildEditorExtensions({ extra: props.extensions });
const contentClass = [
const savedReplyClass = [
"!prose-sm max-w-full overflow-auto py-1.5 px-3",
"rounded-b-4 border border-outline-gray-1 bg-surface-base",
"placeholder-ink-gray-4 text-ink-gray-8 -mt-0.5",
"rounded-b border border-[--surface-gray-2] bg-surface-gray-2",
"placeholder-ink-gray-4",
"hover:border-outline-elevation-2 hover:shadow-sm",
"focus:bg-surface-base focus:border-outline-gray-4 focus:shadow-sm focus:ring-0",
"focus-visible:ring-2 focus-visible:ring-outline-gray-3",
"text-ink-gray-8 transition-colors -mt-0.5",
];
const emailClass = [
"!prose-sm max-w-full overflow-auto py-1.5 px-3",
"rounded-b border border-[--surface-gray-2] bg-surface-base",
"placeholder-ink-gray-4",
"text-ink-gray-8 transition-colors -mt-0.5",
];
const editorClass = computed(() => [
...contentClass,
...(props.type === "Email" ? emailClass : savedReplyClass),
props.minHeight,
props.maxHeight,
]);

View File

@@ -1,14 +1,14 @@
<template>
<div v-if="normalActions.length" class="flex gap-2">
<!-- onClick rides along in `action`; binding it twice would run it twice -->
<Button
v-for="action in normalActions"
:key="action.label"
:label="action.label"
@click="action.onClick()"
v-bind="action"
>
<template v-if="action.icon" #prefix>
<Icon :icon="action.icon" class="h-4 w-4" />
<FeatherIcon :name="action.icon" class="h-4 w-4" />
</template>
</Button>
</div>
@@ -17,8 +17,8 @@
<Dropdown v-slot="{ open }" :options="g.action">
<Button :label="g.label">
<template #suffix>
<component
:is="open ? LucideChevronUp : LucideChevronDown"
<FeatherIcon
:name="open ? 'chevron-up' : 'chevron-down'"
class="h-4"
/>
</template>
@@ -32,9 +32,6 @@
</template>
<script setup>
import LucideChevronUp from "~icons/lucide/chevron-up";
import LucideChevronDown from "~icons/lucide/chevron-down";
import Icon from "@/components/Icon.vue";
import { Dropdown } from "frappe-ui";
import { computed } from "vue";

View File

@@ -16,7 +16,7 @@
<Button
variant="solid"
theme="red"
icon-left="lucide-trash-2"
icon-left="trash-2"
:label="__('Delete')"
:loading="isDeleting"
@click="confirmDelete"
@@ -28,7 +28,7 @@
<script setup lang="ts">
import { __ } from "@/translation";
import { Button, Checkbox, createResource, Dialog } from "frappe-ui";
import { Button, Checkbox, createListResource, Dialog } from "frappe-ui";
import { computed, ref, watch } from "vue";
const props = defineProps<{
@@ -45,18 +45,16 @@ const props = defineProps<{
const open = defineModel<boolean>({ default: false });
const resource = createResource({
url: "frappe.client.get_count",
params: {
doctype: "HD Ticket",
filters: { [props.linkField]: props.name },
},
auto: true,
const resource = createListResource({
doctype: "HD Ticket",
filters: { [props.linkField]: props.name },
fields: ["name"],
limit: 99999, // We just want the count
});
const count = computed<number>(() => {
if (resource.loading) return 0;
return resource.data ?? 0;
return resource.data?.length ?? 0;
});
const deleteLinkedTickets = ref(false);

View File

@@ -36,9 +36,9 @@ function handleDiscard() {
{
label: "Delete",
theme: "red",
iconLeft: "lucide-trash-2",
iconLeft: "trash-2",
variant: "solid",
onClick({ close }: { close: () => void }) {
onClick(close: Function) {
emit("discard");
close();
},

View File

@@ -0,0 +1,300 @@
<template>
<div
:id="`communication-${name}`"
v-bind="$attrs"
class="grow cursor-pointer bg-surface-base rounded-md text-base leading-6 transition-all duration-300 ease-in-out border border-outline-gray-2"
>
<div
class="flex items-center justify-between gap-2"
:class="isMobileView && 'items-start'"
>
<!-- email design for mobile -->
<div v-if="isMobileView" class="flex items-center gap-2 text-sm">
<div class="leading-tight">
<p>{{ sender.full_name || "Guest" }}</p>
<Tooltip :text="dateFormat(creation, dateTooltipFormat)">
<p class="text-xs md:text-sm text-ink-gray-5">
{{ timeAgo(creation) }}
</p>
</Tooltip>
<p class="sm:flex hidden text-sm text-ink-gray-5" v-if="sender.name">
{{ "<" + sender.name + ">" }}
</p>
</div>
</div>
<!-- email design for desktop -->
<div v-else class="flex items-center gap-1">
<span>{{ sender.full_name || "Guest" }}</span>
<span
class="sm:flex hidden text-sm text-ink-gray-5"
v-if="sender.name"
>{{ "<" + sender.name + ">" }}</span
>
</div>
<div class="flex gap-2 items-center">
<div class="gap-0.5 flex items-center">
<Badge
v-if="status.label && !ticket?.doc?.via_customer_portal"
:label="__(status.label)"
variant="subtle"
:theme="status.color"
class="me-1.5"
/>
<Tooltip
:text="dateFormat(creation, dateTooltipFormat)"
v-if="!isMobileView"
>
<p class="text-xs md:text-sm text-ink-gray-5">
{{ timeAgo(creation) }}
</p>
</Tooltip>
</div>
<div class="flex items-center gap-1">
<Button :tooltip="__('Reply')" variant="ghost" @click="reply">
<template #icon>
<ReplyIcon class="text-ink-gray-7" />
</template>
</Button>
<Button :tooltip="__('Reply All')" variant="ghost" @click="replyAll">
<template #icon>
<ReplyAllIcon class="text-ink-gray-7" />
</template>
</Button>
<Dropdown
v-if="showSplitOption"
:placement="'right'"
:options="[
{
label: 'Split Ticket',
icon: LucideSplit,
onClick: () => (showSplitModal = true),
},
]"
>
<Button
icon="lucide-more-horizontal"
class="!text-ink-gray-7"
variant="ghost"
/>
</Dropdown>
</div>
</div>
</div>
<!-- <div class="text-sm leading-5 text-ink-gray-5">
{{ subject }}
</div> -->
<div class="text-p-sm text-ink-gray-5">
<template
v-for="(val, label) in { To: to, cc: cc, bcc: bcc }"
:key="label"
>
<span v-if="val" class="me-1.5">
<span class="me-1 text-ink-gray-7">{{ label }}:</span>
<span> {{ normalizeAndFilter(val).join(", ") }}</span>
</span>
</template>
</div>
<div class="border-0 border-t my-3 border-outline-elevation-2 !-mx-3" />
<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 { AttachmentItem } from "@/components";
import { useScreenSize } from "@/composables/screen";
import { useAuthStore } from "@/stores/auth";
import { TicketSymbol } from "@/types";
import { dateFormat, dateTooltipFormat, timeAgo } from "@/utils";
import { Dropdown } from "frappe-ui";
import { storeToRefs } from "pinia";
import { computed, inject, ref } from "vue";
import LucideSplit from "~icons/lucide/split";
import { ReplyAllIcon, ReplyIcon } from "./icons";
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,
deliveryStatus,
} = props.activity;
const emit = defineEmits(["reply"]);
const ticket = inject(TicketSymbol)!;
const auth = storeToRefs(useAuthStore());
const { isMobileView } = useScreenSize();
const showSplitModal = ref(false);
const status = computed(() => {
let _status = deliveryStatus;
let indicator_color = "red";
if (["Sent", "Clicked"].includes(_status)) {
indicator_color = "green";
} else if (["Sending", "Scheduled"].includes(_status)) {
indicator_color = "orange";
} else if (["Opened", "Read"].includes(_status)) {
indicator_color = "blue";
} else if (_status == "Error") {
indicator_color = "red";
}
return { label: _status, color: indicator_color };
});
const normalizeAndFilter = (
field: string | string[],
valuesToExclude: string[] = []
) => {
let arr = [];
let current = "";
let inQuotes = false;
if (typeof field === "string") {
for (let char of field) {
if (char === '"') {
inQuotes = !inQuotes;
current += char;
} else if (char === "," && !inQuotes) {
arr.push(current.trim());
current = "";
} else {
current += char;
}
}
if (current) arr.push(current.trim());
} else {
arr = field || [];
}
return arr.filter(Boolean).filter((item) => !valuesToExclude.includes(item));
};
const reply = () => {
const user = auth.user.value;
emit("reply", {
content: content,
to: user === sender.name ? to : sender.name,
});
};
const replyAll = () => {
const user = auth.user.value;
const exclude = [user, sender.name];
const filteredTo = normalizeAndFilter(to, exclude);
const filteredCc = normalizeAndFilter(cc, exclude);
const filteredBcc = normalizeAndFilter(bcc, exclude);
let _to, _cc, _bcc;
if (user === sender.name) {
// User is the sender, reply to all original recipients
_to = filteredTo.join(", ");
_cc = filteredCc;
_bcc = filteredBcc;
} else {
// User is a recipient, reply to sender with all other recipients in cc
_to = sender.name;
_cc = [...filteredTo, ...filteredCc];
_bcc = filteredBcc;
}
emit("reply", {
content: content,
to: _to,
cc: _cc.filter(Boolean),
bcc: _bcc.filter(Boolean),
});
};
// 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>

View File

@@ -18,11 +18,7 @@ const props = defineProps({
});
const iframeRef = ref<HTMLIFrameElement | null>(null);
const _content = ref(props.content);
const themedContent = computed(() =>
dataTheme.value === "dark" ? stripEmailColors(_content.value) : _content.value
);
const _content = ref(stripEmailColors(props.content));
// Get CSS path - in dev Vite serves it directly, in prod we need the built path
const cssHref = computed(() => {
@@ -187,8 +183,6 @@ const htmlContent = computed(
.email-content {
word-break: break-word;
}
.email-content :is(:where(img):not(:where([class~='not-prose'], [class~='not-prose'] *))) {
border-width: 0;
}
@@ -201,11 +195,10 @@ const htmlContent = computed(
.email-content :where(blockquote p:last-of-type):not(:where([class~='not-prose'], [class~='not-prose'] *))::after {
content: none;
}
</style>
</head>
<body>
<div class="email-content prose-f">${themedContent.value}</div>
<div class="email-content prose-f">${_content.value}</div>
</body>
</html>
`

View File

@@ -5,10 +5,7 @@
:placeholder="placeholder"
:editable="editable"
:extensions="extensions"
:upload-function="
(file: any, options: any) =>
track(uploadFunction(file, doctype, ticketId, true, options))
"
:upload-function="(file:any)=>uploadFunction(file, doctype, ticketId)"
>
<template #default>
<div @keydown.capture="handleKeydown">
@@ -145,14 +142,16 @@
/>
<!-- Fixed Menu -->
<div
class="flex justify-between gap-2 overflow-scroll px-4 py-2.5 items-center border-t"
class="flex justify-between overflow-scroll px-4 py-2.5 items-center border-t"
>
<div class="flex min-w-0 flex-1 items-center overflow-x-auto">
<div class="flex items-center overflow-x-auto w-[60%]">
<div class="inline-flex items-center gap-1.5 p-1">
<FileUploader
:doctype="doctype"
:docname="ticketId"
private
:upload-args="{
doctype: doctype,
docname: ticketId,
private: true,
}"
@success="
(f) => {
attachments.push(f);
@@ -160,10 +159,10 @@
"
>
<template #default="{ openFileSelector, uploading }">
{{ void (attachmentUploading = uploading) }}
{{ void (isUploading = uploading) }}
<Tooltip :text="__('Attach file')">
<button
class="flex rounded-4 p-1 text-ink-gray-8 transition-colors focus-within:ring-0 hover:bg-surface-gray-3"
class="flex rounded p-1 text-ink-gray-8 transition-colors focus-within:ring-0 hover:bg-surface-gray-3"
@click="openFileSelector()"
:disabled="uploading"
>
@@ -179,7 +178,7 @@
</FileUploader>
<Tooltip :text="__('Saved replies')">
<button
class="flex rounded-4 p-1 text-ink-gray-8 transition-colors focus-within:ring-0 hover:bg-surface-gray-3"
class="flex rounded p-1 text-ink-gray-8 transition-colors focus-within:ring-0 hover:bg-surface-gray-3"
@click="showSavedRepliesSelectorModal = true"
>
<ZapIcon class="h-4 w-4" />
@@ -188,29 +187,20 @@
<div class="h-4 w-[2px] border-s ml-1" />
</div>
<EditorFixedMenu :items="fullToolbar" />
<EditorTableMenu />
</div>
<div class="flex shrink-0 items-center justify-end gap-x-2">
<div class="flex items-center justify-end gap-x-2 sm:mt-0 w-[40%]">
<Button label="Discard" @click="handleDiscard" />
<!-- A disabled button fires no pointer events, so the span
carries the hover for the tooltip -->
<Tooltip
:text="isUploading ? __('Please wait, media is uploading') : ''"
>
<span class="inline-flex">
<Button
variant="solid"
:disabled="isDisabled"
:loading="sendMail.loading"
:label="label"
@click="
() => {
submitMail();
}
"
/>
</span>
</Tooltip>
<Button
variant="solid"
:disabled="isDisabled"
:loading="sendMail.loading"
:label="label"
@click="
() => {
submitMail();
}
"
/>
</div>
</div>
</div>
@@ -233,10 +223,8 @@ import { AttachmentIcon } from "@/components/icons";
import SavedReplyActions from "@/components/SavedReplyActions/SavedReplyActions.vue";
import { useTyping } from "@/composables/realtime";
import { getUserEmailInfo } from "@/composables/useUserEmailInfo";
import { useUploadTracker } from "@/composables/useUploadTracker";
import { replyComposer } from "@/pages/ticket/modalStates";
import { useAuthStore } from "@/stores/auth";
import { useUserStore } from "@/stores/user";
import { __ } from "@/translation";
import { RenderedSavedReply } from "@/types";
import {
@@ -253,17 +241,10 @@ import {
LoadingIndicator,
Tooltip,
createResource,
dayjs,
toast,
} from "frappe-ui";
import {
Editor,
EditorContent,
EditorFixedMenu,
EditorTableMenu,
} from "frappe-ui/editor";
import { addPendingActivity } from "@framework/ui/ActivityTimeline";
import { useOnboarding } from "@framework/ui";
import { Editor, EditorContent, EditorFixedMenu } from "frappe-ui/editor";
import { useOnboarding } from "frappe-ui/frappe";
import {
computed,
nextTick,
@@ -310,12 +291,10 @@ const props = defineProps({
},
});
const emit = defineEmits(["submit", "discard", "sending", "restore"]);
const emit = defineEmits(["submit", "discard"]);
const { updateOnboardingStep } = useOnboarding("helpdesk") ?? {};
const authStore = useAuthStore();
const { isManager } = authStore;
const { getUser } = useUserStore();
const { updateOnboardingStep } = useOnboarding("helpdesk");
const { isManager } = useAuthStore();
const { onUserType, cleanup } = useTyping(props.ticketId);
const extensions = buildEditorExtensions();
@@ -411,13 +390,7 @@ const from = computed(() => {
const hasMultipleSenders = computed(() => (from?.value.length ?? 0) > 1);
const attachments = ref([]);
const attachmentUploading = ref(false);
const { isUploading: editorUploading, track, dropUnused } = useUploadTracker();
// The paperclip and the editor's own media buttons upload by different routes
const isUploading = computed(
() => attachmentUploading.value || editorUploading.value
);
const isUploading = ref(false);
async function removeAttachment(attachment) {
attachments.value = attachments.value.filter((a) => a !== attachment);
@@ -469,46 +442,34 @@ function replaceSavedReply(reply: RenderedSavedReply) {
focusEditorAtStart();
}
/** Set by submitMail, so the composer can be cleared before the request goes out. */
let pendingRow: ReturnType<typeof addPendingActivity> | null = null;
let sentDraft: {
content: string | null;
attachments: any[];
quoted: string | null;
quoteExpanded: boolean;
} | null = null;
const sendMail = createResource({
url: "run_doc_method",
makeParams: (params) => params,
onSuccess: (res: { message?: string } | string) => {
// run_doc_method answers with the whole body, since it always carries `docs`
const name = typeof res === "string" ? res : res?.message;
// the real row replaces the pending one the moment it arrives; unkeyed,
// it would outlive it
name ? pendingRow?.resolve(`email:${name}`) : pendingRow?.drop();
pendingRow = null;
sentDraft = null;
makeParams: () => ({
dt: props.doctype,
dn: props.ticketId,
method: "reply_via_agent",
args: {
attachments: attachments.value.map((x) => x.name),
from_email: selectedFromEmail.value,
to: toEmailsClone.value.join(","),
cc: ccEmailsClone.value?.join(","),
bcc: bccEmailsClone.value?.join(","),
message:
newEmail.value +
(quotedContentRef.value
? `<p class="reply-to-content"></p><blockquote>${quotedContentRef.value.innerHTML}</blockquote>`
: ""),
},
}),
onSuccess: () => {
savedReplyActionsRef.value?.submit();
resetState();
emit("submit");
if (isManager) {
updateOnboardingStep?.("reply_on_ticket");
updateOnboardingStep("reply_on_ticket");
}
},
onError: () => {
toast.error(__("Could not send the reply"));
pendingRow?.drop();
pendingRow = null;
if (sentDraft) {
newEmail.value = sentDraft.content;
attachments.value = sentDraft.attachments;
quotedContent.value = sentDraft.quoted;
isQuoteExpanded.value = sentDraft.quoteExpanded;
sentDraft = null;
}
emit("restore");
},
debounce: 300,
});
@@ -525,8 +486,6 @@ function submitMail() {
if (isContentEmpty(newEmail.value) && isContentEmpty(quotedContent.value)) {
return false;
}
// The keyboard shortcut reaches here without passing the disabled button
if (isUploading.value || sendMail.loading) return false;
if (
!toEmailsClone.value.length &&
!ccEmailsClone.value.length &&
@@ -538,64 +497,7 @@ function submitMail() {
return false;
}
const message =
newEmail.value +
(quotedContentRef.value
? `<p class="reply-to-content"></p><blockquote>${quotedContentRef.value.innerHTML}</blockquote>`
: "");
const sender = selectedFromEmail.value?.email_id ?? authStore.userId;
const ownEmail = getUser(authStore.userId).email;
pendingRow?.drop();
pendingRow = addPendingActivity(props.doctype, props.ticketId, {
type: "email",
timestamp: dayjs().format("YYYY-MM-DD HH:mm:ss"),
author: {
email: sender,
// the users list may still be a stub with a guessed name and no avatar
fullname: authStore.userName,
image: sender === ownEmail ? authStore.userImage : undefined,
},
data: {
name: "",
sender,
to: toEmailsClone.value.join(", "),
cc: ccEmailsClone.value?.join(", "),
bcc: bccEmailsClone.value?.join(", "),
content: message,
attachments: attachments.value.map((a) => ({
file_url: a.file_url,
file_name: a.file_name,
is_private: a.is_private,
})),
},
});
sentDraft = {
content: newEmail.value,
attachments: attachments.value,
quoted: quotedContent.value,
quoteExpanded: isQuoteExpanded.value,
};
const params = {
dt: props.doctype,
dn: props.ticketId,
method: "reply_via_agent",
args: {
attachments: attachments.value.map((x) => x.name),
from_email: selectedFromEmail.value,
to: toEmailsClone.value.join(","),
cc: ccEmailsClone.value?.join(","),
bcc: bccEmailsClone.value?.join(","),
message,
},
};
// drop before resetState clears, or an unmount mid-send deletes what it carries
dropUnused(message);
resetState();
emit("sending");
sendMail.submit(params);
sendMail.submit();
}
function getInitialContent() {
@@ -654,7 +556,6 @@ function handleDiscard() {
showBCC.value = false;
isQuoteExpanded.value = false;
dropUnused(null);
focusEditorAtStart();
emit("discard");
}
@@ -669,9 +570,6 @@ function handleSelectAll(e: KeyboardEvent) {
if (!editorDom.contains(active) && !(quotedEl && quotedEl.contains(active))) {
return;
}
// after the focus check: select-all from a recipient field must not unfold
// the quoted reply
isQuoteExpanded.value = true;
e.preventDefault();
editorContext?.commands.selectAll();
sel.removeAllRanges();
@@ -713,6 +611,7 @@ function handleKeydown(e: KeyboardEvent) {
const key = e.key.toLowerCase();
if ((e.metaKey || e.ctrlKey) && key === "a") {
isQuoteExpanded.value = true;
handleSelectAll(e);
return;
}
@@ -789,14 +688,11 @@ onMounted(() => {
onBeforeUnmount(() => {
replyComposer.value = null;
cleanup();
// the saved draft still references what it shows, so only what it dropped goes
dropUnused(`${newEmail.value ?? ""}${quotedContent.value ?? ""}`);
});
defineExpose({
addToReply,
editor,
isUploading,
submitMail,
});
</script>

View File

@@ -1,7 +1,8 @@
<template>
<div>
<div ref="pills" class="flex flex-wrap gap-1">
<div class="flex flex-wrap gap-1">
<Button
ref="emails"
v-for="value in values"
:key="value"
:label="value"
@@ -10,7 +11,7 @@
:tooltip="copyOnClick ? __('Click to copy') : undefined"
:class="[
{
'rounded-4 !bg-surface-base hover:!bg-surface-gray-1 focus-visible:ring-outline-gray-4':
'rounded !bg-surface-base hover:!bg-surface-gray-1 focus-visible:ring-outline-gray-4':
variant === 'subtle',
},
copyOnClick
@@ -21,7 +22,11 @@
@keydown.delete.capture.stop="removeLastValue"
>
<template #suffix>
<LucideX class="size-3.5" @click.stop="removeValue(value)" />
<FeatherIcon
class="h-3.5"
name="x"
@click.stop="removeValue(value)"
/>
</template>
</Button>
<div class="flex-1 min-w-32">
@@ -34,7 +39,7 @@
highlight-on-hover
>
<ComboboxAnchor
class="flex h-7 max-w-full w-auto items-center gap-2 rounded-4 px-2 py-1 border border-transparent"
class="flex h-7 max-w-full w-auto items-center gap-2 rounded px-2 py-1 border border-transparent"
:class="[
variant == 'ghost'
? 'bg-surface-base hover:bg-surface-base'
@@ -57,7 +62,7 @@
</ComboboxAnchor>
<ComboboxPortal>
<ComboboxContent
class="z-[100] mt-1 min-w-48 w-auto max-w-96 bg-surface-elevation-2 overflow-hidden rounded-6 shadow-2xl ring-1 ring-black ring-opacity-5"
class="z-10 mt-1 min-w-48 w-auto max-w-96 bg-surface-elevation-2 overflow-hidden rounded-lg shadow-2xl ring-1 ring-black ring-opacity-5"
position="popper"
:align="'start'"
@openAutoFocus.prevent
@@ -65,16 +70,16 @@
>
<ComboboxViewport class="max-h-60 overflow-auto p-1.5">
<ComboboxEmpty
class="flex gap-2 rounded-4 px-2 py-1 text-base text-ink-gray-5"
class="flex gap-2 rounded px-2 py-1 text-base text-ink-gray-5"
>
<LucideSearch class="size-4" />
<FeatherIcon name="search" class="h-4" />
{{ __(emptyPlaceholder) }}
</ComboboxEmpty>
<ComboboxItem
v-for="option in options"
:key="option.value"
:value="option.value"
class="text-base leading-none text-ink-gray-7 rounded-4 flex items-center px-2 py-1 relative select-none data-[highlighted]:outline-none data-[highlighted]:bg-surface-gray-3 cursor-pointer"
class="text-base leading-none text-ink-gray-7 rounded flex items-center px-2 py-1 relative select-none data-[highlighted]:outline-none data-[highlighted]:bg-surface-gray-3 cursor-pointer"
@mousedown.prevent="onSelect(option.value)"
>
<UserAvatar
@@ -108,8 +113,6 @@
</template>
<script setup>
import LucideSearch from "~icons/lucide/search";
import LucideX from "~icons/lucide/x";
import UserAvatar from "@/components/UserAvatar.vue";
import { useUserStore } from "@/stores/user";
import { copy } from "@/utils";
@@ -148,7 +151,7 @@ const errorMessage = (value) => __("{0} is an Invalid Email Address", [value]);
const values = defineModel();
// Common state
const pills = ref(null);
const emails = ref([]);
const search = ref(null);
const error = ref(null);
const info = ref(null);
@@ -168,7 +171,6 @@ const filterContacts = createResource({
label: full_name || email_id || name,
value: email_id || name,
email: email_id,
name,
})),
});
@@ -203,12 +205,19 @@ const options = computed(() => {
if (props.existingUsers?.length) {
list = list.filter((o) => !props.existingUsers.includes(o.value));
}
return list.filter(matchesQuery);
if (query.value) {
const q = query.value.toLowerCase();
list = list.filter(
(o) =>
o.label?.toLowerCase().includes(q) ||
o.value?.toLowerCase().includes(q)
);
}
return list;
}
// contacts mode; the search is debounced, so narrow the last results to the
// typed text, or a quick Enter picks a contact that no longer matches
let list = (filterContacts.data || []).filter(matchesQuery);
// contacts mode
let list = filterContacts.data || [];
if (values.value?.length) {
list = list.filter((o) => !values.value.includes(o.value));
}
@@ -227,13 +236,6 @@ const options = computed(() => {
return list;
});
function matchesQuery(option) {
const q = query.value.toLowerCase();
return [option.label, option.value, option.name].some((field) =>
field?.toLowerCase().includes(q)
);
}
function isExistingUser(email) {
if (!email) return false;
return props.existingUsers?.some(
@@ -308,32 +310,24 @@ function removeValue(value) {
values.value = values.value.filter((v) => v !== value);
}
// Read the pills from the DOM: a Button with a tooltip renders extra root
// nodes, so its `$el` is not the <button>.
function lastPill() {
const buttons = pills.value?.querySelectorAll(":scope > button");
return buttons?.[buttons.length - 1] ?? null;
}
function removeLastValue() {
if (query.value) return;
const pill = lastPill();
if (document.activeElement === pill) {
let emailRef = emails.value[emails.value.length - 1]?.rootRef;
if (document.activeElement === emailRef) {
values.value.pop();
nextTick(() => {
if (values.value.length) {
lastPill()?.focus();
emailRef = emails.value[emails.value.length - 1].rootRef;
emailRef?.focus();
} else {
setFocus();
}
});
} else {
pill?.focus();
emailRef?.focus();
}
}
// TODO: use single contact component. This refocus also fires when focus has
// already moved on, so a click elsewhere within 200ms is pulled back here.
function setFocus() {
setTimeout(() => {
search.value?.$el?.focus();

View File

@@ -25,7 +25,7 @@
class="flex h-full items-center justify-center absolute inset-x-0 top-0 pointer-events-none"
>
<div
class="flex flex-col items-center gap-2 text-xl-medium text-ink-gray-4 w-9/12 md:w-4/12"
class="flex flex-col items-center gap-2 text-2xl-medium text-ink-gray-4 w-9/12 md:w-4/12"
>
<!-- overlay variant (for charts) -->
<div
@@ -44,7 +44,7 @@
:class="{
'text-sm font-medium text-ink-gray-8': text === 'sm',
'text-base font-medium text-ink-gray-8': text === 'md' || !text,
'text-md font-medium text-ink-gray-8': text === 'lg',
'text-lg font-medium text-ink-gray-8': text === 'lg',
}"
>
{{ __(title) }}

View File

@@ -12,7 +12,6 @@ import { Tooltip } from "frappe-ui";
defineProps<{
label: string;
// Frappe fields carry 1 / 0, not true / false
required?: boolean | number;
required?: boolean;
}>();
</script>

View File

@@ -0,0 +1,77 @@
<template>
<div class="flex-1">
<div
class="mt-0.5 flex justify-between text-base items-start md:items-center"
>
<div
v-if="relatedActivities.length > 1"
class="inline-flex flex-wrap gap-1.5 text-ink-gray-8 font-medium w-4/5"
>
<span>{{ `${show_others ? __("Hide ") : __("Show ")}` }}</span>
<span>+{{ relatedActivities.length }} </span>
<span>{{ __("changes from") }} </span>
<span>{{ user }}</span>
<Button
class="!size-4"
variant="ghost"
@click="show_others = !show_others"
>
<template #icon>
<SelectIcon />
</template>
</Button>
</div>
<div class="text-ink-gray-5 w-4/6 text-p-base" v-else>
<span class="font-medium text-ink-gray-8">
{{ user }}
</span>
<span> {{ content }}</span>
</div>
<div class="text-ink-gray-5 text-sm w-2/6 flex justify-end">
<Tooltip :text="dateFormat(creation, dateTooltipFormat)">
<span>{{ timeAgo(creation) }}</span>
</Tooltip>
</div>
</div>
<div v-if="show_others">
<div
v-for="relatedActivity in relatedActivities"
:key="relatedActivity.creation"
class="mt-2 flex justify-between text-base"
>
<div class="text-ink-gray-5 w-4/6">
<span class="font-medium text-ink-gray-8">
{{ relatedActivity.user }}
</span>
<span> {{ relatedActivity.content }}</span>
</div>
<Tooltip
:text="dateFormat(relatedActivity.creation, dateTooltipFormat)"
>
<div class="text-ink-gray-5 text-sm w-2/6 flex justify-end">
{{ timeAgo(relatedActivity.creation) }}
</div>
</Tooltip>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { SelectIcon } from "@/components/icons";
import { dateFormat, dateTooltipFormat, timeAgo } from "@/utils";
import { computed, ref } from "vue";
const props = defineProps({
activity: {
type: Object,
required: true,
},
});
const { user, content, creation } = props.activity;
const relatedActivities = computed(() => props.activity.relatedActivities);
let show_others = ref(false);
</script>

View File

@@ -2,18 +2,20 @@
<div v-if="isEmoji(icon)" v-bind="$attrs">
{{ icon }}
</div>
<SpriteIcon
<span
v-else-if="typeof icon == 'string' && icon.startsWith('lucide-')"
:class="icon"
v-bind="$attrs"
/>
<FeatherIcon
v-else-if="typeof icon == 'string'"
:name="icon.replace('lucide-', '')"
:name="icon"
v-bind="$attrs"
/>
<component v-else :is="icon" v-bind="$attrs" />
</template>
<script setup>
import { isEmoji } from "@/utils";
// Sprite, not a `lucide-*` class: these names come from stored view icons, and
// Tailwind only emits CSS for class names it can see in source.
import { Icon as SpriteIcon } from "frappe-ui/experimental";
const props = defineProps({
icon: {

View File

@@ -21,7 +21,7 @@
</button>
<button
type="button"
class="absolute -right-2.5 -top-2.5 flex size-4.5 cursor-pointer items-center justify-center rounded-full bg-surface-base text-ink-gray-4 opacity-0 outline outline-black-overlay-50 duration-300 ease-in-out focus:outline-none focus-visible:outline-none hover:bg-surface-gray-2 group-hover:opacity-100 [@media(hover:none)]:opacity-100"
class="absolute -right-2.5 -top-2.5 flex size-4.5 cursor-pointer items-center justify-center rounded-full bg-surface-base text-ink-gray-4 opacity-0 outline outline-black-overlay-50 duration-300 ease-in-out focus:outline-none focus-visible:outline-none hover:bg-surface-gray-2 group-hover:opacity-100"
:aria-label="__('Remove image')"
@click.prevent="image = ''"
>

View File

@@ -71,8 +71,7 @@ const props = defineProps({
},
});
// the untranslated key: it is lowercased straight into the API period
const currentDuration = ref("Last month");
const currentDuration = ref(__("Last month"));
const chartData = computed(() => {
const isDataFetched = resource.fetched;

View File

@@ -57,13 +57,14 @@
</template>
<script setup>
import { Button, Dropdown } from "frappe-ui";
import {
Button,
Dropdown,
ListGroupHeader,
ListGroupRows,
ListRow,
ListRows,
} from "frappe-ui/experimental";
} from "frappe-ui";
import { computed, ref, watch } from "vue";
import IconMoreHorizontal from "~icons/lucide/more-horizontal";

View File

@@ -2,8 +2,8 @@
<!-- View Controls -->
<div
:class="[
'flex items-center justify-between gap-2 px-5 pb-4 pt-4',
list?.data?.data?.length > 0 ? 'relative' : 'absolute inset-x-0',
'flex items-center justify-between gap-2 px-5 pb-4 pt-3 ',
list?.data?.data?.length > 0 ? 'relative' : 'absolute w-[stretch]',
]"
v-if="showViewControls"
>
@@ -40,7 +40,7 @@
v-if="list.loading && !list.data?.data?.length"
class="flex items-center justify-center h-full w-full absolute top-0 z-100"
>
<LoadingIndicator class="size-6 text-ink-gray-4" />
<LoadingIndicator :scale="8" />
</div>
<!-- List View -->
<ListView
@@ -121,17 +121,7 @@
handlePageLength(count);
}
"
>
<!-- frappe-ui's ListFooter still feeds TabButtons the removed `buttons`
prop, so its own page-length picker renders nothing. -->
<template #left>
<TabButtons
:model-value="defaultParams.page_length_count"
:options="[20, 50, 100].map((o) => ({ label: String(o), value: o }))"
@update:model-value="(count) => handlePageLength(count)"
/>
</template>
</ListFooter>
/>
</div>
<!-- Empty State -->
<EmptyState
@@ -159,30 +149,27 @@ import {
} from "@/composables/useView";
import { useAuthStore } from "@/stores/auth";
import { globalStore } from "@/stores/globalStore";
import { useTicketStatusStore } from "@/stores/ticketStatus";
import { capture } from "@/telemetry";
import { __ } from "@/translation";
import { View, ViewType } from "@/types";
import { getIcon } from "@/utils";
import { formatTimeShort, getIcon } from "@/utils";
import { useStorage } from "@vueuse/core";
import { useTicketStatusStore } from "@/stores/ticketStatus";
import { __ } from "@/translation";
import {
createResource,
dayjsLocal,
Dropdown,
FeatherIcon,
frappeRequest,
LoadingIndicator,
TabButtons,
toast,
} from "frappe-ui";
import {
Icon as SpriteIcon,
ListFooter,
ListHeader,
ListHeaderItem,
ListRowItem,
ListSelectBanner,
ListView,
} from "frappe-ui/experimental";
LoadingIndicator,
dayjs,
toast,
} from "frappe-ui";
import {
computed,
h,
@@ -268,7 +255,7 @@ const defaultOptions = reactive({
label: __("Delete"),
variant: "solid",
theme: "red",
iconLeft: "lucide-trash-2",
iconLeft: "trash-2",
onClick({ close }) {
handleBulkDelete(close, selections);
},
@@ -478,7 +465,7 @@ function getGroupedByRows(listRows, groupByField) {
group: option || " ",
collapsed: false,
rows: filteredRows,
icon: h(SpriteIcon, {
icon: h(FeatherIcon, {
name: "folder",
class: "h-4 w-4 flex-shrink-0 text-ink-gray-6",
}),
@@ -561,8 +548,8 @@ function listCell(column: any, row: any, item: any, idx: number) {
}
if (column.type === "Datetime") {
return h("span", {
class: "text-base",
textContent: dayjsLocal(item).fromNow(),
class: "text-p-xs",
textContent: formatTimeShort(item),
});
}
if (column.type === "MultipleAvatar") {
@@ -601,11 +588,16 @@ function handleFieldClick(e: MouseEvent, column, row, item) {
}
if (column.type === "MultipleAvatar") {
const avatar = (e.target as HTMLElement).closest(".user-avatar");
// the gap between the faces, and the "+n" chip, name nobody to filter by
const name = avatar?.getAttribute("data-name");
if (!name) return;
applyColumnFilter(column.key, "LIKE", `%${name}%`);
if (item.length > 1) {
let target = e.target as HTMLElement;
target = target.closest(".user-avatar");
if (target) {
item = target.getAttribute("data-name");
}
} else {
item = item[0].name;
}
applyColumnFilter(column.key, "LIKE", `%${item}%`);
return;
}
applyColumnFilter(column.key, "=", item);

View File

@@ -1,5 +1,5 @@
<template>
<div class="flex flex-wrap gap-2 rounded-6 bg-surface-gray-2 p-2">
<div class="flex flex-wrap gap-2 rounded-lg bg-surface-gray-2 p-2">
<Pill
v-for="item in items"
:key="item.value"

View File

@@ -5,8 +5,7 @@
>
<div
v-if="_avatars?.length == 1"
class="user-avatar flex min-w-0 items-center gap-2 text-base line-clamp-1"
:data-name="_avatars[0].name"
class="flex min-w-0 items-center gap-2 text-base line-clamp-1"
>
<Tooltip :text="_avatars[0].name">
<Avatar
@@ -51,10 +50,8 @@ import { Avatar, Tooltip } from "frappe-ui";
import { computed } from "vue";
const props = defineProps({
// Frappe hands `_assign` over as a JSON string; callers with the list
// already parsed pass the array itself.
avatars: {
type: [String, Array],
type: String,
},
size: {
type: String,

View File

@@ -0,0 +1,60 @@
<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>

View File

@@ -15,11 +15,11 @@
]"
>
<div class="flex gap-2 items-center">
<p class="text-ink-gray-8 text-xl-medium">
<p class="text-ink-gray-8 text-2xl-medium">
{{ avatar.label }}
</p>
<Tooltip v-if="badge" :text="badge.tooltip ?? ''">
<Badge :label="badge.label" :theme="badge.theme ?? 'amber'" />
<Badge :label="badge.label" :theme="badge.theme ?? 'orange'" />
</Tooltip>
</div>
<div v-if="!isMobileView" class="flex items-center gap-x-1.5">
@@ -69,7 +69,7 @@ interface DocInfoItem {
interface BadgeInfo {
label: string;
theme?: "gray" | "blue" | "green" | "amber" | "red";
theme?: "gray" | "blue" | "green" | "orange" | "red";
tooltip?: string;
}

View File

@@ -2,7 +2,7 @@
<header class="border-b px-5 py-2.5">
<div class="flex items-center justify-between">
<slot name="title">
<div v-if="title" class="text-md-medium text-ink-gray-9">
<div v-if="title" class="text-lg-medium text-ink-gray-9">
{{ title }}
</div>
</slot>

View File

@@ -10,10 +10,10 @@
<slot name="prefix" />
</template>
<template #suffix>
<Tooltip bare>
<template #content>
<Tooltip>
<template #body>
<div
class="rounded-4 bg-surface-gray-10 py-1.5 px-2 text-xs text-ink-base shadow-xl"
class="rounded bg-surface-gray-10 py-1.5 px-2 text-xs text-ink-base shadow-xl"
>
<span class="flex items-center gap-1">
{{ show ? "Hide Password" : "Show Password" }}

View File

@@ -38,6 +38,6 @@ const handleClick = (label) => {
};
defineExpose({
rootRef: computed(() => buttonRef.value?.$el),
rootRef: computed(() => buttonRef.value?.rootRef),
});
</script>

View File

@@ -8,7 +8,7 @@
v-if="current > 0"
variant="ghost"
icon="lucide-chevron-left"
class="!size-7 shrink-0 !rounded-5 absolute -left-11 mt-4"
class="!size-7 shrink-0 !rounded-md absolute -left-11 mt-4"
@click="back"
/>
<div
@@ -16,7 +16,7 @@
class="mx-0 min-w-0 border-0 p-0 flex gap-5 flex-col"
>
<div>
<p class="p-0 text-p-xl font-bold text-ink-gray-9">
<p class="p-0 text-p-2xl font-bold text-ink-gray-9">
{{ question.title
}}<span v-if="titleRequired" class="ms-0.5 text-ink-red-6">*</span>
</p>
@@ -81,7 +81,7 @@
:label="option.label"
:variant="isSelected(option) ? 'subtle' : 'outline'"
size="sm"
class="!rounded-5 border border-solid"
class="!rounded-md border border-solid"
:class="
isSelected(option)
? '!bg-surface-gray-3 hover:!bg-surface-gray-4 !border-outline-gray-3'
@@ -247,7 +247,7 @@ function select(option: Option) {
if (!isOtherSelected.value) {
delete answers[otherKey.value];
} else if (option.value === "other") {
nextTick(() => otherInput.value?.focus({ preventScroll: true }));
nextTick(() => otherInput.value?.el?.focus({ preventScroll: true }));
}
}
@@ -264,7 +264,7 @@ function proceed() {
// "Other" stays selectable with Next enabled; the ask happens on click.
if (isOtherSelected.value && !isOtherFilled.value) {
otherError.value = __("Add a few words so we can continue");
otherInput.value?.focus({ preventScroll: true });
otherInput.value?.el?.focus({ preventScroll: true });
return;
}
if (isLast.value) finish();

View File

@@ -3,7 +3,7 @@
<template #default>
<div class="max-h-[575px]" :style="{ height: 'calc(100vh - 8rem)' }">
<div class="flex items-center justify-between w-full p-4 pb-2">
<div class="text-2xl-semibold">{{ __("Saved Replies") }}</div>
<div class="text-3xl-semibold">{{ __("Saved Replies") }}</div>
<Button
icon-left="lucide-plus"
:label="__('New')"
@@ -35,7 +35,7 @@
class="absolute end-1 top-1/2 -translate-y-1/2"
/>
</div>
<Dropdown :options="filters" align="end">
<Dropdown :options="filters" placement="right">
<Button :label="activeFilterLabel">
<template #prefix><FilterIcon class="h-4" /></template>
</Button>
@@ -59,7 +59,7 @@
<div
v-for="template in savedReplyListResource?.data"
:key="template.name"
class="flex h-56 cursor-pointer flex-col gap-2 rounded-6 border border-outline-gray-1 bg-surface-base p-3 hover:border-outline-gray-3 relative"
class="flex h-56 cursor-pointer flex-col gap-2 rounded-lg border border-outline-gray-1 bg-surface-base p-3 hover:border-outline-gray-3 relative"
@click="onTemplateSelect(template)"
>
<div class="flex items-center gap-2 border-b pb-2">
@@ -99,7 +99,7 @@
selectedTemplate.name === template.name &&
selectedTemplate.isLoading
"
class="flex items-center justify-center absolute top-0 start-0 w-full h-full rounded-6"
class="flex items-center justify-center absolute top-0 start-0 w-full h-full rounded-lg"
>
<LoadingIndicator class="size-4" />
</div>
@@ -366,7 +366,10 @@ watch(
}
// Counts don't move with the selected scope, so this is the only refetch
scopeCounts.reload();
nextTick(() => searchInput.value?.focus());
nextTick(() => {
const inputEl = searchInput.value?.$el?.querySelector("input");
inputEl?.focus();
});
},
{ immediate: true }
);

View File

@@ -1,11 +1,12 @@
<template>
<component
:is="config.doctype ? Link : Combobox"
v-bind="controlProps"
<Combobox
trigger="button"
:disabled="!isEditable"
:model-value="action.value"
:options="pickerOptions"
:placeholder="__('Select {0}', label.toLowerCase())"
@update:model-value="pick(($event ?? '') as string)"
@update:model-value="pick($event as string)"
@update:query="search(action.action_type, $event)"
>
<template #trigger="{ setOpen }">
<!-- The anchor forwards its click to this element, so it has to be a plain
@@ -43,7 +44,7 @@
<button
type="button"
:aria-label="__('Remove {0}', label)"
class="flex items-center rounded-1 text-ink-gray-6 transition-colors hover:text-ink-gray-9 focus-visible:ring-2 focus-visible:ring-outline-gray-3 mt-[1px]"
class="flex items-center rounded-sm text-ink-gray-6 transition-colors hover:text-ink-gray-9 focus-visible:ring-2 focus-visible:ring-outline-gray-3 mt-[1px]"
@click.stop="emit('remove')"
@pointerdown.stop
>
@@ -54,13 +55,12 @@
</Tooltip>
</div>
</template>
</component>
</Combobox>
</template>
<script setup lang="ts">
import { ACTION_TYPES } from "@/components/Settings/SavedReplies/components/actionTypes";
import { useSavedReplyActionOptions } from "@/composables/useSavedReplyActionOptions";
import { Link } from "@framework/ui";
import { __ } from "@/translation";
import { SavedReplyAction } from "@/types";
import { Badge, Combobox, Tooltip } from "frappe-ui";
@@ -78,19 +78,17 @@ const emit = defineEmits<{
remove: [];
}>();
const { valueOptions, linkFilters } = useSavedReplyActionOptions();
const { valueOptions, search } = useSavedReplyActionOptions();
const config = computed(() => ACTION_TYPES[props.action.action_type]);
const label = computed(() => config.value.chipLabel);
// Empty for no-value actions like "Assign to Me"; the noun then stands alone
const value = computed(() => props.action.label || props.action.value);
// A tag chip holds one tag, so it picks like the rest. Excluded rather than
// listed, so a new control type is editable by default instead of silently
// read-only: no-value actions have nothing to pick, and a comment is too long
// for a chip.
const isEditable = computed(
() => !["none", "editor"].includes(config.value.control)
// A tag chip holds one tag, so it picks like the rest; no-value actions have
// nothing to pick
const isEditable = computed(() =>
["select", "combobox", "multiselect"].includes(config.value.control)
);
// Combobox takes string values; the shared options allow numbers too
@@ -103,26 +101,8 @@ const pickerOptions = computed(() =>
}))
);
// A #trigger slot puts Combobox in button mode, and Link forwards that slot,
// so the badge below serves both controls.
const controlProps = computed(() =>
config.value.doctype
? {
doctype: config.value.doctype,
filters: linkFilters(props.action.action_type),
title: value.value,
}
: { options: pickerOptions.value }
);
/** `label` carries the display name (an agent's, not their id), so both move. */
function pick(picked: string) {
// A link picker offers no option list to read a label from; for these
// doctypes the record name is the label.
if (config.value.doctype) {
emit("update", { ...props.action, value: picked, label: picked });
return;
}
const option = pickerOptions.value.find(
(candidate) => candidate.value === picked
);

View File

@@ -75,6 +75,10 @@ const isEdited = computed(
// Same editor the Comment tab uses: rich text with @-mentions
const { dropdown: agentDropdown } = storeToRefs(useAgentStore());
const extensions = buildEditorExtensions({
mentions: () => agentDropdown.value ?? [],
mentions: () =>
(agentDropdown.value ?? []).map((a: { label: string; value: string }) => ({
id: a.value,
label: a.label,
})),
});
</script>

View File

@@ -2,7 +2,7 @@
<div
v-if="pendingActions.length"
ref="container"
class="overflow-hidden rounded-6 border border-outline-gray-1 bg-surface-gray-1"
class="overflow-hidden rounded-lg border border-outline-gray-1 bg-surface-gray-1"
>
<div class="flex h-8 items-center gap-1.5 ps-3.5 pe-1.5">
<LucideInfo class="size-3 shrink-0 text-ink-gray-6" />
@@ -67,7 +67,7 @@
<script setup lang="ts">
import { isTagAction } from "@/components/Settings/SavedReplies/components/actionTypes";
import { reloadTicket, reloadTicketFeed } from "@/composables/useTicket";
import { reloadTicket } from "@/composables/useTicket";
import { userStorage } from "@/composables/userStorage";
import { __ } from "@/translation";
import { RenderedSavedReply, SavedReplyAction } from "@/types";
@@ -194,11 +194,6 @@ function setNoteValue(value: string) {
if (noteAction.value) noteAction.value.value = value;
}
function reloadFeed() {
reloadTicket(props.ticketId);
reloadTicketFeed(props.ticketId);
}
const applyActions = createResource({
url: "helpdesk.api.saved_replies.apply_saved_reply_actions",
onSuccess: (result: {
@@ -219,7 +214,7 @@ const applyActions = createResource({
);
}
pendingActions.value = [];
reloadFeed();
reloadTicket(props.ticketId);
},
onError: (error: { status?: number }) => {
const failed = [...pendingActions.value];
@@ -233,7 +228,7 @@ const applyActions = createResource({
? { action: { label: __("Retry"), onClick: () => retry(failed) } }
: { description: __("Please apply the actions manually") }),
});
reloadFeed();
reloadTicket(props.ticketId);
},
});

View File

@@ -1,7 +1,7 @@
<template>
<div
v-if="Boolean(articles.data?.length) && query.length > 2"
class="rounded-4 border p-4 text-base"
class="rounded border p-4 text-base"
>
<div class="mb-2 font-medium ps-2" v-if="!hideViewAll">
These articles may already cover what you are looking for
@@ -22,7 +22,7 @@
<div
v-for="a in articles.data"
:key="a.id"
class="rounded-5 border-2 p-2 border-hidden hover:bg-surface-gray-2"
class="rounded-md border-2 p-2 border-hidden hover:bg-surface-gray-2"
>
<RouterLink
class="group cursor-pointer hover:text-ink-gray-9 flex flex-col gap-1"
@@ -50,7 +50,7 @@
v-else-if="
!articles.loading && articles.data?.length === 0 && query.length > 2
"
class="flex flex-col items-center justify-center h-[240px] gap-2 rounded-4 border"
class="flex flex-col items-center justify-center h-[240px] gap-2 rounded border"
>
<LucideSearch class="size-8 text-ink-gray-3" />
<div class="flex items-center flex-col justify-center">
@@ -62,7 +62,7 @@
</div>
<div
v-else-if="articles.loading"
class="flex flex-col items-center justify-center h-[240px] gap-2 rounded-4 border"
class="flex flex-col items-center justify-center h-[240px] gap-2 rounded border"
>
<LucideSearch class="size-8 text-ink-gray-3" />
<div class="flex items-center flex-col justify-center">
@@ -99,9 +99,7 @@ watch(
},
});
articles.reload();
},
// Mounted after the third character is typed.
{ immediate: true }
}
);
function handleSearchArticleClick(article) {

View File

@@ -0,0 +1,101 @@
<template>
<Autocomplete
placeholder="Select an option"
:options="options"
:value="selection"
@update:query="(q) => onUpdateQuery(q)"
@change="
(v) => {
if (!resetInput) {
selection = v;
}
emit('change', v);
}
"
/>
</template>
<script setup lang="ts">
import { Autocomplete } from "@/components";
import { createListResource } from "frappe-ui";
import { computed, ref } from "vue";
const emit = defineEmits(["change"]);
const props = defineProps({
value: {
type: String,
required: false,
default: "",
},
doctype: {
type: String,
required: true,
},
searchField: {
type: String,
required: false,
default: "name",
},
labelField: {
type: String,
required: false,
default: "name",
},
valueField: {
type: String,
required: false,
default: "name",
},
pageLength: {
type: Number,
required: false,
default: 100,
},
resetInput: {
type: Boolean,
required: false,
default: false,
},
customFilters: {
type: Object,
required: false,
default: {},
},
});
const r = createListResource({
doctype: props.doctype,
pageLength: props.pageLength,
auto: true,
fields: [props.labelField, props.searchField, props.valueField],
filters: {
[props.searchField]: ["like", `%${props.value}%`],
...props.customFilters,
},
onSuccess: () => {
selection.value = props.value
? options.value.find((o) => o.value === props.value)
: null;
},
});
const options = computed(
() =>
r.data?.map((result) => ({
label: result[props.labelField],
value: result[props.valueField],
})) || []
);
const selection = ref(null);
function onUpdateQuery(query: string) {
r.update({
filters: {
[props.searchField]: ["like", `%${query}%`],
...props.customFilters,
},
});
r.reload();
}
</script>

View File

@@ -50,7 +50,7 @@
<div
v-if="isOpen"
class="absolute z-50 mt-2 w-64 divide-y divide-outline-elevation-2 rounded-6 bg-surface-elevation-2 shadow-2xl ring-1 ring-black ring-opacity-5 focus:outline-none start-0 origin-top-left"
class="absolute z-50 mt-2 w-64 divide-y divide-outline-elevation-2 rounded-lg bg-surface-elevation-2 shadow-2xl ring-1 ring-black ring-opacity-5 focus:outline-none start-0 origin-top-left"
>
<!-- Header -->
<div class="py-1.5 px-1.5">
@@ -85,13 +85,13 @@
<button
v-for="option in filteredIndividualOptions"
:key="`individual-${option.value}`"
class="group flex h-7 w-full items-center rounded-4 px-2 text-base hover:bg-surface-gray-3 text-ink-gray-6"
class="group flex h-7 w-full items-center rounded px-2 text-base hover:bg-surface-gray-3 text-ink-gray-6"
:class="{ 'bg-surface-gray-2': isHighlighted(option) }"
@click="toggleOption(option)"
>
<Checkbox
:modelValue="props.modelValue.includes(option.value)"
class="me-4 flex-shrink-0"
class="me-2 flex-shrink-0"
/>
<component v-if="option.icon" :is="renderIcon(option.icon)" />
@@ -130,13 +130,13 @@
<button
v-for="option in group.items"
:key="`grouped-${option.value}`"
class="group flex h-7 w-full items-center rounded-4 px-2 text-base hover:bg-surface-gray-3 text-ink-gray-6"
class="group flex h-7 w-full items-center rounded px-2 text-base hover:bg-surface-gray-3 text-ink-gray-6"
:class="{ 'bg-surface-gray-2': isHighlighted(option) }"
@click="toggleOption(option)"
>
<Checkbox
:modelValue="props.modelValue.includes(option.value)"
class="me-4 flex-shrink-0"
class="me-2 flex-shrink-0"
/>
<component v-if="option.icon" :is="renderIcon(option.icon)" />

View File

@@ -1,41 +1,35 @@
<template>
<Popover>
<template #trigger="{ close, setOpen }">
<!--
Typing opens this, not clicking. reka turns the trigger's root into the
toggle, so the field stops its own click before it reaches that root.
-->
<div>
<div class="flex flex-col gap-1 w-full" @click.stop>
<slot name="label"></slot>
<FormControl
type="text"
class="w-full focus:outline-none outline-none border-inherit shadow-none"
v-bind="$attrs"
v-model="query"
@update:model-value="
(e: string) => {
if (e.length >= 3) {
setOpen(true);
} else {
close();
}
<Popover
:popover-class="popoverClass.length > 0 ? popoverClass : ''"
class="flex w-full"
>
<template #target="{ open, close }">
<div class="flex flex-col gap-1 w-full">
<slot name="label"></slot>
<FormControl
type="text"
class="w-full focus:outline-none outline-none border-inherit shadow-none"
v-bind="$attrs"
v-model="query"
@update:model-value="
(e: string) => {
if (e.length >= 3) {
open();
} else {
close();
}
"
>
<template #prefix>
<LucideSearch class="size-4 text-ink-gray-4" />
</template>
</FormControl>
</div>
}
"
>
<template #prefix>
<LucideSearch class="size-4 text-ink-gray-4" />
</template>
</FormControl>
</div>
</template>
<template #default>
<template #body-main>
<!-- Searched Articles -->
<div
class="max-h-[320px] md:max-h-[420px] overflow-scroll flex flex-col"
:class="popoverClass"
>
<div class="max-h-[320px] md:max-h-[420px] overflow-scroll flex flex-col">
<SearchArticles
:query="query"
:hideViewAll="true"

View File

@@ -1,12 +1,9 @@
<template>
<Popover
bare
:side="splitPlacement(props.placement).side"
:align="splitPlacement(props.placement).align"
>
<template #trigger>
<Popover :placement="props.placement">
<template #target="{ togglePopover }">
<Button
class="flex items-center justify-between min-w-36"
@click="togglePopover()"
:class="targetClass"
icon-right="lucide-chevron-down"
>
@@ -17,27 +14,31 @@
</div>
</Button>
</template>
<template #default="{ close: closePopover }">
<template #body="{ togglePopover }">
<div
class="mt-1 p-1 text-ink-gray-6 w-[--reka-popper-anchor-width] bg-surface-base shadow-2xl rounded-4"
class="p-1 text-ink-gray-6 top-1 absolute w-[--reka-popper-anchor-width] bg-surface-base shadow-2xl rounded"
:class="bodyClass"
>
<div class="max-h-52 overflow-y-auto">
<div
v-for="option in options"
:key="option.value"
class="p-2 cursor-pointer hover:bg-surface-gray-3 text-base flex items-center justify-between rounded-4"
class="p-2 cursor-pointer hover:bg-surface-gray-3 text-base flex items-center justify-between rounded"
@click="
() => {
onChange(option.value);
closePopover();
togglePopover();
}
"
>
<div class="w-full truncate">
{{ option.label }}
</div>
<LucideCheck v-if="model == option.value" class="size-4 ms-2" />
<FeatherIcon
v-if="model == option.value"
name="check"
class="size-4 ms-2"
/>
</div>
</div>
<hr class="my-1" />
@@ -46,7 +47,7 @@
:label="__('Reset')"
icon-left="lucide-refresh-ccw"
class="w-full focus-visible:ring-0"
@click="onReset(closePopover)"
@click="onReset(togglePopover)"
/>
</div>
</template>
@@ -54,9 +55,7 @@
</template>
<script setup lang="ts">
import { splitPlacement } from "@/utils";
import LucideCheck from "~icons/lucide/check";
import { Button, Popover } from "frappe-ui";
import { Button, FeatherIcon, Popover } from "frappe-ui";
const model = defineModel();
@@ -73,9 +72,9 @@ const props = withDefaults(defineProps<Props>(), {
defaultValue: undefined,
});
const onReset = (closePopover: () => void) => {
const onReset = (togglePopover: () => void) => {
model.value = props.defaultValue !== undefined ? props.defaultValue : null;
closePopover();
togglePopover();
};
const onChange = (value: string) => {

View File

@@ -38,12 +38,12 @@
class="absolute end-1 top-1/2 -translate-y-1/2"
/>
</div>
<Dropdown :options="dropdownOptions" align="end">
<Dropdown :options="dropdownOptions" placement="right">
<template #default="{ open }">
<Button :label="activeFilter">
<template #suffix>
<component
:is="open ? LucideChevronUp : LucideChevronDown"
<FeatherIcon
:name="open ? 'chevron-up' : 'chevron-down'"
class="h-4"
/>
</template>
@@ -51,15 +51,16 @@
</template>
<template #item-label="{ item }">
<button
class="group flex text-ink-gray-6 gap-4 w-full justify-between items-center rounded-4 text-base"
class="group flex text-ink-gray-6 gap-4 w-full justify-between items-center rounded text-base"
@click="item.onClick"
>
<div class="flex items-center justify-between flex-1">
<span class="whitespace-nowrap">
{{ item.label }}
</span>
<LucideCheck
<FeatherIcon
v-if="activeFilter === item.label"
name="check"
class="size-4 text-ink-gray-7"
/>
</div>
@@ -79,7 +80,7 @@
:loading="agents.loading"
variant="ghost"
class="w-full"
size="lg"
size="2xl"
/>
</div>
<!-- Empty State -->
@@ -106,7 +107,7 @@
</div>
<hr class="mt-2" />
<div v-for="(agent, index) in agents.data" :key="agent.agent_name">
<div class="flex items-center justify-between h-14 group rounded-4">
<div class="flex items-center justify-between h-14 group rounded">
<div class="flex items-center gap-x-3 grow">
<Avatar
:image="agent.user_image"
@@ -138,17 +139,22 @@
:label="getUserRole(agent.name)"
:button="{
label: getUserRole(agent.name),
iconRight: 'lucide-chevron-down',
iconRight: 'chevron-down',
iconLeft:
getUserRole(agent.name) === 'Agent'
? 'lucide-user'
? 'user'
: getUserRole(agent.name) === 'Manager'
? 'lucide-briefcase'
? 'briefcase'
: null,
}"
align="end"
placement="right"
/>
<Dropdown :options="getOptions(agent)" :key="agent" align="end">
<Dropdown
:options="getOptions(agent)"
:key="agent"
class="ms-2"
placement="right"
>
<Button icon="lucide-more-horizontal" variant="ghost" />
</Dropdown>
</div>
@@ -173,16 +179,15 @@
</template>
<script setup lang="ts">
import LucideChevronUp from "~icons/lucide/chevron-up";
import LucideChevronDown from "~icons/lucide/chevron-down";
import LucideCheck from "~icons/lucide/check";
import EmptyState from "@/components/EmptyState.vue";
import SettingsLayoutBase from "@/components/layouts/SettingsLayoutBase.vue";
import { useAuthStore } from "@/stores/auth";
import { useUserStore } from "@/stores/user";
import { __ } from "@/translation";
import { Avatar, Button, call, Dropdown, toast } from "frappe-ui";
import { renderOptionIcon } from "@/utils";
import { Avatar, Button, call, Dropdown, FeatherIcon, toast } from "frappe-ui";
import { h, onUnmounted } from "vue";
import LucideCheck from "~icons/lucide/check";
import AgentIcon from "../icons/AgentIcon.vue";
import { activeFilter, useAgents } from "./agents";
import { setActiveSettingsTab } from "./settingsModal";
@@ -196,20 +201,65 @@ const agents = agentStore.agents;
function getRoles(agent: string) {
const agentRole = getUserRole(agent);
const role = (label: string, icon: string) => ({
label,
icon,
selected: agentRole === label,
onClick: () => updateRole(agent, label),
});
const roles = [role("Agent", "lucide-user")];
const roles = [
{
label: "Agent",
component: (props) =>
RoleOption({
role: "Agent",
active: props.active,
selected: agentRole === "Agent",
icon: "lucide-user",
onClick: () => {
updateRole(agent, "Agent");
},
}),
},
];
if (isManager) {
roles.unshift(role("Manager", "lucide-briefcase"));
roles.unshift({
label: "Manager",
component: (props) =>
RoleOption({
role: "Manager",
active: props.active,
selected: agentRole === "Manager",
icon: "lucide-briefcase",
onClick: () => {
updateRole(agent, "Manager");
},
}),
});
}
return roles;
}
function RoleOption({ active, role, onClick, selected, icon = null }) {
return h(
"button",
{
class: [
active ? "bg-surface-gray-2" : "text-ink-gray-7",
"group flex w-full text-ink-gray-8 justify-between items-center rounded-md px-2 py-2 text-sm hover:bg-surface-gray-3",
],
onClick: !selected ? onClick : null,
},
[
h("div", { class: "flex gap-2" }, [
renderOptionIcon(icon),
h("span", { class: "whitespace-nowrap" }, role),
]),
selected
? h(LucideCheck, {
class: ["h-4 w-4 shrink-0 text-ink-gray-7"],
"aria-hidden": true,
})
: null,
]
);
}
function updateRole(agent: string, newRole: string) {
const currentRole = getUserRole(agent);
if (currentRole === newRole) {

View File

@@ -1,7 +1,7 @@
<template>
<div>
<div class="flex flex-col gap-1">
<span class="text-md-semibold text-ink-gray-8">{{
<span class="text-lg-semibold text-ink-gray-8">{{
__("Assignee Rules")
}}</span>
<span class="text-p-sm text-ink-gray-6">
@@ -24,10 +24,11 @@
</div>
</div>
<div>
<Popover bare side="bottom" align="end">
<template #trigger>
<Popover placement="bottom-end">
<template #target="{ togglePopover }">
<div
class="flex items-center justify-between text-base rounded-4 h-7 py-1.5 ps-2 pe-2 border border-[--surface-gray-2] bg-surface-gray-2 placeholder-ink-gray-4 hover:border-outline-elevation-2 hover:bg-surface-gray-3 focus:bg-surface-base focus:border-outline-gray-4 focus:shadow-sm focus:ring-0 focus-visible:ring-2 focus-visible:ring-outline-gray-3 text-ink-gray-8 transition-colors w-full dark:[color-scheme:dark] select-none min-w-44"
class="flex items-center justify-between text-base rounded h-7 py-1.5 ps-2 pe-2 border border-[--surface-gray-2] bg-surface-gray-2 placeholder-ink-gray-4 hover:border-outline-elevation-2 hover:bg-surface-gray-3 focus:bg-surface-base focus:border-outline-gray-4 focus:shadow-sm focus:ring-0 focus-visible:ring-2 focus-visible:ring-outline-gray-3 text-ink-gray-8 transition-colors w-full dark:[color-scheme:dark] select-none min-w-44"
@click="togglePopover()"
>
<div>
{{
@@ -36,29 +37,30 @@
)?.label
}}
</div>
<LucideChevronDown class="size-4" />
<FeatherIcon name="chevron-down" class="size-4" />
</div>
</template>
<template #default="{ close: closePopover }">
<template #body="{ togglePopover }">
<div
class="p-1 text-ink-gray-7 mt-1 bg-surface-base shadow-xl rounded-4 w-[--reka-popper-anchor-width]"
class="p-1 text-ink-gray-7 mt-1 bg-surface-base shadow-xl rounded w-[--reka-popper-anchor-width]"
>
<div
v-for="option in ticketRoutingOptions"
:key="option.value"
class="p-2 cursor-pointer hover:bg-surface-gray-3 text-sm flex items-center justify-between rounded-4"
class="p-2 cursor-pointer hover:bg-surface-gray-3 text-sm flex items-center justify-between rounded"
@click="
() => {
assignmentRuleData.rule = option.value;
closePopover();
togglePopover();
}
"
>
<span>
{{ option.label }}
</span>
<LucideCheck
<FeatherIcon
v-if="assignmentRuleData.rule == option.value"
name="check"
class="size-4"
/>
</div>
@@ -79,56 +81,48 @@
<AssigneeSearch @addAssignee="validateAssignmentRule('users')" />
</div>
<div class="mt-4 flex flex-wrap gap-2">
<Button
<div
v-for="user in users"
:key="user.name"
variant="outline"
size="sm"
:label="user.full_name"
class="flex items-center gap-2 text-sm bg-surface-gray-2 rounded-md p-1 w-max px-2 select-none"
>
<template #prefix>
<Avatar :image="user.user_image" :label="user.full_name" size="sm" />
</template>
<template #suffix>
<Tooltip
v-if="user.email == assignmentRuleData.lastUser"
:text="__('Last user assigned by this rule')"
:hover-delay="350"
side="top"
<Avatar :image="user.user_image" :label="user.full_name" size="sm" />
<div class="text-ink-gray-7">
{{ user.full_name }}
</div>
<Tooltip
v-if="user.email == assignmentRuleData.lastUser"
:text="__('Last user assigned by this rule')"
:hover-delay="0.35"
:placement="'top'"
>
<div
class="text-xs rounded-full select-none bg-surface-blue-3 text-ink-base p-0.5 px-2"
>
<Badge theme="blue" variant="solid" :label="__('Last')" />
</Tooltip>
<LucideX
class="size-4 text-ink-gray-4 transition-colors hover:text-ink-gray-7"
@click.stop="removeAssignedUser(user)"
/>
</template>
</Button>
{{ __("Last") }}
</div>
</Tooltip>
<Button
variant="ghost"
icon="lucide-x"
@click="removeAssignedUser(user)"
/>
</div>
</div>
<ErrorMessage :message="assignmentRulesErrors.users" />
</div>
</template>
<script setup lang="ts">
import LucideCheck from "~icons/lucide/check";
import LucideChevronDown from "~icons/lucide/chevron-down";
import { Avatar, Button, ErrorMessage, Popover, Tooltip } from "frappe-ui";
import {
assignmentRuleData,
assignmentRulesErrors,
validateAssignmentRule,
} from "@/stores/assignmentRules";
import { useUserStore } from "@/stores/user";
import {
Avatar,
Badge,
Button,
ErrorMessage,
Popover,
Tooltip,
} from "frappe-ui";
import LucideX from "~icons/lucide/x";
import { computed } from "vue";
import AssigneeSearch from "./AssigneeSearch.vue";
import { computed } from "vue";
import { useUserStore } from "@/stores/user";
const { getUser } = useUserStore();

View File

@@ -1,17 +1,18 @@
<template>
<Combobox :multiple="true">
<Popover bare side="bottom" align="end">
<template #trigger>
<Popover placement="bottom-end">
<template #target="{ togglePopover }">
<Button
variant="subtle"
icon-left="lucide-plus"
@click="togglePopover()"
:label="__('Add Assignee')"
class="rtl:flex-row-reverse"
/>
</template>
<template #default>
<template #body="{ togglePopover }">
<div
class="mt-1 rounded-6 bg-surface-base py-1 text-base shadow-2xl w-60"
class="mt-1 rounded-lg bg-surface-base py-1 text-base shadow-2xl w-60"
>
<div class="relative px-1.5 pt-0.5">
<ComboboxInput
@@ -31,7 +32,7 @@
class="absolute end-1.5 inline-flex h-7 w-7 items-center justify-center"
@click="query = ''"
>
<LucideX class="w-4" />
<FeatherIcon name="x" class="w-4" />
</button>
</div>
<ComboboxOptions class="my-2 max-h-64 overflow-y-auto px-1.5" static>
@@ -50,7 +51,7 @@
"
>
<li
class="flex items-center rounded-4 p-1.5 w-full text-base"
class="flex items-center rounded p-1.5 w-full text-base"
:class="{ 'bg-surface-gray-2': active }"
>
<div class="flex gap-2 items-center w-full select-none">
@@ -73,7 +74,7 @@
</ComboboxOption>
<li
v-if="users.length == 0"
class="mt-1.5 rounded-5 p-1.5 text-base text-ink-gray-5"
class="mt-1.5 rounded-md p-1.5 text-base text-ink-gray-5"
>
{{ __("No results found") }}
</li>
@@ -100,7 +101,6 @@
</template>
<script setup lang="ts">
import LucideX from "~icons/lucide/x";
import { assignmentRuleData } from "@/stores/assignmentRules";
import {
Combobox,

View File

@@ -1,6 +1,6 @@
<template>
<div
class="grid grid-cols-12 items-center gap-4 cursor-pointer hover:bg-surface-sidebar rounded-4"
class="grid grid-cols-12 items-center gap-4 cursor-pointer hover:bg-surface-sidebar rounded"
>
<div
@click="assignmentRulesActiveScreen = { screen: 'view', data: data }"
@@ -16,7 +16,7 @@
</div>
<div class="col-span-3">
<select
class="w-full h-7 text-base hover:bg-surface-gray-3 rounded-5 p-0 ps-2 pe-5 bg-transparent -ms-2 border-0 text-ink-gray-8 focus-visible:!ring-0 bg-none truncate"
class="w-full h-7 text-base hover:bg-surface-gray-3 rounded-md p-0 ps-2 pe-5 bg-transparent -ms-2 border-0 text-ink-gray-8 focus-visible:!ring-0 bg-none truncate"
v-model="data.priority"
@update:modelValue="onPriorityChange"
@change="onPriorityChange"
@@ -39,12 +39,12 @@
/>
</div>
<div>
<Dropdown
align="end"
:options="dropdownOptions"
@update:open="(open) => open && (isConfirmingDelete = false)"
>
<Button icon="lucide-more-horizontal" variant="ghost" />
<Dropdown placement="right" :options="dropdownOptions">
<Button
icon="lucide-more-horizontal"
variant="ghost"
@click="isConfirmingDelete = false"
/>
</Dropdown>
</div>
</div>

View File

@@ -56,11 +56,12 @@
/>
</div>
<div class="flex flex-col gap-1.5">
<FormLabel :label="__('Priority')" />
<Popover bare>
<template #trigger>
<FormLabel :label="__('Priority')" size="md" />
<Popover>
<template #target="{ togglePopover }">
<div
class="flex items-center justify-between text-base rounded-4 h-7 py-1.5 ps-2 pe-2 border border-[--surface-gray-2] bg-surface-gray-2 placeholder-ink-gray-4 hover:border-outline-elevation-2 hover:bg-surface-gray-3 focus:bg-surface-base focus:border-outline-gray-4 focus:shadow-sm focus:ring-0 focus-visible:ring-2 focus-visible:ring-outline-gray-3 text-ink-gray-8 transition-colors w-full dark:[color-scheme:dark] cursor-default"
class="flex items-center justify-between text-base rounded h-7 py-1.5 ps-2 pe-2 border border-[--surface-gray-2] bg-surface-gray-2 placeholder-ink-gray-4 hover:border-outline-elevation-2 hover:bg-surface-gray-3 focus:bg-surface-base focus:border-outline-gray-4 focus:shadow-sm focus:ring-0 focus-visible:ring-2 focus-visible:ring-outline-gray-3 text-ink-gray-8 transition-colors w-full dark:[color-scheme:dark] cursor-default"
@click="togglePopover()"
>
<div>
{{
@@ -69,25 +70,26 @@
)?.label
}}
</div>
<LucideChevronDown class="size-4" />
<FeatherIcon name="chevron-down" class="size-4" />
</div>
</template>
<template #default="{ close: closePopover }">
<template #body="{ togglePopover }">
<div
class="p-1 text-ink-gray-6 top-1 absolute bg-surface-base shadow-2xl rounded-4 w-[--reka-popper-anchor-width]"
class="p-1 text-ink-gray-6 top-1 absolute bg-surface-base shadow-2xl rounded w-[--reka-popper-anchor-width]"
>
<div
v-for="option in priorityOptions"
:key="option.value"
class="p-2 cursor-pointer hover:bg-surface-sidebar text-base flex items-center justify-between rounded-4"
class="p-2 cursor-pointer hover:bg-surface-sidebar text-base flex items-center justify-between rounded"
@click="
assignmentRuleData.priority = option.value;
closePopover();
togglePopover();
"
>
{{ option.label }}
<LucideCheck
<FeatherIcon
v-if="assignmentRuleData.priority == option.value"
name="check"
class="size-4"
/>
</div>
@@ -116,7 +118,7 @@
<hr class="my-8" />
<div>
<div class="flex flex-col gap-1">
<span class="text-md-semibold text-ink-gray-8">{{
<span class="text-lg-semibold text-ink-gray-8">{{
__("Assignment Condition")
}}</span>
<div class="flex items-center justify-between gap-6">
@@ -136,29 +138,29 @@
<div
v-if="isAssignConditionOld && assignmentRulesActiveScreen.data"
>
<HoverCard :hoverDelay="250" side="top" align="end">
<template #trigger>
<Popover trigger="hover" :hoverDelay="0.25" placement="top-end">
<template #target>
<div
class="text-sm text-ink-gray-6 flex gap-1 cursor-default text-nowrap flex items-center"
>
<span>{{ __("Old Condition") }}</span>
<LucideInfo class="size-4" />
<FeatherIcon name="info" class="size-4" />
</div>
</template>
<template #default>
<template #body-main>
<div
class="text-sm text-ink-gray-6 p-2 bg-surface-base rounded-5 max-w-96 text-wrap whitespace-pre-wrap leading-5"
class="text-sm text-ink-gray-6 p-2 bg-surface-base rounded-md max-w-96 text-wrap whitespace-pre-wrap leading-5"
>
<code>{{ assignmentRuleData.assignCondition }}</code>
</div>
</template>
</HoverCard>
</Popover>
</div>
</div>
</div>
<div class="mt-5">
<div
class="flex flex-col gap-3 items-center text-center text-ink-gray-7 text-sm mb-2 border border-outline-gray-2 rounded-5 p-3 py-4"
class="flex flex-col gap-3 items-center text-center text-ink-gray-7 text-sm mb-2 border border-outline-gray-2 rounded-md p-3 py-4"
v-if="
!useNewUIForAssignCondition &&
assignmentRuleData.assignCondition
@@ -193,7 +195,7 @@
<hr class="my-8" />
<div>
<div class="flex flex-col gap-1">
<span class="text-md-semibold text-ink-gray-8">{{
<span class="text-lg-semibold text-ink-gray-8">{{
__("Unassignment Condition")
}}</span>
<div class="flex items-center justify-between gap-6">
@@ -217,29 +219,29 @@
assignmentRuleData.unassignCondition
"
>
<HoverCard :hoverDelay="250" side="top" align="end">
<template #trigger>
<Popover trigger="hover" :hoverDelay="0.25" placement="top-end">
<template #target>
<div
class="text-sm text-ink-gray-6 flex gap-1 cursor-default text-nowrap flex items-center"
>
<span> {{ __("Old Condition") }} </span>
<LucideInfo class="size-4" />
<FeatherIcon name="info" class="size-4" />
</div>
</template>
<template #default>
<template #body-main>
<div
class="text-sm text-ink-gray-6 p-2 bg-surface-base rounded-5 max-w-96 text-wrap whitespace-pre-wrap leading-5"
class="text-sm text-ink-gray-6 p-2 bg-surface-base rounded-md max-w-96 text-wrap whitespace-pre-wrap leading-5"
>
<code>{{ assignmentRuleData.unassignCondition }}</code>
</div>
</template>
</HoverCard>
</Popover>
</div>
</div>
</div>
<div class="mt-5">
<div
class="flex flex-col gap-3 items-center text-center text-ink-gray-7 text-sm mb-2 border border-outline-gray-2 rounded-5 p-3 py-4"
class="flex flex-col gap-3 items-center text-center text-ink-gray-7 text-sm mb-2 border border-outline-gray-2 rounded-md p-3 py-4"
v-if="
!useNewUIForUnassignCondition &&
assignmentRuleData.unassignCondition
@@ -270,7 +272,7 @@
<hr class="my-8" />
<div>
<div class="flex flex-col gap-1">
<span class="text-md-semibold text-ink-gray-8">{{
<span class="text-lg-semibold text-ink-gray-8">{{
__("Assignment Schedule")
}}</span>
<span class="text-p-sm text-ink-gray-6">
@@ -309,9 +311,6 @@
</template>
<script setup lang="ts">
import LucideCheck from "~icons/lucide/check";
import LucideChevronDown from "~icons/lucide/chevron-down";
import LucideInfo from "~icons/lucide/info";
import ConfirmDialog from "@/components/ConfirmDialog.vue";
import {
Badge,
@@ -321,7 +320,6 @@ import {
ErrorMessage,
FormControl,
FormLabel,
HoverCard,
LoadingIndicator,
Popover,
Switch,

View File

@@ -1,7 +1,7 @@
<template>
<SettingsLayoutBase>
<template #title>
<h1 class="text-md-semibold text-ink-gray-8">
<h1 class="text-lg-semibold text-ink-gray-8">
{{ __("Assignment Rules") }}
</h1>
</template>

View File

@@ -7,13 +7,13 @@
/>
<div
v-if="props.conditions.length == 0"
class="flex p-4 items-center cursor-pointer justify-center gap-2 text-sm border border-outline-gray-2 text-ink-gray-5 rounded-5"
class="flex p-4 items-center cursor-pointer justify-center gap-2 text-sm border border-outline-gray-2 text-ink-gray-5 rounded-md"
@click="
props.conditions.push(['', '', '']);
validateAssignmentRule(props.name);
"
>
<LucidePlus class="size-4" />
<FeatherIcon name="plus" class="h-4" />
{{ __("Add a condition") }}
</div>
<div class="flex items-center justify-between mt-2">
@@ -38,11 +38,10 @@
</template>
<script setup lang="ts">
import LucidePlus from "~icons/lucide/plus";
import CFConditions from "@/components/conditions-filter/CFConditions.vue";
import { validateConditions } from "@/utils";
import { watchDebounced } from "@vueuse/core";
import { Button, Dropdown, ErrorMessage } from "frappe-ui";
import { Button, Dropdown, ErrorMessage, FeatherIcon } from "frappe-ui";
import { validateAssignmentRule } from "@/stores/assignmentRules";
import { __ } from "@/translation";

View File

@@ -1,5 +1,5 @@
<template>
<div class="rounded-5 border px-2 border-outline-gray-2 text-sm">
<div class="rounded-md border px-2 border-outline-gray-2 text-sm">
<div
class="grid p-2 px-4 items-center"
style="grid-template-columns: 3fr 1fr"

View File

@@ -5,15 +5,7 @@
>
<div class="text-ink-gray-7 font-medium">{{ data.day }}</div>
<div class="flex justify-start">
<Switch
:model-value="Boolean(data.active)"
@update:model-value="
(value) => {
data.active = value;
toggleDay(value);
}
"
/>
<Switch v-model="data.active" @update:model-value="toggleDay" />
</div>
</div>
<hr v-if="!isLast" />

View File

@@ -1,13 +1,13 @@
<template>
<div
class="flex justify-between items-center border-outline-elevation-2 p-2 cursor-pointer hover:bg-surface-sidebar rounded-4 h-14"
class="flex justify-between items-center border-outline-elevation-2 p-2 cursor-pointer hover:bg-surface-sidebar rounded h-14"
>
<!-- avatar and name -->
<div class="flex justify-between items-center gap-2">
<EmailProviderIcon :logo="emailIcon[emailAccount.service]" />
<div class="rtl:text-right">
<p class="text-p-base-medium text-ink-gray-7">
{{ __(emailAccount.email_account_name) }}
<p class="text-base-medium text-ink-gray-7">
{{ emailAccount.email_account_name }}
</p>
<div class="text-p-sm w-full text-ink-gray-5 mt-1">
{{ __(emailAccount.email_id) }}

View File

@@ -27,7 +27,7 @@
<!-- email service provider info -->
<div>
<div
class="flex items-center gap-2 rounded-5 p-2 ring-1 ring-outline-elevation-2"
class="flex items-center gap-2 rounded-md p-2 ring-1 ring-outline-elevation-2"
>
<CircleAlert
class="h-6 w-5 w-min-5 w-max-5 min-h-5 max-w-5 text-ink-blue-5"
@@ -39,7 +39,8 @@
target="_blank"
class="text-ink-blue-5 underline"
>here</a
>.
>
.
</div>
</div>
</div>
@@ -164,10 +165,9 @@
import { Link } from "@/components";
import SettingsLayoutBase from "@/components/layouts/SettingsLayoutBase.vue";
import { capture } from "@/telemetry";
import { __ } from "@/translation";
import { EmailAccount, EmailService, EmailStep } from "@/types";
import { call, createResource, toast } from "frappe-ui";
import { useOnboarding } from "@framework/ui";
import { useOnboarding } from "frappe-ui/frappe";
import { computed, reactive, Ref, ref, watch } from "vue";
import CircleAlert from "~icons/lucide/circle-alert";
import {
@@ -181,6 +181,11 @@ import {
validateInputs,
} from "./emailConfig";
import EmailProviderIcon from "./EmailProviderIcon.vue";
import { __ } from "@/translation";
interface E {
(event: "update:step", value: EmailStep): void;
}
interface EmailAccountBaseState {
email_account_name: string;
@@ -216,13 +221,9 @@ type CustomEmailAccountState = {
sent_folder_name?: string;
};
interface E {
(event: "update:step", value: EmailStep): void;
}
const emit = defineEmits<E>();
const { updateOnboardingStep } = useOnboarding("helpdesk") ?? {};
const { updateOnboardingStep } = useOnboarding("helpdesk");
const state = reactive<EmailAccountProviderAuthState>({
service: "",
@@ -261,7 +262,7 @@ function resetCustomState() {
Object.assign(customState, getDefaultCustomState());
}
const selectedService: Ref<EmailService> = ref(null);
const selectedService: Ref<EmailService | null> = ref(null);
const fields = computed(() => {
if (!selectedService.value) return [];
if (selectedService.value.name === "Frappe Mail") {
@@ -305,10 +306,11 @@ function handleSelect(service: EmailService) {
const addEmailRes = createResource({
url: "helpdesk.api.settings.email.create_email_account",
makeParams: (val: EmailAccount) => ({ ...val }),
onSuccess: () => {
toast.success(__("Email account created"));
emit("update:step", "email-list");
updateOnboardingStep?.("setup_email_account");
updateOnboardingStep("setup_email_account");
capture("email_account_created", { data: { service: state.service } });
},
onError: () => {

View File

@@ -12,8 +12,9 @@
:service-name="state.service || accountData.service"
/>
</div>
<!-- banner for setting up email account -->
<div
class="flex items-center gap-2 rounded-5 p-2 ring-1 ring-outline-elevation-2"
class="flex items-center gap-2 rounded-md p-2 ring-1 ring-outline-elevation-2"
>
<CircleAlert
class="h-6 w-5 w-min-5 w-max-5 min-h-5 max-w-5 text-ink-blue-5"
@@ -39,7 +40,7 @@
</span>
</div>
</div>
<!-- fields -->
<div class="flex flex-col gap-4">
<div class="grid grid-cols-1 gap-4">
<div
@@ -129,6 +130,7 @@
</div>
</div>
<!-- action buttons -->
<div class="mt-auto flex justify-between -mb-8">
<Button
:label="__('Back')"
@@ -161,15 +163,13 @@
</template>
<script setup lang="ts">
import { Link } from "@/components";
import SettingsLayoutBase from "@/components/layouts/SettingsLayoutBase.vue";
import { __ } from "@/translation";
import { EmailAccount, EmailStep } from "@/types";
import { useStorage } from "@vueuse/core";
import { call, toast } from "frappe-ui";
import { computed, h, reactive, ref, watch } from "vue";
import CircleAlert from "~icons/lucide/circle-alert";
import EmailProviderIcon from "./EmailProviderIcon.vue";
import { Link } from "@/components";
import {
customIncomingFields,
customOutgoingFields,
@@ -181,6 +181,8 @@ import {
services,
validateInputs,
} from "./emailConfig";
import { __ } from "@/translation";
import SettingsLayoutBase from "@/components/layouts/SettingsLayoutBase.vue";
interface EmailAccountBaseState {
email_account_name: string;
@@ -200,6 +202,7 @@ interface EmailAccountProviderAuthState extends EmailAccountBaseState {
}
type CustomEmailAccountState = {
[key: string]: string | number | boolean | undefined;
domain?: string;
email_server?: string;
smtp_server?: string;
@@ -323,7 +326,6 @@ const loadingPull = useStorage(
`loading-emails-${state.email_account_name}`,
false
);
async function updateAccount() {
const validationState = { ...state, ...customState };
const validationService = isCustomProvider.value
@@ -388,8 +390,9 @@ function buildUpdatePayload() {
function pullEmails() {
loadingPull.value = true;
toast(__("Pulling emails, this may take a few minutes."), {
icon: () => h(CircleAlert, { class: "text-ink-blue-5" }),
toast.create({
message: __("Pulling emails, this may take a few minutes."),
icon: h(CircleAlert, { class: "text-ink-blue-5" }),
});
call("frappe.email.doctype.email_account.email_account.pull_emails", {
@@ -540,5 +543,3 @@ function handleEditDomainClick() {
);
}
</script>
<style scoped></style>

View File

@@ -13,7 +13,7 @@
<span class="sr-only">{{ __("back to email event list") }}</span>
<LucideChevronLeft class="w-4.5 h-4.5 rtl:rotate-180" />
</button>
<h1 class="text-xl-semibold">
<h1 class="text-2xl-semibold">
{{ props.title }}
</h1>
</div>
@@ -62,9 +62,7 @@
:required="true"
:rows="10"
v-model="content"
@update:model-value="
(value) => setUnsavedChanges(undefined, value)
"
:oninput="() => setUnsavedChanges()"
/>
<div class="flex gap-x-1 items-start justify-between">
<p class="text-sm text-ink-gray-7 leading-5">
@@ -153,7 +151,6 @@ const content = defineModel<string>("content", { required: true });
const enabled = defineModel<boolean>("enabled", { required: true });
const unsavedChanges = ref(false);
const slotFieldChanged = ref(false);
const showUnsavedConfirm = ref(false);
const showContentChangeConfirm = ref(false);
@@ -172,25 +169,15 @@ function setUnsavedChanges(
newContent = content.value
) {
unsavedChanges.value =
slotFieldChanged.value ||
newEnabled !== notificationDataResource.data.enabled ||
newContent !== notificationDataResource.data.content;
}
/** For fields a notification adds through `#formFields`, which this component
* cannot diff itself. */
function markUnsavedChanges() {
slotFieldChanged.value = true;
unsavedChanges.value = true;
}
function resetUnsavedChanges() {
notificationDataResource.data = {
...notificationDataResource.data,
enabled: enabled.value,
content: content.value,
};
slotFieldChanged.value = false;
unsavedChanges.value = false;
}
function resetContent() {
@@ -222,7 +209,6 @@ watch(
defineExpose({
setUnsavedChanges,
markUnsavedChanges,
resetUnsavedChanges,
});
</script>

View File

@@ -13,7 +13,7 @@
v-for="(notification, index) in notifications"
:key="notification.name"
>
<li class="flex items-center justify-between p-3 rounded-4 relative">
<li class="flex items-center justify-between p-3 rounded relative">
<div class="flex flex-col gap-1">
<h2
class="text-base-medium text-ink-gray-7 relative z-10 pointer-events-none"
@@ -26,7 +26,8 @@
{{ __(notification.description) }}
</p>
</div>
<LucideChevronRight
<FeatherIcon
name="chevron-right"
class="text-ink-gray-7 size-4 relative z-10 pointer-events-none rtl:rotate-180"
/>
<div
@@ -50,7 +51,6 @@
</template>
<script setup lang="ts">
import LucideChevronRight from "~icons/lucide/chevron-right";
import { __ } from "@/translation";
import type { AtLeastOneNotifcation, Notification } from "./types";
import SettingsLayoutBase from "@/components/layouts/SettingsLayoutBase.vue";

View File

@@ -15,17 +15,16 @@
>
<template #formFields>
<FormControl
type="combobox"
type="autocomplete"
size="sm"
:label="__('On ticket status')"
:options="statusOptions"
:required="true"
:model-value="ticketStatus?.value ?? null"
:model-value="ticketStatus"
@update:model-value="
(value) => {
ticketStatus =
statusOptions.find((option) => option.value === value) ?? null;
compRef.markUnsavedChanges();
(val) => {
ticketStatus = val;
compRef.setUnsavedChanges();
}
"
/>

View File

@@ -14,7 +14,6 @@
<script setup lang="ts">
import { computed } from "vue";
import LucideMail from "~icons/lucide/mail";
interface P {
serviceName?: string;
logo?: string;

View File

@@ -8,11 +8,7 @@
<div class="flex gap-4">
<!-- Switch -->
<div class="flex gap-2 items-center">
<Switch
class="!w-fit"
:model-value="Boolean(state.enabled)"
@update:model-value="(value) => (state.enabled = value)"
/>
<Switch v-model="state.enabled" class="!w-fit" />
<span class="text-p-base text-ink-gray-6">
{{ __("Enabled") }}
</span>

View File

@@ -20,14 +20,15 @@
/>
</div>
</div>
<MultiSelect
class="min-w-[120px] max-w-[120px]"
side="top"
<MultiSelectCombobox
:disabled="!fieldCriteriaState.display.enabled"
class="min-w-[120px] max-w-[120px]"
:options="fieldCriteriaOptions"
:model-value="selectedValues('display')"
:placeholder="__('Select Child Field values')"
:model-value="fieldCriteriaState.display.value"
@update:model-value="handleCriteriaSelection($event, 'display')"
:multiple="true"
placeholder="Select Child Field values"
placement="top"
/>
</div>
<!-- Mandatory Criteria -->
@@ -45,14 +46,15 @@
/>
</div>
</div>
<MultiSelect
class="min-w-[120px] max-w-[120px]"
side="top"
<MultiSelectCombobox
:disabled="!fieldCriteriaState.mandatory.enabled"
class="min-w-[120px] max-w-[120px]"
:options="fieldCriteriaOptions"
:model-value="selectedValues('mandatory')"
:placeholder="__('Select Child Field values')"
:model-value="fieldCriteriaState.mandatory.value"
@update:model-value="handleCriteriaSelection($event, 'mandatory')"
:multiple="true"
placeholder="Select Child Field values"
placement="top"
/>
</div>
</div>
@@ -61,9 +63,9 @@
<script setup lang="ts">
import DocumentationButton from "@/components/DocumentationButton.vue";
import MultiSelectCombobox from "@/components/frappe-ui/MultiSelectCombobox.vue";
import { getMeta } from "@/stores/meta";
import { __ } from "@/translation";
import { MultiSelect, Switch } from "frappe-ui";
import { Switch } from "frappe-ui";
import { computed } from "vue";
const props = defineProps<{
@@ -96,25 +98,21 @@ const fieldCriteriaOptions = computed(() => {
return _options;
});
function selectedValues(stateKey: "display" | "mandatory") {
return fieldCriteriaState.value[stateKey].value.map((v) => v.value);
}
function handleCriteriaSelection(
values: string[],
values: { label: string; value: string }[],
stateKey: "display" | "mandatory"
) {
// "Any" is exclusive: picking it drops the rest, picking anything else drops it
const wasAnySelected = selectedValues(stateKey).includes("Any");
let selected =
values.includes("Any") && !wasAnySelected
? ["Any"]
: values.filter((value) => value !== "Any");
if (!selected.length) selected = ["Any"];
fieldCriteriaState.value[stateKey].value = selected.map((value) => ({
label: value,
value,
}));
const _values = values.map((v) => v.value);
fieldCriteriaState.value[stateKey].value = values;
if (_values.length === 0) {
fieldCriteriaState.value[stateKey].value = [{ label: "Any", value: "Any" }];
} else if (_values[0] === "Any" && _values.length > 1) {
fieldCriteriaState.value[stateKey].value = _values
.filter((value) => value !== "Any")
.map((value) => ({ label: value, value }));
} else if (_values.at(-1) === "Any" && _values.length > 1) {
fieldCriteriaState.value[stateKey].value = [{ label: "Any", value: "Any" }];
}
}
</script>

View File

@@ -2,7 +2,7 @@
<SettingsLayoutBase>
<template #title>
<div class="flex items-center gap-2">
<h1 class="text-md-semibold text-ink-gray-8">
<h1 class="text-lg-semibold text-ink-gray-8">
{{ __("Field Dependencies") }}
</h1>
</div>
@@ -39,7 +39,7 @@
v-if="fieldDependenciesList.loading"
class="flex items-center justify-center py-4"
>
<LoadingIndicator class="size-5" />
<LoadingIndicator :scale="5" />
</div>
<!-- Empty State -->
@@ -75,7 +75,7 @@
:key="row.name"
>
<div
class="grid grid-cols-11 items-center gap-4 cursor-pointer hover:bg-surface-sidebar rounded-4 h-12.5"
class="grid grid-cols-11 items-center gap-4 cursor-pointer hover:bg-surface-sidebar rounded h-12.5"
>
<div
@click.stop="$emit('update:step', 'fd', row.name)"
@@ -100,13 +100,7 @@
/>
</div>
<div>
<Dropdown
align="end"
:options="getOptions(row.name)"
@update:open="
(open) => open && (isConfirmingDelete = false)
"
>
<Dropdown placement="right" :options="getOptions(row.name)">
<Button
variant="ghost"
@click.stop="

View File

@@ -7,9 +7,7 @@
<span class="block text-xs text-ink-gray-5">
Select parent field value
</span>
<div
class="border border-outline-elevation-2 flex-1 border-e-0 rounded-s-4 p-2 flex flex-col gap-2"
>
<div class="border flex-1 border-e-0 rounded-s p-2 flex flex-col gap-2">
<template v-if="state.selectedParentField">
<FormControl
v-model="state.parentSearch"
@@ -26,7 +24,7 @@
<li
v-for="value in filteredParentFieldValues"
:key="value"
class="py-2 mb-1 px-2.5 cursor-pointer rounded-4 flex justify-between items-center hover:bg-surface-gray-1 overflow-hidden max-w-full"
class="py-2 mb-1 px-2.5 cursor-pointer rounded flex justify-between items-center hover:bg-surface-gray-1 overflow-hidden max-w-full"
:class="{
'bg-surface-gray-2 hover:bg-surface-gray-3':
state.currentParentSelection === value,
@@ -68,9 +66,7 @@
<span class="block text-xs text-ink-gray-5 ps-1.5">
Select child field value
</span>
<div
class="border border-outline-elevation-2 flex-1 rounded-e-4 p-2 flex flex-col gap-2"
>
<div class="border flex-1 rounded-e p-2 flex flex-col gap-2">
<template
v-if="state.selectedChildField && state.currentParentSelection"
>
@@ -87,13 +83,13 @@
<div class="flex-1 overflow-y-auto hide-scrollbar basis-0">
<!-- Master Check box -->
<li
class="py-2 mb-1 px-2.5 cursor-pointer rounded-4 flex items-center bg-surface-gray-1 hover:bg-surface-gray-2"
class="py-2 mb-1 px-2.5 cursor-pointer rounded flex items-center bg-surface-gray-1 hover:bg-surface-gray-2"
@click="handleSelectAllChildValues(!toggleAllChildValues)"
>
<FormControl
type="checkbox"
:model-value="toggleAllChildValues"
class="me-4"
class="me-2"
/>
<span class="text-base-medium text-ink-gray-8">
{{ toggleCheckboxLabel }}
@@ -103,13 +99,13 @@
<li
v-for="value in filteredChildFieldValues"
:key="value"
class="py-2 mb-1 px-2.5 cursor-pointer rounded-4 flex items-center hover:bg-surface-gray-1 max-w-full truncate"
class="py-2 mb-1 px-2.5 cursor-pointer rounded flex items-center hover:bg-surface-gray-1 max-w-full truncate"
@click="handleChildValueClick(value)"
>
<FormControl
type="checkbox"
:model-value="isChildValueSelected(value)"
class="me-4"
class="me-2"
/>
<span class="text-base text-ink-gray-6">{{ value }}</span>
</li>

View File

@@ -2,7 +2,7 @@
<SettingsLayoutBase :description="__('Manage general settings of your app.')">
<template #title>
<div class="flex items-center gap-2">
<h1 class="text-md-semibold text-ink-gray-8">
<h1 class="text-lg-semibold text-ink-gray-8">
{{ __("General") }}
</h1>
<UnsavedBadge :show="isDirty" />
@@ -74,7 +74,6 @@ import {
toast,
} from "frappe-ui";
import { computed, provide, ref, watch } from "vue";
import { disableSettingModalOutsideClick } from "../settingsModal";
import Branding from "./components/Branding.vue";
import TicketSettings from "./components/TicketSettings.vue";
import WorkflowKnowledgebaseSettings from "./components/WorkflowKnowledgebaseSettings.vue";
@@ -156,7 +155,6 @@ const saveSettingsResource = createResource({
skip_email_workflow: settingsData.value.skipEmailWorkflow,
disable_saved_replies_global_scope:
settingsData.value.disableSavedRepliesGlobalScope,
enable_outside_hours_banner:
settingsData.value.enableOutsideHoursBanner,
outside_working_hours_message:
@@ -254,61 +252,14 @@ const saveSettings = async () => {
});
};
const toggleFieldnames = {
isFeedbackMandatory: "is_feedback_mandatory",
enableCommentReactions: "enable_comment_reactions",
disableSavedRepliesGlobalScope: "disable_saved_replies_global_scope",
allowAnyoneToCreateTickets: "allow_anyone_to_create_tickets",
preferKnowledgeBase: "prefer_knowledge_base",
skipEmailWorkflow: "skip_email_workflow",
} as const;
const toggleFields = Object.keys(toggleFieldnames) as Array<
keyof typeof toggleFieldnames
>;
// Toggles save on their own, so they never carry unsaved text fields along.
const saveTogglesResource = createResource({
url: "frappe.client.set_value",
makeParams: (values: Record<string, unknown>) => ({
doctype: "HD Settings",
name: "HD Settings",
fieldname: Object.fromEntries(
toggleFields.map((f) => [toggleFieldnames[f], values[f]])
),
}),
});
let pendingToggleSave = Promise.resolve();
function currentToggles() {
return Object.fromEntries(
toggleFields.map((f) => [f, settingsData.value[f]])
);
}
async function saveToggles(sent: Record<string, unknown>) {
try {
await saveTogglesResource.submit(sent);
markTogglesSaved(sent);
toast.success(__("Settings updated"));
} catch {
revertToggles(sent);
}
}
function markTogglesSaved(sent: Record<string, unknown>) {
const initial = JSON.parse(initialData.value!);
toggleFields.forEach((f) => (initial[f] = sent[f]));
initialData.value = JSON.stringify(initial);
configStore.configResource.reload();
}
// Undo only what the failed request sent; a toggle changed since keeps its queued save.
function revertToggles(sent: Record<string, unknown>) {
const initial = JSON.parse(initialData.value!);
toggleFields
.filter((f) => settingsData.value[f] === sent[f])
.forEach((f) => (settingsData.value[f] = initial[f]));
}
const toggleFields = [
"isFeedbackMandatory",
"enableCommentReactions",
"disableSavedRepliesGlobalScope",
"allowAnyoneToCreateTickets",
"preferKnowledgeBase",
"skipEmailWorkflow",
] as const;
// Track dirty state for non-toggle fields only
watch(
@@ -318,7 +269,7 @@ watch(
const initial = JSON.parse(initialData.value);
isDirty.value = Object.keys(data).some(
(key) =>
!(toggleFields as string[]).includes(key) &&
!(toggleFields as readonly string[]).includes(key) &&
JSON.stringify(data[key as keyof typeof data]) !==
JSON.stringify(initial[key])
);
@@ -327,16 +278,16 @@ watch(
{ deep: true }
);
// Queue toggle saves: parallel writes to the single doc fail with a 417.
// auto save when any toggle field changes
watch(
() => toggleFields.map((f) => settingsData.value[f]),
(newVals) => {
async (newVals) => {
if (!initialData.value) return;
const initial = JSON.parse(initialData.value);
if (!newVals.some((v, i) => v !== initial[toggleFields[i]])) return;
pendingToggleSave = pendingToggleSave.then(() =>
saveToggles(currentToggles())
);
if (newVals.some((v, i) => v !== initial[toggleFields[i]])) {
await saveSettingsResource.submit();
toast.success(__("Settings updated"));
}
}
);

View File

@@ -4,7 +4,7 @@
>
<div class="flex flex-col sm:flex-row items-center gap-3.5">
<div
class="flex items-center justify-center min-w-16 min-h-16 rounded-6 overflow-hidden border border-outline-gray-1"
class="flex items-center justify-center min-w-16 min-h-16 rounded-lg overflow-hidden border border-outline-gray-1"
>
<Avatar
v-if="props.image"
@@ -12,7 +12,7 @@
:image="props.image"
:label="props.title"
/>
<LucideImage v-else class="size-6 text-ink-gray-4" />
<FeatherIcon v-else name="image" class="size-6 text-ink-gray-4" />
</div>
<div class="flex flex-col gap-1 max-w-sm items-start">
<span class="text-base-medium text-ink-gray-8">{{ title }}</span>
@@ -57,8 +57,7 @@
</template>
<script setup lang="ts">
import LucideImage from "~icons/lucide/image";
import { Avatar, Button, FileUploader } from "frappe-ui";
import { Avatar, Button, FeatherIcon, FileUploader } from "frappe-ui";
import ImageUpIcon from "~icons/lucide/image-up";
const emit = defineEmits(["onUpload", "onRemove"]);

View File

@@ -133,7 +133,7 @@
}}</span>
</div>
<SelectDropdown
:options="ticketTypeList.data || []"
:options="ticketTypeList.data"
v-model="settingsData.defaultTicketType"
target-class="max-w-40"
placement="bottom-start"
@@ -152,7 +152,7 @@
</div>
<div class="grid grid-cols-2 gap-4 mt-3">
<div class="flex flex-col gap-1.5">
<FormLabel :label="__('Ticket status')" />
<FormLabel :label="__('Ticket status')" size="md" />
<SelectDropdown
:options="autoCloseTicketStatusList"
:model-value="settingsData.autoCloseStatus"
@@ -275,6 +275,7 @@ import {
import { computed, inject } from "vue";
const settingsData = inject(HDSettingsSymbol);
const { statuses } = useTicketStatusStore();
const bannerMsg = createResource({
@@ -294,8 +295,7 @@ function resetBannerContent() {
}
function handleShowBannerToggle(value: boolean) {
// the switch is live before the message resource lands
if (!bannerMsg.data?.current) {
if (!bannerMsg.data.current) {
if (value) {
settingsData.value.outsideWorkingHoursBannerMessage =
bannerMsg.data?.default;

View File

@@ -3,7 +3,7 @@
<div class="text-base-medium mb-2 text-ink-gray-8 ms-2.5">
{{ formattedMonth }}
</div>
<div class="rounded-5 text-sm">
<div class="rounded-md text-sm">
<div class="flex items-center text-xs uppercase">
<div
class="flex size-7.5 items-center justify-center text-center text-ink-gray-5"
@@ -16,51 +16,37 @@
<div class="flex items-center" v-for="(week, i) in datesAsWeeks" :key="i">
<div v-for="date in week" :key="getFormattedDate(date)">
<Popover v-if="isHoliday(date)">
<template #trigger="{ close, setOpen }">
<!--
Hover opens this one. reka turns the whole trigger subtree into
the toggle, so the cell stops its click before it gets there.
-->
<div>
<div
class="flex size-7 cursor-pointer text-ink-orange-6 bg-surface-yellow-2 items-center justify-center rounded-4 hover:bg-surface-yellow-2 select-none m-[1px]"
:class="{
'!text-ink-gray-4 !bg-surface-gray-2': isWeekOff(date),
}"
@mouseover="
handleMouseEnter(getFormattedDate(date), () =>
setOpen(true)
)
"
@mouseleave="handleMouseLeave(getFormattedDate(date), close)"
@click.stop="
() => {
if (isWeekOff(date)) return;
close();
editHoliday(date);
}
"
>
{{ date.getDate() }}
</div>
<template #target="{ open, close }">
<div
class="flex size-7 cursor-pointer text-ink-orange-6 bg-surface-yellow-2 items-center justify-center rounded hover:bg-surface-yellow-2 select-none m-[1px]"
:class="{
'!text-ink-gray-4 !bg-surface-gray-2': isWeekOff(date),
}"
@mouseover="handleMouseEnter(getFormattedDate(date), open)"
@mouseleave="handleMouseLeave(getFormattedDate(date), close)"
@click="
() => {
if (isWeekOff(date)) return;
close();
editHoliday(date);
}
"
>
{{ date.getDate() }}
</div>
</template>
<template
#default="{ close: closePopover, setOpen: setPopoverOpen }"
>
<template #body-main="{ close: closePopover, open: openPopover }">
<div
class="p-3 flex gap-2.5 text-ink-gray-9 w-80 border border-outline-gray-1 rounded-5"
class="p-3 flex gap-2.5 text-ink-gray-9 w-80 border border-outline-gray-1 rounded-md"
@mouseover="
handleMouseEnter(getFormattedDate(date), () =>
setPopoverOpen(true)
)
handleMouseEnter(getFormattedDate(date), openPopover)
"
@mouseleave="
handleMouseLeave(getFormattedDate(date), closePopover)
"
>
<div class="w-[5%]">
<div class="size-3.5 bg-surface-orange-5 rounded-1 mt-1" />
<div class="size-3.5 bg-surface-orange-5 rounded-sm mt-1" />
</div>
<div class="grow">
<div class="text-sm-semibold">
@@ -74,10 +60,11 @@
v-if="!isWeekOff(date)"
@close="isConfirmingDelete = false"
>
<template #trigger="{ close }">
<template #target="{ open, close }">
<Button
icon="lucide-more-horizontal"
variant="ghost"
@click="open"
@mouseleave="
handleMouseLeave(
getFormattedDate(date) + 'dropdown',
@@ -87,20 +74,15 @@
/>
</template>
<template
#default="{
close: closeDropdown,
setOpen: setDropdownOpen,
}"
#body-main="{ close: closeDropdown, open: openDropdown }"
>
<div
class="p-2 flex flex-col gap-1 w-40 text-ink-gray-9 border border-outline-gray-1 rounded-5"
class="p-2 flex flex-col gap-1 w-40 text-ink-gray-9 border border-outline-gray-1 rounded-md"
@mouseover="
handleMouseEnter(getFormattedDate(date), () =>
setPopoverOpen(true)
);
handleMouseEnter(getFormattedDate(date), openPopover);
handleMouseEnter(
getFormattedDate(date) + 'dropdown',
() => setDropdownOpen(true)
openDropdown
);
"
@mouseleave="
@@ -149,7 +131,7 @@
</Popover>
<div
v-else
class="flex size-7 items-center justify-center rounded-4 m-[1px] select-none"
class="flex size-7 items-center justify-center rounded m-[1px] select-none"
:class="{
'cursor-pointer hover:bg-surface-gray-2': isDateInRange(date),
'text-ink-gray-3':
@@ -173,8 +155,7 @@
<script setup lang="ts">
import { holidayData } from "@/stores/holidayList";
import { getFormattedDate, htmlToText } from "@/utils";
import { dayjs, Popover } from "frappe-ui";
import { useDatePicker } from "@/composables/useDatePicker";
import { dayjs, Popover, useDatePicker } from "frappe-ui";
import { ref, watch } from "vue";
import AddHolidayModal from "./Modals/AddHolidayModal.vue";

View File

@@ -1,6 +1,6 @@
<template>
<div
class="flex items-center cursor-pointer hover:bg-surface-sidebar rounded-4"
class="flex items-center cursor-pointer hover:bg-surface-sidebar rounded"
>
<div
class="w-full ps-2 flex flex-col justify-center h-14"
@@ -16,12 +16,12 @@
</div>
<div class="flex justify-between items-center pe-2">
<div>
<Dropdown
align="end"
:options="dropdownOptions"
@update:open="(open) => open && (isConfirmingDelete = false)"
>
<Button icon="lucide-more-horizontal" variant="ghost" />
<Dropdown placement="right" :options="dropdownOptions">
<Button
icon="lucide-more-horizontal"
variant="ghost"
@click="isConfirmingDelete = false"
/>
</Dropdown>
</div>
</div>

View File

@@ -59,7 +59,7 @@
<hr class="my-8" />
<div>
<div class="flex flex-col gap-1">
<span class="text-md-semibold text-ink-gray-8">{{
<span class="text-lg-semibold text-ink-gray-8">{{
__("Valid From")
}}</span>
<span class="text-p-sm text-ink-gray-6">
@@ -68,7 +68,12 @@
</div>
<div class="mt-3.5 flex gap-5 flex-col md:flex-row">
<div class="w-full space-y-1.5">
<FormLabel :label="__('From date')" for="from_date" required />
<FormLabel
:label="__('From date')"
for="from_date"
required
size="md"
/>
<DatePicker
v-model="holidayData.from_date"
variant="subtle"
@@ -89,7 +94,12 @@
/>
</div>
<div class="w-full space-y-1.5">
<FormLabel :label="__('To date')" for="to_date" required />
<FormLabel
:label="__('To date')"
for="to_date"
required
size="md"
/>
<DatePicker
v-model="holidayData.to_date"
variant="subtle"
@@ -110,7 +120,7 @@
<hr class="my-8" />
<div>
<div class="flex flex-col gap-1">
<div class="text-md-semibold text-ink-gray-8">
<div class="text-lg-semibold text-ink-gray-8">
{{ __("Recurring Holidays") }}
</div>
<div class="text-p-sm text-ink-gray-6">
@@ -128,7 +138,7 @@
<div>
<div class="flex justify-between items-center">
<div class="flex justify-between flex-col gap-1">
<span class="text-md-semibold text-ink-gray-8">
<span class="text-lg-semibold text-ink-gray-8">
{{ __("Holidays") }}
</span>
<div class="text-p-sm text-ink-gray-6">
@@ -140,15 +150,13 @@
</div>
</div>
<TabButtons
:options="[
:buttons="[
{
value: 'calendar',
label: __('Calendar'),
icon: 'lucide-calendar',
},
{
value: 'list',
label: __('List'),
icon: 'lucide-list',
},
]"
@@ -169,13 +177,13 @@
<!-- Indicators -->
<div class="flex gap-4" v-if="holidayListView === 'calendar'">
<div class="gap-1 flex items-center">
<span class="bg-surface-yellow-2 size-4 rounded-1" />
<span class="bg-surface-yellow-2 size-4 rounded-sm" />
<span class="text-sm text-ink-gray-6">{{
__("Holidays")
}}</span>
</div>
<div class="gap-1 flex items-center">
<span class="bg-surface-gray-2 size-4 rounded-1" />
<span class="bg-surface-gray-2 size-4 rounded-sm" />
<span class="text-sm text-ink-gray-6">{{
__("Recurring holidays")
}}</span>

View File

@@ -74,8 +74,10 @@ watch(holidaySearchRef, (newValue) => {
holidayList.filters = {
name: ["like", `%${newValue}%`],
};
// no pager on this list, so a shrunken pageLength would hide the rest for good
if (!newValue) holidayList.start = 0;
if (!newValue) {
holidayList.start = 0;
holidayList.pageLength = 10;
}
holidayList.reload();
});
</script>

View File

@@ -1,17 +1,18 @@
<template>
<div class="p-6.5 px-5 rounded-7 border border-outline-gray-2">
<div class="p-6.5 px-5 rounded-xl border border-outline-gray-2">
<div class="mb-6.5 flex justify-between items-center">
<div class="ms-1">
<Popover v-if="startYear !== endYear">
<template #trigger>
<template #target="{ togglePopover }">
<Button
class="flex items-center gap-2 text-xl-semibold cursor-pointer select-none"
class="flex items-center gap-2 text-2xl-semibold cursor-pointer select-none"
variant="ghost"
@click="togglePopover"
:label="currentYear + ''"
icon-right="lucide-chevron-down"
/>
</template>
<template #default="{ close: closePopover }">
<template #body-main="{ togglePopover }">
<div class="w-24">
<div ref="yearsContainer" class="max-h-60 overflow-y-auto py-1">
<div
@@ -19,10 +20,14 @@
:key="year"
ref="yearItems"
class="cursor-pointer px-3 py-1.5 text-sm hover:bg-surface-gray-2 flex items-center justify-between"
@click="onYearChange(closePopover, year)"
@click="onYearChange(togglePopover, year)"
>
{{ year }}
<LucideCheck class="size-4" v-if="year === currentYear" />
<FeatherIcon
name="check"
class="size-4"
v-if="year === currentYear"
/>
</div>
</div>
</div>
@@ -30,7 +35,7 @@
</Popover>
<div
v-else
class="flex items-center gap-2 px-2 text-xl-semibold select-none"
class="flex items-center gap-2 px-2 text-2xl-semibold select-none"
>
{{ startYear }}
</div>
@@ -100,8 +105,7 @@
</div>
</template>
<script setup lang="ts">
import LucideCheck from "~icons/lucide/check";
import { computed, ref, watch } from "vue";
import { computed, onMounted, ref, watch } from "vue";
import HLCalender from "./HLCalender.vue";
import { holidayData } from "@/stores/holidayList";
import { Button, dayjs, Popover } from "frappe-ui";
@@ -121,7 +125,7 @@ const yearsList = computed(() => {
return yearList;
});
const onYearChange = (closePopover: () => void, year: number) => {
const onYearChange = (togglePopover: () => void, year: number) => {
currentYear.value = year;
if (year === dayjs(holidayData.value.from_date).year()) {
if (dayjs(holidayData.value.from_date).month() >= 6) {
@@ -134,7 +138,7 @@ const onYearChange = (closePopover: () => void, year: number) => {
} else {
visibleMonths.value = "first-half";
}
closePopover();
togglePopover();
};
const goToToday = () => {
@@ -146,14 +150,17 @@ const goToToday = () => {
watch(
() => [holidayData.value.from_date, holidayData.value.to_date],
([fromDate, toDate]) => {
fromDate = dayjs(fromDate || dayjs());
toDate = dayjs(toDate || dayjs());
fromDate = dayjs(fromDate);
toDate = dayjs(toDate);
startYear.value = fromDate.year();
endYear.value = toDate.year();
currentYear.value = fromDate.year();
visibleMonths.value = fromDate.month() >= 6 ? "second-half" : "first-half";
},
// The list is loaded before this view mounts, so a change-only watch never fires.
{ immediate: true }
}
);
onMounted(() => {
const fromDate = dayjs(holidayData.value.from_date || dayjs());
visibleMonths.value = fromDate.month() >= 6 ? "second-half" : "first-half";
});
</script>

View File

@@ -1,5 +1,5 @@
<template>
<div class="rounded-5 border px-2 border-outline-gray-2 text-sm">
<div class="rounded-md border px-2 border-outline-gray-2 text-sm">
<div
class="grid p-2 px-4 items-center gap-2"
:style="{
@@ -37,12 +37,12 @@
</div>
</div>
<div class="flex justify-end">
<Dropdown
align="end"
:options="dropdownOptions(holiday)"
@update:open="(open) => open && (isConfirmingDelete = false)"
>
<Button icon="lucide-more-horizontal" variant="ghost" />
<Dropdown placement="right" :options="dropdownOptions(holiday)">
<Button
icon="lucide-more-horizontal"
variant="ghost"
@click="isConfirmingDelete = false"
/>
</Dropdown>
</div>
</div>

View File

@@ -8,7 +8,7 @@
<template #default>
<div class="flex flex-col gap-4 mt-4">
<div class="flex flex-col gap-1.5">
<FormLabel label="Date" required />
<FormLabel label="Date" required size="md" />
<DatePicker
:model-value="dayjs(dialog.holiday_date).format('YYYY-MM-DD')"
@update:model-value="

View File

@@ -1,5 +1,5 @@
<template>
<div class="rounded-5 border p-1 border-outline-gray-2 text-sm">
<div class="rounded-md border p-1 border-outline-gray-2 text-sm">
<div
class="grid p-2 items-center"
:style="{
@@ -32,12 +32,12 @@
<div v-else>{{ holiday[column.key] }}</div>
</div>
<div class="flex justify-end">
<Dropdown
align="end"
:options="dropdownOptions(holiday)"
@update:open="(open) => open && (isConfirmingDelete = false)"
>
<Button icon="lucide-more-horizontal" variant="ghost" />
<Dropdown placement="right" :options="dropdownOptions(holiday)">
<Button
icon="lucide-more-horizontal"
variant="ghost"
@click="isConfirmingDelete = false"
/>
</Dropdown>
</div>
</div>
@@ -71,7 +71,7 @@
</div>
<div v-else class="flex flex-col gap-4">
<div class="flex flex-col gap-1.5">
<FormLabel label="Day" required />
<FormLabel label="Day" required size="md" />
<Select
:options="availableWorkDays"
v-model="recurringHolidayData.day"
@@ -79,7 +79,7 @@
/>
</div>
<div class="flex flex-col gap-1.5">
<FormLabel label="Repetition" required />
<FormLabel label="Repetition" required size="md" />
<div class="grid grid-cols-2 gap-2 mt-2">
<Checkbox
v-model="recurringHolidayData.repetition.all"

View File

@@ -45,7 +45,7 @@
<li
v-for="invite in pendingInvitesResource.data"
:key="invite.name"
class="flex items-center justify-between px-3 py-1 rounded-6 bg-surface-gray-2"
class="flex items-center justify-between px-3 py-1 rounded-lg bg-surface-gray-2"
>
<div class="text-base">
<span class="text-ink-gray-8">
@@ -116,7 +116,7 @@ import {
createResource,
toast,
} from "frappe-ui";
import { useOnboarding } from "@framework/ui";
import { useOnboarding } from "frappe-ui/frappe";
import { computed, ref } from "vue";
import LucideChevronDown from "~icons/lucide/chevron-down";
@@ -124,7 +124,7 @@ const authStore = useAuthStore();
const { isAdmin, isManager } = authStore;
// @ts-expect-error
const { updateOnboardingStep } = useOnboarding("helpdesk") ?? {};
const { updateOnboardingStep } = useOnboarding("helpdesk");
const emails = ref("");
@@ -215,7 +215,7 @@ const inviteByEmailResource = createResource({
resetInputValues();
handleInviteUserSuccess(data);
pendingInvitesResource.reload();
updateOnboardingStep?.("invite_agents");
updateOnboardingStep("invite_your_team");
capture("agents_invited", {
data: {
role: role.value,

View File

@@ -2,7 +2,7 @@
<SettingsLayoutBase :description="__('Manage your personal preferences.')">
<template #title>
<div class="flex items-center gap-2">
<h1 class="text-md-semibold text-ink-gray-8">
<h1 class="text-lg-semibold text-ink-gray-8">
{{ __("Preferences") }}
</h1>
<UnsavedBadge :show="isDirty" />

View File

@@ -13,10 +13,6 @@
:model-value="user.doc?.language"
doctype="Language"
class="w-40"
side="top"
align="end"
:placeholder="__('Select language')"
hide-clear-button
@update:model-value="updateLanguage"
/>
</div>
@@ -29,8 +25,11 @@
{{ __("Change timezone of the application.") }}
</span>
</div>
<TimezoneControl
<Autocomplete
:model-value="user.doc?.time_zone"
:options="timezoneOptions"
:placeholder="__('Select Timezone')"
size="sm"
class="w-40"
@update:model-value="updateTimezone"
/>
@@ -39,8 +38,8 @@
</template>
<script setup lang="ts">
import Link from "@/components/frappe-ui/Link.vue";
import TimezoneControl from "@/components/TimezoneControl.vue";
import { ref } from "vue";
import { createResource } from "frappe-ui";
import { __ } from "@/translation";
const props = defineProps<{ user: any }>();
@@ -50,8 +49,20 @@ function updateLanguage(value: string | null) {
props.user.doc.language = value || props.user.originalDoc?.language;
}
function updateTimezone(value: string | null) {
function updateTimezone(value: { label: string; value: string } | null) {
if (!props.user.doc) return;
props.user.doc.time_zone = value || props.user.originalDoc?.time_zone;
props.user.doc.time_zone = value?.value || props.user.originalDoc?.time_zone;
}
const timezoneOptions = ref<{ label: string; value: string }[]>([]);
createResource({
url: "frappe.core.doctype.user.user.get_timezones",
auto: true,
onSuccess(data: { timezones: string[] }) {
timezoneOptions.value = data.timezones.map((tz) => ({
label: tz,
value: tz,
}));
},
});
</script>

View File

@@ -16,7 +16,7 @@
<div
v-for="option in themeOptions"
:key="option.value"
class="flex-1 rounded-6 border cursor-pointer min-h-[42px]"
class="flex-1 rounded-lg border cursor-pointer min-h-[42px]"
:class="
theme === option.value
? 'border-outline-gray-7'
@@ -57,7 +57,7 @@
<component
:is="logo"
v-else-if="logo"
class="size-5 shrink-0 rounded-4"
class="size-5 shrink-0 rounded"
/>
<div>{{ __(name) }}</div>
</div>
@@ -100,7 +100,7 @@
<script setup lang="ts">
import { __ } from "@/translation";
import { useColorScheme, type ColorScheme } from "frappe-ui";
import { useTheme, type Theme } from "frappe-ui";
import { computed, type Component } from "vue";
type Pane = {
@@ -112,7 +112,7 @@ type Pane = {
const props = withDefaults(
defineProps<{
/** Controlled value. When omitted the global frappe-ui theme is used. */
modelValue?: ColorScheme;
modelValue?: Theme;
/** Brand logo shown in the previews: image URL or component. */
logo?: string | Component;
/** Brand name shown in the previews. */
@@ -121,12 +121,12 @@ const props = withDefaults(
{ logo: "", name: "" }
);
const emit = defineEmits<{ "update:modelValue": [theme: ColorScheme] }>();
const emit = defineEmits<{ "update:modelValue": [theme: Theme] }>();
const { colorScheme, setColorScheme } = useColorScheme();
const { currentTheme, setTheme } = useTheme();
const themeOptions: {
value: ColorScheme;
value: Theme;
label: string;
panes: Pane[];
bars: boolean;
@@ -139,7 +139,7 @@ const themeOptions: {
{
tone: "light",
containerClass: "pl-5 pt-3.5 bg-surface-gray-2 rounded-t-[10.5px]",
screenClass: "bg-white rounded-tl-1",
screenClass: "bg-white rounded-tl-sm",
},
],
},
@@ -151,7 +151,7 @@ const themeOptions: {
{
tone: "dark",
containerClass: "pl-5 pt-3.5 bg-surface-gray-2 rounded-t-[10.5px]",
screenClass: "bg-gray-900 rounded-tl-1",
screenClass: "bg-gray-900 rounded-tl-sm",
},
],
},
@@ -164,13 +164,13 @@ const themeOptions: {
tone: "light",
containerClass:
"flex flex-1 pl-5 pt-3.5 bg-surface-gray-2 rounded-tl-[10.5px]",
screenClass: "bg-white rounded-tl-1 w-full",
screenClass: "bg-white rounded-tl-sm w-full",
},
{
tone: "dark",
containerClass:
"flex flex-1 pl-5 pt-3.5 bg-surface-gray-3 rounded-tr-[10.5px]",
screenClass: "bg-gray-900 rounded-tl-1 w-full",
screenClass: "bg-gray-900 rounded-tl-sm w-full",
},
],
},
@@ -180,15 +180,15 @@ const logoIsImage = computed(
() => typeof props.logo === "string" && props.logo.length > 0
);
const theme = computed<ColorScheme>({
const theme = computed<Theme>({
get() {
const value = props.modelValue ?? colorScheme.value;
const value = props.modelValue ?? currentTheme.value;
if (value === "light") return "light";
if (value === "dark") return "dark";
return "system";
},
set(value) {
setColorScheme(value);
setTheme(value);
emit("update:modelValue", value);
},
});

View File

@@ -23,7 +23,7 @@
/>
<div
v-if="agentStatusStore.myStatus"
class="absolute -bottom-0.5 end-0 rounded-full bg-surface-elevation-2 p-1"
class="absolute bottom-0.5 right-0.5 rounded-full bg-surface-elevation-2 p-1"
>
<div
class="size-3.5 rounded-full"
@@ -32,24 +32,26 @@
"
/>
</div>
<!-- one Tooltip each: it wires only its first child -->
<Tooltip :hoverDelay="0" side="bottom" :text="uploadTooltip">
<Tooltip
:hoverDelay="0"
placement="bottom"
:text="profileTooltipText"
>
<div
class="z-1 absolute top-0 left-0 flex h-9 cursor-pointer items-center justify-center rounded-full !size-16"
@click.stop="openFileSelector"
/>
</Tooltip>
<Tooltip
v-if="user.doc?.user_image"
:hoverDelay="0"
side="bottom"
:text="__('Remove Photo')"
>
<div
class="z-1 size-4 absolute -top-1 -right-1 flex cursor-pointer items-center justify-center rounded-full bg-surface-base opacity-0 duration-300 ease-in-out group-hover:opacity-100 [@media(hover:none)]:opacity-100 hover:bg-surface-gray-2 outline outline-black-overlay-50"
v-if="user.doc?.user_image"
class="z-1 size-4 absolute -top-1 -right-1 flex cursor-pointer items-center justify-center rounded-full bg-surface-base opacity-0 duration-300 ease-in-out group-hover:opacity-100 hover:bg-surface-gray-2 outline outline-black-overlay-50"
@click.stop="updateImage()"
@mouseenter="isHoveringRemove = true"
@mouseleave="isHoveringRemove = false"
>
<LucideX class="size-3.5 cursor-pointer text-ink-gray-4" />
<FeatherIcon
name="x"
class="size-3.5 cursor-pointer text-ink-gray-4"
/>
</div>
</Tooltip>
<div
@@ -59,39 +61,10 @@
<LoadingIndicator class="size-4" />
</div>
</div>
<div class="flex flex-col gap-1">
<div class="flex flex-col gap-1">
<div v-if="!editName" class="flex items-end gap-1">
<span
class="text-md sm:text-xl !font-semibold text-ink-gray-8"
>
{{ user?.doc?.full_name }}
</span>
<Button
class="!px-1 !h-5"
variant="ghost"
@click="editFullName"
>
<EditIcon class="size-3.5" />
</Button>
</div>
<div v-else class="flex items-center gap-1">
<TextInput
ref="fullNameRef"
v-model="fullName"
@keydown.enter="isNameDirty ? save() : (editName = false)"
@keydown.esc.stop="editName = false"
/>
<Button
variant="outline"
icon="lucide-check"
:loading="user?.save?.loading"
:disabled="user?.save?.loading"
@click="isNameDirty ? save() : (editName = false)"
/>
</div>
<span class="text-p-sm text-ink-gray-6">
{{ user?.doc?.email }}
<div class="flex flex-col gap-0.5 min-w-0">
<div v-if="!editName" class="flex items-center gap-1">
<span class="text-lg font-semibold text-ink-gray-9 truncate">
{{ user?.doc?.full_name }}
</span>
</div>
</div>
@@ -166,7 +139,6 @@
</template>
<script setup lang="ts">
import LucideX from "~icons/lucide/x";
import {
Avatar,
Button,
@@ -184,6 +156,7 @@ const emit = defineEmits(["updateStep"]);
import AvailabilityMenu from "@/components/AvailabilityMenu.vue";
import SettingsLayoutBase from "@/components/layouts/SettingsLayoutBase.vue";
import { useAvailability } from "@/composables/useAvailability";
import { useAgentStatusStore } from "@/stores/agentStatus";
import ChangePasswordModal from "./components/ChangePasswordModal.vue";
@@ -193,11 +166,13 @@ const showChangePasswordModal = ref(false);
const { userId, hasAgentRecord } = useAuthStore();
const user = createDocumentResource({ doctype: "User", name: userId });
const isHoveringRemove = ref(false);
const editName = ref(false);
const uploadTooltip = computed(() =>
user.doc?.user_image ? __("Change Photo") : __("Upload Photo")
);
const profileTooltipText = computed(() => {
if (isHoveringRemove.value) return __("Remove Photo");
return user.doc?.user_image ? __("Change Photo") : __("Upload Photo");
});
const fullNameRef = useTemplateRef("fullNameRef");
const fullName = computed({
@@ -212,7 +187,7 @@ const fullName = computed({
function editFullName() {
editName.value = true;
nextTick(() => fullNameRef.value?.focus());
nextTick(() => fullNameRef.value?.el?.focus());
}
const isNameDirty = computed(() => {
@@ -235,6 +210,7 @@ function save() {
}
function updateImage(fileUrl = "") {
isHoveringRemove.value = false;
user.doc.user_image = fileUrl;
save();
}

View File

@@ -10,7 +10,7 @@
<Button
variant="solid"
:label="__('Update')"
:loading="user.save.loading || saveEmailAccountsResource.loading"
:loading="user?.save?.loading"
@click="update"
/></div
></Transition>
@@ -28,10 +28,6 @@
<div>
<CompactEditor
v-model="user.doc.email_signature"
:upload-fn="
(file: any, options: any) =>
uploadFunction(file, 'User', userId, false, options)
"
:placeholder="__('Write your email signature here.')"
/>
</div>
@@ -51,8 +47,8 @@
</div>
<div>
<div
v-if="linkedEmails.length"
class="w-full border rounded-5 mb-2 border-outline-elevation-2"
v-if="user.doc.user_emails?.length"
class="w-full border rounded-md mb-2 border-outline-elevation-2"
>
<div
class="grid grid-cols-[4fr_4fr_0.3fr] gap-2 px-4 py-3 text-sm-medium text-ink-gray-5 border-b border-outline-elevation-2"
@@ -62,50 +58,48 @@
<span></span>
</div>
<div
v-for="e in linkedEmails"
:key="e.email_account"
v-for="e in user.doc.user_emails"
:key="e.name"
class="grid grid-cols-[4fr_4fr_0.3fr] gap-2 group items-center px-4 py-2.5 text-base border-b border-outline-elevation-2 last:border-b-0"
>
<span class="text-ink-gray-8 font-medium truncate">
{{ e.email_account }}
</span>
<span class="text-ink-gray-6 truncate">{{ e.email_id }}</span>
<div
class="group-hover:opacity-100 opacity-0 transition-opacity [@media(hover:none)]:opacity-100"
>
<div class="group-hover:opacity-100 opacity-0 transition-opacity">
<Button
class="w-10"
variant="ghost"
:tooltip="__('Remove')"
:aria-label="__('Remove')"
icon="lucide-x"
@click.prevent="removeEmail(e)"
/>
</div>
</div>
</div>
<Combobox
:model-value="null"
<Autocomplete
value=""
:options="filteredEmails"
@update:selected-option="(option) => option && addEmail(option)"
@change="(e) => addEmail(e)"
>
<template #trigger>
<template #target="{ togglePopover }">
<Button
class="!bg-surface-elevation-2"
variant="outline"
:label="__('Add Email')"
iconLeft="lucide-plus"
@click="togglePopover()"
/>
</template>
<template #item-label="{ item }">
<template #item-label="{ option }">
<div class="flex flex-col gap-1 text-ink-gray-9">
<div>{{ item.label }}</div>
<div>{{ option.label }}</div>
<div class="text-ink-gray-4 text-sm">
{{ item.email }}
{{ option.email }}
</div>
</div>
</template>
</Combobox>
</Autocomplete>
</div>
</div>
</template>
@@ -129,18 +123,13 @@
<script setup>
import CompactEditor from "@/components/CompactEditor.vue";
import ConfirmDialog from "@/components/ConfirmDialog.vue";
import Autocomplete from "@/components/frappe-ui/Autocomplete.vue";
import SettingsLayoutBase from "@/components/layouts/SettingsLayoutBase.vue";
import { getUserEmailInfo } from "@/composables/useUserEmailInfo";
import { useAuthStore } from "@/stores/auth";
import { __ } from "@/translation";
import { normalize, uploadFunction } from "@/utils";
import {
Button,
Combobox,
createDocumentResource,
createResource,
toast,
} from "frappe-ui";
import { normalize } from "@/utils";
import { Badge, Button, createDocumentResource, toast } from "frappe-ui";
import { computed, ref, watch } from "vue";
import { disableSettingModalOutsideClick } from "../settingsModal";
@@ -150,41 +139,16 @@ const emit = defineEmits(["updateStep"]);
const currentUserEmailInfo = getUserEmailInfo();
// user_emails is System Manager-only, so the User doc never carries it for
// agents; the list comes from the email info API and is saved through it
const linkedEmails = ref([]);
watch(
() => currentUserEmailInfo.data?.outgoing_emails,
(emails, previousEmails) => {
// the info is shared with the composer; a reload from there must not
// wipe unsaved edits here
if (
sortedAccountNames(linkedEmails.value) !==
sortedAccountNames(previousEmails)
)
return;
linkedEmails.value = [...(emails || [])];
},
{ immediate: true }
);
const saveEmailAccountsResource = createResource({
url: "helpdesk.api.auth.set_user_email_accounts",
makeParams: () => ({
email_accounts: linkedAccountNames(linkedEmails.value),
}),
});
const filteredEmails = computed(() => {
if (!currentUserEmailInfo.data?.available_emails) return [];
const linkedAccounts = linkedAccountNames(linkedEmails.value);
const linkedEmails = user.doc.user_emails?.map((e) => e.email_id) || [];
return currentUserEmailInfo.data.available_emails
.map((doc) => ({
label: doc.name,
value: doc.name,
email: doc.email_id,
}))
.filter((e) => !linkedAccounts.includes(e.value));
.filter((e) => !linkedEmails.includes(e.email));
});
const isSignatureDirty = computed(() => {
@@ -195,9 +159,10 @@ const isSignatureDirty = computed(() => {
});
const isUserEmailListDirty = computed(() => {
const emailIds = (list = []) => list.map((e) => e.email_id).sort();
return (
sortedAccountNames(currentUserEmailInfo.data?.outgoing_emails) !==
sortedAccountNames(linkedEmails.value)
JSON.stringify(emailIds(currentUserEmailInfo.data?.outgoing_emails)) !==
JSON.stringify(emailIds(user.doc.user_emails))
);
});
@@ -211,39 +176,28 @@ if (isDirty.value) {
disableSettingModalOutsideClick.value = false;
}
function linkedAccountNames(list = []) {
return list.map((e) => e.email_account);
}
function sortedAccountNames(list) {
return linkedAccountNames(list).sort().join();
}
function addEmail(email) {
linkedEmails.value.push({
email_account: email.value,
if (!user.doc.user_emails) user.doc.user_emails = [];
user.doc.user_emails.push({
email_account: email.label,
email_id: email.email,
});
}
function removeEmail(email) {
linkedEmails.value = linkedEmails.value.filter(
(e) => e.email_account !== email.email_account
user.doc.user_emails = user.doc.user_emails.filter(
(e) => e.email_id !== email.email_id
);
}
async function update() {
// one after the other, since both save the same User doc
try {
if (isSignatureDirty.value) await user.save.submit();
if (isUserEmailListDirty.value) await saveEmailAccountsResource.submit();
} catch {
return; // the fallback error handler already showed a toast
}
toast.success(__("Email settings updated successfully."));
user.reload();
await currentUserEmailInfo.reload();
linkedEmails.value = [...currentUserEmailInfo.data.outgoing_emails];
function update() {
user.save.submit(null, {
onSuccess: () => {
toast.success(__("Email settings updated successfully."));
currentUserEmailInfo.reload();
user.reload();
},
});
}
watch(isDirty, (val) => {

View File

@@ -60,7 +60,7 @@
</template>
<script setup lang="ts">
import LockKeyhole from "~icons/lucide/lock-keyhole";
import { createResource, Dialog, Password, toast } from "frappe-ui";
import { Dialog, toast, createResource } from "frappe-ui";
import { ref, watch } from "vue";
import { __ } from "@/translation";
import { useAuthStore } from "@/stores/auth";

View File

@@ -39,16 +39,12 @@
class="absolute end-1 top-1/2 -translate-y-1/2"
/>
</div>
<Dropdown
:options="filterOptions"
align="end"
@update:open="(open) => open && (isConfirmingDelete = false)"
>
<Dropdown :options="filterOptions" placement="right">
<template #default="{ open }">
<Button :label="activeFilterLabel">
<template #suffix>
<component
:is="open ? LucideChevronUp : LucideChevronDown"
<FeatherIcon
:name="open ? 'chevron-up' : 'chevron-down'"
class="h-4"
/>
</template>
@@ -60,11 +56,11 @@
<template #content>
<div
v-if="savedRepliesListResource?.list?.loading"
class="flex items-center justify-center absolute inset-x-0 top-5.5 bottom-0"
class="flex items-center justify-center my-auto"
>
<LoadingIndicator class="w-4" />
</div>
<EmptyState
<div
v-if="
!savedRepliesListResource?.list?.loading &&
!savedRepliesListResource?.data?.length
@@ -94,7 +90,7 @@
:key="savedReply.name"
>
<div
class="grid grid-cols-12 items-center gap-4 cursor-pointer hover:bg-surface-sidebar rounded-4"
class="grid grid-cols-12 items-center gap-4 cursor-pointer hover:bg-surface-sidebar rounded"
>
<div
@click="
@@ -134,15 +130,14 @@
/>
{{ savedReply.scope }}
</div>
<!-- the confirm state is shared, so each menu clears it on open -->
<Dropdown
align="end"
placement="right"
:options="dropdownOptions(savedReply)"
@update:open="(open) => open && (isConfirmingDelete = false)"
>
<Button
icon="lucide-more-horizontal"
variant="ghost"
@click="isConfirmingDelete = false"
class="me-2"
/>
</Dropdown>
@@ -183,9 +178,6 @@
</template>
<script setup lang="ts">
import LucideChevronUp from "~icons/lucide/chevron-up";
import LucideChevronDown from "~icons/lucide/chevron-down";
import EmptyState from "@/components/EmptyState.vue";
import { useConfigStore } from "@/stores/config";
import { __ } from "@/translation";
import { ConfirmDelete } from "@/utils";
@@ -194,12 +186,14 @@ import {
Button,
call,
Dropdown,
FeatherIcon,
LoadingIndicator,
TextInput,
toast,
} from "frappe-ui";
import { storeToRefs } from "pinia";
import { computed, inject, ref, Ref, watch } from "vue";
import EmptyState from "@/components/EmptyState.vue";
import GlobeIcon from "~icons/lucide/globe";
import UserIcon from "~icons/lucide/user";
import UsersIcon from "~icons/lucide/users";

View File

@@ -55,7 +55,7 @@
</div>
<div class="space-y-1.5">
<Select
:label="__('Visibility')"
label="Scope"
v-model="savedReplyData.scope"
:options="scopeDropdownOptions"
required
@@ -67,11 +67,12 @@
</Select>
<FormLabel
:label="__('Choose who can view and use this response.')"
size="md"
/>
</div>
</div>
<div v-if="savedReplyData.scope === 'Team'" class="space-y-1.5">
<FormLabel :label="__('Teams')" required />
<FormLabel :label="__('Teams')" required size="md" />
<MultiSelect
:options="teamsList"
v-model="savedReplyData.teams"
@@ -86,7 +87,7 @@
</div>
<div class="space-y-1.5">
<div class="flex items-center justify-between">
<FormLabel :label="__('Response')" required />
<FormLabel :label="__('Response')" required size="md" />
<DocumentationButton
url="https://docs.frappe.io/helpdesk/saved-replies"
/>
@@ -95,16 +96,6 @@
<CompactEditor
ref="content"
v-model="savedReplyData.message"
:upload-fn="
(file: any, options: any) =>
uploadFunction(
file,
'HD Saved Reply',
savedReplyData.name,
false,
options
)
"
:extensions="[FieldAutocomplete]"
:placeholder="
__(
@@ -138,7 +129,6 @@ import DocumentationButton from "@/components/DocumentationButton.vue";
import { useAuthStore } from "@/stores/auth";
import { useConfigStore } from "@/stores/config";
import { __ } from "@/translation";
import { uploadFunction } from "@/utils";
import {
Button,
createListResource,
@@ -152,6 +142,7 @@ import {
toast,
} from "frappe-ui";
import { storeToRefs } from "pinia";
import UnsavedBadge from "@/components/UnsavedBadge.vue";
import { computed, inject, onUnmounted, ref, watch } from "vue";
import GlobeIcon from "~icons/lucide/globe";
import UserIcon from "~icons/lucide/user";
@@ -230,11 +221,9 @@ const scopeDropdownOptions = computed(() => {
const getSavedReplyData = createResource({
url: "frappe.client.get",
makeParams() {
return {
doctype: "HD Saved Reply",
name: savedRepliesActiveScreen.value.data?.name,
};
params: {
doctype: "HD Saved Reply",
name: savedRepliesActiveScreen.value.data?.name,
},
auto: false,
onSuccess: (data: SavedReply) => {

View File

@@ -8,17 +8,6 @@
:placeholder="placeholder"
@update:model-value="emit('update:modelValue', $event as string)"
/>
<Link
v-else-if="config.control === 'link'"
class="w-full"
variant="ghost"
:doctype="config.doctype!"
:filters="linkFilters(type)"
:model-value="(modelValue as string)"
:placeholder="placeholder"
:title="(modelValue as string)"
@update:model-value="emit('update:modelValue', ($event ?? '') as string)"
/>
<Combobox
v-else-if="config.control === 'combobox'"
class="w-full"
@@ -28,6 +17,7 @@
:options="options"
:placeholder="placeholder"
@update:model-value="emit('update:modelValue', $event as string)"
@update:query="emit('search', $event)"
>
<template v-if="type === 'Assign Agent'" #item-prefix="{ item }">
<Avatar size="xs" :image="item.image" :label="item.label" />
@@ -95,15 +85,13 @@
<script setup lang="ts">
import { buildEditorExtensions } from "@/components/editor/config";
import TagChip from "@/components/tag/TagChip.vue";
import { useSavedReplyActionOptions } from "@/composables/useSavedReplyActionOptions";
import { colorToken } from "@/composables/useTags";
import { __ } from "@/translation";
import { SavedReplyActionType } from "@/types";
import { Link } from "@framework/ui";
import { Avatar, Combobox, MultiSelect, Select } from "frappe-ui";
import { Editor, EditorContent } from "frappe-ui/editor";
import { computed } from "vue";
import { ACTION_TYPES } from "./actionTypes";
import { ACTION_TYPES, type ActionOption } from "./actionTypes";
const props = defineProps<{
type: SavedReplyActionType;
@@ -113,10 +101,9 @@ const props = defineProps<{
const emit = defineEmits<{
"update:modelValue": [value: string | string[]];
search: [query: string];
}>();
const { linkFilters } = useSavedReplyActionOptions();
const config = computed(() => ACTION_TYPES[props.type]);
const placeholder = computed(() =>
__("Select {0}", (config.value.fieldname || __("a value")).toLowerCase())

View File

@@ -1,12 +1,12 @@
<template>
<div class="space-y-3">
<div class="flex flex-col gap-1">
<span class="text-md-medium text-ink-gray-8">{{ __("Actions") }}</span>
<span class="text-lg-medium text-ink-gray-8">{{ __("Actions") }}</span>
<span class="text-p-base text-ink-gray-6">
{{ __("Applied to the ticket when this reply is sent") }}
</span>
</div>
<div class="rounded-5 border border-outline-gray-2 px-1 text-sm">
<div class="rounded-md border border-outline-gray-2 px-1 text-sm">
<template v-if="rows.length">
<div
class="grid items-center gap-6 p-2"
@@ -47,11 +47,12 @@
:model-value="row.value"
:options="valueOptions(row.action_type)"
@update:model-value="row.value = $event"
@search="search(row.action_type, $event)"
/>
</div>
<div class="flex min-h-8 items-center justify-end">
<Dropdown
align="end"
placement="right"
:options="[
{
label: __('Delete'),
@@ -121,8 +122,11 @@ defineProps<{
const actions = defineModel<SavedReplyAction[]>({ required: true });
const { valueOptions: sharedValueOptions, tagOptions } =
useSavedReplyActionOptions();
const {
valueOptions: sharedValueOptions,
tagOptions,
search,
} = useSavedReplyActionOptions();
const columns = [
{ key: "action_type", label: __("Action"), width: "190px" },

Some files were not shown because too many files have changed in this diff Show More