Improve document upload UX and refactor wizard layout
Enhanced the `CreateEnvelopeWizardPopup` component: - Added a new grid layout (`sender-create-wizard__body-layout`) to separate main content and side panel. - Introduced a collapsible side panel for document upload and preview. - Replaced old upload logic with `PdfFileDropZone` and added support for displaying document metadata (name, size) and replacement hints. - Added asynchronous document preview rendering with `EnsureDocumentPreviewPreparedAsync`. Localization updates: - Added new localized strings for document upload hints in `de-DE`, `en-US`, and `fr-FR`. CSS updates: - Styled the new layout and side panel with transitions. - Updated `PdfFileDropZone` styles for different states (e.g., document uploaded). Refactored code for better maintainability and improved user feedback during document upload and preview preparation.
This commit is contained in:
@@ -778,6 +778,8 @@
|
||||
<data name="SignedDocument" xml:space="preserve"><value>Signiertes Dokument</value></data>
|
||||
<data name="System" xml:space="preserve"><value>System</value></data>
|
||||
<data name="SenderWizard_Step_Start" xml:space="preserve"><value>Start</value></data>
|
||||
<data name="SenderWizard_DocumentUploadSimpleHint" xml:space="preserve"><value>Dokument hinzufuegen: klicken oder per Drag-and-Drop ablegen</value></data>
|
||||
<data name="SenderWizard_DocumentReplaceHint" xml:space="preserve"><value>Zum Ersetzen klicken oder eine Datei auf diese Flaeche ziehen.</value></data>
|
||||
<data name="UnexpectedErrorTryAgainLater" xml:space="preserve"><value>Ein unerwarteter Fehler ist aufgetreten. Bitte versuchen Sie es später erneut.</value></data>
|
||||
<data name="UploadPdf" xml:space="preserve"><value>PDF hochladen</value></data>
|
||||
<data name="UserName" xml:space="preserve"><value>Benutzername</value></data>
|
||||
|
||||
@@ -778,6 +778,8 @@
|
||||
<data name="SignedDocument" xml:space="preserve"><value>Signed document</value></data>
|
||||
<data name="System" xml:space="preserve"><value>System</value></data>
|
||||
<data name="SenderWizard_Step_Start" xml:space="preserve"><value>Start</value></data>
|
||||
<data name="SenderWizard_DocumentUploadSimpleHint" xml:space="preserve"><value>Add document: click or drag and drop</value></data>
|
||||
<data name="SenderWizard_DocumentReplaceHint" xml:space="preserve"><value>Click to replace or drag a file onto this area.</value></data>
|
||||
<data name="UnexpectedErrorTryAgainLater" xml:space="preserve"><value>An unexpected error occurred. Please try again later.</value></data>
|
||||
<data name="UploadPdf" xml:space="preserve"><value>Upload PDF</value></data>
|
||||
<data name="UserName" xml:space="preserve"><value>Username</value></data>
|
||||
|
||||
@@ -778,6 +778,8 @@
|
||||
<data name="SignedDocument" xml:space="preserve"><value>Document signé</value></data>
|
||||
<data name="System" xml:space="preserve"><value>Système</value></data>
|
||||
<data name="SenderWizard_Step_Start" xml:space="preserve"><value>Démarrer</value></data>
|
||||
<data name="SenderWizard_DocumentUploadSimpleHint" xml:space="preserve"><value>Ajouter un document : cliquer ou glisser-deposer</value></data>
|
||||
<data name="SenderWizard_DocumentReplaceHint" xml:space="preserve"><value>Cliquez pour remplacer ou glissez un fichier sur cette zone.</value></data>
|
||||
<data name="UnexpectedErrorTryAgainLater" xml:space="preserve"><value>Une erreur inattendue s'est produite. Veuillez réessayer plus tard.</value></data>
|
||||
<data name="UploadPdf" xml:space="preserve"><value>Téléverser un PDF</value></data>
|
||||
<data name="UserName" xml:space="preserve"><value>Nom d'utilisateur</value></data>
|
||||
|
||||
@@ -28,387 +28,404 @@
|
||||
<div class="sender-create-wizard"
|
||||
tabindex="0"
|
||||
@onkeydown="OnWizardKeyDownAsync">
|
||||
<MudPaper Class="sender-create-wizard__stepper-shell" Elevation="0">
|
||||
<MudStepper Vertical="true"
|
||||
NonLinear="false"
|
||||
ShowResetButton="false"
|
||||
CurrentStepColor="Color.Info"
|
||||
CompletedStepColor="Color.Success"
|
||||
ErrorStepColor="Color.Error"
|
||||
StepCompleteIcon="@Icons.Material.Filled.CheckCircle"
|
||||
ActiveIndex="@_currentStep"
|
||||
Class="sender-create-wizard__stepper">
|
||||
<ChildContent>
|
||||
@for (var step = 0; step < TotalSteps; step++)
|
||||
{
|
||||
var stepIndex = step;
|
||||
<div class="sender-create-wizard__body-layout @(_currentStep == 4 ? "sender-create-wizard__body-layout--document" : string.Empty)">
|
||||
<MudPaper Class="sender-create-wizard__stepper-shell" Elevation="0">
|
||||
<MudStepper Vertical="true"
|
||||
NonLinear="false"
|
||||
ShowResetButton="false"
|
||||
CurrentStepColor="Color.Info"
|
||||
CompletedStepColor="Color.Success"
|
||||
ErrorStepColor="Color.Error"
|
||||
StepCompleteIcon="@Icons.Material.Filled.CheckCircle"
|
||||
ActiveIndex="@_currentStep"
|
||||
Class="sender-create-wizard__stepper">
|
||||
<ChildContent>
|
||||
@for (var step = 0; step < TotalSteps; step++)
|
||||
{
|
||||
var stepIndex = step;
|
||||
|
||||
<MudStep Title="@GetStepTitle(stepIndex)"
|
||||
Completed="@_completedSteps.Contains(stepIndex)"
|
||||
Skippable="@(stepIndex == 3)">
|
||||
<div class="sender-create-wizard__stepper-description">@GetStepDescription(stepIndex)</div>
|
||||
|
||||
@if (stepIndex == _currentStep)
|
||||
{
|
||||
<div class="sender-create-wizard__step-content">
|
||||
@if (_currentStep == 0)
|
||||
{
|
||||
<div class="sender-create-wizard__form-grid">
|
||||
<div class="sender-create-wizard__field">
|
||||
<label class="sender-create-wizard__label sender-create-wizard__label-row">
|
||||
<span>@L("Title", "Titel") <span class="sender-create-wizard__required">*</span></span>
|
||||
<MudTooltip Text='@L("SenderWizard_Help_Title", "Ein kurzer, eindeutiger Titel hilft beim schnellen Wiederfinden des Umschlags.")'>
|
||||
<MudIconButton Icon="@Icons.Material.Filled.Info" Color="Color.Tertiary" Size="Size.Small" Class="sender-create-wizard__help-icon" aria-label='@L("SenderWizard_HelpAria_Title", "Hilfe zum Feld Titel")' />
|
||||
</MudTooltip>
|
||||
</label>
|
||||
<DxTextBox Text="@_title"
|
||||
TextChanged="OnTitleChanged"
|
||||
BindValueMode="BindValueMode.OnInput"
|
||||
NullText='@L("SenderEditor_Title_Placeholder", "z.B. Arbeitsvertrag 2025")'
|
||||
CssClass="w-100" />
|
||||
</div>
|
||||
|
||||
<div class="sender-create-wizard__field">
|
||||
<label class="sender-create-wizard__label sender-create-wizard__label-row">
|
||||
<span>@L("EnvelopeType", "Umschlagtyp") <span class="sender-create-wizard__required">*</span></span>
|
||||
<MudTooltip Text='@L("SenderWizard_Help_EnvelopeType", "Der Umschlagtyp kann Standardwerte wie Sprache, Erinnerungen und Sicherheit vorbelegen.")'>
|
||||
<MudIconButton Icon="@Icons.Material.Filled.Info" Color="Color.Tertiary" Size="Size.Small" Class="sender-create-wizard__help-icon" aria-label='@L("SenderWizard_HelpAria_EnvelopeType", "Hilfe zum Feld Umschlagtyp")' />
|
||||
</MudTooltip>
|
||||
</label>
|
||||
<select value="@(_selectedEnvelopeTypeId?.ToString() ?? string.Empty)"
|
||||
@onchange="OnEnvelopeTypeChanged"
|
||||
class="sender-create-wizard__select">
|
||||
@foreach (var type in EnvelopeTypes)
|
||||
{
|
||||
<option value="@type.Id">@type.Title</option>
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
else if (_currentStep == 3)
|
||||
{
|
||||
<div class="sender-create-wizard__form-grid">
|
||||
<div class="sender-create-wizard__field sender-create-wizard__field--full">
|
||||
<label class="sender-create-wizard__label sender-create-wizard__label-row">
|
||||
<span>@L("Message", "Nachricht") <span class="sender-create-wizard__optional">(@L("Optional", "optional"))</span></span>
|
||||
<MudTooltip Text='@L("SenderWizard_Help_Message", "Diese Nachricht wird den Empfaengern in der E-Mail und im Signaturprozess angezeigt.")'>
|
||||
<MudIconButton Icon="@Icons.Material.Filled.Info" Color="Color.Tertiary" Size="Size.Small" Class="sender-create-wizard__help-icon" aria-label='@L("SenderWizard_HelpAria_Message", "Hilfe zum Feld Nachricht")' />
|
||||
</MudTooltip>
|
||||
</label>
|
||||
<DxMemo Text="@_message"
|
||||
TextChanged="OnMessageChanged"
|
||||
Rows="5"
|
||||
MaxLength="500"
|
||||
NullText='@L("SenderEditor_Message_Placeholder", "Bitte unterzeichnen Sie das beigefügte Dokument.")'
|
||||
CssClass="w-100" />
|
||||
</div>
|
||||
|
||||
<div class="sender-create-wizard__field">
|
||||
<label class="sender-create-wizard__label sender-create-wizard__label-row">
|
||||
<span>@L("Language", "Sprache")</span>
|
||||
<MudTooltip Text='@L("SenderWizard_Help_Language", "Legt die Sprache fuer Hinweise, E-Mails und Oberflaechentexte fest.")'>
|
||||
<MudIconButton Icon="@Icons.Material.Filled.Info" Color="Color.Tertiary" Size="Size.Small" Class="sender-create-wizard__help-icon" aria-label='@L("SenderWizard_HelpAria_Language", "Hilfe zum Feld Sprache")' />
|
||||
</MudTooltip>
|
||||
</label>
|
||||
<select @bind="_language" class="sender-create-wizard__select">
|
||||
<option value="de-DE">Deutsch (de-DE)</option>
|
||||
<option value="en-US">English (en-US)</option>
|
||||
<option value="de">Deutsch (de)</option>
|
||||
<option value="en">English (en)</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
else if (_currentStep == 2)
|
||||
{
|
||||
<div class="sender-create-wizard__settings-grid">
|
||||
<div class="sender-create-wizard__settings-group">
|
||||
<div class="sender-create-wizard__settings-title">
|
||||
@L("SenderEditor_EnvelopeSettings", "Envelope-Einstellungen")
|
||||
</div>
|
||||
<MudStep Title="@GetStepTitle(stepIndex)"
|
||||
Completed="@_completedSteps.Contains(stepIndex)"
|
||||
Skippable="@(stepIndex == 3)">
|
||||
<div class="sender-create-wizard__stepper-description">@GetStepDescription(stepIndex)</div>
|
||||
|
||||
@if (stepIndex == _currentStep)
|
||||
{
|
||||
<div class="sender-create-wizard__step-content">
|
||||
<div class="sender-create-wizard__step-layout">
|
||||
<div class="sender-create-wizard__step-main">
|
||||
@if (_currentStep == 0)
|
||||
{
|
||||
<div class="sender-create-wizard__form-grid">
|
||||
<div class="sender-create-wizard__field">
|
||||
<label class="sender-create-wizard__label sender-create-wizard__label-row">
|
||||
<span>@L("CertificationType", "Zertifizierung")</span>
|
||||
<MudTooltip Text='@L("SenderWizard_Help_CertificationType", "Bestimmt das Signaturniveau fuer diesen Umschlag.")'>
|
||||
<MudIconButton Icon="@Icons.Material.Filled.Info" Color="Color.Tertiary" Size="Size.Small" Class="sender-create-wizard__help-icon" aria-label='@L("SenderWizard_HelpAria_CertificationType", "Hilfe zum Feld Zertifizierung")' />
|
||||
<span>@L("Title", "Titel") <span class="sender-create-wizard__required">*</span></span>
|
||||
<MudTooltip Text='@L("SenderWizard_Help_Title", "Ein kurzer, eindeutiger Titel hilft beim schnellen Wiederfinden des Umschlags.")'>
|
||||
<MudIconButton Icon="@Icons.Material.Filled.Info" Color="Color.Tertiary" Size="Size.Small" Class="sender-create-wizard__help-icon" aria-label='@L("SenderWizard_HelpAria_Title", "Hilfe zum Feld Titel")' />
|
||||
</MudTooltip>
|
||||
</label>
|
||||
<select @bind="_certificationType" class="sender-create-wizard__select">
|
||||
<option value="@CertificationType.AdvancedElectronicSignature">@L("AdvancedElectronicSignature", "Advanced Electronic Signature")</option>
|
||||
<option value="@CertificationType.ElectronicSignature">@L("ElectronicSignature", "Electronic Signature")</option>
|
||||
</select>
|
||||
<DxTextBox Text="@_title"
|
||||
TextChanged="OnTitleChanged"
|
||||
BindValueMode="BindValueMode.OnInput"
|
||||
NullText='@L("SenderEditor_Title_Placeholder", "z.B. Arbeitsvertrag 2025")'
|
||||
CssClass="w-100" />
|
||||
</div>
|
||||
|
||||
<div class="sender-create-wizard__field">
|
||||
<label class="sender-create-wizard__label sender-create-wizard__label-row">
|
||||
<span>@L("FinalEmailToCreator", "Abgeschlossenes Dokument an Ersteller")</span>
|
||||
<MudTooltip Text='@L("SenderWizard_Help_FinalEmailToCreator", "Steuert, ob der Ersteller nach Abschluss eine finale E-Mail erhaelt und ob das Dokument angehaengt wird.")'>
|
||||
<MudIconButton Icon="@Icons.Material.Filled.Info" Color="Color.Tertiary" Size="Size.Small" Class="sender-create-wizard__help-icon" aria-label='@L("SenderWizard_HelpAria_FinalEmailToCreator", "Hilfe zum Feld Abgeschlossenes Dokument an Ersteller")' />
|
||||
<span>@L("EnvelopeType", "Umschlagtyp") <span class="sender-create-wizard__required">*</span></span>
|
||||
<MudTooltip Text='@L("SenderWizard_Help_EnvelopeType", "Der Umschlagtyp kann Standardwerte wie Sprache, Erinnerungen und Sicherheit vorbelegen.")'>
|
||||
<MudIconButton Icon="@Icons.Material.Filled.Info" Color="Color.Tertiary" Size="Size.Small" Class="sender-create-wizard__help-icon" aria-label='@L("SenderWizard_HelpAria_EnvelopeType", "Hilfe zum Feld Umschlagtyp")' />
|
||||
</MudTooltip>
|
||||
</label>
|
||||
<select @bind="_finalEmailToCreator" class="sender-create-wizard__select">
|
||||
<option value="0">@L("No", "Nein")</option>
|
||||
<option value="1">@L("Yes", "Ja")</option>
|
||||
<option value="2">@L("YesWithAttachment", "Ja, mit Anhang")</option>
|
||||
<select value="@(_selectedEnvelopeTypeId?.ToString() ?? string.Empty)"
|
||||
@onchange="OnEnvelopeTypeChanged"
|
||||
class="sender-create-wizard__select">
|
||||
@foreach (var type in EnvelopeTypes)
|
||||
{
|
||||
<option value="@type.Id">@type.Title</option>
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="sender-create-wizard__field">
|
||||
<label class="sender-create-wizard__label sender-create-wizard__label-row">
|
||||
<span>@L("FinalEmailToReceivers", "Abgeschlossenes Dokument an Empfänger")</span>
|
||||
<MudTooltip Text='@L("SenderWizard_Help_FinalEmailToReceivers", "Steuert, ob Empfaenger nach Abschluss eine finale E-Mail erhalten und ob das Dokument angehaengt wird.")'>
|
||||
<MudIconButton Icon="@Icons.Material.Filled.Info" Color="Color.Tertiary" Size="Size.Small" Class="sender-create-wizard__help-icon" aria-label='@L("SenderWizard_HelpAria_FinalEmailToReceivers", "Hilfe zum Feld Abgeschlossenes Dokument an Empfaenger")' />
|
||||
</MudTooltip>
|
||||
</label>
|
||||
<select @bind="_finalEmailToReceivers" class="sender-create-wizard__select">
|
||||
<option value="0">@L("No", "Nein")</option>
|
||||
<option value="1">@L("Yes", "Ja")</option>
|
||||
<option value="2">@L("YesWithAttachment", "Ja, mit Anhang")</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="sender-create-wizard__field sender-create-wizard__field--full">
|
||||
<div class="sender-create-wizard__settings-toggles">
|
||||
<label class="sender-create-wizard__settings-toggle">
|
||||
<input type="checkbox" checked="@_tfaEnabled" @onchange="OnTfaChanged" />
|
||||
<span>@L("TFAEnabled", "2FA aktiviert")</span>
|
||||
<MudTooltip Text='@L("SenderWizard_Help_TfaEnabled", "Wenn aktiviert, ist die Signaturfreigabe nur mit zusaetzlicher Verifizierung moeglich.")'>
|
||||
<MudIconButton Icon="@Icons.Material.Filled.Info" Color="Color.Tertiary" Size="Size.Small" Class="sender-create-wizard__help-icon" aria-label='@L("SenderWizard_HelpAria_TfaEnabled", "Hilfe zur Option 2FA")' />
|
||||
</MudTooltip>
|
||||
</label>
|
||||
<label class="sender-create-wizard__settings-toggle">
|
||||
<input type="checkbox" checked="@_useAccessCode" @onchange="OnUseAccessCodeChanged" disabled="@_tfaEnabled" />
|
||||
<span>@L("UseAccessCode", "Zugriffscode verwenden")</span>
|
||||
<MudTooltip Text='@L("SenderWizard_Help_UseAccessCode", "Empfaenger muessen einen Zugriffscode eingeben. Bei aktivem 2FA bleibt diese Option immer aktiv.")'>
|
||||
<MudIconButton Icon="@Icons.Material.Filled.Info" Color="Color.Tertiary" Size="Size.Small" Class="sender-create-wizard__help-icon" aria-label='@L("SenderWizard_HelpAria_UseAccessCode", "Hilfe zur Option Zugriffscode verwenden")' />
|
||||
</MudTooltip>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sender-create-wizard__settings-group">
|
||||
<div class="sender-create-wizard__settings-title">
|
||||
@L("SendReminderEmails", "Erinnerungs-E-Mails senden")
|
||||
</div>
|
||||
|
||||
}
|
||||
else if (_currentStep == 3)
|
||||
{
|
||||
<div class="sender-create-wizard__form-grid">
|
||||
<div class="sender-create-wizard__field sender-create-wizard__field--full">
|
||||
<label class="sender-create-wizard__settings-toggle">
|
||||
<input type="checkbox" checked="@_sendReminderEmails" @onchange="OnSendReminderEmailsChanged" />
|
||||
<span>@L("SendReminderEmails", "Erinnerungs-E-Mails senden")</span>
|
||||
<MudTooltip Text='@L("SenderWizard_Help_SendReminderEmails", "Aktiviert automatische Erinnerungsmails fuer noch offene Signaturen.")'>
|
||||
<MudIconButton Icon="@Icons.Material.Filled.Info" Color="Color.Tertiary" Size="Size.Small" Class="sender-create-wizard__help-icon" aria-label='@L("SenderWizard_HelpAria_SendReminderEmails", "Hilfe zur Option Erinnerungs-E-Mails senden")' />
|
||||
<label class="sender-create-wizard__label sender-create-wizard__label-row">
|
||||
<span>@L("Message", "Nachricht") <span class="sender-create-wizard__optional">(@L("Optional", "optional"))</span></span>
|
||||
<MudTooltip Text='@L("SenderWizard_Help_Message", "Diese Nachricht wird den Empfaengern in der E-Mail und im Signaturprozess angezeigt.")'>
|
||||
<MudIconButton Icon="@Icons.Material.Filled.Info" Color="Color.Tertiary" Size="Size.Small" Class="sender-create-wizard__help-icon" aria-label='@L("SenderWizard_HelpAria_Message", "Hilfe zum Feld Nachricht")' />
|
||||
</MudTooltip>
|
||||
</label>
|
||||
<DxMemo Text="@_message"
|
||||
TextChanged="OnMessageChanged"
|
||||
Rows="5"
|
||||
MaxLength="500"
|
||||
NullText='@L("SenderEditor_Message_Placeholder", "Bitte unterzeichnen Sie das beigefügte Dokument.")'
|
||||
CssClass="w-100" />
|
||||
</div>
|
||||
|
||||
<div class="sender-create-wizard__field">
|
||||
<label class="sender-create-wizard__label sender-create-wizard__label-row">
|
||||
<span>@L("FirstReminderDays", "Erste Erinnerung (Tage)")</span>
|
||||
<MudTooltip Text='@L("SenderWizard_Help_FirstReminderDays", "Anzahl Tage nach Versand bis zur ersten Erinnerung.")'>
|
||||
<MudIconButton Icon="@Icons.Material.Filled.Info" Color="Color.Tertiary" Size="Size.Small" Class="sender-create-wizard__help-icon" aria-label='@L("SenderWizard_HelpAria_FirstReminderDays", "Hilfe zum Feld Erste Erinnerung")' />
|
||||
<span>@L("Language", "Sprache")</span>
|
||||
<MudTooltip Text='@L("SenderWizard_Help_Language", "Legt die Sprache fuer Hinweise, E-Mails und Oberflaechentexte fest.")'>
|
||||
<MudIconButton Icon="@Icons.Material.Filled.Info" Color="Color.Tertiary" Size="Size.Small" Class="sender-create-wizard__help-icon" aria-label='@L("SenderWizard_HelpAria_Language", "Hilfe zum Feld Sprache")' />
|
||||
</MudTooltip>
|
||||
</label>
|
||||
<InputNumber @bind-Value="_firstReminderDays" class="form-control form-control-sm" disabled="@(!_sendReminderEmails)" />
|
||||
<select @bind="_language" class="sender-create-wizard__select">
|
||||
<option value="de-DE">Deutsch (de-DE)</option>
|
||||
<option value="en-US">English (en-US)</option>
|
||||
<option value="de">Deutsch (de)</option>
|
||||
<option value="en">English (en)</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="sender-create-wizard__field">
|
||||
<label class="sender-create-wizard__label sender-create-wizard__label-row">
|
||||
<span>@L("ReminderIntervalDays", "Erinnerungsintervall (Tage)")</span>
|
||||
<MudTooltip Text='@L("SenderWizard_Help_ReminderIntervalDays", "Abstand in Tagen zwischen den weiteren Erinnerungen.")'>
|
||||
<MudIconButton Icon="@Icons.Material.Filled.Info" Color="Color.Tertiary" Size="Size.Small" Class="sender-create-wizard__help-icon" aria-label='@L("SenderWizard_HelpAria_ReminderIntervalDays", "Hilfe zum Feld Erinnerungsintervall")' />
|
||||
</MudTooltip>
|
||||
</label>
|
||||
<InputNumber @bind-Value="_reminderIntervalDays" class="form-control form-control-sm" disabled="@(!_sendReminderEmails)" />
|
||||
</div>
|
||||
|
||||
<div class="sender-create-wizard__field">
|
||||
<label class="sender-create-wizard__label sender-create-wizard__label-row">
|
||||
<span>@L("ExpiresWhenDays", "Laeuft ab nach (Tage)")</span>
|
||||
<MudTooltip Text='@L("SenderWizard_Help_ExpiresWhenDays", "Legt fest, nach wie vielen Tagen der Umschlag automatisch ablaeuft.")'>
|
||||
<MudIconButton Icon="@Icons.Material.Filled.Info" Color="Color.Tertiary" Size="Size.Small" Class="sender-create-wizard__help-icon" aria-label='@L("SenderWizard_HelpAria_ExpiresWhenDays", "Hilfe zum Feld Laeuft ab nach")' />
|
||||
</MudTooltip>
|
||||
</label>
|
||||
<InputNumber @bind-Value="_expiresWhenDays" class="form-control form-control-sm" />
|
||||
</div>
|
||||
|
||||
<div class="sender-create-wizard__field">
|
||||
<label class="sender-create-wizard__label sender-create-wizard__label-row">
|
||||
<span>@L("ExpiresWarningWhenDays", "Ablaufwarnung (Tage)")</span>
|
||||
<MudTooltip Text='@L("SenderWizard_Help_ExpiresWarningWhenDays", "Tage vor Ablauf, an denen eine Warnung versendet wird.")'>
|
||||
<MudIconButton Icon="@Icons.Material.Filled.Info" Color="Color.Tertiary" Size="Size.Small" Class="sender-create-wizard__help-icon" aria-label='@L("SenderWizard_HelpAria_ExpiresWarningWhenDays", "Hilfe zum Feld Ablaufwarnung")' />
|
||||
</MudTooltip>
|
||||
</label>
|
||||
<InputNumber @bind-Value="_expiresWarningWhenDays" class="form-control form-control-sm" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
else if (_currentStep == 1)
|
||||
{
|
||||
<div class="sender-create-wizard__suggestions">
|
||||
<DxTextBox Text="@_receiverSuggestionFilterText"
|
||||
TextChanged="OnReceiverSuggestionFilterChanged"
|
||||
BindValueMode="BindValueMode.OnInput"
|
||||
NullText='@L("SenderWizard_FilterRecentReceivers_Placeholder", "Empfänger in Vorschlägen filtern...")'
|
||||
CssClass="w-100" />
|
||||
|
||||
@if (_isLoadingRecentSuggestions)
|
||||
{
|
||||
<div class="sender-create-wizard__empty-list">@L("Loading", "Lädt...")</div>
|
||||
}
|
||||
else if (_recentReceiverSuggestions.Count > 0)
|
||||
{
|
||||
<div class="sender-create-wizard__suggestion-list" role="listbox" aria-label="Recent receivers">
|
||||
@foreach (var suggestion in FilteredRecentSuggestions)
|
||||
{
|
||||
<button type="button"
|
||||
class="sender-create-wizard__suggestion-item"
|
||||
@onclick="() => ApplyRecentSuggestionAndAddAsync(suggestion)"
|
||||
disabled="@IsActionLocked">
|
||||
<span class="sender-create-wizard__suggestion-name">@suggestion.FullName</span>
|
||||
<span class="sender-create-wizard__suggestion-email">@suggestion.EmailAddress</span>
|
||||
</button>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
else if (_currentStep == 2)
|
||||
{
|
||||
<div class="sender-create-wizard__settings-grid">
|
||||
<div class="sender-create-wizard__settings-group">
|
||||
<div class="sender-create-wizard__settings-title">
|
||||
@L("SenderEditor_EnvelopeSettings", "Envelope-Einstellungen")
|
||||
</div>
|
||||
|
||||
<div class="sender-create-wizard__receiver-tagbox-wrap">
|
||||
<div class="sender-create-wizard__receiver-list" role="table" aria-label="Added receivers">
|
||||
<div class="sender-create-wizard__receiver-existing-list">
|
||||
@for (var i = 0; i < _receivers.Count; i++)
|
||||
{
|
||||
var rowIndex = i;
|
||||
var receiver = _receivers[rowIndex];
|
||||
<div class="sender-create-wizard__form-grid">
|
||||
<div class="sender-create-wizard__field">
|
||||
<label class="sender-create-wizard__label sender-create-wizard__label-row">
|
||||
<span>@L("CertificationType", "Zertifizierung")</span>
|
||||
<MudTooltip Text='@L("SenderWizard_Help_CertificationType", "Bestimmt das Signaturniveau fuer diesen Umschlag.")'>
|
||||
<MudIconButton Icon="@Icons.Material.Filled.Info" Color="Color.Tertiary" Size="Size.Small" Class="sender-create-wizard__help-icon" aria-label='@L("SenderWizard_HelpAria_CertificationType", "Hilfe zum Feld Zertifizierung")' />
|
||||
</MudTooltip>
|
||||
</label>
|
||||
<select @bind="_certificationType" class="sender-create-wizard__select">
|
||||
<option value="@CertificationType.AdvancedElectronicSignature">@L("AdvancedElectronicSignature", "Advanced Electronic Signature")</option>
|
||||
<option value="@CertificationType.ElectronicSignature">@L("ElectronicSignature", "Electronic Signature")</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="sender-create-wizard__receiver-row" role="row">
|
||||
<div class="sender-create-wizard__receiver-fields-stack sender-create-wizard__field--full">
|
||||
<div class="sender-create-wizard__field">
|
||||
<DxTextBox Text="@receiver.FullName"
|
||||
TextChanged="@(value => OnReceiverListNameChanged(rowIndex, value))"
|
||||
BindValueMode="BindValueMode.OnInput"
|
||||
NullText='@L("FullName", "Vor- und Nachname")'
|
||||
CssClass="w-100"
|
||||
Enabled="@(!IsActionLocked)" />
|
||||
</div>
|
||||
<div class="sender-create-wizard__field">
|
||||
<DxTextBox Text="@receiver.EmailAddress"
|
||||
TextChanged="@(value => OnReceiverListEmailChanged(rowIndex, value))"
|
||||
BindValueMode="BindValueMode.OnInput"
|
||||
NullText='@L("EmailAddress", "E-Mail-Adresse")'
|
||||
CssClass="w-100"
|
||||
Enabled="@(!IsActionLocked)" />
|
||||
<div class="sender-create-wizard__field">
|
||||
<label class="sender-create-wizard__label sender-create-wizard__label-row">
|
||||
<span>@L("FinalEmailToCreator", "Abgeschlossenes Dokument an Ersteller")</span>
|
||||
<MudTooltip Text='@L("SenderWizard_Help_FinalEmailToCreator", "Steuert, ob der Ersteller nach Abschluss eine finale E-Mail erhaelt und ob das Dokument angehaengt wird.")'>
|
||||
<MudIconButton Icon="@Icons.Material.Filled.Info" Color="Color.Tertiary" Size="Size.Small" Class="sender-create-wizard__help-icon" aria-label='@L("SenderWizard_HelpAria_FinalEmailToCreator", "Hilfe zum Feld Abgeschlossenes Dokument an Ersteller")' />
|
||||
</MudTooltip>
|
||||
</label>
|
||||
<select @bind="_finalEmailToCreator" class="sender-create-wizard__select">
|
||||
<option value="0">@L("No", "Nein")</option>
|
||||
<option value="1">@L("Yes", "Ja")</option>
|
||||
<option value="2">@L("YesWithAttachment", "Ja, mit Anhang")</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="sender-create-wizard__field">
|
||||
<label class="sender-create-wizard__label sender-create-wizard__label-row">
|
||||
<span>@L("FinalEmailToReceivers", "Abgeschlossenes Dokument an Empfänger")</span>
|
||||
<MudTooltip Text='@L("SenderWizard_Help_FinalEmailToReceivers", "Steuert, ob Empfaenger nach Abschluss eine finale E-Mail erhalten und ob das Dokument angehaengt wird.")'>
|
||||
<MudIconButton Icon="@Icons.Material.Filled.Info" Color="Color.Tertiary" Size="Size.Small" Class="sender-create-wizard__help-icon" aria-label='@L("SenderWizard_HelpAria_FinalEmailToReceivers", "Hilfe zum Feld Abgeschlossenes Dokument an Empfaenger")' />
|
||||
</MudTooltip>
|
||||
</label>
|
||||
<select @bind="_finalEmailToReceivers" class="sender-create-wizard__select">
|
||||
<option value="0">@L("No", "Nein")</option>
|
||||
<option value="1">@L("Yes", "Ja")</option>
|
||||
<option value="2">@L("YesWithAttachment", "Ja, mit Anhang")</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="sender-create-wizard__field sender-create-wizard__field--full">
|
||||
<div class="sender-create-wizard__settings-toggles">
|
||||
<label class="sender-create-wizard__settings-toggle">
|
||||
<input type="checkbox" checked="@_tfaEnabled" @onchange="OnTfaChanged" />
|
||||
<span>@L("TFAEnabled", "2FA aktiviert")</span>
|
||||
<MudTooltip Text='@L("SenderWizard_Help_TfaEnabled", "Wenn aktiviert, ist die Signaturfreigabe nur mit zusaetzlicher Verifizierung moeglich.")'>
|
||||
<MudIconButton Icon="@Icons.Material.Filled.Info" Color="Color.Tertiary" Size="Size.Small" Class="sender-create-wizard__help-icon" aria-label='@L("SenderWizard_HelpAria_TfaEnabled", "Hilfe zur Option 2FA")' />
|
||||
</MudTooltip>
|
||||
</label>
|
||||
<label class="sender-create-wizard__settings-toggle">
|
||||
<input type="checkbox" checked="@_useAccessCode" @onchange="OnUseAccessCodeChanged" disabled="@_tfaEnabled" />
|
||||
<span>@L("UseAccessCode", "Zugriffscode verwenden")</span>
|
||||
<MudTooltip Text='@L("SenderWizard_Help_UseAccessCode", "Empfaenger muessen einen Zugriffscode eingeben. Bei aktivem 2FA bleibt diese Option immer aktiv.")'>
|
||||
<MudIconButton Icon="@Icons.Material.Filled.Info" Color="Color.Tertiary" Size="Size.Small" Class="sender-create-wizard__help-icon" aria-label='@L("SenderWizard_HelpAria_UseAccessCode", "Hilfe zur Option Zugriffscode verwenden")' />
|
||||
</MudTooltip>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<button type="button"
|
||||
class="sender-create-wizard__receiver-remove-btn"
|
||||
@onclick="() => RemoveReceiver(receiver)"
|
||||
disabled="@IsActionLocked"
|
||||
title='@L("Remove", "Entfernen")'
|
||||
aria-label='@L("Remove", "Entfernen")'>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16" aria-hidden="true">
|
||||
<path d="M5.5 5.5A.5.5 0 0 1 6 6v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5zm2.5 0a.5.5 0 0 1 .5.5v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5zm3 .5a.5.5 0 0 0-1 0v6a.5.5 0 0 0 1 0V6z" />
|
||||
<path fill-rule="evenodd" d="M14.5 3a1 1 0 0 1-1 1H13v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V4h-.5a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1H6a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1h3.5a1 1 0 0 1 1 1v1zM4.118 4 4 4.059V13a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1V4.059L11.882 4H4.118zM2.5 3V2h11v1h-11z" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
}
|
||||
<div class="sender-create-wizard__receiver-row sender-create-wizard__receiver-row--new" role="row">
|
||||
<div class="sender-create-wizard__receiver-fields-stack sender-create-wizard__field--full">
|
||||
<div class="sender-create-wizard__field">
|
||||
<DxTextBox Text="@_receiverName"
|
||||
TextChanged="OnReceiverNameChanged"
|
||||
BindValueMode="BindValueMode.OnInput"
|
||||
NullText="Max Mustermann"
|
||||
CssClass="w-100"
|
||||
Enabled="@(!IsActionLocked)" />
|
||||
</div>
|
||||
|
||||
<div class="sender-create-wizard__settings-group">
|
||||
<div class="sender-create-wizard__settings-title">
|
||||
@L("SendReminderEmails", "Erinnerungs-E-Mails senden")
|
||||
</div>
|
||||
|
||||
<div class="sender-create-wizard__form-grid">
|
||||
<div class="sender-create-wizard__field sender-create-wizard__field--full">
|
||||
<label class="sender-create-wizard__settings-toggle">
|
||||
<input type="checkbox" checked="@_sendReminderEmails" @onchange="OnSendReminderEmailsChanged" />
|
||||
<span>@L("SendReminderEmails", "Erinnerungs-E-Mails senden")</span>
|
||||
<MudTooltip Text='@L("SenderWizard_Help_SendReminderEmails", "Aktiviert automatische Erinnerungsmails fuer noch offene Signaturen.")'>
|
||||
<MudIconButton Icon="@Icons.Material.Filled.Info" Color="Color.Tertiary" Size="Size.Small" Class="sender-create-wizard__help-icon" aria-label='@L("SenderWizard_HelpAria_SendReminderEmails", "Hilfe zur Option Erinnerungs-E-Mails senden")' />
|
||||
</MudTooltip>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="sender-create-wizard__field">
|
||||
<DxTextBox Text="@_receiverEmail"
|
||||
TextChanged="OnReceiverEmailChanged"
|
||||
BindValueMode="BindValueMode.OnInput"
|
||||
NullText="name@beispiel.de"
|
||||
CssClass="w-100"
|
||||
Enabled="@(!IsActionLocked)" />
|
||||
<label class="sender-create-wizard__label sender-create-wizard__label-row">
|
||||
<span>@L("FirstReminderDays", "Erste Erinnerung (Tage)")</span>
|
||||
<MudTooltip Text='@L("SenderWizard_Help_FirstReminderDays", "Anzahl Tage nach Versand bis zur ersten Erinnerung.")'>
|
||||
<MudIconButton Icon="@Icons.Material.Filled.Info" Color="Color.Tertiary" Size="Size.Small" Class="sender-create-wizard__help-icon" aria-label='@L("SenderWizard_HelpAria_FirstReminderDays", "Hilfe zum Feld Erste Erinnerung")' />
|
||||
</MudTooltip>
|
||||
</label>
|
||||
<InputNumber @bind-Value="_firstReminderDays" class="form-control form-control-sm" disabled="@(!_sendReminderEmails)" />
|
||||
</div>
|
||||
|
||||
<div class="sender-create-wizard__field">
|
||||
<label class="sender-create-wizard__label sender-create-wizard__label-row">
|
||||
<span>@L("ReminderIntervalDays", "Erinnerungsintervall (Tage)")</span>
|
||||
<MudTooltip Text='@L("SenderWizard_Help_ReminderIntervalDays", "Abstand in Tagen zwischen den weiteren Erinnerungen.")'>
|
||||
<MudIconButton Icon="@Icons.Material.Filled.Info" Color="Color.Tertiary" Size="Size.Small" Class="sender-create-wizard__help-icon" aria-label='@L("SenderWizard_HelpAria_ReminderIntervalDays", "Hilfe zum Feld Erinnerungsintervall")' />
|
||||
</MudTooltip>
|
||||
</label>
|
||||
<InputNumber @bind-Value="_reminderIntervalDays" class="form-control form-control-sm" disabled="@(!_sendReminderEmails)" />
|
||||
</div>
|
||||
|
||||
<div class="sender-create-wizard__field">
|
||||
<label class="sender-create-wizard__label sender-create-wizard__label-row">
|
||||
<span>@L("ExpiresWhenDays", "Laeuft ab nach (Tage)")</span>
|
||||
<MudTooltip Text='@L("SenderWizard_Help_ExpiresWhenDays", "Legt fest, nach wie vielen Tagen der Umschlag automatisch ablaeuft.")'>
|
||||
<MudIconButton Icon="@Icons.Material.Filled.Info" Color="Color.Tertiary" Size="Size.Small" Class="sender-create-wizard__help-icon" aria-label='@L("SenderWizard_HelpAria_ExpiresWhenDays", "Hilfe zum Feld Laeuft ab nach")' />
|
||||
</MudTooltip>
|
||||
</label>
|
||||
<InputNumber @bind-Value="_expiresWhenDays" class="form-control form-control-sm" />
|
||||
</div>
|
||||
|
||||
<div class="sender-create-wizard__field">
|
||||
<label class="sender-create-wizard__label sender-create-wizard__label-row">
|
||||
<span>@L("ExpiresWarningWhenDays", "Ablaufwarnung (Tage)")</span>
|
||||
<MudTooltip Text='@L("SenderWizard_Help_ExpiresWarningWhenDays", "Tage vor Ablauf, an denen eine Warnung versendet wird.")'>
|
||||
<MudIconButton Icon="@Icons.Material.Filled.Info" Color="Color.Tertiary" Size="Size.Small" Class="sender-create-wizard__help-icon" aria-label='@L("SenderWizard_HelpAria_ExpiresWarningWhenDays", "Hilfe zum Feld Ablaufwarnung")' />
|
||||
</MudTooltip>
|
||||
</label>
|
||||
<InputNumber @bind-Value="_expiresWarningWhenDays" class="form-control form-control-sm" />
|
||||
</div>
|
||||
</div>
|
||||
<button type="button"
|
||||
class="sender-create-wizard__receiver-add-inline-btn"
|
||||
@onclick="AddReceiver"
|
||||
disabled="@IsActionLocked"
|
||||
title='@L("AddReceiver", "Empfänger hinzufügen")'
|
||||
aria-label='@L("AddReceiver", "Empfänger hinzufügen")'>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16" aria-hidden="true">
|
||||
<path d="M8 1a.5.5 0 0 1 .5.5V7.5h6a.5.5 0 0 1 0 1h-6v6a.5.5 0 0 1-1 0v-6h-6a.5.5 0 0 1 0-1h6v-6A.5.5 0 0 1 8 1z" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="sender-create-wizard__upload-stage">
|
||||
<label class="sender-create-wizard__upload-btn @(IsActionLocked ? "sender-create-wizard__upload-btn--disabled" : string.Empty)">
|
||||
@if (_documentBytes is null)
|
||||
{
|
||||
<span>@L("UploadPdf", "PDF hochladen")</span>
|
||||
}
|
||||
else
|
||||
{
|
||||
<span>@L("SenderWizard_ReplacePdf", "PDF ersetzen")</span>
|
||||
}
|
||||
<InputFile OnChange="OnDocumentSelectedAsync"
|
||||
accept=".pdf"
|
||||
disabled="@IsActionLocked"
|
||||
class="sender-create-wizard__hidden-input" />
|
||||
</label>
|
||||
|
||||
@if (_documentBytes is not null)
|
||||
}
|
||||
else if (_currentStep == 1)
|
||||
{
|
||||
<div class="sender-create-wizard__document-preview-card">
|
||||
<div class="sender-create-wizard__document-meta">
|
||||
<div class="sender-create-wizard__document-name">@_documentFileName</div>
|
||||
<div class="sender-create-wizard__document-size">@_documentSizeText</div>
|
||||
</div>
|
||||
<div class="sender-create-wizard__document-preview-wrap">
|
||||
<SenderPdfImageEditor IsPlacementMode="false"
|
||||
PageCount="@_documentPreviewPageCount"
|
||||
Pages="@_documentPreviewPages"
|
||||
PdfDataUrl="@DocumentPreviewDataUrl"
|
||||
PdfFileName="@_documentFileName"
|
||||
Fields="@_documentPreviewFieldOverlays"
|
||||
EditorClick="OnDocumentPreviewEditorClickAsync"
|
||||
RemoveField="OnDocumentPreviewRemoveFieldAsync"
|
||||
MoveField="OnDocumentPreviewMoveFieldAsync" />
|
||||
<div class="sender-create-wizard__suggestions">
|
||||
<DxTextBox Text="@_receiverSuggestionFilterText"
|
||||
TextChanged="OnReceiverSuggestionFilterChanged"
|
||||
BindValueMode="BindValueMode.OnInput"
|
||||
NullText='@L("SenderWizard_FilterRecentReceivers_Placeholder", "Empfänger in Vorschlägen filtern...")'
|
||||
CssClass="w-100" />
|
||||
|
||||
@if (_isLoadingRecentSuggestions)
|
||||
{
|
||||
<div class="sender-create-wizard__empty-list">@L("Loading", "Lädt...")</div>
|
||||
}
|
||||
else if (_recentReceiverSuggestions.Count > 0)
|
||||
{
|
||||
<div class="sender-create-wizard__suggestion-list" role="listbox" aria-label="Recent receivers">
|
||||
@foreach (var suggestion in FilteredRecentSuggestions)
|
||||
{
|
||||
<button type="button"
|
||||
class="sender-create-wizard__suggestion-item"
|
||||
@onclick="() => ApplyRecentSuggestionAndAddAsync(suggestion)"
|
||||
disabled="@IsActionLocked">
|
||||
<span class="sender-create-wizard__suggestion-name">@suggestion.FullName</span>
|
||||
<span class="sender-create-wizard__suggestion-email">@suggestion.EmailAddress</span>
|
||||
</button>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
<div class="sender-create-wizard__receiver-tagbox-wrap">
|
||||
<div class="sender-create-wizard__receiver-list" role="table" aria-label="Added receivers">
|
||||
<div class="sender-create-wizard__receiver-existing-list">
|
||||
@for (var i = 0; i < _receivers.Count; i++)
|
||||
{
|
||||
var rowIndex = i;
|
||||
var receiver = _receivers[rowIndex];
|
||||
|
||||
<div class="sender-create-wizard__receiver-row" role="row">
|
||||
<div class="sender-create-wizard__receiver-fields-stack sender-create-wizard__field--full">
|
||||
<div class="sender-create-wizard__field">
|
||||
<DxTextBox Text="@receiver.FullName"
|
||||
TextChanged="@(value => OnReceiverListNameChanged(rowIndex, value))"
|
||||
BindValueMode="BindValueMode.OnInput"
|
||||
NullText='@L("FullName", "Vor- und Nachname")'
|
||||
CssClass="w-100"
|
||||
Enabled="@(!IsActionLocked)" />
|
||||
</div>
|
||||
<div class="sender-create-wizard__field">
|
||||
<DxTextBox Text="@receiver.EmailAddress"
|
||||
TextChanged="@(value => OnReceiverListEmailChanged(rowIndex, value))"
|
||||
BindValueMode="BindValueMode.OnInput"
|
||||
NullText='@L("EmailAddress", "E-Mail-Adresse")'
|
||||
CssClass="w-100"
|
||||
Enabled="@(!IsActionLocked)" />
|
||||
</div>
|
||||
</div>
|
||||
<button type="button"
|
||||
class="sender-create-wizard__receiver-remove-btn"
|
||||
@onclick="() => RemoveReceiver(receiver)"
|
||||
disabled="@IsActionLocked"
|
||||
title='@L("Remove", "Entfernen")'
|
||||
aria-label='@L("Remove", "Entfernen")'>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16" aria-hidden="true">
|
||||
<path d="M5.5 5.5A.5.5 0 0 1 6 6v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5zm2.5 0a.5.5 0 0 1 .5.5v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5zm3 .5a.5.5 0 0 0-1 0v6a.5.5 0 0 0 1 0V6z" />
|
||||
<path fill-rule="evenodd" d="M14.5 3a1 1 0 0 1-1 1H13v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V4h-.5a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1H6a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1h3.5a1 1 0 0 1 1 1v1zM4.118 4 4 4.059V13a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1V4.059L11.882 4H4.118zM2.5 3V2h11v1h-11z" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
}
|
||||
<div class="sender-create-wizard__receiver-row sender-create-wizard__receiver-row--new" role="row">
|
||||
<div class="sender-create-wizard__receiver-fields-stack sender-create-wizard__field--full">
|
||||
<div class="sender-create-wizard__field">
|
||||
<DxTextBox Text="@_receiverName"
|
||||
TextChanged="OnReceiverNameChanged"
|
||||
BindValueMode="BindValueMode.OnInput"
|
||||
NullText="Max Mustermann"
|
||||
CssClass="w-100"
|
||||
Enabled="@(!IsActionLocked)" />
|
||||
</div>
|
||||
<div class="sender-create-wizard__field">
|
||||
<DxTextBox Text="@_receiverEmail"
|
||||
TextChanged="OnReceiverEmailChanged"
|
||||
BindValueMode="BindValueMode.OnInput"
|
||||
NullText="name@beispiel.de"
|
||||
CssClass="w-100"
|
||||
Enabled="@(!IsActionLocked)" />
|
||||
</div>
|
||||
</div>
|
||||
<button type="button"
|
||||
class="sender-create-wizard__receiver-add-inline-btn"
|
||||
@onclick="AddReceiver"
|
||||
disabled="@IsActionLocked"
|
||||
title='@L("AddReceiver", "Empfänger hinzufügen")'
|
||||
aria-label='@L("AddReceiver", "Empfänger hinzufügen")'>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16" aria-hidden="true">
|
||||
<path d="M8 1a.5.5 0 0 1 .5.5V7.5h6a.5.5 0 0 1 0 1h-6v6a.5.5 0 0 1-1 0v-6h-6a.5.5 0 0 1 0-1h6v-6A.5.5 0 0 1 8 1z" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<PdfFileDropZone Disabled="@IsActionLocked"
|
||||
HasDocument="false"
|
||||
UploadText='@L("SenderWizard_DocumentRequiredHint", "Bitte laden Sie ein PDF-Dokument hoch, um fortzufahren.")'
|
||||
DragDropHintText='@L("SenderWizard_DragDropPdfHint", "Oder ziehen Sie die PDF-Datei hierher.")'
|
||||
FileSelected="OnDocumentSelectedAsync" />
|
||||
<div class="sender-create-wizard__upload-stage">
|
||||
<label class="sender-create-wizard__upload-btn @(IsActionLocked ? "sender-create-wizard__upload-btn--disabled" : string.Empty)">
|
||||
@if (_documentBytes is null)
|
||||
{
|
||||
<span>@L("UploadPdf", "PDF hochladen")</span>
|
||||
}
|
||||
else
|
||||
{
|
||||
<span>@L("SenderWizard_ReplacePdf", "PDF ersetzen")</span>
|
||||
}
|
||||
<InputFile OnChange="OnDocumentSelectedAsync"
|
||||
accept=".pdf"
|
||||
disabled="@IsActionLocked"
|
||||
class="sender-create-wizard__hidden-input" />
|
||||
</label>
|
||||
|
||||
@if (_documentBytes is not null)
|
||||
{
|
||||
<div class="sender-create-wizard__document-preview-card">
|
||||
<div class="sender-create-wizard__document-meta">
|
||||
<div class="sender-create-wizard__document-name">@_documentFileName</div>
|
||||
<div class="sender-create-wizard__document-size">@_documentSizeText</div>
|
||||
</div>
|
||||
<div class="sender-create-wizard__document-preview-wrap">
|
||||
<SenderPdfImageEditor IsPlacementMode="false"
|
||||
PageCount="@_documentPreviewPageCount"
|
||||
Pages="@_documentPreviewPages"
|
||||
PdfDataUrl="@DocumentPreviewDataUrl"
|
||||
PdfFileName="@_documentFileName"
|
||||
Fields="@_documentPreviewFieldOverlays"
|
||||
EditorClick="OnDocumentPreviewEditorClickAsync"
|
||||
RemoveField="OnDocumentPreviewRemoveFieldAsync"
|
||||
MoveField="OnDocumentPreviewMoveFieldAsync" />
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<PdfFileDropZone Disabled="@IsActionLocked"
|
||||
HasDocument="false"
|
||||
UploadText='@L("SenderWizard_DocumentRequiredHint", "Bitte laden Sie ein PDF-Dokument hoch, um fortzufahren.")'
|
||||
DragDropHintText='@L("SenderWizard_DragDropPdfHint", "Oder ziehen Sie die PDF-Datei hierher.")'
|
||||
FileSelected="OnDocumentSelectedAsync" />
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</MudStep>
|
||||
}
|
||||
</ChildContent>
|
||||
</MudStepper>
|
||||
</MudPaper>
|
||||
</MudStep>
|
||||
}
|
||||
</ChildContent>
|
||||
</MudStepper>
|
||||
</MudPaper>
|
||||
|
||||
<aside class="sender-create-wizard__wizard-side @(_currentStep == 4 ? "sender-create-wizard__wizard-side--hidden" : string.Empty)" aria-hidden="@(_currentStep == 4)">
|
||||
<PdfFileDropZone Disabled="@IsActionLocked"
|
||||
HasDocument="@(_documentBytes is { Length: > 0 })"
|
||||
DocumentName="@_documentFileName"
|
||||
DocumentSizeText="@_documentSizeText"
|
||||
UploadText='@L("SenderWizard_DocumentUploadSimpleHint", "Dokument hinzufuegen: klicken oder per Drag-and-Drop ablegen")'
|
||||
ReplaceText='@L("SenderWizard_DocumentUploadSimpleHint", "Dokument hinzufuegen: klicken oder per Drag-and-Drop ablegen")'
|
||||
UploadedHintText='@L("SenderWizard_DocumentReplaceHint", "Zum Ersetzen klicken oder eine Datei auf diese Fläche ziehen.")'
|
||||
FileSelected="OnDocumentSelectedAsync" />
|
||||
</aside>
|
||||
</div>
|
||||
|
||||
@if (!string.IsNullOrWhiteSpace(_validationMessage))
|
||||
{
|
||||
@@ -507,6 +524,7 @@
|
||||
private int _documentPreviewPageCount;
|
||||
private List<PdfPageImageDto> _documentPreviewPages = [];
|
||||
private bool _isDocumentUploading;
|
||||
private bool _isDocumentPreviewPrepared;
|
||||
private bool _isStepActionRunning;
|
||||
private bool _isFinishing;
|
||||
|
||||
@@ -736,22 +754,12 @@
|
||||
_documentBytes = ms.ToArray();
|
||||
_documentFileName = file.Name;
|
||||
_documentSizeText = FormatSize(_documentBytes.Length);
|
||||
|
||||
_documentPreviewPages = [];
|
||||
try
|
||||
{
|
||||
_documentPreviewPages = (await PdfRenderService.RenderPagesAsync(_documentBytes))
|
||||
.OrderBy(x => x.PageNumber)
|
||||
.ToList();
|
||||
}
|
||||
catch
|
||||
{
|
||||
_documentPreviewPages = [];
|
||||
}
|
||||
_documentPreviewPageCount = 0;
|
||||
_isDocumentPreviewPrepared = false;
|
||||
|
||||
_documentPreviewPageCount = _documentPreviewPages.Count > 0
|
||||
? _documentPreviewPages.Count
|
||||
: EstimatePdfPageCount(_documentBytes) ?? 1;
|
||||
if (_currentStep == 4)
|
||||
await EnsureDocumentPreviewPreparedAsync();
|
||||
}
|
||||
finally
|
||||
{
|
||||
@@ -792,6 +800,9 @@
|
||||
|
||||
if (_currentStep == 1)
|
||||
await EnsureRecentSuggestionsLoadedAsync();
|
||||
|
||||
if (_currentStep == 4)
|
||||
await EnsureDocumentPreviewPreparedAsync();
|
||||
}
|
||||
}
|
||||
finally
|
||||
@@ -948,6 +959,33 @@
|
||||
await AddReceiver();
|
||||
}
|
||||
|
||||
private async Task EnsureDocumentPreviewPreparedAsync()
|
||||
{
|
||||
if (_documentBytes is null || _documentBytes.Length == 0 || _isDocumentPreviewPrepared)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
_isDocumentUploading = true;
|
||||
_documentPreviewPages = (await PdfRenderService.RenderPagesAsync(_documentBytes))
|
||||
.OrderBy(x => x.PageNumber)
|
||||
.ToList();
|
||||
}
|
||||
catch
|
||||
{
|
||||
_documentPreviewPages = [];
|
||||
}
|
||||
finally
|
||||
{
|
||||
_documentPreviewPageCount = _documentPreviewPages.Count > 0
|
||||
? _documentPreviewPages.Count
|
||||
: EstimatePdfPageCount(_documentBytes) ?? 1;
|
||||
|
||||
_isDocumentPreviewPrepared = true;
|
||||
_isDocumentUploading = false;
|
||||
}
|
||||
}
|
||||
|
||||
private bool ValidateCurrentStep()
|
||||
{
|
||||
if (_currentStep == 0)
|
||||
@@ -1260,6 +1298,7 @@
|
||||
_documentSizeText = string.Empty;
|
||||
_documentPreviewPageCount = 0;
|
||||
_documentPreviewPages = [];
|
||||
_isDocumentPreviewPrepared = false;
|
||||
|
||||
ApplyDefaultEnvelopeType();
|
||||
}
|
||||
|
||||
@@ -2,10 +2,24 @@
|
||||
|
||||
<div class="sender-pdf-dropzone @DropZoneClass">
|
||||
<div class="sender-pdf-dropzone__content">
|
||||
<div class="sender-pdf-dropzone__title">@CurrentActionText</div>
|
||||
@if (!string.IsNullOrWhiteSpace(DragDropHintText))
|
||||
@if (HasDocument)
|
||||
{
|
||||
<div class="sender-pdf-dropzone__hint">@DragDropHintText</div>
|
||||
@if (!string.IsNullOrWhiteSpace(DocumentName))
|
||||
{
|
||||
<div class="sender-pdf-dropzone__doc-name">@DocumentName</div>
|
||||
}
|
||||
@if (!string.IsNullOrWhiteSpace(DocumentSizeText))
|
||||
{
|
||||
<div class="sender-pdf-dropzone__doc-size">@DocumentSizeText</div>
|
||||
}
|
||||
@if (!string.IsNullOrWhiteSpace(UploadedHintText))
|
||||
{
|
||||
<div class="sender-pdf-dropzone__hint">@UploadedHintText</div>
|
||||
}
|
||||
}
|
||||
else if (!string.IsNullOrWhiteSpace(CurrentActionText))
|
||||
{
|
||||
<div class="sender-pdf-dropzone__hint">@CurrentActionText</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
@@ -38,6 +52,15 @@
|
||||
[Parameter]
|
||||
public string DragDropHintText { get; set; } = "Datei hierhin ziehen oder klicken";
|
||||
|
||||
[Parameter]
|
||||
public string? DocumentName { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public string? DocumentSizeText { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public string UploadedHintText { get; set; } = "Zum Ersetzen klicken oder eine Datei hierher ziehen.";
|
||||
|
||||
[Parameter]
|
||||
public EventCallback<InputFileChangeEventArgs> FileSelected { get; set; }
|
||||
|
||||
@@ -53,6 +76,9 @@
|
||||
if (Disabled)
|
||||
return "sender-pdf-dropzone--disabled";
|
||||
|
||||
if (HasDocument)
|
||||
return "sender-pdf-dropzone--has-document";
|
||||
|
||||
return _isDragActive ? "sender-pdf-dropzone--drag-active" : string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1103,6 +1103,20 @@
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.sender-create-wizard__body-layout {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1fr) minmax(240px, 280px);
|
||||
gap: 0.85rem;
|
||||
align-items: stretch;
|
||||
min-height: min(66vh, 620px);
|
||||
transition: grid-template-columns 220ms ease 0.2s, gap 220ms ease 0.2s;
|
||||
}
|
||||
|
||||
.sender-create-wizard__body-layout--document {
|
||||
grid-template-columns: minmax(0, 1fr) 0;
|
||||
gap: 0;
|
||||
}
|
||||
|
||||
.sender-create-wizard-popup .dxbl-popup-content {
|
||||
max-height: min(78vh, 760px);
|
||||
overflow: auto;
|
||||
@@ -1121,6 +1135,7 @@
|
||||
border-radius: 10px;
|
||||
background: rgba(126, 34, 206, 0.04);
|
||||
padding: 0.75rem;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.sender-create-wizard__stepper {
|
||||
@@ -1214,6 +1229,47 @@
|
||||
margin-top: 0.7rem;
|
||||
}
|
||||
|
||||
.sender-create-wizard__step-layout {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.sender-create-wizard__step-main {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.sender-create-wizard__wizard-side {
|
||||
min-width: 0;
|
||||
max-width: 280px;
|
||||
border: 1px solid rgba(126, 34, 206, 0.12);
|
||||
border-radius: 10px;
|
||||
background: rgba(126, 34, 206, 0.04);
|
||||
padding: 0.75rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: stretch;
|
||||
opacity: 1;
|
||||
transition: opacity 220ms ease 0.2s, transform 220ms ease 0.2s;
|
||||
}
|
||||
|
||||
.sender-create-wizard__wizard-side--hidden {
|
||||
opacity: 0;
|
||||
transform: translateX(12px);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.sender-create-wizard__body-layout--document .sender-create-wizard__wizard-side {
|
||||
max-width: 0;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
border-width: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.sender-create-wizard__wizard-side .sender-pdf-dropzone {
|
||||
height: 100%;
|
||||
min-height: 100%;
|
||||
}
|
||||
|
||||
.sender-create-wizard__meta {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -1658,6 +1714,11 @@
|
||||
box-shadow: 0 0 0 3px rgba(16, 185, 129, 0.16);
|
||||
}
|
||||
|
||||
.sender-pdf-dropzone--has-document {
|
||||
border-color: rgba(16, 185, 129, 0.55);
|
||||
background: linear-gradient(180deg, rgba(16, 185, 129, 0.16), rgba(16, 185, 129, 0.07));
|
||||
}
|
||||
|
||||
.sender-pdf-dropzone--disabled {
|
||||
opacity: 0.55;
|
||||
cursor: not-allowed;
|
||||
@@ -1680,6 +1741,18 @@
|
||||
color: #64748b;
|
||||
}
|
||||
|
||||
.sender-pdf-dropzone__doc-name {
|
||||
font-size: 0.82rem;
|
||||
font-weight: 700;
|
||||
color: #065f46;
|
||||
line-height: 1.25;
|
||||
}
|
||||
|
||||
.sender-pdf-dropzone__doc-size {
|
||||
font-size: 0.76rem;
|
||||
color: #047857;
|
||||
}
|
||||
|
||||
.sender-pdf-dropzone__input {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
@@ -1786,6 +1859,16 @@
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.sender-create-wizard__body-layout {
|
||||
grid-template-columns: 1fr;
|
||||
gap: 0.7rem;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.sender-create-wizard__wizard-side {
|
||||
max-width: none;
|
||||
}
|
||||
|
||||
.sender-create-wizard__receiver-remove-btn {
|
||||
align-self: flex-end;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user