Add edit functionality for EinAb interactions: implement UpdateInteraction method, extend InteractionDialog for edit mode, and add edit button in InteractionRow
This commit is contained in:
@@ -0,0 +1,155 @@
|
|||||||
|
---
|
||||||
|
name: EinAb Interaction Edit
|
||||||
|
overview: Add edit mode for EinAb (Einführung) interactions by extending the existing InteractionDialog with an update path, a new ProspectService.UpdateInteraction method, and an edit button in InteractionRow — scoped to EinAb initially but designed for future interaction types.
|
||||||
|
todos:
|
||||||
|
- id: service-update
|
||||||
|
content: Add ProspectService.UpdateInteraction + AuditType.EditInteraction + AuditHelper case
|
||||||
|
status: completed
|
||||||
|
- id: dialog-edit-mode
|
||||||
|
content: Extend InteractionDialog with IsEditMode, IsEditable helper, and unified SaveAsync
|
||||||
|
status: completed
|
||||||
|
- id: row-edit-button
|
||||||
|
content: Add AllowEdit/EditClick to InteractionRow with pencil icon in item list
|
||||||
|
status: completed
|
||||||
|
- id: container-wire
|
||||||
|
content: Add EditInteraction handler in ProspectContainer and enable AllowEdit on EinAb row
|
||||||
|
status: completed
|
||||||
|
isProject: false
|
||||||
|
---
|
||||||
|
|
||||||
|
# EinAb Interaction Edit Mode
|
||||||
|
|
||||||
|
## Current State
|
||||||
|
|
||||||
|
EinAb interactions ("Einführung") are multi-entry (minimum 3) and support date, business/person fields (`Info1`/`Info2`), and feedback (thumbs up/down/neutral). Users can **add** via [`InteractionDialog`](FoodsharingSiegen.Server/Dialogs/InteractionDialog.razor) and **remove** via the X icon in [`InteractionRow`](FoodsharingSiegen.Server/Controls/InteractionRow.razor). There is no update path at any layer.
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
flowchart LR
|
||||||
|
subgraph current [Current Flow]
|
||||||
|
AddBtn["+ Button"] --> Dialog["InteractionDialog"]
|
||||||
|
Dialog --> AddSvc["ProspectService.AddInteraction"]
|
||||||
|
XBtn["X Button"] --> Confirm["ConfirmDialog"]
|
||||||
|
Confirm --> RemoveSvc["ProspectService.RemoveInteraction"]
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
## Target Flow
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
flowchart LR
|
||||||
|
subgraph target [New Edit Flow]
|
||||||
|
EditBtn["Pencil Button"] --> EditDialog["InteractionDialog (edit mode)"]
|
||||||
|
EditDialog --> UpdateSvc["ProspectService.UpdateInteraction"]
|
||||||
|
end
|
||||||
|
AddBtn["+ Button"] --> AddDialog["InteractionDialog (add mode)"]
|
||||||
|
AddDialog --> AddSvc["ProspectService.AddInteraction"]
|
||||||
|
XBtn["X Button"] --> RemoveSvc["ProspectService.RemoveInteraction"]
|
||||||
|
```
|
||||||
|
|
||||||
|
Edit and remove will coexist. Only EinAb gets the edit button initially.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Service Layer — `UpdateInteraction`
|
||||||
|
|
||||||
|
**File:** [`FoodsharingSiegen.Server/Data/Service/ProspectService.cs`](FoodsharingSiegen.Server/Data/Service/ProspectService.cs)
|
||||||
|
|
||||||
|
Add `UpdateInteraction(Interaction interaction)` following the existing `UpdateAsync(Prospect)` pattern:
|
||||||
|
|
||||||
|
- Load tracked entity by `interaction.Id`; return error if not found
|
||||||
|
- Update editable fields only: `Date`, `Info1`, `Info2`, `Feedback`, `FeedbackInfo`, `Alert`
|
||||||
|
- Do **not** change: `Id`, `Created`, `UserID` (preserves original creator), `Type`, `ProspectID`, `NotNeeded`
|
||||||
|
- Set parent `Prospect.Modified = DateTime.UtcNow`
|
||||||
|
- Audit via new `AuditType.EditInteraction` (prospect name + interaction type as data)
|
||||||
|
- Detach entities after save (consistent with `AddInteraction`)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Audit Support
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- [`FoodsharingSiegen.Contracts/Enums/AuditType.cs`](FoodsharingSiegen.Contracts/Enums/AuditType.cs) — add `EditInteraction = 160`
|
||||||
|
- [`FoodsharingSiegen.Server/Data/AuditHelper.cs`](FoodsharingSiegen.Server/Data/AuditHelper.cs) — add case: `"hat eine Interaktion bei {Data1} bearbeitet: {Data2}"`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. InteractionDialog — Add/Edit Mode
|
||||||
|
|
||||||
|
**Files:** [`InteractionDialog.razor.cs`](FoodsharingSiegen.Server/Dialogs/InteractionDialog.razor.cs), [`InteractionDialog.razor`](FoodsharingSiegen.Server/Dialogs/InteractionDialog.razor)
|
||||||
|
|
||||||
|
Follow the [`EditProspectDialog`](FoodsharingSiegen.Server/Dialogs/EditProspectDialog.razor.cs) pattern (`IsUpdateMode` + conditional save):
|
||||||
|
|
||||||
|
- Add `IsEditMode` parameter and a static extensibility helper:
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
public static bool IsEditable(InteractionType type) => type switch
|
||||||
|
{
|
||||||
|
InteractionType.EinAb => true,
|
||||||
|
_ => false
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
- Extend `InteractionDialogParameter` with optional `Interaction? ExistingInteraction = null`
|
||||||
|
- In `ShowAsync`: when `ExistingInteraction` is provided, pass it as the bound `Interaction` and set `IsEditMode = true`; otherwise keep current "new interaction" behavior
|
||||||
|
- Replace `AddInteractionAsync` with a unified `SaveAsync`:
|
||||||
|
- **Add mode:** `Interaction.UserID = CurrentUser.Id` → `ProspectService.AddInteraction`
|
||||||
|
- **Edit mode:** `ProspectService.UpdateInteraction`
|
||||||
|
- In the razor template, change OK button label: `"OK"` (add) / `"Speichern"` (edit) — same fields render in both modes (date, Betrieb, Mit wem, feedback)
|
||||||
|
|
||||||
|
**Header text** (in `ProspectContainer`): `"Einführung für {Name} bearbeiten"` for edit vs existing `"… eintragen"` for add.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. InteractionRow — Edit Button
|
||||||
|
|
||||||
|
**Files:** [`InteractionRow.razor`](FoodsharingSiegen.Server/Controls/InteractionRow.razor), [`InteractionRow.razor.cs`](FoodsharingSiegen.Server/Controls/InteractionRow.razor.cs)
|
||||||
|
|
||||||
|
- Add parameters:
|
||||||
|
- `bool AllowEdit { get; set; }` — controls visibility
|
||||||
|
- `Func<Guid, Task>? EditClick { get; set; }` — callback with interaction Id
|
||||||
|
- In the per-item loop (lines 46–66), show a pencil icon (`fa-solid fa-pen-to-square`) next to the existing X remove icon when `AllowEdit && AllowInteraction`
|
||||||
|
- Same visibility guard as remove: hidden when prospect is complete (unless Complete-type interaction)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. ProspectContainer — Wire Up Edit
|
||||||
|
|
||||||
|
**Files:** [`ProspectContainer.razor`](FoodsharingSiegen.Server/Controls/ProspectContainer.razor), [`ProspectContainer.razor.cs`](FoodsharingSiegen.Server/Controls/ProspectContainer.razor.cs)
|
||||||
|
|
||||||
|
- Add `EditInteraction(Guid interactionId)`:
|
||||||
|
- Look up interaction from `Prospect.Interactions`
|
||||||
|
- Guard: only proceed if `InteractionDialog.IsEditable(interaction.Type)`
|
||||||
|
- Open dialog with existing interaction and header `"Einführung für {Name} bearbeiten"`
|
||||||
|
- On success → `OnDataChanged()`
|
||||||
|
- On the EinAb `InteractionRow`, add:
|
||||||
|
- `AllowEdit="true"`
|
||||||
|
- `EditClick="@EditInteraction"`
|
||||||
|
|
||||||
|
Other interaction rows remain unchanged (no edit button).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Extensibility Notes
|
||||||
|
|
||||||
|
To enable edit for another type later:
|
||||||
|
1. Add the type to `InteractionDialog.IsEditable()`
|
||||||
|
2. Set `AllowEdit="true"` on that row in `ProspectContainer.razor`
|
||||||
|
3. Ensure field labels in `ShowAsync`'s type switch cover that type (already done for several types)
|
||||||
|
|
||||||
|
No separate edit dialog component is needed — the same form handles both modes.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Files Changed (summary)
|
||||||
|
|
||||||
|
| File | Change |
|
||||||
|
|------|--------|
|
||||||
|
| `ProspectService.cs` | New `UpdateInteraction` method |
|
||||||
|
| `AuditType.cs` | New `EditInteraction` enum value |
|
||||||
|
| `AuditHelper.cs` | New audit text case |
|
||||||
|
| `InteractionDialog.razor.cs` | Edit mode, `IsEditable`, unified save |
|
||||||
|
| `InteractionDialog.razor` | Conditional button label |
|
||||||
|
| `InteractionRow.razor` / `.cs` | Edit button + parameters |
|
||||||
|
| `ProspectContainer.razor` / `.cs` | `EditInteraction` handler, EinAb wiring |
|
||||||
|
|
||||||
|
No database migration required — all editable fields already exist on the `Interaction` entity.
|
||||||
@@ -87,7 +87,12 @@ namespace FoodsharingSiegen.Contracts.Enums
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The change own password audit type
|
/// The change own password audit type
|
||||||
/// </summary>
|
/// </summary>
|
||||||
ChangeOwnPassword = 150
|
ChangeOwnPassword = 150,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The edit interaction audit type
|
||||||
|
/// </summary>
|
||||||
|
EditInteraction = 160
|
||||||
|
|
||||||
#endregion Prospects
|
#endregion Prospects
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,11 +45,29 @@ else
|
|||||||
|
|
||||||
@foreach (var interaction in Interactions)
|
@foreach (var interaction in Interactions)
|
||||||
{
|
{
|
||||||
<div class="d-flex justify-content-end">
|
<div class="d-flex justify-content-end align-items-center interaction-row-action-group">
|
||||||
@if ((Prospect is not { Complete: true } || interaction.Type == InteractionType.Complete) && AllowInteraction)
|
@if ((Prospect is not { Complete: true } || interaction.Type == InteractionType.Complete) && AllowInteraction)
|
||||||
{
|
{
|
||||||
<a style="display: inline-block;"" href=""><i class="fa-solid fa-square-xmark" @onclick="async () => { if (RemoveClick != null) await RemoveClick.Invoke(interaction.Id); }" @onclick:preventDefault></i></a>
|
<div class="d-flex align-items-center interaction-row-actions">
|
||||||
} else {
|
@if (AllowEdit)
|
||||||
|
{
|
||||||
|
<Button Size="Size.Small"
|
||||||
|
Class="interaction-row-action interaction-row-action-edit"
|
||||||
|
title="Eintrag bearbeiten"
|
||||||
|
Clicked="@(async () => { if (EditClick != null) await EditClick.Invoke(interaction.Id); })">
|
||||||
|
<i class="fa-solid fa-pen-to-square"></i>
|
||||||
|
</Button>
|
||||||
|
}
|
||||||
|
<Button Size="Size.Small"
|
||||||
|
Class="interaction-row-action interaction-row-action-delete"
|
||||||
|
title="Eintrag löschen"
|
||||||
|
Clicked="@(async () => { if (RemoveClick != null) await RemoveClick.Invoke(interaction.Id); })">
|
||||||
|
<i class="fa-solid fa-square-xmark"></i>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
<span>•</span>
|
<span>•</span>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -62,6 +62,18 @@ namespace FoodsharingSiegen.Server.Controls
|
|||||||
[Parameter]
|
[Parameter]
|
||||||
public Func<Guid, Task>? RemoveClick { get; set; }
|
public Func<Guid, Task>? RemoveClick { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets whether editing existing interactions is allowed.
|
||||||
|
/// </summary>
|
||||||
|
[Parameter]
|
||||||
|
public bool AllowEdit { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the callback invoked when an interaction is edited.
|
||||||
|
/// </summary>
|
||||||
|
[Parameter]
|
||||||
|
public Func<Guid, Task>? EditClick { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the value of the type (ab)
|
/// Gets or sets the value of the type (ab)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -1,4 +1,38 @@
|
|||||||
tr.done th {
|
.interaction-row-action-group {
|
||||||
|
gap: 0.25rem;
|
||||||
|
min-width: 2.7rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.interaction-row-actions {
|
||||||
|
gap: 0.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.interaction-row-action {
|
||||||
|
width: 1rem;
|
||||||
|
min-width: 1.25rem;
|
||||||
|
height: 1.25rem;
|
||||||
|
min-height: 1.25rem;
|
||||||
|
padding: 0;
|
||||||
|
display: inline-flex !important;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: 0.7rem;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.interaction-row-action i {
|
||||||
|
font-size: 0.95rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.interaction-row-action-edit i {
|
||||||
|
color: #1f2f3a;
|
||||||
|
}
|
||||||
|
|
||||||
|
.interaction-row-action-delete i {
|
||||||
|
color: rgb(153, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
tr.done th {
|
||||||
color: #64ae24;
|
color: #64ae24;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -81,6 +81,8 @@
|
|||||||
AllowInteraction="@(StateFilter == ProspectStateFilter.OnBoarding && CurrentUser.IsInGroup(UserGroup.WelcomeTeam, UserGroup.Ambassador))"
|
AllowInteraction="@(StateFilter == ProspectStateFilter.OnBoarding && CurrentUser.IsInGroup(UserGroup.WelcomeTeam, UserGroup.Ambassador))"
|
||||||
AddClick="AddInteraction"
|
AddClick="AddInteraction"
|
||||||
RemoveClick="@RemoveInteraction"
|
RemoveClick="@RemoveInteraction"
|
||||||
|
AllowEdit="true"
|
||||||
|
EditClick="@EditInteraction"
|
||||||
Multiple="true"
|
Multiple="true"
|
||||||
Minimum="3"
|
Minimum="3"
|
||||||
ButtonIconClass="fa-solid fa-plus"
|
ButtonIconClass="fa-solid fa-plus"
|
||||||
|
|||||||
@@ -62,6 +62,24 @@ namespace FoodsharingSiegen.Server.Controls
|
|||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region Private Method EditInteraction
|
||||||
|
|
||||||
|
private async Task EditInteraction(Guid interactionId)
|
||||||
|
{
|
||||||
|
if (Prospect == null || OnDataChanged == null) return;
|
||||||
|
|
||||||
|
var interaction = Prospect.Interactions.FirstOrDefault(x => x.Id == interactionId);
|
||||||
|
if (interaction == null || !InteractionDialog.IsEditable(interaction.Type)) return;
|
||||||
|
|
||||||
|
var headerText = $"{interaction.Type.Translate(AppSettings)} für {Prospect.Name} bearbeiten";
|
||||||
|
|
||||||
|
Func<Task> onSuccess = async () => await OnDataChanged();
|
||||||
|
|
||||||
|
await InteractionDialog.ShowAsync(ModalService, new(interaction.Type, Prospect.Id, headerText, onSuccess, interaction));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
#region Private Method DeleteProspectAsync
|
#region Private Method DeleteProspectAsync
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -37,6 +37,8 @@ namespace FoodsharingSiegen.Server.Data
|
|||||||
return $"hat dem Neuling {audit.Data1} folgendes hinzugefügt: {audit.Data2}";
|
return $"hat dem Neuling {audit.Data1} folgendes hinzugefügt: {audit.Data2}";
|
||||||
case AuditType.RemoveInteraction:
|
case AuditType.RemoveInteraction:
|
||||||
return $"hat eine Interaktion bei {audit.Data1} gelöscht.";
|
return $"hat eine Interaktion bei {audit.Data1} gelöscht.";
|
||||||
|
case AuditType.EditInteraction:
|
||||||
|
return $"hat eine Interaktion bei {audit.Data1} bearbeitet: {audit.Data2}";
|
||||||
case AuditType.DeleteProspectImages:
|
case AuditType.DeleteProspectImages:
|
||||||
return $"hat die Bilder von {audit.Data1} gelöscht.";
|
return $"hat die Bilder von {audit.Data1} gelöscht.";
|
||||||
case AuditType.ViewProspectImages:
|
case AuditType.ViewProspectImages:
|
||||||
|
|||||||
@@ -174,6 +174,53 @@ namespace FoodsharingSiegen.Server.Data.Service
|
|||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region Public Method UpdateInteraction
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Updates an existing interaction with the specified values.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="interaction">The interaction with updated values.</param>
|
||||||
|
/// <returns>A task containing an operation result of interaction.</returns>
|
||||||
|
public async Task<OperationResult<Interaction>> UpdateInteraction(Interaction interaction)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var entityInteraction = await Context.Interactions!.FirstOrDefaultAsync(x => x.Id == interaction.Id);
|
||||||
|
if (entityInteraction == null) return new(new Exception("Interaction not found"));
|
||||||
|
|
||||||
|
entityInteraction.Date = interaction.Date;
|
||||||
|
entityInteraction.Info1 = interaction.Info1;
|
||||||
|
entityInteraction.Info2 = interaction.Info2;
|
||||||
|
entityInteraction.Feedback = interaction.Feedback;
|
||||||
|
entityInteraction.FeedbackInfo = interaction.FeedbackInfo;
|
||||||
|
entityInteraction.Alert = interaction.Alert;
|
||||||
|
|
||||||
|
var prospect = await Context.Prospects!.FirstOrDefaultAsync(x => x.Id == entityInteraction.ProspectID);
|
||||||
|
if (prospect != null)
|
||||||
|
{
|
||||||
|
prospect.Modified = DateTime.UtcNow;
|
||||||
|
}
|
||||||
|
|
||||||
|
await Context.SaveChangesAsync();
|
||||||
|
|
||||||
|
if (prospect != null)
|
||||||
|
{
|
||||||
|
await AuditService.Insert(AuditType.EditInteraction, prospect.Name, entityInteraction.Type.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
Context.Entry(entityInteraction).State = EntityState.Detached;
|
||||||
|
if (prospect != null) Context.Entry(prospect).State = EntityState.Detached;
|
||||||
|
|
||||||
|
return new(entityInteraction);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
return new(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
#region Public Method UpdateAsync
|
#region Public Method UpdateAsync
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -76,5 +76,5 @@
|
|||||||
|
|
||||||
<div class="d-flex justify-content-end">
|
<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" Class="ml-2">OK</Button>
|
<Button Color="Color.Primary" Clicked="@SaveAsync" Class="ml-2">@(IsEditMode ? "Speichern" : "OK")</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Blazorise;
|
using Blazorise;
|
||||||
|
using FoodsharingSiegen.Contracts;
|
||||||
using FoodsharingSiegen.Contracts.Entity;
|
using FoodsharingSiegen.Contracts.Entity;
|
||||||
using FoodsharingSiegen.Contracts.Enums;
|
using FoodsharingSiegen.Contracts.Enums;
|
||||||
using FoodsharingSiegen.Server.BaseClasses;
|
using FoodsharingSiegen.Server.BaseClasses;
|
||||||
@@ -7,7 +8,7 @@ using Microsoft.AspNetCore.Components;
|
|||||||
|
|
||||||
namespace FoodsharingSiegen.Server.Dialogs
|
namespace FoodsharingSiegen.Server.Dialogs
|
||||||
{
|
{
|
||||||
public record InteractionDialogParameter(InteractionType Type, Guid ProspectId, string HeaderText, Func<Task> OnSuccess);
|
public record InteractionDialogParameter(InteractionType Type, Guid ProspectId, string HeaderText, Func<Task> OnSuccess, Interaction? ExistingInteraction = null);
|
||||||
|
|
||||||
public partial class InteractionDialog : FsBase
|
public partial class InteractionDialog : FsBase
|
||||||
{
|
{
|
||||||
@@ -44,6 +45,19 @@ namespace FoodsharingSiegen.Server.Dialogs
|
|||||||
[Parameter]
|
[Parameter]
|
||||||
public bool ShowNotNeeded { get; set; }
|
public bool ShowNotNeeded { get; set; }
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public bool IsEditMode { get; set; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Public Method IsEditable
|
||||||
|
|
||||||
|
public static bool IsEditable(InteractionType type) => type switch
|
||||||
|
{
|
||||||
|
InteractionType.EinAb => true,
|
||||||
|
_ => false
|
||||||
|
};
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Public Method ShowAsync
|
#region Public Method ShowAsync
|
||||||
@@ -93,7 +107,24 @@ namespace FoodsharingSiegen.Server.Dialogs
|
|||||||
_ => false
|
_ => false
|
||||||
};
|
};
|
||||||
|
|
||||||
var interaction = new Interaction
|
var isEditMode = parameter.ExistingInteraction != null;
|
||||||
|
var interaction = isEditMode
|
||||||
|
? new Interaction
|
||||||
|
{
|
||||||
|
Id = parameter.ExistingInteraction!.Id,
|
||||||
|
Type = parameter.ExistingInteraction.Type,
|
||||||
|
Date = parameter.ExistingInteraction.Date,
|
||||||
|
ProspectID = parameter.ExistingInteraction.ProspectID,
|
||||||
|
UserID = parameter.ExistingInteraction.UserID,
|
||||||
|
Info1 = parameter.ExistingInteraction.Info1,
|
||||||
|
Info2 = parameter.ExistingInteraction.Info2,
|
||||||
|
Feedback = parameter.ExistingInteraction.Feedback,
|
||||||
|
FeedbackInfo = parameter.ExistingInteraction.FeedbackInfo,
|
||||||
|
Alert = parameter.ExistingInteraction.Alert,
|
||||||
|
NotNeeded = parameter.ExistingInteraction.NotNeeded,
|
||||||
|
Created = parameter.ExistingInteraction.Created
|
||||||
|
}
|
||||||
|
: new Interaction
|
||||||
{
|
{
|
||||||
Type = parameter.Type,
|
Type = parameter.Type,
|
||||||
Date = DateTime.UtcNow,
|
Date = DateTime.UtcNow,
|
||||||
@@ -108,29 +139,41 @@ namespace FoodsharingSiegen.Server.Dialogs
|
|||||||
p.Add(nameof(Info2Name), info2Name);
|
p.Add(nameof(Info2Name), info2Name);
|
||||||
p.Add(nameof(ShowAlert), showAlert);
|
p.Add(nameof(ShowAlert), showAlert);
|
||||||
p.Add(nameof(ShowNotNeeded), showNotNeeded);
|
p.Add(nameof(ShowNotNeeded), showNotNeeded);
|
||||||
|
p.Add(nameof(IsEditMode), isEditMode);
|
||||||
p.Add(nameof(OnSuccess), parameter.OnSuccess);
|
p.Add(nameof(OnSuccess), parameter.OnSuccess);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Private Method AddInteractionAsync
|
#region Private Method SaveAsync
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds a new interaction for the current user using the ProspectService and hides the modal.
|
/// Saves the interaction (add or update) and hides the modal on success.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>
|
private async Task SaveAsync()
|
||||||
/// A task representing the asynchronous operation.
|
{
|
||||||
/// </returns>
|
OperationResult<Interaction> result;
|
||||||
private async Task AddInteractionAsync()
|
|
||||||
|
if (IsEditMode)
|
||||||
|
{
|
||||||
|
result = await ProspectService.UpdateInteraction(Interaction);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
Interaction.UserID = CurrentUser.Id;
|
Interaction.UserID = CurrentUser.Id;
|
||||||
|
result = await ProspectService.AddInteraction(Interaction);
|
||||||
|
}
|
||||||
|
|
||||||
var addR = await ProspectService.AddInteraction(Interaction);
|
if (result.Success)
|
||||||
|
{
|
||||||
await ModalService.Hide();
|
await ModalService.Hide();
|
||||||
|
if (OnSuccess != null) await OnSuccess.Invoke();
|
||||||
if (addR.Success && OnSuccess != null) await OnSuccess.Invoke();
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await Notification.Error(result.Exception?.Message ?? "Unbekannter Fehler beim Speichern.", "Fehler");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|||||||
Reference in New Issue
Block a user