Two bugs reported after v1.1.2:
1. False-negative "נכשלו" toast even though the file was on disk. Root
cause from the log: Polly's 15s timeout on /NetworkStorage/action/upload
fires while the server is still writing larger PDFs, so the client sees
TimeoutRejectedException → Outcome.Failed, while the server quietly
finishes the write. The outcome is now decided by listing the target
folder, not by the upload response. If the upload exception fires, the
listing is retried up to 4 times with 2s delays to let the server
finish. Saved if the file appears, Failed only if it never does.
2. The filename TextBox in the attachments list exposed the extension
(.pdf / .docx). Users have to delete it manually when renaming and
risk dropping it. AttachmentRowViewModel now splits FileName into
BaseName (editable) and Extension (frozen at construction). The XAML
binds the TextBox to BaseName and shows the Extension as a muted
adjacent chip. The on-disk filename = BaseName + Extension always.
Bump to 1.1.3.0 for the patch release.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- DataGrid case picker now shows status via CaseStatusToHebrewConverter
(added PendingHearing / PendingDecision mappings)
- Attachment row replaces the read-only filename TextBlock with a TwoWay
TextBox so users can rename a file before saving (flows through
EspoAttachment.Name into the upload + the on-disk path)
- SaveAttachmentsViewModel.IsLoadingSubfolders gates the folder ComboBox
while EnsureCaseSubfolders / GetCase / ListNetworkStorageFolder run,
so users can't pick a stale "(שורש התיק)" before the real list arrives
- About tab: ResolveDisplayVersion now reads from the host VSTO assembly
(*.OutlookAddin) instead of the UI assembly. The UI csproj is SDK-style
with no <Version> so it always reported 1.0.0.0, which leaked into the
About line on dev installs
- Bump to 1.1.2.0 (csproj + AssemblyInfo) to match the v1.1.2 tag that
will trigger the Gitea Actions auto-publish to platform.dev
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
New workflow alongside "תייק ל-Klear": save just the attachments of a
mail to a Case in EspoCRM (no Email entity created), with an optional
DocumentFolder.
Core:
- AttachmentEntity, DocumentEntity, DocumentFolder DTOs
- IEspoCrmClient gets three new endpoints:
UploadAttachmentAsync (POST /Attachment, data-URI base64, role=Attachment)
CreateDocumentAsync (POST /Document, fileId + parent + folderId)
ListDocumentFoldersAsync (GET /DocumentFolder, returns envelope)
- AttachmentSaveService orchestrates per-attachment upload + Document
create, short-circuits on EspoCrmAuthorizationException, aggregates
per-file Saved/Failed/AuthRequired outcomes into AttachmentSaveSummary
UI:
- SaveAttachmentsDialog (RTL, card layout matching FileToCaseDialog):
Case search + folder dropdown + per-attachment checkbox list
- SaveAttachmentsViewModel: debounced GlobalSearch filtered to Case,
optional folder selector (with a "(no folder)" sentinel row),
Attachments collection of AttachmentRowViewModel rows
- AttachmentRowViewModel: IsSelected checkbox + display name + size
computed from base64 length
Host:
- AddInHost.LaunchSaveAttachmentsAsync(MailItem) — extracts on the STA
via MailItemExtractor, fetches folders, shows the dialog (anchored to
Outlook via AttachOwnerToOutlook), runs AttachmentSaveService on OK,
reports a Hebrew MessageBox summary
- AttachmentSaveService field on AddInHost + dispose hook
Ribbon:
- New "שמור קבצים" button in the Marcus-Law group, between Klear and
פרטי תיק. Enabled only when exactly one MailItem is selected and it
has at least one attachment
- klear-attach.png paperclip icon (32x32, blue rounded square),
embedded as a resource and resolved by the existing OnGetImage
callback (new case in the switch)
Tests: 39 still passing.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>