Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b1dc57324e | |||
| 18b6640e57 | |||
| dbd7f3068b | |||
| b6624a924f | |||
| e3fb0e95d1 | |||
| 9e7a64045f | |||
| 017f10e60b |
@@ -0,0 +1,15 @@
|
||||
* text=auto
|
||||
|
||||
# ClickOnce publish output must be byte-identical to the hashes recorded
|
||||
# in dll.manifest at publish time. Treat everything under Publish/ as
|
||||
# binary so git's CRLF/LF normalization can't change the bytes between
|
||||
# what VS published and what end-users download via setup.exe.
|
||||
Publish/** -text
|
||||
|
||||
# Defense in depth — apply the same rule to ClickOnce extensions
|
||||
# regardless of where they live.
|
||||
*.deploy binary
|
||||
*.manifest binary
|
||||
*.vsto binary
|
||||
*.application binary
|
||||
*.pfx binary
|
||||
+8
-2
@@ -24,16 +24,22 @@ project.lock.json
|
||||
project.fragment.lock.json
|
||||
|
||||
# Publish output (ClickOnce / MSIX)
|
||||
publish/
|
||||
# NOTE: Publish/ itself is COMMITTED so end-users can fetch the ClickOnce
|
||||
# bundle via Gitea raw URLs (https://gitea.dev.marcus-law.co.il/.../raw/
|
||||
# branch/main/Publish/). VS dumps build output there on every Publish.
|
||||
PublishProfiles/
|
||||
*.pubxml.user
|
||||
|
||||
# VSTO build output
|
||||
# VSTO build output — these wildcards exclude intermediate bin/obj
|
||||
# artifacts. Re-include everything under Publish/ which is the
|
||||
# ClickOnce distribution root (must contain .vsto/.application/.deploy
|
||||
# /.manifest files for the installer to work).
|
||||
*_TemporaryKey.pfx
|
||||
*.vsto
|
||||
*.application
|
||||
*.deploy
|
||||
*.manifest
|
||||
!Publish/**
|
||||
|
||||
# Code signing — NEVER commit private keys
|
||||
*.pfx
|
||||
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
+35
@@ -0,0 +1,35 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<runtime>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Microsoft.Bcl.AsyncInterfaces" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-8.0.0.0" newVersion="8.0.0.0" />
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Microsoft.Extensions.DependencyInjection.Abstractions" publicKeyToken="adb9793829ddae60" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-8.0.0.2" newVersion="8.0.0.2" />
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Buffers" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.3.0" newVersion="4.0.3.0" />
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.ComponentModel.Annotations" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.2.1.0" newVersion="4.2.1.0" />
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
</configuration>
|
||||
BIN
Binary file not shown.
+588
@@ -0,0 +1,588 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<asmv1:assembly xsi:schemaLocation="urn:schemas-microsoft-com:asm.v1 assembly.adaptive.xsd" manifestVersion="1.0" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns="urn:schemas-microsoft-com:asm.v2" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:co.v1="urn:schemas-microsoft-com:clickonce.v1" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" xmlns:dsig="http://www.w3.org/2000/09/xmldsig#" xmlns:co.v2="urn:schemas-microsoft-com:clickonce.v2">
|
||||
<asmv1:assemblyIdentity name="MarcusLaw.OutlookAddin.dll" version="1.0.7.0" publicKeyToken="41d8d795775ea8cb" language="neutral" processorArchitecture="msil" type="win32" />
|
||||
<description xmlns="urn:schemas-microsoft-com:asm.v1">MarcusLaw.OutlookAddin</description>
|
||||
<application />
|
||||
<entryPoint>
|
||||
<co.v1:customHostSpecified />
|
||||
</entryPoint>
|
||||
<trustInfo>
|
||||
<security>
|
||||
<applicationRequestMinimum>
|
||||
<PermissionSet Unrestricted="true" ID="Custom" SameSite="site" />
|
||||
<defaultAssemblyRequest permissionSetReference="Custom" />
|
||||
</applicationRequestMinimum>
|
||||
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||
<!--
|
||||
UAC Manifest Options
|
||||
If you want to change the Windows User Account Control level replace the
|
||||
requestedExecutionLevel node with one of the following.
|
||||
|
||||
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
|
||||
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
|
||||
<requestedExecutionLevel level="highestAvailable" uiAccess="false" />
|
||||
|
||||
If you want to utilize File and Registry Virtualization for backward
|
||||
compatibility then delete the requestedExecutionLevel node.
|
||||
-->
|
||||
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
|
||||
</requestedPrivileges>
|
||||
</security>
|
||||
</trustInfo>
|
||||
<dependency>
|
||||
<dependentOS>
|
||||
<osVersionInfo>
|
||||
<os majorVersion="5" minorVersion="1" buildNumber="2600" servicePackMajor="0" />
|
||||
</osVersionInfo>
|
||||
</dependentOS>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<dependentAssembly dependencyType="preRequisite" allowDelayedBinding="true">
|
||||
<assemblyIdentity name="Microsoft.Windows.CommonLanguageRuntime" version="4.0.30319.0" />
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<dependentAssembly dependencyType="preRequisite" allowDelayedBinding="true">
|
||||
<assemblyIdentity name="Accessibility" version="4.0.0.0" publicKeyToken="B03F5F7F11D50A3A" language="neutral" />
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<dependentAssembly dependencyType="preRequisite" allowDelayedBinding="true">
|
||||
<assemblyIdentity name="Microsoft.CSharp" version="4.0.0.0" publicKeyToken="B03F5F7F11D50A3A" language="neutral" />
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<dependentAssembly dependencyType="preRequisite" allowDelayedBinding="true">
|
||||
<assemblyIdentity name="Microsoft.Office.Tools" version="10.0.0.0" publicKeyToken="B03F5F7F11D50A3A" language="neutral" processorArchitecture="msil" />
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<dependentAssembly dependencyType="preRequisite" allowDelayedBinding="true">
|
||||
<assemblyIdentity name="Microsoft.Office.Tools.Common" version="10.0.0.0" publicKeyToken="B03F5F7F11D50A3A" language="neutral" processorArchitecture="msil" />
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<dependentAssembly dependencyType="preRequisite" allowDelayedBinding="true">
|
||||
<assemblyIdentity name="Microsoft.Office.Tools.Outlook" version="10.0.0.0" publicKeyToken="B03F5F7F11D50A3A" language="neutral" processorArchitecture="msil" />
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<dependentAssembly dependencyType="preRequisite" allowDelayedBinding="true">
|
||||
<assemblyIdentity name="Microsoft.Office.Tools.v4.0.Framework" version="10.0.0.0" publicKeyToken="B03F5F7F11D50A3A" language="neutral" processorArchitecture="msil" />
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<dependentAssembly dependencyType="preRequisite" allowDelayedBinding="true">
|
||||
<assemblyIdentity name="Microsoft.VisualStudio.Tools.Applications.Runtime" version="10.0.0.0" publicKeyToken="B03F5F7F11D50A3A" language="neutral" processorArchitecture="msil" />
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<dependentAssembly dependencyType="preRequisite" allowDelayedBinding="true">
|
||||
<assemblyIdentity name="mscorlib" version="4.0.0.0" publicKeyToken="B77A5C561934E089" language="neutral" />
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<dependentAssembly dependencyType="preRequisite" allowDelayedBinding="true">
|
||||
<assemblyIdentity name="netstandard" version="2.0.0.0" publicKeyToken="CC7B13FFCD2DDD51" language="neutral" />
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<dependentAssembly dependencyType="preRequisite" allowDelayedBinding="true">
|
||||
<assemblyIdentity name="PresentationCore" version="4.0.0.0" publicKeyToken="31BF3856AD364E35" language="neutral" />
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<dependentAssembly dependencyType="preRequisite" allowDelayedBinding="true">
|
||||
<assemblyIdentity name="PresentationFramework" version="4.0.0.0" publicKeyToken="31BF3856AD364E35" language="neutral" />
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<dependentAssembly dependencyType="preRequisite" allowDelayedBinding="true">
|
||||
<assemblyIdentity name="stdole" version="7.0.3300.0" publicKeyToken="B03F5F7F11D50A3A" language="neutral" />
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<dependentAssembly dependencyType="preRequisite" allowDelayedBinding="true">
|
||||
<assemblyIdentity name="System" version="4.0.0.0" publicKeyToken="B77A5C561934E089" language="neutral" />
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<dependentAssembly dependencyType="preRequisite" allowDelayedBinding="true">
|
||||
<assemblyIdentity name="System.ComponentModel.DataAnnotations" version="4.0.0.0" publicKeyToken="31BF3856AD364E35" language="neutral" />
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<dependentAssembly dependencyType="preRequisite" allowDelayedBinding="true">
|
||||
<assemblyIdentity name="System.Core" version="4.0.0.0" publicKeyToken="B77A5C561934E089" language="neutral" />
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<dependentAssembly dependencyType="preRequisite" allowDelayedBinding="true">
|
||||
<assemblyIdentity name="System.Data" version="4.0.0.0" publicKeyToken="B77A5C561934E089" language="neutral" />
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<dependentAssembly dependencyType="preRequisite" allowDelayedBinding="true">
|
||||
<assemblyIdentity name="System.Data.DataSetExtensions" version="4.0.0.0" publicKeyToken="B77A5C561934E089" language="neutral" />
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<dependentAssembly dependencyType="preRequisite" allowDelayedBinding="true">
|
||||
<assemblyIdentity name="System.Deployment" version="4.0.0.0" publicKeyToken="B03F5F7F11D50A3A" language="neutral" />
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<dependentAssembly dependencyType="preRequisite" allowDelayedBinding="true">
|
||||
<assemblyIdentity name="System.Drawing" version="4.0.0.0" publicKeyToken="B03F5F7F11D50A3A" language="neutral" />
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<dependentAssembly dependencyType="preRequisite" allowDelayedBinding="true">
|
||||
<assemblyIdentity name="System.Net.Http" version="4.2.0.0" publicKeyToken="B03F5F7F11D50A3A" language="neutral" />
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<dependentAssembly dependencyType="preRequisite" allowDelayedBinding="true">
|
||||
<assemblyIdentity name="System.Numerics" version="4.0.0.0" publicKeyToken="B77A5C561934E089" language="neutral" />
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<dependentAssembly dependencyType="preRequisite" allowDelayedBinding="true">
|
||||
<assemblyIdentity name="System.Security" version="4.0.0.0" publicKeyToken="B03F5F7F11D50A3A" language="neutral" />
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<dependentAssembly dependencyType="preRequisite" allowDelayedBinding="true">
|
||||
<assemblyIdentity name="System.Windows.Forms" version="4.0.0.0" publicKeyToken="B77A5C561934E089" language="neutral" />
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<dependentAssembly dependencyType="preRequisite" allowDelayedBinding="true">
|
||||
<assemblyIdentity name="System.Xaml" version="4.0.0.0" publicKeyToken="B77A5C561934E089" language="neutral" />
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<dependentAssembly dependencyType="preRequisite" allowDelayedBinding="true">
|
||||
<assemblyIdentity name="System.Xml" version="4.0.0.0" publicKeyToken="B77A5C561934E089" language="neutral" />
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<dependentAssembly dependencyType="preRequisite" allowDelayedBinding="true">
|
||||
<assemblyIdentity name="System.Xml.Linq" version="4.0.0.0" publicKeyToken="B77A5C561934E089" language="neutral" />
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<dependentAssembly dependencyType="preRequisite" allowDelayedBinding="true">
|
||||
<assemblyIdentity name="WindowsBase" version="4.0.0.0" publicKeyToken="31BF3856AD364E35" language="neutral" />
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<dependentAssembly dependencyType="preRequisite" allowDelayedBinding="true">
|
||||
<assemblyIdentity name="WindowsFormsIntegration" version="4.0.0.0" publicKeyToken="31BF3856AD364E35" language="neutral" />
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<dependentAssembly dependencyType="install" allowDelayedBinding="true" codebase="CommunityToolkit.Mvvm.dll" size="115496">
|
||||
<assemblyIdentity name="CommunityToolkit.Mvvm" version="8.3.0.0" publicKeyToken="4AFF67A105548EE2" language="neutral" processorArchitecture="msil" />
|
||||
<hash>
|
||||
<dsig:Transforms>
|
||||
<dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />
|
||||
</dsig:Transforms>
|
||||
<dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha256" />
|
||||
<dsig:DigestValue>6Jm7PxxMSE5OkBu7iJrppKUcBydJn1dv4z/0D/2bhio=</dsig:DigestValue>
|
||||
</hash>
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<dependentAssembly dependencyType="install" allowDelayedBinding="true" codebase="MarcusLaw.OutlookAddin.dll" size="104960">
|
||||
<assemblyIdentity name="MarcusLaw.OutlookAddin" version="1.0.7.0" language="neutral" processorArchitecture="msil" />
|
||||
<hash>
|
||||
<dsig:Transforms>
|
||||
<dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />
|
||||
</dsig:Transforms>
|
||||
<dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha256" />
|
||||
<dsig:DigestValue>UFDuAUnK7LIuno/5e6mwDuBGdKJjD6uv4mhSODRsaLI=</dsig:DigestValue>
|
||||
</hash>
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<dependentAssembly dependencyType="install" allowDelayedBinding="true" codebase="MarcusLaw.OutlookAddin.Core.dll" size="94208">
|
||||
<assemblyIdentity name="MarcusLaw.OutlookAddin.Core" version="1.0.0.0" language="neutral" processorArchitecture="msil" />
|
||||
<hash>
|
||||
<dsig:Transforms>
|
||||
<dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />
|
||||
</dsig:Transforms>
|
||||
<dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha256" />
|
||||
<dsig:DigestValue>AycV+vLsh7n9HMhrJdeglo3VQIc0GxGLYzffJuzQEKI=</dsig:DigestValue>
|
||||
</hash>
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<dependentAssembly dependencyType="install" allowDelayedBinding="true" codebase="MarcusLaw.OutlookAddin.UI.dll" size="98816">
|
||||
<assemblyIdentity name="MarcusLaw.OutlookAddin.UI" version="1.0.0.0" language="neutral" processorArchitecture="msil" />
|
||||
<hash>
|
||||
<dsig:Transforms>
|
||||
<dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />
|
||||
</dsig:Transforms>
|
||||
<dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha256" />
|
||||
<dsig:DigestValue>QrrK6ct5D6PUeQW7tkvGmMXXafUw1y/cYMzlf05OkWk=</dsig:DigestValue>
|
||||
</hash>
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<dependentAssembly dependencyType="install" allowDelayedBinding="true" codebase="en-US\MarcusLaw.OutlookAddin.UI.resources.dll" size="7168">
|
||||
<assemblyIdentity name="MarcusLaw.OutlookAddin.UI.resources" version="1.0.0.0" language="en-US" processorArchitecture="msil" />
|
||||
<hash>
|
||||
<dsig:Transforms>
|
||||
<dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />
|
||||
</dsig:Transforms>
|
||||
<dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha256" />
|
||||
<dsig:DigestValue>bwKiIldXtJujP3A/5q5LqYQmTcq5rk3P1IKlRHPF5ks=</dsig:DigestValue>
|
||||
</hash>
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<dependentAssembly dependencyType="install" allowDelayedBinding="true" codebase="Microsoft.Bcl.AsyncInterfaces.dll" size="26904">
|
||||
<assemblyIdentity name="Microsoft.Bcl.AsyncInterfaces" version="8.0.0.0" publicKeyToken="CC7B13FFCD2DDD51" language="neutral" processorArchitecture="msil" />
|
||||
<hash>
|
||||
<dsig:Transforms>
|
||||
<dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />
|
||||
</dsig:Transforms>
|
||||
<dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha256" />
|
||||
<dsig:DigestValue>gGeCA70CA6ZZT04zCyJUPA3lBZOCuxyTNLeGi48xsbw=</dsig:DigestValue>
|
||||
</hash>
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<dependentAssembly dependencyType="install" allowDelayedBinding="true" codebase="Microsoft.Bcl.TimeProvider.dll" size="32528">
|
||||
<assemblyIdentity name="Microsoft.Bcl.TimeProvider" version="8.0.0.0" publicKeyToken="CC7B13FFCD2DDD51" language="neutral" processorArchitecture="msil" />
|
||||
<hash>
|
||||
<dsig:Transforms>
|
||||
<dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />
|
||||
</dsig:Transforms>
|
||||
<dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha256" />
|
||||
<dsig:DigestValue>aTJCtn2pGveN2kuR1gIOC4zaCNTJECF3oSUiAJ75uUA=</dsig:DigestValue>
|
||||
</hash>
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<dependentAssembly dependencyType="install" allowDelayedBinding="true" codebase="Microsoft.Extensions.Caching.Abstractions.dll" size="34464">
|
||||
<assemblyIdentity name="Microsoft.Extensions.Caching.Abstractions" version="8.0.0.0" publicKeyToken="ADB9793829DDAE60" language="neutral" processorArchitecture="msil" />
|
||||
<hash>
|
||||
<dsig:Transforms>
|
||||
<dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />
|
||||
</dsig:Transforms>
|
||||
<dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha256" />
|
||||
<dsig:DigestValue>9SqzavfWhbalT0vUMnzHXHpjwQOdET0vxf4gYix1WxM=</dsig:DigestValue>
|
||||
</hash>
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<dependentAssembly dependencyType="install" allowDelayedBinding="true" codebase="Microsoft.Extensions.Caching.Memory.dll" size="50984">
|
||||
<assemblyIdentity name="Microsoft.Extensions.Caching.Memory" version="8.0.0.1" publicKeyToken="ADB9793829DDAE60" language="neutral" processorArchitecture="msil" />
|
||||
<hash>
|
||||
<dsig:Transforms>
|
||||
<dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />
|
||||
</dsig:Transforms>
|
||||
<dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha256" />
|
||||
<dsig:DigestValue>wv358DZn4LYfOU9AvtIkha8QuSsRT8pHei2JPVvfUB8=</dsig:DigestValue>
|
||||
</hash>
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<dependentAssembly dependencyType="install" allowDelayedBinding="true" codebase="Microsoft.Extensions.DependencyInjection.Abstractions.dll" size="63784">
|
||||
<assemblyIdentity name="Microsoft.Extensions.DependencyInjection.Abstractions" version="8.0.0.2" publicKeyToken="ADB9793829DDAE60" language="neutral" processorArchitecture="msil" />
|
||||
<hash>
|
||||
<dsig:Transforms>
|
||||
<dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />
|
||||
</dsig:Transforms>
|
||||
<dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha256" />
|
||||
<dsig:DigestValue>Ge3U9eaaRYncMUkJtYVKIvicS5qwQFkXcTl7LLGhe6Y=</dsig:DigestValue>
|
||||
</hash>
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<dependentAssembly dependencyType="install" allowDelayedBinding="true" codebase="Microsoft.Extensions.Logging.Abstractions.dll" size="67880">
|
||||
<assemblyIdentity name="Microsoft.Extensions.Logging.Abstractions" version="8.0.0.2" publicKeyToken="ADB9793829DDAE60" language="neutral" processorArchitecture="msil" />
|
||||
<hash>
|
||||
<dsig:Transforms>
|
||||
<dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />
|
||||
</dsig:Transforms>
|
||||
<dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha256" />
|
||||
<dsig:DigestValue>QBBtlRffKDtnxOXKG4YRVpA7fmvyDMzbFmSVRDFdQu4=</dsig:DigestValue>
|
||||
</hash>
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<dependentAssembly dependencyType="install" allowDelayedBinding="true" codebase="Microsoft.Extensions.Options.dll" size="68768">
|
||||
<assemblyIdentity name="Microsoft.Extensions.Options" version="8.0.0.2" publicKeyToken="ADB9793829DDAE60" language="neutral" processorArchitecture="msil" />
|
||||
<hash>
|
||||
<dsig:Transforms>
|
||||
<dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />
|
||||
</dsig:Transforms>
|
||||
<dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha256" />
|
||||
<dsig:DigestValue>c3DHL4ddmRGH4ntasuwkQro05v8nlQFTxmlq7JBVPF0=</dsig:DigestValue>
|
||||
</hash>
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<dependentAssembly dependencyType="install" allowDelayedBinding="true" codebase="Microsoft.Extensions.Primitives.dll" size="49936">
|
||||
<assemblyIdentity name="Microsoft.Extensions.Primitives" version="8.0.0.0" publicKeyToken="ADB9793829DDAE60" language="neutral" processorArchitecture="msil" />
|
||||
<hash>
|
||||
<dsig:Transforms>
|
||||
<dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />
|
||||
</dsig:Transforms>
|
||||
<dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha256" />
|
||||
<dsig:DigestValue>PG6lVZRDPi8DQCJ70ViPurG6ihDJkxm1KMxVcyWTQMs=</dsig:DigestValue>
|
||||
</hash>
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<dependentAssembly dependencyType="install" allowDelayedBinding="true" codebase="Microsoft.Office.Tools.Common.v4.0.Utilities.dll" size="32664">
|
||||
<assemblyIdentity name="Microsoft.Office.Tools.Common.v4.0.Utilities" version="10.0.0.0" publicKeyToken="B03F5F7F11D50A3A" language="neutral" processorArchitecture="msil" />
|
||||
<hash>
|
||||
<dsig:Transforms>
|
||||
<dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />
|
||||
</dsig:Transforms>
|
||||
<dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha256" />
|
||||
<dsig:DigestValue>jLCTF8Mm6bD4PDN+rnzN6q0+ReXaNgPh68kMWgatFwI=</dsig:DigestValue>
|
||||
</hash>
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<dependentAssembly dependencyType="install" allowDelayedBinding="true" codebase="Microsoft.Office.Tools.Outlook.v4.0.Utilities.dll" size="49048">
|
||||
<assemblyIdentity name="Microsoft.Office.Tools.Outlook.v4.0.Utilities" version="10.0.0.0" publicKeyToken="B03F5F7F11D50A3A" language="neutral" processorArchitecture="msil" />
|
||||
<hash>
|
||||
<dsig:Transforms>
|
||||
<dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />
|
||||
</dsig:Transforms>
|
||||
<dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha256" />
|
||||
<dsig:DigestValue>AY9f4ogMVBnNqNKvGc0Ko8U3XsIDeLhU/c5jky7x2Zc=</dsig:DigestValue>
|
||||
</hash>
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<dependentAssembly dependencyType="install" allowDelayedBinding="true" codebase="Polly.dll" size="294960">
|
||||
<assemblyIdentity name="Polly" version="8.0.0.0" publicKeyToken="C8A3FFC3F8F825CC" language="neutral" processorArchitecture="msil" />
|
||||
<hash>
|
||||
<dsig:Transforms>
|
||||
<dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />
|
||||
</dsig:Transforms>
|
||||
<dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha256" />
|
||||
<dsig:DigestValue>01vtaLqFx2ZiynhO4GgatEAd0Y1XmUo1AMI+CSIy5Ag=</dsig:DigestValue>
|
||||
</hash>
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<dependentAssembly dependencyType="install" allowDelayedBinding="true" codebase="Polly.Core.dll" size="241712">
|
||||
<assemblyIdentity name="Polly.Core" version="8.0.0.0" publicKeyToken="C8A3FFC3F8F825CC" language="neutral" processorArchitecture="msil" />
|
||||
<hash>
|
||||
<dsig:Transforms>
|
||||
<dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />
|
||||
</dsig:Transforms>
|
||||
<dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha256" />
|
||||
<dsig:DigestValue>rxJ4TrxMsT8aI+YQY5A92tKKH4VDZnPLN6QPyHLgZsI=</dsig:DigestValue>
|
||||
</hash>
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<dependentAssembly dependencyType="install" allowDelayedBinding="true" codebase="Serilog.dll" size="154112">
|
||||
<assemblyIdentity name="Serilog" version="4.0.0.0" publicKeyToken="24C2F752A8E58A10" language="neutral" processorArchitecture="msil" />
|
||||
<hash>
|
||||
<dsig:Transforms>
|
||||
<dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />
|
||||
</dsig:Transforms>
|
||||
<dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha256" />
|
||||
<dsig:DigestValue>E2b/L9D/pZ/Wsjo3IVAHEvDqtyucnyzPiJ0rn4CBiOQ=</dsig:DigestValue>
|
||||
</hash>
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<dependentAssembly dependencyType="install" allowDelayedBinding="true" codebase="Serilog.Sinks.File.dll" size="32768">
|
||||
<assemblyIdentity name="Serilog.Sinks.File" version="6.0.0.0" publicKeyToken="24C2F752A8E58A10" language="neutral" processorArchitecture="msil" />
|
||||
<hash>
|
||||
<dsig:Transforms>
|
||||
<dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />
|
||||
</dsig:Transforms>
|
||||
<dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha256" />
|
||||
<dsig:DigestValue>yZtkok6s9F6xTZBKEpT9bm3EbA/+YcU+p7nFj1TNsOM=</dsig:DigestValue>
|
||||
</hash>
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<dependentAssembly dependencyType="install" allowDelayedBinding="true" codebase="System.Buffers.dll" size="20856">
|
||||
<assemblyIdentity name="System.Buffers" version="4.0.3.0" publicKeyToken="CC7B13FFCD2DDD51" language="neutral" processorArchitecture="msil" />
|
||||
<hash>
|
||||
<dsig:Transforms>
|
||||
<dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />
|
||||
</dsig:Transforms>
|
||||
<dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha256" />
|
||||
<dsig:DigestValue>rMzPvkXZ8I/+7ZkW43sz6YxlvgEs//bn+ntnIQzh/vs=</dsig:DigestValue>
|
||||
</hash>
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<dependentAssembly dependencyType="install" allowDelayedBinding="true" codebase="System.ComponentModel.Annotations.dll" size="43152">
|
||||
<assemblyIdentity name="System.ComponentModel.Annotations" version="4.2.1.0" publicKeyToken="B03F5F7F11D50A3A" language="neutral" processorArchitecture="msil" />
|
||||
<hash>
|
||||
<dsig:Transforms>
|
||||
<dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />
|
||||
</dsig:Transforms>
|
||||
<dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha256" />
|
||||
<dsig:DigestValue>BBE8hUkYVRnzICeQzrI99glkSHK5wkmlbSvPWVZhAsQ=</dsig:DigestValue>
|
||||
</hash>
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<dependentAssembly dependencyType="install" allowDelayedBinding="true" codebase="System.Diagnostics.DiagnosticSource.dll" size="189104">
|
||||
<assemblyIdentity name="System.Diagnostics.DiagnosticSource" version="8.0.0.1" publicKeyToken="CC7B13FFCD2DDD51" language="neutral" processorArchitecture="msil" />
|
||||
<hash>
|
||||
<dsig:Transforms>
|
||||
<dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />
|
||||
</dsig:Transforms>
|
||||
<dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha256" />
|
||||
<dsig:DigestValue>GIdZJhX8CLvJGtYjB8jBHfwUxFvxINJx1mvkoNGhSac=</dsig:DigestValue>
|
||||
</hash>
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<dependentAssembly dependencyType="install" allowDelayedBinding="true" codebase="System.Memory.dll" size="142240">
|
||||
<assemblyIdentity name="System.Memory" version="4.0.1.2" publicKeyToken="CC7B13FFCD2DDD51" language="neutral" processorArchitecture="msil" />
|
||||
<hash>
|
||||
<dsig:Transforms>
|
||||
<dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />
|
||||
</dsig:Transforms>
|
||||
<dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha256" />
|
||||
<dsig:DigestValue>vz+4RmT0CX8aipvHGlHc+M8akF1AgKTSkNoXMIZuhW8=</dsig:DigestValue>
|
||||
</hash>
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<dependentAssembly dependencyType="install" allowDelayedBinding="true" codebase="System.Numerics.Vectors.dll" size="115856">
|
||||
<assemblyIdentity name="System.Numerics.Vectors" version="4.1.4.0" publicKeyToken="B03F5F7F11D50A3A" language="neutral" processorArchitecture="msil" />
|
||||
<hash>
|
||||
<dsig:Transforms>
|
||||
<dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />
|
||||
</dsig:Transforms>
|
||||
<dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha256" />
|
||||
<dsig:DigestValue>HT74aYKB589zcdFVSv71hys5+Wwm2nciEKM9oEG6EYM=</dsig:DigestValue>
|
||||
</hash>
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<dependentAssembly dependencyType="install" allowDelayedBinding="true" codebase="System.Runtime.CompilerServices.Unsafe.dll" size="18024">
|
||||
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" version="6.0.0.0" publicKeyToken="B03F5F7F11D50A3A" language="neutral" processorArchitecture="msil" />
|
||||
<hash>
|
||||
<dsig:Transforms>
|
||||
<dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />
|
||||
</dsig:Transforms>
|
||||
<dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha256" />
|
||||
<dsig:DigestValue>N3aEiOjvRXKbx9miZ3YzxkUAQpdbuWUW4YbabLnNDc8=</dsig:DigestValue>
|
||||
</hash>
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<dependentAssembly dependencyType="install" allowDelayedBinding="true" codebase="System.Security.Cryptography.ProtectedData.dll" size="21776">
|
||||
<assemblyIdentity name="System.Security.Cryptography.ProtectedData" version="8.0.0.0" publicKeyToken="B03F5F7F11D50A3A" language="neutral" processorArchitecture="msil" />
|
||||
<hash>
|
||||
<dsig:Transforms>
|
||||
<dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />
|
||||
</dsig:Transforms>
|
||||
<dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha256" />
|
||||
<dsig:DigestValue>N/qb7rtPZhOmNTeKfhRfkYfgk0cboq7VzfmuFIdKX3s=</dsig:DigestValue>
|
||||
</hash>
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<dependentAssembly dependencyType="install" allowDelayedBinding="true" codebase="System.Text.Encodings.Web.dll" size="79024">
|
||||
<assemblyIdentity name="System.Text.Encodings.Web" version="8.0.0.0" publicKeyToken="CC7B13FFCD2DDD51" language="neutral" processorArchitecture="msil" />
|
||||
<hash>
|
||||
<dsig:Transforms>
|
||||
<dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />
|
||||
</dsig:Transforms>
|
||||
<dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha256" />
|
||||
<dsig:DigestValue>6cT17tGGyxKcUnxLjWfRY+ovI5bp2LluMLXnwSIDzoQ=</dsig:DigestValue>
|
||||
</hash>
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<dependentAssembly dependencyType="install" allowDelayedBinding="true" codebase="System.Text.Json.dll" size="644888">
|
||||
<assemblyIdentity name="System.Text.Json" version="8.0.0.5" publicKeyToken="CC7B13FFCD2DDD51" language="neutral" processorArchitecture="msil" />
|
||||
<hash>
|
||||
<dsig:Transforms>
|
||||
<dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />
|
||||
</dsig:Transforms>
|
||||
<dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha256" />
|
||||
<dsig:DigestValue>hsPyY66bRGmrEmbIBHEIcIJEfrSjjmuXv16E3hXAeh0=</dsig:DigestValue>
|
||||
</hash>
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<dependentAssembly dependencyType="install" allowDelayedBinding="true" codebase="System.Threading.Channels.dll" size="74000">
|
||||
<assemblyIdentity name="System.Threading.Channels" version="8.0.0.0" publicKeyToken="CC7B13FFCD2DDD51" language="neutral" processorArchitecture="msil" />
|
||||
<hash>
|
||||
<dsig:Transforms>
|
||||
<dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />
|
||||
</dsig:Transforms>
|
||||
<dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha256" />
|
||||
<dsig:DigestValue>pC5FobuOZSjSRPhhHPHj5zHKtIGmeSjBvoFeY1/+jsc=</dsig:DigestValue>
|
||||
</hash>
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<dependentAssembly dependencyType="install" allowDelayedBinding="true" codebase="System.Threading.Tasks.Extensions.dll" size="25984">
|
||||
<assemblyIdentity name="System.Threading.Tasks.Extensions" version="4.2.0.1" publicKeyToken="CC7B13FFCD2DDD51" language="neutral" processorArchitecture="msil" />
|
||||
<hash>
|
||||
<dsig:Transforms>
|
||||
<dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />
|
||||
</dsig:Transforms>
|
||||
<dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha256" />
|
||||
<dsig:DigestValue>T4H/0NxyBNt1r8NepCkXabB8RAWS8oiUJg7qdmJqI8Y=</dsig:DigestValue>
|
||||
</hash>
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<dependentAssembly dependencyType="install" allowDelayedBinding="true" codebase="System.ValueTuple.dll" size="25232">
|
||||
<assemblyIdentity name="System.ValueTuple" version="4.0.3.0" publicKeyToken="CC7B13FFCD2DDD51" language="neutral" processorArchitecture="msil" />
|
||||
<hash>
|
||||
<dsig:Transforms>
|
||||
<dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />
|
||||
</dsig:Transforms>
|
||||
<dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha256" />
|
||||
<dsig:DigestValue>6QXRAlhbIsbfBPIZr1y9v6e8Fll56XiLYt9tzBZeEPQ=</dsig:DigestValue>
|
||||
</hash>
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
<file name="MarcusLaw.OutlookAddin.dll.config" size="1827">
|
||||
<hash>
|
||||
<dsig:Transforms>
|
||||
<dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />
|
||||
</dsig:Transforms>
|
||||
<dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha256" />
|
||||
<dsig:DigestValue>uMegIvfUIIUq0XcXNVowCSN4iTs7XAuPmHY2Gb/9AR4=</dsig:DigestValue>
|
||||
</hash>
|
||||
</file>
|
||||
<vstav3:addIn xmlns:vstav3="urn:schemas-microsoft-com:vsta.v3">
|
||||
<vstav3:entryPointsCollection>
|
||||
<vstav3:entryPoints>
|
||||
<vstav3:entryPoint class="OutlookAddin.ThisAddIn">
|
||||
<assemblyIdentity name="MarcusLaw.OutlookAddin" version="1.0.7.0" language="neutral" processorArchitecture="msil" />
|
||||
</vstav3:entryPoint>
|
||||
</vstav3:entryPoints>
|
||||
</vstav3:entryPointsCollection>
|
||||
<vstav3:update enabled="true">
|
||||
<vstav3:expiration maximumAge="7" unit="days" />
|
||||
</vstav3:update>
|
||||
<vstav3:application>
|
||||
<vstov4:customizations xmlns:vstov4="urn:schemas-microsoft-com:vsto.v4">
|
||||
<vstov4:customization>
|
||||
<vstov4:appAddIn application="Outlook" loadBehavior="3" keyName="MarcusLaw.OutlookAddin">
|
||||
<vstov4:friendlyName>MarcusLaw.OutlookAddin</vstov4:friendlyName>
|
||||
<vstov4:description>MarcusLaw.OutlookAddin</vstov4:description>
|
||||
<vstov4.1:ribbonTypes xmlns:vstov4.1="urn:schemas-microsoft-com:vsto.v4.1" />
|
||||
</vstov4:appAddIn>
|
||||
</vstov4:customization>
|
||||
</vstov4:customizations>
|
||||
</vstav3:application>
|
||||
</vstav3:addIn>
|
||||
<publisherIdentity name="CN=HP-OFFICE1\Chaim" issuerKeyHash="461191bb791c8dcf6417521bc4cc018623c19538" /><Signature Id="StrongNameSignature" xmlns="http://www.w3.org/2000/09/xmldsig#"><SignedInfo><CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /><SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha256" /><Reference URI=""><Transforms><Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" /><Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /></Transforms><DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha256" /><DigestValue>wM13VCTBORPvZvtVa3YF66dro2pCcN8pucJyy+jTfoA=</DigestValue></Reference></SignedInfo><SignatureValue>dsDElqrcVTLfCKtMxmY/j7UatomYO80a72g8QUQgqIe4KmJyTr3gQkmu18UjhT2+mTbTIahwj03kIVNnAiFQK0FkGcK7HI758be3Wo0Ib3RDJevFegV/uNH5U4SImdPk1mHFoV7RuqB08ioQtHKd1VWi/vaEc8EVFCgRnLANrL4=</SignatureValue><KeyInfo Id="StrongNameKeyInfo"><KeyValue><RSAKeyValue><Modulus>xREBVt621l5WQ3HNT3kMrcZSyVcrSzXGDKTMvBwbaOmt7ZSsM5F8hZ+AQTmTC2BoXM8LeiP+wZAVU0MYokbWdHIG9TSqT5Uaud77qpDIfgJKk24CMS0ptE1PI4usLdwO1KyfRESHW8gxgVt0hAWuDudgI/EnOiyM5YRZNEf8Di0=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue></KeyValue><msrel:RelData xmlns:msrel="http://schemas.microsoft.com/windows/rel/2005/reldata"><r:license xmlns:r="urn:mpeg:mpeg21:2003:01-REL-R-NS" xmlns:as="http://schemas.microsoft.com/windows/pki/2005/Authenticode"><r:grant><as:ManifestInformation Hash="807ed3e8cb72c2b929df70426aa36ba7eb05766b55fb66ef1339c1245477cdc0" Description="" Url=""><as:assemblyIdentity name="MarcusLaw.OutlookAddin.dll" version="1.0.7.0" publicKeyToken="41d8d795775ea8cb" language="neutral" processorArchitecture="msil" type="win32" /></as:ManifestInformation><as:SignedBy /><as:AuthenticodePublisher><as:X509SubjectName>CN=HP-OFFICE1\Chaim</as:X509SubjectName></as:AuthenticodePublisher></r:grant><r:issuer><Signature Id="AuthenticodeSignature" xmlns="http://www.w3.org/2000/09/xmldsig#"><SignedInfo><CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /><SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha256" /><Reference URI=""><Transforms><Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" /><Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /></Transforms><DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha256" /><DigestValue>UgZbGtjRWoDrCAiV0IY5v0u4waIeDBt21bIbnTo2Cmk=</DigestValue></Reference></SignedInfo><SignatureValue>rksSK/JiE2/Zsf1ESCzwLUilq+7Vv9kThYx7oxnWU7vzliAUhTRl/smA0NNZqJLlrQ0KmNP79OR0Z4c9o7hnGr+q6fUfjoevcSKdSSaHkrLMU70b799w+A2mP3Bn01znZjncPW5/WUGq5euehFDkfCaPU9IEGKx62XFjh8QIq7c=</SignatureValue><KeyInfo><KeyValue><RSAKeyValue><Modulus>xREBVt621l5WQ3HNT3kMrcZSyVcrSzXGDKTMvBwbaOmt7ZSsM5F8hZ+AQTmTC2BoXM8LeiP+wZAVU0MYokbWdHIG9TSqT5Uaud77qpDIfgJKk24CMS0ptE1PI4usLdwO1KyfRESHW8gxgVt0hAWuDudgI/EnOiyM5YRZNEf8Di0=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue></KeyValue><X509Data><X509Certificate>MIIB2TCCAUKgAwIBAgIQc4FF18qP9L1B37xzsUPl3jANBgkqhkiG9w0BAQsFADArMSkwJwYDVQQDHiAASABQAC0ATwBGAEYASQBDAEUAMQBcAEMAaABhAGkAbTAeFw0yNjA1MTExMTQ0MDlaFw0yNzA1MTExNzQ0MDlaMCsxKTAnBgNVBAMeIABIAFAALQBPAEYARgBJAEMARQAxAFwAQwBoAGEAaQBtMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDFEQFW3rbWXlZDcc1PeQytxlLJVytLNcYMpMy8HBto6a3tlKwzkXyFn4BBOZMLYGhczwt6I/7BkBVTQxiiRtZ0cgb1NKpPlRq53vuqkMh+AkqTbgIxLSm0TU8ji6wt3A7UrJ9ERIdbyDGBW3SEBa4O52Aj8Sc6LIzlhFk0R/wOLQIDAQABMA0GCSqGSIb3DQEBCwUAA4GBAFqX6W2LgF51biJUxrAe0KCZRG1YJsBhXyKf3RUDIWbyMuYmiwfIGKSEi5SX1wOD+4dF6+tBclK9pGOgqqNsfro67Mhdoo2HUhnrRXPUeqjgo5NR0qbxVYszhFBBBCjCxrDVjh8j7/lutwWUWGnF9mc3Bcw5GIHMZ+3d9T4IUYpI</X509Certificate></X509Data></KeyInfo></Signature></r:issuer></r:license></msrel:RelData></KeyInfo></Signature></asmv1:assembly>
|
||||
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<asmv1:assembly xsi:schemaLocation="urn:schemas-microsoft-com:asm.v1 assembly.adaptive.xsd" manifestVersion="1.0" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns="urn:schemas-microsoft-com:asm.v2" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xrml="urn:mpeg:mpeg21:2003:01-REL-R-NS" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" xmlns:dsig="http://www.w3.org/2000/09/xmldsig#" xmlns:co.v1="urn:schemas-microsoft-com:clickonce.v1" xmlns:co.v2="urn:schemas-microsoft-com:clickonce.v2">
|
||||
<assemblyIdentity name="MarcusLaw.OutlookAddin.vsto" version="1.0.7.0" publicKeyToken="41d8d795775ea8cb" language="neutral" processorArchitecture="msil" xmlns="urn:schemas-microsoft-com:asm.v1" />
|
||||
<description asmv2:publisher="MarcusLaw.OutlookAddin" asmv2:product="MarcusLaw.OutlookAddin" xmlns="urn:schemas-microsoft-com:asm.v1" />
|
||||
<deployment install="false" mapFileExtensions="true" />
|
||||
<compatibleFrameworks xmlns="urn:schemas-microsoft-com:clickonce.v2">
|
||||
<framework targetVersion="4.8" profile="Full" supportedRuntime="4.0.30319" />
|
||||
</compatibleFrameworks>
|
||||
<dependency>
|
||||
<dependentAssembly dependencyType="install" codebase="Application Files\MarcusLaw.OutlookAddin_1_0_7_0\MarcusLaw.OutlookAddin.dll.manifest" size="36548">
|
||||
<assemblyIdentity name="MarcusLaw.OutlookAddin.dll" version="1.0.7.0" publicKeyToken="41d8d795775ea8cb" language="neutral" processorArchitecture="msil" type="win32" />
|
||||
<hash>
|
||||
<dsig:Transforms>
|
||||
<dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />
|
||||
</dsig:Transforms>
|
||||
<dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha256" />
|
||||
<dsig:DigestValue>oFrXd0JDtHBok3bcmFLDAa5KFf5jBZVRZPJUYiSPakQ=</dsig:DigestValue>
|
||||
</hash>
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
<publisherIdentity name="CN=HP-OFFICE1\Chaim" issuerKeyHash="461191bb791c8dcf6417521bc4cc018623c19538" /><Signature Id="StrongNameSignature" xmlns="http://www.w3.org/2000/09/xmldsig#"><SignedInfo><CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /><SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha256" /><Reference URI=""><Transforms><Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" /><Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /></Transforms><DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha256" /><DigestValue>AoiIvEZEDw5NCrymwVAvIW1PN4f6L/G/2Jw2WXuAemM=</DigestValue></Reference></SignedInfo><SignatureValue>dllu0k2mVVdH4KTiz7PQJQO5ZO3uO7Yzi5EGrzcM+SlFppRxFcu35Xgm82GLJ5UbsgzugIiHcq69HYsbYgqQ5KRAV2W2jFSLMbqXyXFTpGR3ZP/mV8DF9Od1Ha+Ul61ZPfLHqSsK+TyStc+P5DkiXnLkhKLqkUyWpSpVFlHGkNE=</SignatureValue><KeyInfo Id="StrongNameKeyInfo"><KeyValue><RSAKeyValue><Modulus>xREBVt621l5WQ3HNT3kMrcZSyVcrSzXGDKTMvBwbaOmt7ZSsM5F8hZ+AQTmTC2BoXM8LeiP+wZAVU0MYokbWdHIG9TSqT5Uaud77qpDIfgJKk24CMS0ptE1PI4usLdwO1KyfRESHW8gxgVt0hAWuDudgI/EnOiyM5YRZNEf8Di0=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue></KeyValue><msrel:RelData xmlns:msrel="http://schemas.microsoft.com/windows/rel/2005/reldata"><r:license xmlns:r="urn:mpeg:mpeg21:2003:01-REL-R-NS" xmlns:as="http://schemas.microsoft.com/windows/pki/2005/Authenticode"><r:grant><as:ManifestInformation Hash="637a807b59369cd8bff12ffa87374f6d212f50c1a6bc0a4d0e0f4446bc888802" Description="" Url=""><as:assemblyIdentity name="MarcusLaw.OutlookAddin.vsto" version="1.0.7.0" publicKeyToken="41d8d795775ea8cb" language="neutral" processorArchitecture="msil" xmlns="urn:schemas-microsoft-com:asm.v1" /></as:ManifestInformation><as:SignedBy /><as:AuthenticodePublisher><as:X509SubjectName>CN=HP-OFFICE1\Chaim</as:X509SubjectName></as:AuthenticodePublisher></r:grant><r:issuer><Signature Id="AuthenticodeSignature" xmlns="http://www.w3.org/2000/09/xmldsig#"><SignedInfo><CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /><SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha256" /><Reference URI=""><Transforms><Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" /><Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /></Transforms><DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha256" /><DigestValue>a2ZfU5jaiU9/spzQ38LrO3Oh5H1amjxMKA+UDGIxk88=</DigestValue></Reference></SignedInfo><SignatureValue>ASngBgbaDxF8ymTll++oets2qBL0KP7cDJTN34zncwwk2+I+ToCM0Mg7z1cwvQZftfxnKgcwKD5b57mIHIqj6Aklgyf3Bh5ifXN9kUIyNjHxhe905AYjBWHyKLQm+ld6V3eb+N8HJ7jYUewbevols9Mm3pQVYr8eWHL3FOp0dyA=</SignatureValue><KeyInfo><KeyValue><RSAKeyValue><Modulus>xREBVt621l5WQ3HNT3kMrcZSyVcrSzXGDKTMvBwbaOmt7ZSsM5F8hZ+AQTmTC2BoXM8LeiP+wZAVU0MYokbWdHIG9TSqT5Uaud77qpDIfgJKk24CMS0ptE1PI4usLdwO1KyfRESHW8gxgVt0hAWuDudgI/EnOiyM5YRZNEf8Di0=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue></KeyValue><X509Data><X509Certificate>MIIB2TCCAUKgAwIBAgIQc4FF18qP9L1B37xzsUPl3jANBgkqhkiG9w0BAQsFADArMSkwJwYDVQQDHiAASABQAC0ATwBGAEYASQBDAEUAMQBcAEMAaABhAGkAbTAeFw0yNjA1MTExMTQ0MDlaFw0yNzA1MTExNzQ0MDlaMCsxKTAnBgNVBAMeIABIAFAALQBPAEYARgBJAEMARQAxAFwAQwBoAGEAaQBtMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDFEQFW3rbWXlZDcc1PeQytxlLJVytLNcYMpMy8HBto6a3tlKwzkXyFn4BBOZMLYGhczwt6I/7BkBVTQxiiRtZ0cgb1NKpPlRq53vuqkMh+AkqTbgIxLSm0TU8ji6wt3A7UrJ9ERIdbyDGBW3SEBa4O52Aj8Sc6LIzlhFk0R/wOLQIDAQABMA0GCSqGSIb3DQEBCwUAA4GBAFqX6W2LgF51biJUxrAe0KCZRG1YJsBhXyKf3RUDIWbyMuYmiwfIGKSEi5SX1wOD+4dF6+tBclK9pGOgqqNsfro67Mhdoo2HUhnrRXPUeqjgo5NR0qbxVYszhFBBBCjCxrDVjh8j7/lutwWUWGnF9mc3Bcw5GIHMZ+3d9T4IUYpI</X509Certificate></X509Data></KeyInfo></Signature></r:issuer></r:license></msrel:RelData></KeyInfo></Signature></asmv1:assembly>
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<asmv1:assembly xsi:schemaLocation="urn:schemas-microsoft-com:asm.v1 assembly.adaptive.xsd" manifestVersion="1.0" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns="urn:schemas-microsoft-com:asm.v2" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xrml="urn:mpeg:mpeg21:2003:01-REL-R-NS" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" xmlns:dsig="http://www.w3.org/2000/09/xmldsig#" xmlns:co.v1="urn:schemas-microsoft-com:clickonce.v1" xmlns:co.v2="urn:schemas-microsoft-com:clickonce.v2">
|
||||
<assemblyIdentity name="MarcusLaw.OutlookAddin.vsto" version="1.0.7.0" publicKeyToken="41d8d795775ea8cb" language="neutral" processorArchitecture="msil" xmlns="urn:schemas-microsoft-com:asm.v1" />
|
||||
<description asmv2:publisher="MarcusLaw.OutlookAddin" asmv2:product="MarcusLaw.OutlookAddin" xmlns="urn:schemas-microsoft-com:asm.v1" />
|
||||
<deployment install="false" mapFileExtensions="true" />
|
||||
<compatibleFrameworks xmlns="urn:schemas-microsoft-com:clickonce.v2">
|
||||
<framework targetVersion="4.8" profile="Full" supportedRuntime="4.0.30319" />
|
||||
</compatibleFrameworks>
|
||||
<dependency>
|
||||
<dependentAssembly dependencyType="install" codebase="Application Files\MarcusLaw.OutlookAddin_1_0_7_0\MarcusLaw.OutlookAddin.dll.manifest" size="36548">
|
||||
<assemblyIdentity name="MarcusLaw.OutlookAddin.dll" version="1.0.7.0" publicKeyToken="41d8d795775ea8cb" language="neutral" processorArchitecture="msil" type="win32" />
|
||||
<hash>
|
||||
<dsig:Transforms>
|
||||
<dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />
|
||||
</dsig:Transforms>
|
||||
<dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha256" />
|
||||
<dsig:DigestValue>oFrXd0JDtHBok3bcmFLDAa5KFf5jBZVRZPJUYiSPakQ=</dsig:DigestValue>
|
||||
</hash>
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
<publisherIdentity name="CN=HP-OFFICE1\Chaim" issuerKeyHash="461191bb791c8dcf6417521bc4cc018623c19538" /><Signature Id="StrongNameSignature" xmlns="http://www.w3.org/2000/09/xmldsig#"><SignedInfo><CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /><SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha256" /><Reference URI=""><Transforms><Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" /><Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /></Transforms><DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha256" /><DigestValue>AoiIvEZEDw5NCrymwVAvIW1PN4f6L/G/2Jw2WXuAemM=</DigestValue></Reference></SignedInfo><SignatureValue>dllu0k2mVVdH4KTiz7PQJQO5ZO3uO7Yzi5EGrzcM+SlFppRxFcu35Xgm82GLJ5UbsgzugIiHcq69HYsbYgqQ5KRAV2W2jFSLMbqXyXFTpGR3ZP/mV8DF9Od1Ha+Ul61ZPfLHqSsK+TyStc+P5DkiXnLkhKLqkUyWpSpVFlHGkNE=</SignatureValue><KeyInfo Id="StrongNameKeyInfo"><KeyValue><RSAKeyValue><Modulus>xREBVt621l5WQ3HNT3kMrcZSyVcrSzXGDKTMvBwbaOmt7ZSsM5F8hZ+AQTmTC2BoXM8LeiP+wZAVU0MYokbWdHIG9TSqT5Uaud77qpDIfgJKk24CMS0ptE1PI4usLdwO1KyfRESHW8gxgVt0hAWuDudgI/EnOiyM5YRZNEf8Di0=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue></KeyValue><msrel:RelData xmlns:msrel="http://schemas.microsoft.com/windows/rel/2005/reldata"><r:license xmlns:r="urn:mpeg:mpeg21:2003:01-REL-R-NS" xmlns:as="http://schemas.microsoft.com/windows/pki/2005/Authenticode"><r:grant><as:ManifestInformation Hash="637a807b59369cd8bff12ffa87374f6d212f50c1a6bc0a4d0e0f4446bc888802" Description="" Url=""><as:assemblyIdentity name="MarcusLaw.OutlookAddin.vsto" version="1.0.7.0" publicKeyToken="41d8d795775ea8cb" language="neutral" processorArchitecture="msil" xmlns="urn:schemas-microsoft-com:asm.v1" /></as:ManifestInformation><as:SignedBy /><as:AuthenticodePublisher><as:X509SubjectName>CN=HP-OFFICE1\Chaim</as:X509SubjectName></as:AuthenticodePublisher></r:grant><r:issuer><Signature Id="AuthenticodeSignature" xmlns="http://www.w3.org/2000/09/xmldsig#"><SignedInfo><CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /><SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha256" /><Reference URI=""><Transforms><Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" /><Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /></Transforms><DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha256" /><DigestValue>a2ZfU5jaiU9/spzQ38LrO3Oh5H1amjxMKA+UDGIxk88=</DigestValue></Reference></SignedInfo><SignatureValue>ASngBgbaDxF8ymTll++oets2qBL0KP7cDJTN34zncwwk2+I+ToCM0Mg7z1cwvQZftfxnKgcwKD5b57mIHIqj6Aklgyf3Bh5ifXN9kUIyNjHxhe905AYjBWHyKLQm+ld6V3eb+N8HJ7jYUewbevols9Mm3pQVYr8eWHL3FOp0dyA=</SignatureValue><KeyInfo><KeyValue><RSAKeyValue><Modulus>xREBVt621l5WQ3HNT3kMrcZSyVcrSzXGDKTMvBwbaOmt7ZSsM5F8hZ+AQTmTC2BoXM8LeiP+wZAVU0MYokbWdHIG9TSqT5Uaud77qpDIfgJKk24CMS0ptE1PI4usLdwO1KyfRESHW8gxgVt0hAWuDudgI/EnOiyM5YRZNEf8Di0=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue></KeyValue><X509Data><X509Certificate>MIIB2TCCAUKgAwIBAgIQc4FF18qP9L1B37xzsUPl3jANBgkqhkiG9w0BAQsFADArMSkwJwYDVQQDHiAASABQAC0ATwBGAEYASQBDAEUAMQBcAEMAaABhAGkAbTAeFw0yNjA1MTExMTQ0MDlaFw0yNzA1MTExNzQ0MDlaMCsxKTAnBgNVBAMeIABIAFAALQBPAEYARgBJAEMARQAxAFwAQwBoAGEAaQBtMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDFEQFW3rbWXlZDcc1PeQytxlLJVytLNcYMpMy8HBto6a3tlKwzkXyFn4BBOZMLYGhczwt6I/7BkBVTQxiiRtZ0cgb1NKpPlRq53vuqkMh+AkqTbgIxLSm0TU8ji6wt3A7UrJ9ERIdbyDGBW3SEBa4O52Aj8Sc6LIzlhFk0R/wOLQIDAQABMA0GCSqGSIb3DQEBCwUAA4GBAFqX6W2LgF51biJUxrAe0KCZRG1YJsBhXyKf3RUDIWbyMuYmiwfIGKSEi5SX1wOD+4dF6+tBclK9pGOgqqNsfro67Mhdoo2HUhnrRXPUeqjgo5NR0qbxVYszhFBBBCjCxrDVjh8j7/lutwWUWGnF9mc3Bcw5GIHMZ+3d9T4IUYpI</X509Certificate></X509Data></KeyInfo></Signature></r:issuer></r:license></msrel:RelData></KeyInfo></Signature></asmv1:assembly>
|
||||
Binary file not shown.
@@ -23,6 +23,13 @@ namespace MarcusLaw.OutlookAddin.Core.Models
|
||||
[JsonPropertyName("status")]
|
||||
public string? Status { get; set; }
|
||||
|
||||
// Marcus-Law custom field on Case — court file/docket number.
|
||||
// Field name guessed from EspoCRM "c-prefixed PascalCase" convention;
|
||||
// adjust if the admin used a different name.
|
||||
[JsonPropertyName("cCourtCaseNumber")]
|
||||
[JsonConverter(typeof(FlexibleStringConverter))]
|
||||
public string? CourtCaseNumber { get; set; }
|
||||
|
||||
[JsonPropertyName("accountId")]
|
||||
public string? AccountId { get; set; }
|
||||
|
||||
|
||||
@@ -17,6 +17,13 @@ namespace MarcusLaw.OutlookAddin.Core.Models
|
||||
|
||||
public int CandidateCount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// When <see cref="IsAmbiguous"/> is true, holds the candidate
|
||||
/// contacts that share the sender's email so the sidebar can show
|
||||
/// a picker instead of bouncing the user into manual search.
|
||||
/// </summary>
|
||||
public List<ContactEntity> Candidates { get; set; } = new List<ContactEntity>();
|
||||
|
||||
public DateTimeOffset RetrievedAt { get; set; } = DateTimeOffset.UtcNow;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,35 +46,17 @@ namespace MarcusLaw.OutlookAddin.Core.Services
|
||||
continue;
|
||||
}
|
||||
|
||||
string? attachmentId = null;
|
||||
Exception? uploadException = null;
|
||||
|
||||
// Step 1: create the EspoCRM Attachment (binary stored in
|
||||
// data/upload/<id>; not yet on the network share). Auth
|
||||
// failures here are terminal — skip remaining items.
|
||||
try
|
||||
{
|
||||
// Step 1: create the EspoCRM Attachment (binary stored
|
||||
// in data/upload/<id>; not yet on the network share).
|
||||
var uploaded = await _client.UploadAttachmentAsync(
|
||||
att.Name, att.ContentType, att.ContentBase64, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
// Step 2: ask Marcus-Law's NetworkStorageIntegration
|
||||
// to place the uploaded blob under <targetFolderPath>.
|
||||
// The integration appends the filename to the path.
|
||||
await _client.UploadAttachmentToNetworkStorageAsync(
|
||||
uploaded.Id, trimmedFolder, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
// Step 3: verify the file actually landed on the share —
|
||||
// the server can return 200 yet leave nothing on disk
|
||||
// when a downstream WebDAV proxy silently fails. Read
|
||||
// the folder back and look for our filename.
|
||||
await VerifyArrivedAsync(att.Name, trimmedFolder, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
_logger.Information(
|
||||
"Saved attachment {Name} → {Path} (attachmentId={AttachmentId})",
|
||||
att.Name, trimmedFolder, uploaded.Id);
|
||||
|
||||
summary.Items.Add(new AttachmentSaveItemResult
|
||||
{
|
||||
FileName = att.Name,
|
||||
Outcome = AttachmentSaveOutcome.Saved,
|
||||
AttachmentId = uploaded.Id
|
||||
});
|
||||
attachmentId = uploaded.Id;
|
||||
}
|
||||
catch (EspoCrmAuthorizationException ex)
|
||||
{
|
||||
@@ -86,20 +68,85 @@ namespace MarcusLaw.OutlookAddin.Core.Services
|
||||
Outcome = AttachmentSaveOutcome.AuthRequired,
|
||||
ErrorMessage = ex.Message
|
||||
});
|
||||
continue;
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
catch (OperationCanceledException) { throw; }
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Warning(ex, "Attachment save failed for {Name}", att.Name);
|
||||
// No attachment ID means we have nothing on the share —
|
||||
// a hard fail.
|
||||
_logger.Warning(ex, "Attachment upload (Step 1) failed for {Name}", att.Name);
|
||||
summary.Items.Add(new AttachmentSaveItemResult
|
||||
{
|
||||
FileName = att.Name,
|
||||
Outcome = AttachmentSaveOutcome.Failed,
|
||||
ErrorMessage = ex.Message
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
||||
// Step 2: ask the NetworkStorageIntegration to place the
|
||||
// uploaded blob under <targetFolderPath>. The 15s Polly
|
||||
// timeout sometimes fires while the server is still
|
||||
// writing the file — capture the exception but don't
|
||||
// decide the outcome yet.
|
||||
try
|
||||
{
|
||||
await _client.UploadAttachmentToNetworkStorageAsync(
|
||||
attachmentId, trimmedFolder, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
catch (EspoCrmAuthorizationException ex)
|
||||
{
|
||||
_logger.Warning(ex, "Attachment save aborted on Step 2: EspoCRM rejected credentials");
|
||||
summary.AuthRequired = true;
|
||||
summary.Items.Add(new AttachmentSaveItemResult
|
||||
{
|
||||
FileName = att.Name,
|
||||
Outcome = AttachmentSaveOutcome.AuthRequired,
|
||||
ErrorMessage = ex.Message
|
||||
});
|
||||
continue;
|
||||
}
|
||||
catch (OperationCanceledException) { throw; }
|
||||
catch (Exception ex)
|
||||
{
|
||||
uploadException = ex;
|
||||
_logger.Warning(ex,
|
||||
"Attachment NetworkStorage upload (Step 2) reported failure for {Name}; will verify disk before declaring failure",
|
||||
att.Name);
|
||||
}
|
||||
|
||||
// Step 3: verify on disk. Authoritative — if the file is
|
||||
// there, the save succeeded regardless of what Step 2
|
||||
// reported (Polly timeouts during large writes are common).
|
||||
var verified = await VerifyArrivedWithRetryAsync(
|
||||
att.Name, trimmedFolder, uploadException != null, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
if (verified)
|
||||
{
|
||||
_logger.Information(
|
||||
"Saved attachment {Name} → {Path} (attachmentId={AttachmentId}, uploadException={HadException})",
|
||||
att.Name, trimmedFolder, attachmentId, uploadException != null);
|
||||
summary.Items.Add(new AttachmentSaveItemResult
|
||||
{
|
||||
FileName = att.Name,
|
||||
Outcome = AttachmentSaveOutcome.Saved,
|
||||
AttachmentId = attachmentId
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
var message = uploadException?.Message
|
||||
?? "Server reported success but the file is not on the share.";
|
||||
_logger.Warning(
|
||||
"Attachment save Failed for {Name}: not present after verify (uploadException={Msg})",
|
||||
att.Name, message);
|
||||
summary.Items.Add(new AttachmentSaveItemResult
|
||||
{
|
||||
FileName = att.Name,
|
||||
Outcome = AttachmentSaveOutcome.Failed,
|
||||
ErrorMessage = message
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,51 +154,60 @@ namespace MarcusLaw.OutlookAddin.Core.Services
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Post-upload sanity check: list the folder we just wrote into
|
||||
/// and confirm a file with the same (possibly sanitized) name
|
||||
/// shows up. Diagnostic only — does not change the outcome. If
|
||||
/// the file isn't there, log a WARNING with everything that IS
|
||||
/// in the folder so we can spot the actual server-side path.
|
||||
/// Authoritative post-upload check. Returns true if the file is on
|
||||
/// disk under <paramref name="folderPath"/>. When the upload call
|
||||
/// raised (typically Polly's 15s timeout on a still-writing server),
|
||||
/// we retry the listing a few times so the server gets a chance
|
||||
/// to finish.
|
||||
/// </summary>
|
||||
private async Task VerifyArrivedAsync(string expectedName, string folderPath, CancellationToken ct)
|
||||
private async Task<bool> VerifyArrivedWithRetryAsync(string expectedName, string folderPath, bool afterFailure, CancellationToken ct)
|
||||
{
|
||||
// When the upload appeared to succeed, one check is plenty — the
|
||||
// file is already there. When it appeared to fail, the server
|
||||
// may still be writing; give it a few extra seconds.
|
||||
var attempts = afterFailure ? 4 : 1;
|
||||
var delay = TimeSpan.FromSeconds(2);
|
||||
|
||||
for (int i = 0; i < attempts; i++)
|
||||
{
|
||||
ct.ThrowIfCancellationRequested();
|
||||
if (i > 0) await Task.Delay(delay, ct).ConfigureAwait(false);
|
||||
|
||||
if (await IsPresentAsync(expectedName, folderPath, ct).ConfigureAwait(false))
|
||||
{
|
||||
if (i > 0)
|
||||
{
|
||||
_logger.Information(
|
||||
"Post-upload verify: '{Expected}' appeared under '{Path}' on attempt {Attempt}/{Total} despite upload exception",
|
||||
expectedName, folderPath, i + 1, attempts);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private async Task<bool> IsPresentAsync(string expectedName, string folderPath, CancellationToken ct)
|
||||
{
|
||||
try
|
||||
{
|
||||
var items = await _client.ListNetworkStorageFolderAsync(folderPath, ct).ConfigureAwait(false);
|
||||
var trimmedExpected = expectedName.Trim().TrimStart('-', ' ').TrimEnd('-', ' ');
|
||||
bool found = false;
|
||||
foreach (var it in items)
|
||||
{
|
||||
if (it.IsFolder) continue;
|
||||
if (string.Equals(it.Name, expectedName, StringComparison.Ordinal) ||
|
||||
string.Equals(it.Name, trimmedExpected, StringComparison.Ordinal))
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
{
|
||||
var names = new List<string>();
|
||||
foreach (var it in items)
|
||||
{
|
||||
if (it.IsFolder) continue;
|
||||
names.Add(it.Name);
|
||||
}
|
||||
_logger.Warning(
|
||||
"Post-upload verify: expected '{Expected}' under '{Path}' but it's NOT in the listing. " +
|
||||
"Server reported the upload as successful but the file is not on the share. " +
|
||||
"Files currently in that folder: [{Files}]",
|
||||
expectedName, folderPath, string.Join(", ", names));
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.Information("Post-upload verify: '{Expected}' present under '{Path}'", expectedName, folderPath);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Warning(ex, "Post-upload verify failed for '{Expected}' under '{Path}'", expectedName, folderPath);
|
||||
_logger.Warning(ex, "Post-upload listing under '{Path}' failed", folderPath);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,15 @@ namespace MarcusLaw.OutlookAddin.Core.Services
|
||||
/// </summary>
|
||||
Task<MatchResult?> LookupAsync(string senderEmail, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Loads the full contact + account + recent-cases bundle for a
|
||||
/// specific contact id. Used when the sender's email matches
|
||||
/// multiple contacts and the user picks one from the candidate
|
||||
/// list — we then drill into that contact's cases without
|
||||
/// dropping back to manual search.
|
||||
/// </summary>
|
||||
Task<MatchResult?> LookupContactAsync(string contactId, string? senderEmail = null, CancellationToken cancellationToken = default);
|
||||
|
||||
void Invalidate(string senderEmail);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using MarcusLaw.OutlookAddin.Core.Models;
|
||||
@@ -44,60 +45,51 @@ namespace MarcusLaw.OutlookAddin.Core.Services
|
||||
return null;
|
||||
}
|
||||
|
||||
if (matches.Count > 1)
|
||||
// EspoCRM's /EmailAddress/search can return the same Contact
|
||||
// more than once when the contact has the searched-for
|
||||
// address registered under multiple emailAddressData rows.
|
||||
// Dedupe by Id so the sidebar shows one row per unique person.
|
||||
var distinctIds = matches
|
||||
.Where(m => !string.IsNullOrWhiteSpace(m.Id))
|
||||
.Select(m => m.Id)
|
||||
.Distinct(StringComparer.Ordinal)
|
||||
.Take(20)
|
||||
.ToList();
|
||||
|
||||
if (distinctIds.Count == 0)
|
||||
{
|
||||
var ambiguous = new MatchResult
|
||||
{
|
||||
SenderEmail = senderEmail,
|
||||
IsAmbiguous = true,
|
||||
CandidateCount = matches.Count
|
||||
};
|
||||
_cache.Set<MatchResult?>(key, ambiguous, CacheExpiry);
|
||||
return ambiguous;
|
||||
_cache.Set(key, (MatchResult?)null, CacheExpiry);
|
||||
return null;
|
||||
}
|
||||
|
||||
var contactRef = matches[0];
|
||||
var contact = await _client.GetContactAsync(contactRef.Id, ContactSelect, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
AccountEntity? account = null;
|
||||
if (!string.IsNullOrWhiteSpace(contact.AccountId))
|
||||
if (distinctIds.Count == 1)
|
||||
{
|
||||
try
|
||||
{
|
||||
account = await _client.GetAccountAsync(contact.AccountId!, "id,name,emailAddress", cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Warning(ex, "MatchingService: failed to load account {AccountId} for {Email}", contact.AccountId, senderEmail);
|
||||
}
|
||||
var single = await LoadContactBundleAsync(distinctIds[0], senderEmail, cancellationToken).ConfigureAwait(false);
|
||||
_cache.Set<MatchResult?>(key, single, CacheExpiry);
|
||||
return single;
|
||||
}
|
||||
|
||||
var cases = new System.Collections.Generic.List<CaseEntity>();
|
||||
try
|
||||
{
|
||||
// Pull up to 50 cases per contact so the sidebar can show the
|
||||
// whole list, not just the 5 most recent. 50 is well below the
|
||||
// EspoCRM default page limit and large enough for any realistic
|
||||
// attorney/contact relationship.
|
||||
var list = await _client.ListCasesForContactAsync(contact.Id, 50, cancellationToken).ConfigureAwait(false);
|
||||
cases.AddRange(list.List);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Warning(ex, "MatchingService: failed to list cases for {ContactId}", contact.Id);
|
||||
}
|
||||
// Two or more genuinely distinct contacts. Fetch each one's
|
||||
// full record (in parallel) so the picker can show real
|
||||
// name + account, not just the bare email payload.
|
||||
var fetched = await Task.WhenAll(
|
||||
distinctIds.Select(id => SafeGetContactAsync(id, cancellationToken))
|
||||
).ConfigureAwait(false);
|
||||
|
||||
var result = new MatchResult
|
||||
var candidates = fetched
|
||||
.Where(c => c != null && !string.IsNullOrWhiteSpace(c!.Id))
|
||||
.Select(c => c!)
|
||||
.ToList();
|
||||
|
||||
var ambiguous = new MatchResult
|
||||
{
|
||||
SenderEmail = senderEmail,
|
||||
Contact = contact,
|
||||
Account = account,
|
||||
RecentCases = cases,
|
||||
CandidateCount = 1
|
||||
IsAmbiguous = true,
|
||||
CandidateCount = candidates.Count,
|
||||
Candidates = candidates
|
||||
};
|
||||
|
||||
_cache.Set<MatchResult?>(key, result, CacheExpiry);
|
||||
return result;
|
||||
_cache.Set<MatchResult?>(key, ambiguous, CacheExpiry);
|
||||
return ambiguous;
|
||||
}
|
||||
catch (EspoCrmAuthorizationException)
|
||||
{
|
||||
@@ -114,6 +106,86 @@ namespace MarcusLaw.OutlookAddin.Core.Services
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<MatchResult?> LookupContactAsync(string contactId, string? senderEmail = null, CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(contactId)) return null;
|
||||
|
||||
try
|
||||
{
|
||||
return await LoadContactBundleAsync(contactId, senderEmail ?? string.Empty, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
catch (EspoCrmAuthorizationException)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Warning(ex, "MatchingService: LookupContactAsync failed for {ContactId}", contactId);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<MatchResult> LoadContactBundleAsync(string contactId, string senderEmail, CancellationToken cancellationToken)
|
||||
{
|
||||
var contact = await _client.GetContactAsync(contactId, ContactSelect, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
AccountEntity? account = null;
|
||||
if (!string.IsNullOrWhiteSpace(contact.AccountId))
|
||||
{
|
||||
try
|
||||
{
|
||||
account = await _client.GetAccountAsync(contact.AccountId!, "id,name,emailAddress", cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Warning(ex, "MatchingService: failed to load account {AccountId} for contact {ContactId}", contact.AccountId, contactId);
|
||||
}
|
||||
}
|
||||
|
||||
var cases = new System.Collections.Generic.List<CaseEntity>();
|
||||
try
|
||||
{
|
||||
// Pull up to 50 cases per contact so the sidebar can show the
|
||||
// whole list, not just the 5 most recent. 50 is well below the
|
||||
// EspoCRM default page limit and large enough for any realistic
|
||||
// attorney/contact relationship.
|
||||
var list = await _client.ListCasesForContactAsync(contact.Id, 50, cancellationToken).ConfigureAwait(false);
|
||||
cases.AddRange(list.List);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Warning(ex, "MatchingService: failed to list cases for {ContactId}", contact.Id);
|
||||
}
|
||||
|
||||
return new MatchResult
|
||||
{
|
||||
SenderEmail = senderEmail,
|
||||
Contact = contact,
|
||||
Account = account,
|
||||
RecentCases = cases,
|
||||
CandidateCount = 1
|
||||
};
|
||||
}
|
||||
|
||||
private async Task<ContactEntity?> SafeGetContactAsync(string contactId, CancellationToken cancellationToken)
|
||||
{
|
||||
try
|
||||
{
|
||||
return await _client.GetContactAsync(contactId, ContactSelect, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
catch (OperationCanceledException) { throw; }
|
||||
catch (EspoCrmAuthorizationException) { throw; }
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Warning(ex, "MatchingService: candidate contact fetch failed for {Id}", contactId);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void Invalidate(string senderEmail)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(senderEmail)) return;
|
||||
|
||||
@@ -84,6 +84,10 @@ namespace MarcusLaw.OutlookAddin.UI.Converters
|
||||
["New"] = "חדש",
|
||||
["Assigned"] = "הוקצה",
|
||||
["Pending"] = "ממתין",
|
||||
["PendingHearing"] = "ממתין לדיון",
|
||||
["Pending Hearing"] = "ממתין לדיון",
|
||||
["PendingDecision"] = "ממתין להחלטה",
|
||||
["Pending Decision"] = "ממתין להחלטה",
|
||||
["In Progress"] = "בטיפול",
|
||||
["InProgress"] = "בטיפול",
|
||||
["Open"] = "פתוח",
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<Window x:Class="MarcusLaw.OutlookAddin.UI.Dialogs.SaveAttachmentsDialog"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:conv="clr-namespace:MarcusLaw.OutlookAddin.UI.Converters"
|
||||
Title="שמור קבצים מצורפים ל-Klear"
|
||||
Height="560" Width="620"
|
||||
MinHeight="420" MinWidth="500"
|
||||
@@ -11,6 +12,9 @@
|
||||
Background="#F8FAFC"
|
||||
FontFamily="Segoe UI, David, Frank Ruehl, Arial">
|
||||
<Window.Resources>
|
||||
<conv:CaseStatusToHebrewConverter x:Key="CaseStatusHe" />
|
||||
<BooleanToVisibilityConverter x:Key="BoolToVis" />
|
||||
|
||||
<SolidColorBrush x:Key="Primary" Color="#2563EB" />
|
||||
<SolidColorBrush x:Key="PrimaryHover" Color="#1D4ED8" />
|
||||
<SolidColorBrush x:Key="Border" Color="#E2E8F0" />
|
||||
@@ -80,32 +84,28 @@
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="CaseItem" TargetType="ListBoxItem">
|
||||
<Setter Property="Padding" Value="0" />
|
||||
<Setter Property="Margin" Value="0" />
|
||||
<Setter Property="Background" Value="Transparent" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="ListBoxItem">
|
||||
<Border x:Name="Bd" Background="{TemplateBinding Background}" CornerRadius="4"
|
||||
Margin="2,1" Padding="8,6">
|
||||
<ContentPresenter />
|
||||
</Border>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="IsMouseOver" Value="True">
|
||||
<Setter TargetName="Bd" Property="Background" Value="{StaticResource HoverBg}" />
|
||||
</Trigger>
|
||||
<Trigger Property="IsSelected" Value="True">
|
||||
<Setter TargetName="Bd" Property="Background" Value="{StaticResource SelectedBg}" />
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
</Window.Resources>
|
||||
|
||||
<Grid Margin="16">
|
||||
<Grid Margin="16" x:Name="RootGrid">
|
||||
<Grid.Resources>
|
||||
<Style x:Key="CaseGrid" TargetType="DataGrid">
|
||||
<Setter Property="AutoGenerateColumns" Value="False" />
|
||||
<Setter Property="HeadersVisibility" Value="Column" />
|
||||
<Setter Property="GridLinesVisibility" Value="Horizontal" />
|
||||
<Setter Property="HorizontalGridLinesBrush" Value="#E2E8F0" />
|
||||
<Setter Property="RowBackground" Value="White" />
|
||||
<Setter Property="AlternatingRowBackground" Value="#F8FAFC" />
|
||||
<Setter Property="BorderThickness" Value="0" />
|
||||
<Setter Property="CanUserAddRows" Value="False" />
|
||||
<Setter Property="CanUserDeleteRows" Value="False" />
|
||||
<Setter Property="CanUserResizeRows" Value="False" />
|
||||
<Setter Property="CanUserReorderColumns" Value="False" />
|
||||
<Setter Property="SelectionMode" Value="Single" />
|
||||
<Setter Property="SelectionUnit" Value="FullRow" />
|
||||
<Setter Property="IsReadOnly" Value="True" />
|
||||
<Setter Property="RowHeight" Value="30" />
|
||||
</Style>
|
||||
</Grid.Resources>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
@@ -130,32 +130,38 @@
|
||||
|
||||
<!-- Cases -->
|
||||
<Border Grid.Row="1" Style="{StaticResource Card}">
|
||||
<ListBox ItemsSource="{Binding Cases}"
|
||||
SelectedItem="{Binding SelectedCase}"
|
||||
BorderThickness="0"
|
||||
Background="Transparent"
|
||||
ItemContainerStyle="{StaticResource CaseItem}"
|
||||
Padding="4">
|
||||
<ListBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<StackPanel>
|
||||
<TextBlock FontSize="13">
|
||||
<Run Text="[" /><Run Text="{Binding Number, Mode=OneWay}" /><Run Text="] " />
|
||||
<Run Text="{Binding Name, Mode=OneWay}" FontWeight="SemiBold" />
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</ListBox.ItemTemplate>
|
||||
</ListBox>
|
||||
<DataGrid ItemsSource="{Binding Cases}"
|
||||
SelectedItem="{Binding SelectedCase}"
|
||||
Style="{StaticResource CaseGrid}">
|
||||
<DataGrid.Columns>
|
||||
<DataGridTextColumn Header="מס׳ תיק" Binding="{Binding Number}" Width="80" />
|
||||
<DataGridTextColumn Header="שם" Binding="{Binding Name}" Width="*" />
|
||||
<DataGridTextColumn Header="מס׳ בבית משפט" Binding="{Binding CourtCaseNumber}" Width="140" />
|
||||
<DataGridTextColumn Header="סטטוס" Binding="{Binding Status, Converter={StaticResource CaseStatusHe}}" Width="110" />
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
</Border>
|
||||
|
||||
<!-- Folder -->
|
||||
<DockPanel Grid.Row="2" Margin="0,10,0,0" LastChildFill="True">
|
||||
<TextBlock DockPanel.Dock="Left" Text="תיקייה:" VerticalAlignment="Center"
|
||||
Margin="0,0,8,0" Foreground="{StaticResource Muted}" FontSize="12" />
|
||||
<TextBlock DockPanel.Dock="Right" Text="טוען…" VerticalAlignment="Center"
|
||||
Margin="8,0,0,0" Foreground="{StaticResource Muted}" FontSize="12"
|
||||
Visibility="{Binding IsLoadingSubfolders, Converter={StaticResource BoolToVis}}" />
|
||||
<ComboBox ItemsSource="{Binding Subfolders}"
|
||||
SelectedItem="{Binding SelectedSubfolder}"
|
||||
Padding="6,4" />
|
||||
Padding="6,4">
|
||||
<ComboBox.Style>
|
||||
<Style TargetType="ComboBox">
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding IsLoadingSubfolders}" Value="True">
|
||||
<Setter Property="IsEnabled" Value="False" />
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</ComboBox.Style>
|
||||
</ComboBox>
|
||||
</DockPanel>
|
||||
|
||||
<!-- Attachments header -->
|
||||
@@ -178,10 +184,20 @@
|
||||
FontSize="11"
|
||||
VerticalAlignment="Center"
|
||||
Margin="8,0,0,0" />
|
||||
<TextBlock Text="{Binding FileName}"
|
||||
<TextBlock Text="{Binding Extension}"
|
||||
DockPanel.Dock="Left"
|
||||
Foreground="{StaticResource Muted}"
|
||||
FontSize="12"
|
||||
VerticalAlignment="Center"
|
||||
TextTrimming="CharacterEllipsis"
|
||||
Margin="8,0,0,0" />
|
||||
Margin="6,0,0,0" />
|
||||
<TextBox Text="{Binding BaseName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
||||
IsEnabled="{Binding IsSelected}"
|
||||
VerticalAlignment="Center"
|
||||
BorderThickness="1"
|
||||
BorderBrush="{StaticResource Border}"
|
||||
Padding="6,3"
|
||||
Margin="8,0,0,0"
|
||||
ToolTip="לחץ כדי לערוך את שם הקובץ (הסיומת נשמרת אוטומטית)" />
|
||||
</DockPanel>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using System.IO;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using MarcusLaw.OutlookAddin.Core.Models;
|
||||
|
||||
@@ -10,6 +11,34 @@ namespace MarcusLaw.OutlookAddin.UI.ViewModels
|
||||
[ObservableProperty]
|
||||
private bool isSelected = true;
|
||||
|
||||
/// <summary>
|
||||
/// Frozen at construction from the original filename. The user
|
||||
/// edits only the base name; the extension always tags along.
|
||||
/// </summary>
|
||||
public string Extension { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Editable base name without the extension. Setting this rewrites
|
||||
/// <see cref="EspoAttachment.Name"/> as <basename><Extension>.
|
||||
/// </summary>
|
||||
public string BaseName
|
||||
{
|
||||
get => Path.GetFileNameWithoutExtension(Data.Name) ?? string.Empty;
|
||||
set
|
||||
{
|
||||
var newBase = (value ?? string.Empty).Trim();
|
||||
var newFull = newBase + Extension;
|
||||
if (Data.Name == newFull) return;
|
||||
Data.Name = newFull;
|
||||
OnPropertyChanged();
|
||||
OnPropertyChanged(nameof(FileName));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Full filename including extension — what actually goes to the
|
||||
/// server. Read-only mirror of <see cref="EspoAttachment.Name"/>.
|
||||
/// </summary>
|
||||
public string FileName => Data.Name;
|
||||
|
||||
public string SizeDisplay { get; }
|
||||
@@ -17,6 +46,7 @@ namespace MarcusLaw.OutlookAddin.UI.ViewModels
|
||||
public AttachmentRowViewModel(EspoAttachment data)
|
||||
{
|
||||
Data = data;
|
||||
Extension = Path.GetExtension(data.Name) ?? string.Empty;
|
||||
SizeDisplay = ComputeSize(data.ContentBase64);
|
||||
}
|
||||
|
||||
|
||||
@@ -30,6 +30,9 @@ namespace MarcusLaw.OutlookAddin.UI.ViewModels
|
||||
private readonly IMatchingService _matchingService;
|
||||
private readonly ILogger _logger;
|
||||
private CancellationTokenSource? _activeLookup;
|
||||
// Stashes the ambiguous MatchResult while the user is drilling into
|
||||
// one of its candidates, so the "→ חזור" button can restore it.
|
||||
private MatchResult? _ambiguousReturnTarget;
|
||||
|
||||
[ObservableProperty]
|
||||
private ReadingPaneState state = ReadingPaneState.Empty;
|
||||
@@ -51,6 +54,8 @@ namespace MarcusLaw.OutlookAddin.UI.ViewModels
|
||||
|
||||
public ObservableCollection<CaseEntity> RecentCases { get; } = new ObservableCollection<CaseEntity>();
|
||||
|
||||
public ObservableCollection<ContactEntity> Candidates { get; } = new ObservableCollection<ContactEntity>();
|
||||
|
||||
public Visibility EmptyVisibility => Vis(State == ReadingPaneState.Empty);
|
||||
public Visibility LoadingVisibility => Vis(State == ReadingPaneState.Loading);
|
||||
public Visibility MatchVisibility => Vis(State == ReadingPaneState.Match);
|
||||
@@ -61,6 +66,22 @@ namespace MarcusLaw.OutlookAddin.UI.ViewModels
|
||||
public Visibility NoCasesVisibility => Vis(State == ReadingPaneState.Match && RecentCases.Count == 0);
|
||||
public Visibility ActionsVisibility => Vis(State == ReadingPaneState.Match);
|
||||
|
||||
/// <summary>
|
||||
/// True when the matched contact has 2+ linked cases. The sidebar
|
||||
/// uses this to hide the bottom "תייק לתיק הזה" button (which is
|
||||
/// ambiguous in that scenario) and to surface the per-row "תייק"
|
||||
/// buttons that let the user pick which case to file to.
|
||||
/// </summary>
|
||||
public Visibility MultiCaseHintVisibility => Vis(State == ReadingPaneState.Match && RecentCases.Count >= 2);
|
||||
public Visibility SingleCaseFileVisibility => Vis(State == ReadingPaneState.Match && RecentCases.Count == 1);
|
||||
|
||||
/// <summary>
|
||||
/// "→ חזור לרשימת אנשי קשר" is only shown when the user drilled
|
||||
/// into a candidate from the ambiguous picker; not in a normal
|
||||
/// single-match lookup.
|
||||
/// </summary>
|
||||
public Visibility BackToCandidatesVisibility => Vis(State == ReadingPaneState.Match && _ambiguousReturnTarget != null);
|
||||
|
||||
/// <summary>
|
||||
/// Raised when the user clicks "File to this case" (carries the chosen
|
||||
/// MatchResult.Contact / RecentCases pick) or "File elsewhere" (null).
|
||||
@@ -89,6 +110,9 @@ namespace MarcusLaw.OutlookAddin.UI.ViewModels
|
||||
OnPropertyChanged(nameof(ErrorVisibility));
|
||||
OnPropertyChanged(nameof(ActionsVisibility));
|
||||
OnPropertyChanged(nameof(NoCasesVisibility));
|
||||
OnPropertyChanged(nameof(MultiCaseHintVisibility));
|
||||
OnPropertyChanged(nameof(SingleCaseFileVisibility));
|
||||
OnPropertyChanged(nameof(BackToCandidatesVisibility));
|
||||
FileToThisCommand.NotifyCanExecuteChanged();
|
||||
FileElsewhereCommand.NotifyCanExecuteChanged();
|
||||
OpenInEspoCrmCommand.NotifyCanExecuteChanged();
|
||||
@@ -101,8 +125,16 @@ namespace MarcusLaw.OutlookAddin.UI.ViewModels
|
||||
{
|
||||
foreach (var c in value.RecentCases) RecentCases.Add(c);
|
||||
}
|
||||
Candidates.Clear();
|
||||
if (value?.Candidates != null)
|
||||
{
|
||||
foreach (var c in value.Candidates) Candidates.Add(c);
|
||||
}
|
||||
OnPropertyChanged(nameof(AccountVisibility));
|
||||
OnPropertyChanged(nameof(NoCasesVisibility));
|
||||
OnPropertyChanged(nameof(MultiCaseHintVisibility));
|
||||
OnPropertyChanged(nameof(SingleCaseFileVisibility));
|
||||
OnPropertyChanged(nameof(BackToCandidatesVisibility));
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
@@ -112,6 +144,7 @@ namespace MarcusLaw.OutlookAddin.UI.ViewModels
|
||||
Match = null;
|
||||
ErrorMessage = null;
|
||||
AmbiguousMessage = null;
|
||||
_ambiguousReturnTarget = null;
|
||||
State = ReadingPaneState.Empty;
|
||||
}
|
||||
|
||||
@@ -125,6 +158,8 @@ namespace MarcusLaw.OutlookAddin.UI.ViewModels
|
||||
}
|
||||
|
||||
SenderEmail = senderEmail;
|
||||
// New email selection — drop any stashed candidate-list state.
|
||||
_ambiguousReturnTarget = null;
|
||||
State = ReadingPaneState.Loading;
|
||||
|
||||
var cts = new CancellationTokenSource();
|
||||
@@ -182,7 +217,28 @@ namespace MarcusLaw.OutlookAddin.UI.ViewModels
|
||||
FileRequested?.Invoke(this, new FileFromSidebarEventArgs(Match!));
|
||||
}
|
||||
|
||||
private bool CanFileToThis() => State == ReadingPaneState.Match && Match?.Contact != null;
|
||||
// Bottom "תייק לתיק הזה" only makes sense with exactly one linked
|
||||
// case. 0 cases → nothing to file to; 2+ cases → ambiguous, the
|
||||
// per-row "תייק" buttons handle the pick.
|
||||
private bool CanFileToThis() => State == ReadingPaneState.Match && Match?.Contact != null && RecentCases.Count == 1;
|
||||
|
||||
[RelayCommand]
|
||||
private void FileToCase(CaseEntity? caseEntity)
|
||||
{
|
||||
if (caseEntity == null || string.IsNullOrWhiteSpace(caseEntity.Id) || Match == null) return;
|
||||
// Build a synthetic MatchResult so the host's
|
||||
// TryResolveSidebarAutoTarget path sees exactly one case and
|
||||
// auto-files without re-opening the search dialog.
|
||||
var synthetic = new MatchResult
|
||||
{
|
||||
SenderEmail = Match.SenderEmail,
|
||||
Contact = Match.Contact,
|
||||
Account = Match.Account,
|
||||
RecentCases = new System.Collections.Generic.List<CaseEntity> { caseEntity },
|
||||
CandidateCount = 1
|
||||
};
|
||||
FileRequested?.Invoke(this, new FileFromSidebarEventArgs(synthetic));
|
||||
}
|
||||
|
||||
[RelayCommand(CanExecute = nameof(CanFileElsewhere))]
|
||||
private void FileElsewhere()
|
||||
@@ -202,12 +258,88 @@ namespace MarcusLaw.OutlookAddin.UI.ViewModels
|
||||
|
||||
private bool CanOpenInCrm() => State == ReadingPaneState.Match && Match?.Contact != null;
|
||||
|
||||
[RelayCommand]
|
||||
private void OpenCaseInCrm(CaseEntity? caseEntity)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(EspoCrmBaseUrl) || caseEntity == null || string.IsNullOrWhiteSpace(caseEntity.Id)) return;
|
||||
var url = EspoCrmBaseUrl!.TrimEnd('/') + "/#Case/view/" + caseEntity.Id;
|
||||
OpenInBrowserRequested?.Invoke(this, url);
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void OpenManualSearch()
|
||||
{
|
||||
FileRequested?.Invoke(this, new FileFromSidebarEventArgs(null));
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void BackToCandidates()
|
||||
{
|
||||
if (_ambiguousReturnTarget == null) return;
|
||||
var stash = _ambiguousReturnTarget;
|
||||
// Clear stash before we re-enter Ambiguous so visibility refresh
|
||||
// (triggered by OnMatchChanged) sees the cleared state and hides
|
||||
// the back button until the user drills in again.
|
||||
_ambiguousReturnTarget = null;
|
||||
Match = stash;
|
||||
AmbiguousMessage = $"נמצאו {stash.CandidateCount} אנשי קשר עם הכתובת הזו.";
|
||||
State = ReadingPaneState.Ambiguous;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// User picked one of the ambiguous candidates from the sidebar.
|
||||
/// Load that contact's full bundle (account + cases) and transition
|
||||
/// to the Match state so the user can pick a case or file.
|
||||
/// </summary>
|
||||
[RelayCommand]
|
||||
private async Task SelectCandidateAsync(ContactEntity? candidate)
|
||||
{
|
||||
if (candidate == null || string.IsNullOrWhiteSpace(candidate.Id)) return;
|
||||
|
||||
CancelInFlight();
|
||||
var cts = new CancellationTokenSource();
|
||||
_activeLookup = cts;
|
||||
|
||||
var rememberedEmail = SenderEmail;
|
||||
// Stash the ambiguous result so "→ חזור" can restore it.
|
||||
if (Match?.IsAmbiguous == true)
|
||||
{
|
||||
_ambiguousReturnTarget = Match;
|
||||
}
|
||||
State = ReadingPaneState.Loading;
|
||||
|
||||
try
|
||||
{
|
||||
var result = await _matchingService.LookupContactAsync(candidate.Id, rememberedEmail, cts.Token).ConfigureAwait(true);
|
||||
if (cts.IsCancellationRequested) return;
|
||||
|
||||
if (result == null || result.Contact == null)
|
||||
{
|
||||
ErrorMessage = "טעינת איש הקשר נכשלה.";
|
||||
State = ReadingPaneState.Error;
|
||||
return;
|
||||
}
|
||||
|
||||
Match = result;
|
||||
State = ReadingPaneState.Match;
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
// Selection changed before lookup finished — ignore.
|
||||
}
|
||||
catch (EspoCrmAuthorizationException)
|
||||
{
|
||||
ErrorMessage = "מפתח ה-API נדחה. עדכן בהגדרות.";
|
||||
State = ReadingPaneState.Error;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Warning(ex, "ReadingPaneViewModel.SelectCandidateAsync failed for {ContactId}", candidate.Id);
|
||||
ErrorMessage = "שגיאת התחברות לשרת.";
|
||||
State = ReadingPaneState.Error;
|
||||
}
|
||||
}
|
||||
|
||||
private static Visibility Vis(bool show) => show ? Visibility.Visible : Visibility.Collapsed;
|
||||
}
|
||||
|
||||
|
||||
@@ -45,6 +45,9 @@ namespace MarcusLaw.OutlookAddin.UI.ViewModels
|
||||
[ObservableProperty]
|
||||
private string? statusMessage;
|
||||
|
||||
[ObservableProperty]
|
||||
private bool isLoadingSubfolders;
|
||||
|
||||
/// <summary>
|
||||
/// Resolved server-side case folder path for the currently
|
||||
/// selected case (e.g. "47-אריאל מונאס"). Populated by
|
||||
@@ -140,6 +143,19 @@ namespace MarcusLaw.OutlookAddin.UI.ViewModels
|
||||
var c = SelectedCase;
|
||||
if (c == null || string.IsNullOrEmpty(c.Id)) return;
|
||||
|
||||
IsLoadingSubfolders = true;
|
||||
try
|
||||
{
|
||||
await RefreshSubfoldersCoreAsync(c).ConfigureAwait(true);
|
||||
}
|
||||
finally
|
||||
{
|
||||
IsLoadingSubfolders = false;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task RefreshSubfoldersCoreAsync(CaseEntity c)
|
||||
{
|
||||
try { await _client.EnsureCaseSubfoldersAsync(c.Id).ConfigureAwait(true); }
|
||||
catch (Exception ex) { _logger.Warning(ex, "EnsureCaseSubfolders failed; subfolders may be missing on disk"); }
|
||||
|
||||
@@ -237,6 +253,27 @@ namespace MarcusLaw.OutlookAddin.UI.ViewModels
|
||||
return name.Trim(' ', '-');
|
||||
}
|
||||
|
||||
private async Task<CaseEntity?> LoadCaseRowAsync(EspoEntityRef hit, CancellationToken ct)
|
||||
{
|
||||
var row = new CaseEntity { Id = hit.Id, Name = hit.Name };
|
||||
if (string.IsNullOrEmpty(hit.Id)) return row;
|
||||
try
|
||||
{
|
||||
var detail = await _client.GetCaseAsync(
|
||||
hit.Id, "id,name,number,status,cCourtCaseNumber", ct).ConfigureAwait(false);
|
||||
row.Number = detail.Number;
|
||||
row.Status = detail.Status;
|
||||
row.CourtCaseNumber = detail.CourtCaseNumber;
|
||||
if (!string.IsNullOrEmpty(detail.Name)) row.Name = detail.Name;
|
||||
}
|
||||
catch (OperationCanceledException) { throw; }
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Warning(ex, "Hydrating case {CaseId} for picker failed", hit.Id);
|
||||
}
|
||||
return row;
|
||||
}
|
||||
|
||||
private async Task SearchAsync(string query, CancellationToken ct)
|
||||
{
|
||||
try
|
||||
@@ -255,20 +292,32 @@ namespace MarcusLaw.OutlookAddin.UI.ViewModels
|
||||
ct.ThrowIfCancellationRequested();
|
||||
|
||||
Cases.Clear();
|
||||
int kept = 0;
|
||||
var caseHits = new List<EspoEntityRef>();
|
||||
foreach (var hit in search.List)
|
||||
{
|
||||
if (!string.Equals(hit.EntityType, "Case", StringComparison.OrdinalIgnoreCase)) continue;
|
||||
Cases.Add(new CaseEntity
|
||||
{
|
||||
Id = hit.Id,
|
||||
Name = hit.Name
|
||||
});
|
||||
kept++;
|
||||
if (string.Equals(hit.EntityType, "Case", StringComparison.OrdinalIgnoreCase))
|
||||
caseHits.Add(hit);
|
||||
}
|
||||
StatusMessage = kept == 0
|
||||
? "אין תוצאות מסוג תיק (Case)"
|
||||
: $"נמצאו {kept} תיקים";
|
||||
|
||||
if (caseHits.Count == 0)
|
||||
{
|
||||
StatusMessage = "אין תוצאות מסוג תיק (Case)";
|
||||
return;
|
||||
}
|
||||
|
||||
var detailTasks = new List<Task<CaseEntity?>>(caseHits.Count);
|
||||
foreach (var hit in caseHits)
|
||||
{
|
||||
detailTasks.Add(LoadCaseRowAsync(hit, ct));
|
||||
}
|
||||
var details = await Task.WhenAll(detailTasks).ConfigureAwait(true);
|
||||
ct.ThrowIfCancellationRequested();
|
||||
|
||||
foreach (var row in details)
|
||||
{
|
||||
if (row != null) Cases.Add(row);
|
||||
}
|
||||
StatusMessage = $"נמצאו {Cases.Count} תיקים";
|
||||
}
|
||||
catch (OperationCanceledException) { /* superseded */ }
|
||||
catch (EspoCrmAuthorizationException)
|
||||
|
||||
@@ -91,12 +91,13 @@ namespace MarcusLaw.OutlookAddin.UI.ViewModels
|
||||
/// </summary>
|
||||
private static string ResolveDisplayVersion()
|
||||
{
|
||||
Version? v = null;
|
||||
try
|
||||
{
|
||||
if (System.Deployment.Application.ApplicationDeployment.IsNetworkDeployed)
|
||||
{
|
||||
return System.Deployment.Application.ApplicationDeployment
|
||||
.CurrentDeployment.CurrentVersion.ToString();
|
||||
v = System.Deployment.Application.ApplicationDeployment
|
||||
.CurrentDeployment.CurrentVersion;
|
||||
}
|
||||
}
|
||||
catch
|
||||
@@ -104,7 +105,30 @@ namespace MarcusLaw.OutlookAddin.UI.ViewModels
|
||||
// Not running under ClickOnce (dev / F5), or System.Deployment
|
||||
// is not available — fall through to the AssemblyVersion.
|
||||
}
|
||||
return typeof(SettingsViewModel).Assembly.GetName().Version?.ToString() ?? "1.0.0";
|
||||
// The host VSTO assembly is where versioning policy lives
|
||||
// (csproj + AssemblyInfo). The UI assembly is SDK-style with
|
||||
// no <Version>, so it always reports 1.0.0.0 — don't fall back
|
||||
// to it. Walk loaded assemblies for the host by name suffix.
|
||||
if (v == null)
|
||||
{
|
||||
foreach (var asm in AppDomain.CurrentDomain.GetAssemblies())
|
||||
{
|
||||
var name = asm.GetName().Name;
|
||||
if (name != null && name.EndsWith(".OutlookAddin", StringComparison.Ordinal))
|
||||
{
|
||||
v = asm.GetName().Version;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
v ??= typeof(SettingsViewModel).Assembly.GetName().Version;
|
||||
if (v == null) return "1.0.0";
|
||||
|
||||
// ClickOnce stores 4 components; project policy is MAJOR.MINOR.PATCH —
|
||||
// hide the trailing revision when it's 0.
|
||||
return v.Revision == 0
|
||||
? $"{v.Major}.{v.Minor}.{v.Build}"
|
||||
: v.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -62,6 +62,29 @@
|
||||
<!-- Ambiguous -->
|
||||
<StackPanel Visibility="{Binding AmbiguousVisibility}">
|
||||
<TextBlock Text="{Binding AmbiguousMessage}" Foreground="DarkOrange" />
|
||||
<TextBlock Style="{StaticResource LabelStyle}" Text="בחר איש קשר:" Margin="0,8,0,2" />
|
||||
<ItemsControl ItemsSource="{Binding Candidates}">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Border BorderBrush="#EEE" BorderThickness="0,0,0,1" Padding="0,4">
|
||||
<Button Command="{Binding DataContext.SelectCandidateCommand, RelativeSource={RelativeSource AncestorType=ItemsControl}}"
|
||||
CommandParameter="{Binding}"
|
||||
Background="Transparent"
|
||||
BorderThickness="0"
|
||||
Padding="0"
|
||||
Cursor="Hand"
|
||||
HorizontalContentAlignment="Right"
|
||||
HorizontalAlignment="Stretch">
|
||||
<StackPanel HorizontalAlignment="Stretch">
|
||||
<TextBlock Text="{Binding Name}" FontWeight="SemiBold" Foreground="#0066CC" />
|
||||
<TextBlock Text="{Binding AccountName}" Foreground="DimGray" FontSize="11" />
|
||||
<TextBlock Text="{Binding EmailAddress}" Foreground="Gray" FontSize="10" />
|
||||
</StackPanel>
|
||||
</Button>
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
<Button Content="פתח חיפוש ידני"
|
||||
Command="{Binding OpenManualSearchCommand}"
|
||||
Style="{StaticResource LinkButtonStyle}"
|
||||
@@ -70,8 +93,20 @@
|
||||
|
||||
<!-- Match -->
|
||||
<StackPanel Visibility="{Binding MatchVisibility}">
|
||||
<Button Content="→ חזור לרשימת אנשי קשר"
|
||||
Command="{Binding BackToCandidatesCommand}"
|
||||
Style="{StaticResource LinkButtonStyle}"
|
||||
HorizontalAlignment="Right"
|
||||
Margin="0,0,0,4"
|
||||
Visibility="{Binding BackToCandidatesVisibility}" />
|
||||
<TextBlock Style="{StaticResource LabelStyle}" Text="איש קשר" />
|
||||
<TextBlock Text="{Binding Match.Contact.Name}" FontSize="14" FontWeight="Bold" />
|
||||
<TextBlock FontSize="14" FontWeight="Bold">
|
||||
<Hyperlink Command="{Binding OpenInEspoCrmCommand}"
|
||||
TextDecorations="{x:Null}"
|
||||
Foreground="#0066CC">
|
||||
<Run Text="{Binding Match.Contact.Name, Mode=OneWay}" />
|
||||
</Hyperlink>
|
||||
</TextBlock>
|
||||
<TextBlock Text="{Binding Match.Contact.EmailAddress}" Foreground="Gray" />
|
||||
|
||||
<TextBlock Style="{StaticResource LabelStyle}" Text="לקוח/חברה" Visibility="{Binding AccountVisibility}" />
|
||||
@@ -82,14 +117,33 @@
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Border BorderBrush="#EEE" BorderThickness="0,0,0,1" Padding="0,4">
|
||||
<StackPanel>
|
||||
<TextBlock>
|
||||
<Run Text="["/><Run Text="{Binding Number, Mode=OneWay}"/><Run Text="] " />
|
||||
<Run Text="{Binding Name, Mode=OneWay}" FontWeight="SemiBold" />
|
||||
</TextBlock>
|
||||
<TextBlock Text="{Binding Status, Converter={StaticResource HebrewStatus}}"
|
||||
Foreground="Gray" FontSize="10" />
|
||||
</StackPanel>
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<StackPanel Grid.Column="0">
|
||||
<TextBlock>
|
||||
<Hyperlink Command="{Binding DataContext.OpenCaseInCrmCommand, RelativeSource={RelativeSource AncestorType=ItemsControl}}"
|
||||
CommandParameter="{Binding}"
|
||||
TextDecorations="{x:Null}"
|
||||
Foreground="#0066CC">
|
||||
<Run Text="["/><Run Text="{Binding Number, Mode=OneWay}"/><Run Text="] " />
|
||||
<Run Text="{Binding Name, Mode=OneWay}" FontWeight="SemiBold" />
|
||||
</Hyperlink>
|
||||
</TextBlock>
|
||||
<TextBlock Text="{Binding Status, Converter={StaticResource HebrewStatus}}"
|
||||
Foreground="Gray" FontSize="10" />
|
||||
</StackPanel>
|
||||
<Button Grid.Column="1"
|
||||
Content="תייק"
|
||||
Command="{Binding DataContext.FileToCaseCommand, RelativeSource={RelativeSource AncestorType=ItemsControl}}"
|
||||
CommandParameter="{Binding}"
|
||||
Padding="8,2"
|
||||
Margin="6,0,0,0"
|
||||
VerticalAlignment="Top"
|
||||
ToolTip="תייק את המייל הנוכחי לתיק הזה" />
|
||||
</Grid>
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
@@ -110,7 +164,12 @@
|
||||
<Button Content="תייק לתיק הזה"
|
||||
Command="{Binding FileToThisCommand}"
|
||||
Padding="8,4" Margin="0,0,0,4"
|
||||
HorizontalAlignment="Stretch" />
|
||||
HorizontalAlignment="Stretch"
|
||||
Visibility="{Binding SingleCaseFileVisibility}" />
|
||||
<TextBlock Text="יש כמה תיקים מקושרים — בחר תיק מהרשימה למעלה."
|
||||
Foreground="Gray" FontStyle="Italic" FontSize="10"
|
||||
Margin="0,0,0,4"
|
||||
Visibility="{Binding MultiCaseHintVisibility}" />
|
||||
<Button Content="תייק למקום אחר…"
|
||||
Command="{Binding FileElsewhereCommand}"
|
||||
Padding="8,4" Margin="0,0,0,4"
|
||||
|
||||
@@ -31,13 +31,13 @@
|
||||
<Nullable>enable</Nullable>
|
||||
<DefineConstants>VSTO40;UseOfficeInterop</DefineConstants>
|
||||
<ResolveComReferenceSilent>true</ResolveComReferenceSilent>
|
||||
<IsWebBootstrapper>False</IsWebBootstrapper>
|
||||
<IsWebBootstrapper>True</IsWebBootstrapper>
|
||||
<BootstrapperEnabled>true</BootstrapperEnabled>
|
||||
<PublishUrl>C:\Users\Chaim\source\repos\OutlookAddin\Publish\</PublishUrl>
|
||||
<InstallUrl>\\192.168.10.97\Projects\LegalCRM\Add-in\</InstallUrl>
|
||||
<InstallUrl>https://gitea.dev.marcus-law.co.il/espocrm-extensions/OutlookAddin/raw/branch/main/Publish/</InstallUrl>
|
||||
<TargetCulture>en</TargetCulture>
|
||||
<ApplicationVersion>1.0.0.5</ApplicationVersion>
|
||||
<AutoIncrementApplicationRevision>true</AutoIncrementApplicationRevision>
|
||||
<ApplicationVersion>1.1.3.0</ApplicationVersion>
|
||||
<AutoIncrementApplicationRevision>false</AutoIncrementApplicationRevision>
|
||||
<UpdateEnabled>true</UpdateEnabled>
|
||||
<UpdateInterval>7</UpdateInterval>
|
||||
<UpdateIntervalUnits>days</UpdateIntervalUnits>
|
||||
|
||||
@@ -33,6 +33,6 @@ using System.Security;
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
[assembly: AssemblyVersion("1.1.3.0")]
|
||||
[assembly: AssemblyFileVersion("1.1.3.0")]
|
||||
|
||||
|
||||
@@ -643,7 +643,14 @@ namespace OutlookAddin.Services
|
||||
/// current Explorer selection, opens the search dialog, files on success,
|
||||
/// and stamps categories on the chosen MailItems.
|
||||
/// </summary>
|
||||
public async Task LaunchFileToCaseAsync()
|
||||
public Task LaunchFileToCaseAsync() => LaunchFileToCaseAsync(null);
|
||||
|
||||
/// <summary>
|
||||
/// Same as <see cref="LaunchFileToCaseAsync()"/>, but when the sidebar
|
||||
/// already resolved a single linked case for the sender we skip the
|
||||
/// search dialog and file directly to that case.
|
||||
/// </summary>
|
||||
public async Task LaunchFileToCaseAsync(MatchResult? preselectedMatch)
|
||||
{
|
||||
if (!IsConfigured)
|
||||
{
|
||||
@@ -673,39 +680,50 @@ namespace OutlookAddin.Services
|
||||
try
|
||||
{
|
||||
var envelopes = mailItems.Select(MailItemExtractor.Extract).ToList();
|
||||
var firstEnvelope = envelopes[0];
|
||||
|
||||
var vm = new FileToCaseViewModel(CrmClient!, Settings, Logger)
|
||||
FilingTarget? target = TryResolveSidebarAutoTarget(preselectedMatch);
|
||||
if (target != null)
|
||||
{
|
||||
SenderEmail = firstEnvelope.From,
|
||||
SenderName = TryGetSenderName(mailItems[0])
|
||||
};
|
||||
|
||||
var dialog = new FileToCaseDialog(vm);
|
||||
AttachOwnerToOutlook(dialog);
|
||||
var ok = dialog.ShowDialog();
|
||||
Logger.Information(
|
||||
"FileToCase dialog closed (ok={Ok}, selected id={Id}, entityType={Type})",
|
||||
ok, vm.SelectedTarget?.Id, vm.SelectedTarget?.EntityType);
|
||||
if (ok != true) return;
|
||||
|
||||
var target = vm.GetSelectedFilingTarget();
|
||||
if (target == null)
|
||||
{
|
||||
Logger.Warning(
|
||||
"Filing skipped — selected EspoEntityRef has no usable Id/EntityType (id={Id}, name={Name}, type={Type})",
|
||||
vm.SelectedTarget?.Id, vm.SelectedTarget?.Name, vm.SelectedTarget?.EntityType);
|
||||
MessageBox.Show(
|
||||
"התיק שנבחר לא הוחזר עם סוג ישות (entityType) תקין. ייתכן ש-Klear שלך מחזיר שדה אחר; הלוג מכיל את הפרטים. שלח לאדמין.",
|
||||
"Marcus-Law OutlookAddin",
|
||||
MessageBoxButton.OK,
|
||||
MessageBoxImage.Warning);
|
||||
return;
|
||||
Logger.Information(
|
||||
"Auto-filing {Count} mail item(s) from sidebar to {Type}/{Id} ({Name})",
|
||||
envelopes.Count, target.ParentType, target.ParentId, target.ParentName);
|
||||
}
|
||||
else
|
||||
{
|
||||
var firstEnvelope = envelopes[0];
|
||||
|
||||
Logger.Information(
|
||||
"Filing {Count} mail item(s) to {Type}/{Id} ({Name})",
|
||||
envelopes.Count, target.ParentType, target.ParentId, target.ParentName);
|
||||
var vm = new FileToCaseViewModel(CrmClient!, Settings, Logger)
|
||||
{
|
||||
SenderEmail = firstEnvelope.From,
|
||||
SenderName = TryGetSenderName(mailItems[0])
|
||||
};
|
||||
|
||||
var dialog = new FileToCaseDialog(vm);
|
||||
AttachOwnerToOutlook(dialog);
|
||||
var ok = dialog.ShowDialog();
|
||||
Logger.Information(
|
||||
"FileToCase dialog closed (ok={Ok}, selected id={Id}, entityType={Type})",
|
||||
ok, vm.SelectedTarget?.Id, vm.SelectedTarget?.EntityType);
|
||||
if (ok != true) return;
|
||||
|
||||
target = vm.GetSelectedFilingTarget();
|
||||
if (target == null)
|
||||
{
|
||||
Logger.Warning(
|
||||
"Filing skipped — selected EspoEntityRef has no usable Id/EntityType (id={Id}, name={Name}, type={Type})",
|
||||
vm.SelectedTarget?.Id, vm.SelectedTarget?.Name, vm.SelectedTarget?.EntityType);
|
||||
MessageBox.Show(
|
||||
"התיק שנבחר לא הוחזר עם סוג ישות (entityType) תקין. ייתכן ש-Klear שלך מחזיר שדה אחר; הלוג מכיל את הפרטים. שלח לאדמין.",
|
||||
"Marcus-Law OutlookAddin",
|
||||
MessageBoxButton.OK,
|
||||
MessageBoxImage.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
Logger.Information(
|
||||
"Filing {Count} mail item(s) to {Type}/{Id} ({Name})",
|
||||
envelopes.Count, target.ParentType, target.ParentId, target.ParentName);
|
||||
}
|
||||
|
||||
var summary = await FilingService!.FileAsync(envelopes, target).ConfigureAwait(true);
|
||||
|
||||
@@ -722,6 +740,21 @@ namespace OutlookAddin.Services
|
||||
}
|
||||
}
|
||||
|
||||
// Sidebar's "תייק לתיק הזה" makes a hard promise about which case
|
||||
// gets the mail — only honour it when the match resolved a single
|
||||
// linked case. With 0 or 2+ cases there is no unambiguous "this",
|
||||
// and the caller falls back to the manual search dialog.
|
||||
private static FilingTarget? TryResolveSidebarAutoTarget(MatchResult? match)
|
||||
{
|
||||
if (match?.RecentCases == null || match.RecentCases.Count != 1) return null;
|
||||
var c = match.RecentCases[0];
|
||||
if (string.IsNullOrWhiteSpace(c.Id)) return null;
|
||||
var label = !string.IsNullOrWhiteSpace(c.Number)
|
||||
? $"[{c.Number}] {c.Name}"
|
||||
: (c.Name ?? c.Id);
|
||||
return new FilingTarget("Case", c.Id, label);
|
||||
}
|
||||
|
||||
private List<Outlook.MailItem> ReadCurrentSelection()
|
||||
{
|
||||
var result = new List<Outlook.MailItem>();
|
||||
|
||||
@@ -109,7 +109,7 @@ namespace OutlookAddin.Services
|
||||
|
||||
vm.FileRequested += async (s, e) =>
|
||||
{
|
||||
try { await _host.LaunchFileToCaseAsync().ConfigureAwait(true); }
|
||||
try { await _host.LaunchFileToCaseAsync(e.PreselectedMatch).ConfigureAwait(true); }
|
||||
catch (Exception ex) { _logger.Warning(ex, "Sidebar file-request handler failed"); }
|
||||
};
|
||||
vm.OpenInBrowserRequested += (s, url) => TryOpenInBrowser(url);
|
||||
|
||||
Reference in New Issue
Block a user