Refactor interaction handling with utility for translations

Introduced `TermHelper.Translate` to centralize string mappings for `InteractionType`, reducing duplication across components. Updated related code to leverage this utility and streamline interaction row implementation by removing the `Caption` parameter. Minor UI adjustments were also made to align button positioning and styling.
This commit is contained in:
Andre Beging
2025-03-28 20:31:25 +01:00
parent 350e2003ca
commit 0324e0f529
7 changed files with 70 additions and 45 deletions

View File

@@ -1,4 +1,7 @@
@using FoodsharingSiegen.Contracts.Entity @using FoodsharingSiegen.Contracts.Entity
@using FoodsharingSiegen.Shared.Helper
@inherits FsBase
@{ @{
var rowClass = ""; var rowClass = "";
@@ -11,7 +14,7 @@
<th class="text-center align-top pr-2"> <th class="text-center align-top pr-2">
<i class="@IconClass"></i> <i class="@IconClass"></i>
</th> </th>
<th class="pr-2 align-top" style="white-space: nowrap;">@Caption:</th> <th class="pr-2 align-top" style="white-space: nowrap;">@Type.Translate(AppSettings):</th>
<td class="align-top d-flex flex-column"> <td class="align-top d-flex flex-column">
@if (Interactions.Count > 0) @if (Interactions.Count > 0)
{ {
@@ -39,7 +42,7 @@
{ {
if (Multiple) ButtonIconClass = "fa-solid fa-plus"; if (Multiple) ButtonIconClass = "fa-solid fa-plus";
<div class="m-auto"> <div class="m-auto">
<Button Size="Size.Small" Clicked="AddClick"><i class="@ButtonIconClass" style="color: #64ae24;"></i></Button> <Button Size="Size.Small" Clicked="@(async () => { if (AddClick != null) await AddClick(Type); })"><i class="@ButtonIconClass" style="color: #64ae24;"></i></Button>
</div> </div>
} }
</td> </td>

View File

@@ -1,4 +1,5 @@
using FoodsharingSiegen.Contracts.Entity; using FoodsharingSiegen.Contracts.Entity;
using FoodsharingSiegen.Server.BaseClasses;
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
namespace FoodsharingSiegen.Server.Controls namespace FoodsharingSiegen.Server.Controls
@@ -6,7 +7,7 @@ namespace FoodsharingSiegen.Server.Controls
/// <summary> /// <summary>
/// The interaction row class (a. beging, 31.05.2022) /// The interaction row class (a. beging, 31.05.2022)
/// </summary> /// </summary>
public partial class InteractionRow public partial class InteractionRow : FsBase
{ {
#region Parameters #region Parameters
@@ -14,7 +15,7 @@ namespace FoodsharingSiegen.Server.Controls
/// Gets or sets the value of the add click (ab) /// Gets or sets the value of the add click (ab)
/// </summary> /// </summary>
[Parameter] [Parameter]
public EventCallback AddClick { get; set; } public Func<InteractionType, Task>? AddClick { get; set; }
/// <summary> /// <summary>
/// Gets or sets the value of the allow add interaction (ab) /// Gets or sets the value of the allow add interaction (ab)
@@ -28,12 +29,6 @@ namespace FoodsharingSiegen.Server.Controls
[Parameter] [Parameter]
public string? ButtonIconClass { get; set; } public string? ButtonIconClass { get; set; }
/// <summary>
/// Gets or sets the value of the caption (ab)
/// </summary>
[Parameter]
public string? Caption { get; set; }
/// <summary> /// <summary>
/// Gets or sets the value of the icon class (ab) /// Gets or sets the value of the icon class (ab)
/// </summary> /// </summary>
@@ -87,7 +82,7 @@ namespace FoodsharingSiegen.Server.Controls
/// <summary> /// <summary>
/// Gets the value of the interactions (ab) /// Gets the value of the interactions (ab)
/// </summary> /// </summary>
private List<Interaction> Interactions => Prospect?.Interactions?.Where(x => x.Type == Type).ToList() ?? new List<Interaction>(); private List<Interaction> Interactions => Prospect?.Interactions.Where(x => x.Type == Type).ToList() ?? [];
/// <summary> /// <summary>
/// Gets the value of the not needed (ab) /// Gets the value of the not needed (ab)

View File

@@ -1,4 +1,5 @@
@inherits FsBase @using FoodsharingSiegen.Shared.Helper
@inherits FsBase
@{ @{
var divClass = $"{CssClass} pc-main"; var divClass = $"{CssClass} pc-main";
@@ -35,9 +36,8 @@
Prospect="Prospect" Prospect="Prospect"
Type="InteractionType.Welcome" Type="InteractionType.Welcome"
AllowInteraction="@(StateFilter == ProspectStateFilter.OnBoarding && CurrentUser.IsInGroup(UserGroup.WelcomeTeam))" AllowInteraction="@(StateFilter == ProspectStateFilter.OnBoarding && CurrentUser.IsInGroup(UserGroup.WelcomeTeam))"
AddClick="() => AddInteraction(InteractionType.Welcome)" AddClick="AddInteraction"
RemoveClick="@RemoveInteraction" RemoveClick="@RemoveInteraction"
Caption="Begrüßung"
ButtonIconClass="fa-solid fa-check" ButtonIconClass="fa-solid fa-check"
IconClass="fa-solid fa-handshake-simple"> IconClass="fa-solid fa-handshake-simple">
</InteractionRow> </InteractionRow>
@@ -46,9 +46,8 @@
Prospect="Prospect" Prospect="Prospect"
Type="InteractionType.StepInBriefing" Type="InteractionType.StepInBriefing"
AllowInteraction="@(StateFilter == ProspectStateFilter.OnBoarding && CurrentUser.IsInGroup(UserGroup.WelcomeTeam))" AllowInteraction="@(StateFilter == ProspectStateFilter.OnBoarding && CurrentUser.IsInGroup(UserGroup.WelcomeTeam))"
AddClick="() => AddInteraction(InteractionType.StepInBriefing)" AddClick="AddInteraction"
RemoveClick="@RemoveInteraction" RemoveClick="@RemoveInteraction"
Caption="@AppSettings.Terms.StepInName"
ButtonIconClass="fa-solid fa-check" ButtonIconClass="fa-solid fa-check"
IconClass="fa-solid fa-graduation-cap"> IconClass="fa-solid fa-graduation-cap">
</InteractionRow> </InteractionRow>
@@ -57,9 +56,8 @@
Prospect="Prospect" Prospect="Prospect"
Type="InteractionType.EinAb" Type="InteractionType.EinAb"
AllowInteraction="@(StateFilter == ProspectStateFilter.OnBoarding && CurrentUser.IsInGroup(UserGroup.WelcomeTeam, UserGroup.StoreManager, UserGroup.Ambassador))" AllowInteraction="@(StateFilter == ProspectStateFilter.OnBoarding && CurrentUser.IsInGroup(UserGroup.WelcomeTeam, UserGroup.StoreManager, UserGroup.Ambassador))"
AddClick="() => AddInteraction(InteractionType.EinAb)" AddClick="AddInteraction"
RemoveClick="@RemoveInteraction" RemoveClick="@RemoveInteraction"
Caption="Einführungen"
Multiple="true" Multiple="true"
Minimum="3" Minimum="3"
ButtonIconClass="fa-solid fa-plus" ButtonIconClass="fa-solid fa-plus"
@@ -76,9 +74,8 @@
Prospect="Prospect" Prospect="Prospect"
Type="InteractionType.ReleasedForVerification" Type="InteractionType.ReleasedForVerification"
AllowInteraction="@(StateFilter is ProspectStateFilter.OnBoarding or ProspectStateFilter.Verification && CurrentUser.IsInGroup(UserGroup.WelcomeTeam))" AllowInteraction="@(StateFilter is ProspectStateFilter.OnBoarding or ProspectStateFilter.Verification && CurrentUser.IsInGroup(UserGroup.WelcomeTeam))"
AddClick="() => AddInteraction(InteractionType.ReleasedForVerification)" AddClick="AddInteraction"
RemoveClick="@RemoveInteraction" RemoveClick="@RemoveInteraction"
Caption="Freigabe zur Verifizierung"
ButtonIconClass="fa-solid fa-check" ButtonIconClass="fa-solid fa-check"
IconClass="fa-solid fa-id-card"> IconClass="fa-solid fa-id-card">
</InteractionRow> </InteractionRow>
@@ -89,9 +86,8 @@
Prospect="Prospect" Prospect="Prospect"
Type="InteractionType.IdCheck" Type="InteractionType.IdCheck"
AllowInteraction="@CurrentUser.IsInGroup(UserGroup.Ambassador)" AllowInteraction="@CurrentUser.IsInGroup(UserGroup.Ambassador)"
AddClick="() => AddInteraction(InteractionType.IdCheck)" AddClick="AddInteraction"
RemoveClick="@RemoveInteraction" RemoveClick="@RemoveInteraction"
Caption="Perso checken"
ButtonIconClass="fa-solid fa-check" ButtonIconClass="fa-solid fa-check"
IconClass="fa-solid fa-magnifying-glass"> IconClass="fa-solid fa-magnifying-glass">
</InteractionRow> </InteractionRow>
@@ -103,9 +99,8 @@
Prospect="Prospect" Prospect="Prospect"
Type="InteractionType.PrintPass" Type="InteractionType.PrintPass"
AllowInteraction="@CurrentUser.IsInGroup(UserGroup.Ambassador)" AllowInteraction="@CurrentUser.IsInGroup(UserGroup.Ambassador)"
AddClick="() => AddInteraction(InteractionType.PrintPass)" AddClick="AddInteraction"
RemoveClick="@RemoveInteraction" RemoveClick="@RemoveInteraction"
Caption="FS-Ausweis (print)"
ButtonIconClass="fa-solid fa-check" ButtonIconClass="fa-solid fa-check"
IconClass="fa-solid fa-id-card"> IconClass="fa-solid fa-id-card">
</InteractionRow> </InteractionRow>
@@ -114,9 +109,8 @@
Prospect="Prospect" Prospect="Prospect"
AllowInteraction="@CurrentUser.IsInGroup(UserGroup.Ambassador)" AllowInteraction="@CurrentUser.IsInGroup(UserGroup.Ambassador)"
Type="InteractionType.Verify" Type="InteractionType.Verify"
AddClick="() => AddInteraction(InteractionType.Verify)" AddClick="AddInteraction"
RemoveClick="@RemoveInteraction" RemoveClick="@RemoveInteraction"
Caption="Verifizieren"
ButtonIconClass="fa-solid fa-check" ButtonIconClass="fa-solid fa-check"
IconClass="fa-solid fa-user-check"> IconClass="fa-solid fa-user-check">
</InteractionRow> </InteractionRow>
@@ -131,9 +125,8 @@
Prospect="Prospect" Prospect="Prospect"
AllowInteraction="@CurrentUser.IsInGroup(UserGroup.Ambassador)" AllowInteraction="@CurrentUser.IsInGroup(UserGroup.Ambassador)"
Type="InteractionType.Complete" Type="InteractionType.Complete"
AddClick="() => AddInteraction(InteractionType.Complete)" AddClick="AddInteraction"
RemoveClick="@RemoveInteraction" RemoveClick="@RemoveInteraction"
Caption="Fertig"
ButtonIconClass="fa-solid fa-check" ButtonIconClass="fa-solid fa-check"
IconClass="fa-solid fa-flag-checkered"> IconClass="fa-solid fa-flag-checkered">
</InteractionRow> </InteractionRow>

View File

@@ -1,6 +1,7 @@
using FoodsharingSiegen.Contracts.Entity; using FoodsharingSiegen.Contracts.Entity;
using FoodsharingSiegen.Server.Data.Service; using FoodsharingSiegen.Server.Data.Service;
using FoodsharingSiegen.Server.Dialogs; using FoodsharingSiegen.Server.Dialogs;
using FoodsharingSiegen.Shared.Helper;
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
namespace FoodsharingSiegen.Server.Controls namespace FoodsharingSiegen.Server.Controls
@@ -20,19 +21,7 @@ namespace FoodsharingSiegen.Server.Controls
{ {
if (Prospect != null && OnDataChanged != null) if (Prospect != null && OnDataChanged != null)
{ {
var headerText = type switch var headerText = $"{type.Translate(AppSettings)} eintragen";
{
InteractionType.EinAb => "Einführung eintragen",
InteractionType.Welcome => "Begrüßung eintragen",
InteractionType.IdCheck => "Ausweisprüfung eintragen",
InteractionType.PrintPass => "FS-Ausweis (Print)",
InteractionType.PdfPass => "FS-Ausweis (PDF)",
InteractionType.Verify => "Verifizierung eintragen",
InteractionType.Complete => "Als fertig markieren",
InteractionType.StepInBriefing => $"{AppSettings.Terms.StepInName} absolviert",
InteractionType.ReleasedForVerification => "Zur Verifizierung freigegeben",
_ => "Neuer Eintrag"
};
await InteractionDialog.ShowAsync(ModalService, new(type, Prospect.Id, headerText, OnDataChanged)); await InteractionDialog.ShowAsync(ModalService, new(type, Prospect.Id, headerText, OnDataChanged));
} }
@@ -57,7 +46,10 @@ namespace FoodsharingSiegen.Server.Controls
private async Task RemoveInteraction(Guid arg) private async Task RemoveInteraction(Guid arg)
{ {
var confirm = await Message.Confirm("Interaktion wirklich löschen?", "Bestätigen", o => var type = Prospect?.Interactions.FirstOrDefault(x => x.Id == arg)?.Type;
var typeName = type != null ? type.Value.Translate(AppSettings) : "Interaktion";
var confirm = await Message.Confirm($"{typeName} wirklich entfernen?", "Bestätigen", o =>
{ {
o.ConfirmButtonText = "Ja, wirklich!"; o.ConfirmButtonText = "Ja, wirklich!";
o.CancelButtonText = "Abbrechen"; o.CancelButtonText = "Abbrechen";

View File

@@ -25,4 +25,6 @@
<Switch TValue="bool" @bind-Checked="Prospect.Warning">Achtung!</Switch> <Switch TValue="bool" @bind-Checked="Prospect.Warning">Achtung!</Switch>
</Field> </Field>
<div class="d-flex justify-content-end">
<Button Color="Color.Primary" Clicked="@SaveClick">@SaveButtonText</Button> <Button Color="Color.Primary" Clicked="@SaveClick">@SaveButtonText</Button>
</div>

View File

@@ -33,5 +33,7 @@
</Field> </Field>
} }
<div class="d-flex justify-content-end">
<Button Color="Color.Secondary" Clicked="@ModalService.Hide">Abbrechen</Button> <Button Color="Color.Secondary" Clicked="@ModalService.Hide">Abbrechen</Button>
<Button Color="Color.Primary" Clicked="@AddInteractionAsync">OK</Button> <Button Color="Color.Primary" Clicked="@AddInteractionAsync" Class="ml-2">OK</Button>
</div>

View File

@@ -0,0 +1,38 @@
#nullable enable
using FoodsharingSiegen.Contracts.Entity;
using FoodsharingSiegen.Contracts.Model;
namespace FoodsharingSiegen.Shared.Helper
{
public static class TermHelper
{
#region Public Method Translate
/// <summary>
/// Translates an <see cref="InteractionType" /> instance into a corresponding string representation,
/// using the provided application settings if necessary.
/// </summary>
/// <param name="type">The interaction type to translate.</param>
/// <param name="appSettings">The application settings used for custom translations.</param>
/// <returns>A string representation of the specified interaction type.</returns>
public static string Translate(this InteractionType type, AppSettings appSettings)
{
return type switch
{
InteractionType.EinAb => "Einführung",
InteractionType.Welcome => "Begrüßung",
InteractionType.IdCheck => "Perso prüfen",
InteractionType.PrintPass => "FS-Ausweis (Print)",
InteractionType.PdfPass => "FS-Ausweis (PDF)",
InteractionType.Verify => "Verifizieren",
InteractionType.Complete => "Fertig",
InteractionType.StepInBriefing => appSettings.Terms.StepInName ?? "StepIn",
InteractionType.ReleasedForVerification => "Freigabe zur Verifizierung",
_ => type.ToString()
};
}
#endregion
}
}