Show provider name in view mode + own extension in edit dropdown
Two bugs on **************** 1. View mode dumped the raw UUID — "Instance 32f520b0-347a-…" — because the instance list was only loaded inside handleVoipEdit...
Show sales type path in Add Lead subtitle
Append the market's Sales Type and Sub-Type to the "Adding to" line so the form mirrors the labels used in the Edit Market popup at **************** Renders as ...
Move Create Lead action into header, drop sticky bar
Replace the top-right Cancel button with the primary Create Lead action and remove the bottom sticky action bar entirely. Add a back IconButton to the left of t...
Scope Add Lead scroll and footer to its content area
The form was using minHeight: 100vh inside a parent that's already calc(100vh - 56px), forcing an outer scrollbar even when content fit. The action bar also use...
Unified PhoneSdk supporting RingCentral + sip.js (FreePBX)
The softphone hook used to instantiate ringcentral-web-phone unconditionally, which threw on any FreePBX credential shape because that SDK is hard-coded to Ring...
Smart multi-column layout for Add Lead form
Restructure the page into a top-level grid so sections compose horizontally instead of stretching individual fields: - Market & Assignment uses a 3-col interio...
Use /api/security/members/names for assigned-member name resolution
The by-department endpoint filters to active TeamMembers only, missing assignments to base Members or inactive members. Switch to /names which returns all membe...
Make Best Contact Time a free-text field
Replace the Morning/Afternoon/Evening dropdown on the Add Lead and Lead View edit forms with a plain text input so members can describe specific windows (e.g., ...
Full-width Add Lead form and clearance for sticky footer
Drop the 1200px max-width on /leads/new so the form spans the page area, and bump bottom padding so the sticky action bar no longer overlaps the last form secti...
Single-lead Add Lead form at /leads/new
Refactor Add Lead from an in-page multi-tab pane into a dedicated route at /leads/new so it can be linked directly. The current market is passed through as ?mar...
Add missing isDisplayOnIntake field to FormField interface and new field literal
Add member name display and unassign button to per-instance extensions tab
Show member names and add Unassign action to org-level extensions tab
Wire VOIP configuration to provider+extension selectors with assignment enforcement
Add typed DTOs, unassign API method, and update MembershipPermissionsTab VOIP types
Probe master model endpoint and fix appliedModel org ID
- Replace appliedModel.source-based gate with a direct probe of /api/security/master-model on mount; r.ok=false (409) means the org is governed by a branch ...
Gate censorship tab options by applied model constraints
- Hide EDIT MASTER MODEL button when org is governed by a branch type (use appliedModel.source instead of unreliable org context branchTypeID) - Hide ATF fiel...
Persist active mailbox in URL query params
Switching mailboxes now updates the URL (?mailboxType, ?mailboxId, ?mailbox) so refreshing the browser restores the same mailbox. MessageBrowser reads window.lo...
Mark-as-read and message fetch for shared/member mailboxes
Classic mode now loads shared mailbox messages via the correct /messages/{folder} endpoint (was calling the non-existent /conversations endpoint). Fetching a fu...
Show accurate provider connection status from isConnected field
Replaces the old logic that showed "Connected" for any provider with no sync error (including brand-new providers that were never tested). New three-state badg...
Wire Available/Unavailable switch to backend and fix OFFLINE presence bug
- Rename Paused/Active chip to Available/Unavailable in NavTop - Fetch initial availability on mount and persist toggles via new me/availability API - Add isAva...
Pass selectedFolder to ThreadDetailView so email:folder-changed fires with a valid folder
conversation.folder is always undefined because the Java ConversationEntity has folderIds (text[]) not a folder string field. This caused loadThread to call mar...
Sync mailbox dropdown to primary mailbox on load
Dropdown defaulted to first list item because selectedMailbox initialized without a mailboxId, causing currentValue to resolve to bare 'personal' which matched ...
Surface HTTP errors so upload failures are visible
Replaced silent console.warn with a thrown Error on non-OK status, so the user sees the actual failure reason (status + response body) instead of silently proce...
Trust backend pendingCount, drop client offsets
Backend pendingCount is now unread-based (counts SUPPORT_TICKET sessions with messages newer than the owner's lastViewed). When the agent opens a ticket, markAs...
MarkAsRead after agent send so lastViewed advances
On support tickets, both visitor and agent messages are stored under the same systemMember, so the unread-count query is member-agnostic and relies entirely on ...
Add logging to upload-background proxy route
Log org/index, file name/size/type, and upstream response status to diagnose why background uploads are not reaching APIService.
Add Location column to ticket datagrid
Reads **************** straight off the SupportTicketDTO (now snapshot on the ticket entity at creation time — no extra round trip). Renders flag + city/region/...
Pass folder to loadThread retry button
loadThread takes (threadId, folder); the error-state retry button only passed threadId, breaking the kamo-internal build. Match the call to the signature.
Per-ticket unread badge + 'New messages only' filter
- Ticket list shows a chat-bubble badge with the unread count next to ticket# whenever the session has messages newer than the agent's last viewed message. ...
Clear unread indicators when conversation is opened
ThreadDetailView now dispatches email:folder-changed after markConversationRead succeeds so MailButton refetches the navtop inbox badge count. ConversationListV...
Break min-w-0 chain to contain email scroll in body column only
Add min-w-0 to outer container and main content flex div so flex children cannot expand to email min-content width, which was causing the page-wide horizontal s...
Hoist providers above ToolProviders
Same root cause as the ChatWebSocketProvider hoist: SupportTicketWindow calls **************** and ChatBox calls useUnread().markAsRead(), but both tool windows...
Remove debug console.log statements and add missing routes
Remove all temporary debug logging added during WebSocket tracing from ChatBox, TicketChat, MemberItem, ChatTool, and useChatWebSocket; add redirect pages for /...
Prevent message header from expanding column on long addresses
The header's left flex child had no min-w-0, so long unbreakable email addresses in From/To/Cc forced its min-content width to grow, dragging the header (and th...
Hoist ChatWebSocketProvider above ToolProviders
ToolDock (and its tool windows like SupportTicketWindow → TicketChat) is mounted inside ToolProviders, which sits ABOVE PresenceWrapper in the tree to avoid unm...
Drop Shadow DOM in email renderer so overflow-x-auto fires
Shadow DOM was the root cause. Wide email content (fixed-width tables) inside the shadow tree painted past the host without contributing to the host's layout bo...
Align ChatWebSocketContext import path to match provider
TicketChat and ChatNotificationListener imported the context via the '@/app/contexts/...' alias while PresenceWrapper (the provider) imports it via the relative...
Temporary console.log to trace TicketChat STOMP subscription path
Adds console logs at every stage of the subscribe pipeline (effect fire, guard pass, subscribe() call, attachSessionSubscription, client.subscribe, /app/chat/su...
Force shadow host containment with inline styles + contain: layout
Class-based overflow-x-auto on the shadow host wasn't reliably winning against the shadow ':host { all: initial }' reset, so wide email content (fixed-width tab...
Scroll wide email content inside shadow DOM, not outside
The previous attempts at adding overflow-x-auto to light DOM ancestors could not catch wide email content because the shadow tree's visual paint overflow does n...
Like what you see shipping?
All of it arrives in your workspace on its own. Start on the free plan and read this page again in a month.
