feat(compose): Task #5 — Compose from Case + URL protocol + auto-file
UI:
- ComposeFromCaseDialog (RTL, search-then-pick a single Case via
GlobalSearch + entityType=Case filter)
- ComposeFromCaseViewModel — debounced GlobalSearch, returns chosen
EspoEntityRef
Host:
- ComposeService.ApplyCaseToMailAsync:
* fetches Case + primary Contact
* stamps UserProperties EspoCaseId, EspoCaseName, OutlookAddinGuid
* pre-fills To/Subject and appends an RTL footer with a CRM deep link
- ItemSend hook (in AddInHost.HookItemSend): when the user sends a
tagged compose, register guid → target with SentItemsWatcher
- SentItemsWatcher: rooted Items reference (prevents GC), 30s expiry
sweep, 2-min default timeout per pending tag, MailMatched event
- AddInHost.OnSentMailMatched: extracts the sent MailItem, files via
FilingService, stamps "Filed: {name}" category
- LaunchComposeFromCaseAsync (Inspector ribbon) and
LaunchComposeFromCaseByIdAsync (URL protocol) entry points
- NamedPipeListener (\.\pipe\MarcusLaw.OutlookAddin) — listens for
"COMPOSE <caseId>" lines, dispatches on WPF Dispatcher
Ribbon:
- InspectorRibbon.xml — "כתוב מתיק" button on Mail Compose ribbon, hidden
for received/read mail via getVisible
- ExplorerRibbon class now serves both Explorer and Inspector ribbons
(single IRibbonExtensibility, dispatches by ribbonID)
URL protocol:
- New OutlookAddinProtocolHandler console project (net48 WinExe):
parses outlookaddin://compose?caseId=<id>, connects to named pipe,
writes "COMPOSE <id>\n"
- tools/install-protocol.ps1 + uninstall-protocol.ps1 register the
scheme under HKCU\Software\Classes\outlookaddin
Core/UI/Tests + protocol handler all build; 38 unit tests still green.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
# Registers the `outlookaddin://` URL protocol in HKCU so that
|
||||
# clicking a link like `outlookaddin://compose?caseId=…` launches the
|
||||
# OutlookAddinProtocolHandler.exe shim, which forwards the request over
|
||||
# a named pipe to the running VSTO add-in.
|
||||
#
|
||||
# Usage:
|
||||
# .\install-protocol.ps1 -ExePath "C:\Path\To\OutlookAddinProtocolHandler.exe"
|
||||
#
|
||||
# Or, to derive the path automatically from a ClickOnce install:
|
||||
# .\install-protocol.ps1
|
||||
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[string]$ExePath
|
||||
)
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
if (-not $ExePath) {
|
||||
$candidate = Join-Path $env:LOCALAPPDATA "Apps\OutlookAddinProtocolHandler\OutlookAddinProtocolHandler.exe"
|
||||
if (Test-Path $candidate) {
|
||||
$ExePath = $candidate
|
||||
} else {
|
||||
throw "ExePath not supplied and default location not found: $candidate"
|
||||
}
|
||||
}
|
||||
|
||||
if (-not (Test-Path $ExePath)) {
|
||||
throw "Protocol handler not found: $ExePath"
|
||||
}
|
||||
|
||||
$root = "HKCU:\Software\Classes\outlookaddin"
|
||||
New-Item -Path $root -Force | Out-Null
|
||||
Set-ItemProperty -Path $root -Name "(default)" -Value "URL:OutlookAddin Protocol"
|
||||
Set-ItemProperty -Path $root -Name "URL Protocol" -Value ""
|
||||
|
||||
$shellCmd = Join-Path $root "shell\open\command"
|
||||
New-Item -Path $shellCmd -Force | Out-Null
|
||||
Set-ItemProperty -Path $shellCmd -Name "(default)" -Value ("`"" + $ExePath + "`" `"%1`"")
|
||||
|
||||
Write-Host "Registered outlookaddin:// -> $ExePath" -ForegroundColor Green
|
||||
@@ -0,0 +1,3 @@
|
||||
$ErrorActionPreference = 'SilentlyContinue'
|
||||
Remove-Item -Path "HKCU:\Software\Classes\outlookaddin" -Recurse -Force
|
||||
Write-Host "Removed outlookaddin:// protocol registration" -ForegroundColor Yellow
|
||||
Reference in New Issue
Block a user