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.
|
||||
Reference in New Issue
Block a user