feat: in-app updater button + correct case-folder resolution
Two related improvements:
1. About tab → "בדוק עדכונים" button. Calls ClickOnce's
ApplicationDeployment.CurrentDeployment.CheckForDetailedUpdate +
Update on background threads, so the user can pull a new release
immediately without leaving Outlook — no PowerShell, no
CleanOnlineAppCache dance.
Status messages cover the four real outcomes:
• not deployed via ClickOnce (F5 / dev install) → explicit error
• on the latest version → green "already up to date"
• update available → progress text, then "installed — restart
Outlook"
• download / manifest / generic exception → red, with reason
2. Case folder resolution now matches the server. The previous client
logic used Case.name (the lawsuit title, e.g. "מונאס אריאל נ' ביטוח
לאומי") which produced "47-מונאס אריאל נ ביטוח לאומי". But
NetworkStorageIntegration's buildEntityFolderName uses the primary
contact's name from Case.contactsIds[0] → server actually creates
"47-אריאל מונאס" for the same case, so the two diverged and our
uploads went to a phantom folder.
New flow on case selection:
a) EnsureCaseSubfoldersAsync (creates server's canonical folders)
b) GetCase with select=contactsIds + networkStorageFolderPath
c) GetContactAsync on contactsIds[0] → grab Name
d) ResolveCaseFolderPath(case, contactName) → exact match
e) Cache result on vm.ResolvedCaseFolderPath; AddInHost reads it
instead of recomputing.
ResolveCaseFolderPath fallback order is now (1) the integration's
stored path, (2) <number>-<primary contact name>, (3) <number>-<case
name>, (4) the contact / case name alone — matching the server's
buildEntityFolderName logic step by step.
Tests: 39 passing.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -40,6 +40,15 @@ namespace MarcusLaw.OutlookAddin.UI.ViewModels
|
||||
[ObservableProperty]
|
||||
private Brush statusBrush = NeutralBrush;
|
||||
|
||||
[ObservableProperty]
|
||||
private string? updateStatus;
|
||||
|
||||
[ObservableProperty]
|
||||
private Brush updateStatusBrush = NeutralBrush;
|
||||
|
||||
[ObservableProperty]
|
||||
private bool isCheckingForUpdate;
|
||||
|
||||
public string InitialApiKey { get; }
|
||||
|
||||
public string VersionLine { get; }
|
||||
@@ -129,6 +138,66 @@ namespace MarcusLaw.OutlookAddin.UI.ViewModels
|
||||
|
||||
private static string WatchedKey(string storeId, string path) => storeId + "|" + path;
|
||||
|
||||
[RelayCommand(CanExecute = nameof(CanCheckForUpdate))]
|
||||
private async Task CheckForUpdateAsync()
|
||||
{
|
||||
IsCheckingForUpdate = true;
|
||||
UpdateStatusBrush = NeutralBrush;
|
||||
UpdateStatus = "בודק עדכונים…";
|
||||
try
|
||||
{
|
||||
if (!System.Deployment.Application.ApplicationDeployment.IsNetworkDeployed)
|
||||
{
|
||||
UpdateStatusBrush = ErrorBrush;
|
||||
UpdateStatus = "התוסף לא מותקן דרך ClickOnce — אין כאן עדכון אוטומטי.";
|
||||
return;
|
||||
}
|
||||
|
||||
var deployment = System.Deployment.Application.ApplicationDeployment.CurrentDeployment;
|
||||
var info = await Task.Run(() => deployment.CheckForDetailedUpdate(false)).ConfigureAwait(true);
|
||||
if (!info.UpdateAvailable)
|
||||
{
|
||||
UpdateStatusBrush = SuccessBrush;
|
||||
UpdateStatus = "אתה על הגרסה האחרונה (" + deployment.CurrentVersion + ").";
|
||||
return;
|
||||
}
|
||||
|
||||
UpdateStatus = $"זמינה גרסה {info.AvailableVersion} — מוריד…";
|
||||
var result = await Task.Run(() => deployment.Update()).ConfigureAwait(true);
|
||||
UpdateStatusBrush = SuccessBrush;
|
||||
UpdateStatus = $"הותקנה גרסה {info.AvailableVersion}. סגור ופתח את Outlook כדי לטעון אותה.";
|
||||
}
|
||||
catch (System.Deployment.Application.DeploymentDownloadException ex)
|
||||
{
|
||||
_logger.Warning(ex, "CheckForUpdate: download failed");
|
||||
UpdateStatusBrush = ErrorBrush;
|
||||
UpdateStatus = "הורדת העדכון נכשלה: " + ex.Message;
|
||||
}
|
||||
catch (System.Deployment.Application.InvalidDeploymentException ex)
|
||||
{
|
||||
_logger.Warning(ex, "CheckForUpdate: invalid deployment manifest");
|
||||
UpdateStatusBrush = ErrorBrush;
|
||||
UpdateStatus = "ה-deployment manifest על השרת לא תקין: " + ex.Message;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Warning(ex, "CheckForUpdate failed");
|
||||
UpdateStatusBrush = ErrorBrush;
|
||||
UpdateStatus = "שגיאה בבדיקת עדכונים: " + ex.Message;
|
||||
}
|
||||
finally
|
||||
{
|
||||
IsCheckingForUpdate = false;
|
||||
}
|
||||
}
|
||||
|
||||
private bool CanCheckForUpdate() => !IsCheckingForUpdate;
|
||||
|
||||
partial void OnIsCheckingForUpdateChanged(bool value)
|
||||
{
|
||||
CheckForUpdateCommand.NotifyCanExecuteChanged();
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private async Task TestConnectionAsync()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user