--- 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? 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.