mcp
This commit is contained in:
@@ -57,6 +57,20 @@
|
||||
Template
|
||||
</button>
|
||||
|
||||
<button
|
||||
mat-stroked-button
|
||||
type="button"
|
||||
[disabled]="cleaningList() || !onlineStatus.online()"
|
||||
(click)="applyCleanup()"
|
||||
>
|
||||
@if (cleaningList()) {
|
||||
<mat-progress-spinner mode="indeterminate" diameter="18" />
|
||||
} @else {
|
||||
<mat-icon aria-hidden="true">auto_fix_high</mat-icon>
|
||||
}
|
||||
AI Cleanup
|
||||
</button>
|
||||
|
||||
<button mat-stroked-button type="button" (click)="showEditor() ? cancelEditing() : startEditing()">
|
||||
<mat-icon aria-hidden="true">{{ showEditor() ? 'close' : 'edit' }}</mat-icon>
|
||||
{{ showEditor() ? 'Abbrechen' : 'Bearbeiten' }}
|
||||
|
||||
@@ -20,6 +20,7 @@ import { OnboardingService } from '../../onboarding/onboarding.service';
|
||||
import { ConfirmDeleteListDialogComponent } from '../confirm-delete-list-dialog/confirm-delete-list-dialog.component';
|
||||
import { OnlineStatusService } from '../../offline/online-status.service';
|
||||
import {
|
||||
ApplyListCleanupResponse,
|
||||
ListItemSuggestion,
|
||||
ListRealtimeEvent,
|
||||
UserList,
|
||||
@@ -66,6 +67,7 @@ export class ListDetailComponent implements OnInit {
|
||||
protected readonly saving = signal(false);
|
||||
protected readonly creatingWithAi = signal(false);
|
||||
protected readonly creatingTemplate = signal(false);
|
||||
protected readonly cleaningList = signal(false);
|
||||
protected readonly deletingList = signal(false);
|
||||
protected readonly editing = signal(false);
|
||||
protected readonly addingItem = signal(false);
|
||||
@@ -342,6 +344,32 @@ export class ListDetailComponent implements OnInit {
|
||||
});
|
||||
}
|
||||
|
||||
protected applyCleanup(): void {
|
||||
const listId = this.currentListId();
|
||||
|
||||
if (!listId || this.cleaningList()) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.cleaningList.set(true);
|
||||
this.listsService
|
||||
.applyCleanup(listId)
|
||||
.pipe(finalize(() => this.cleaningList.set(false)))
|
||||
.subscribe({
|
||||
next: (response) => {
|
||||
this.setList(response.list, !this.showEditor());
|
||||
this.itemSuggestions.set([]);
|
||||
this.suggestionsLoaded.set(false);
|
||||
this.snackBar.open(this.cleanupSummary(response), 'OK', {
|
||||
duration: 4000,
|
||||
});
|
||||
},
|
||||
error: (error: unknown) => {
|
||||
this.snackBar.open(getAuthErrorMessage(error), 'OK', { duration: 5000 });
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
protected addSuggestion(suggestion: ListItemSuggestion): void {
|
||||
const listId = this.currentListId();
|
||||
|
||||
@@ -615,4 +643,23 @@ export class ListDetailComponent implements OnInit {
|
||||
private suggestionKey(value: string): string {
|
||||
return value.trim().replace(/\s+/g, ' ').toLowerCase();
|
||||
}
|
||||
|
||||
private cleanupSummary(response: ApplyListCleanupResponse): string {
|
||||
const parts = [
|
||||
response.summary.listUpdated ? 'Details aktualisiert' : null,
|
||||
response.summary.itemsUpdated > 0
|
||||
? `${response.summary.itemsUpdated} Items verbessert`
|
||||
: null,
|
||||
response.summary.duplicatesDeleted > 0
|
||||
? `${response.summary.duplicatesDeleted} Duplikate entfernt`
|
||||
: null,
|
||||
response.summary.itemsAdded > 0
|
||||
? `${response.summary.itemsAdded} Items hinzugefuegt`
|
||||
: null,
|
||||
].filter((part): part is string => part !== null);
|
||||
|
||||
return parts.length > 0
|
||||
? `Cleanup angewendet: ${parts.join(', ')}.`
|
||||
: 'Cleanup geprueft: keine sinnvollen Aenderungen gefunden.';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,6 +79,53 @@ export interface CreateListWithItemSuggestionsResponse {
|
||||
suggestions: ListItemSuggestion[];
|
||||
}
|
||||
|
||||
export interface ListCleanupListUpdate {
|
||||
name?: string;
|
||||
description?: string;
|
||||
reason?: string;
|
||||
}
|
||||
|
||||
export interface ListCleanupItemUpdate {
|
||||
itemId: string;
|
||||
title?: string;
|
||||
notes?: string;
|
||||
quantity?: number;
|
||||
required?: boolean;
|
||||
reason?: string;
|
||||
}
|
||||
|
||||
export interface ListCleanupDuplicateDeletion {
|
||||
itemId: string;
|
||||
keptItemId: string;
|
||||
reason?: string;
|
||||
}
|
||||
|
||||
export interface ListCleanupItemAddition extends ListItemSuggestion {
|
||||
reason?: string;
|
||||
}
|
||||
|
||||
export interface ListCleanupSuggestion {
|
||||
listUpdate?: ListCleanupListUpdate;
|
||||
itemUpdates: ListCleanupItemUpdate[];
|
||||
duplicateDeletions: ListCleanupDuplicateDeletion[];
|
||||
itemAdditions: ListCleanupItemAddition[];
|
||||
}
|
||||
|
||||
export interface ListCleanupSuggestionsResponse {
|
||||
cleanup: ListCleanupSuggestion;
|
||||
}
|
||||
|
||||
export interface ApplyListCleanupResponse {
|
||||
list: UserList;
|
||||
cleanup: ListCleanupSuggestion;
|
||||
summary: {
|
||||
listUpdated: boolean;
|
||||
itemsUpdated: number;
|
||||
duplicatesDeleted: number;
|
||||
itemsAdded: number;
|
||||
};
|
||||
}
|
||||
|
||||
export interface UpdateListItemRequest {
|
||||
title?: string;
|
||||
notes?: string;
|
||||
|
||||
@@ -4,8 +4,10 @@ import { Observable } from 'rxjs';
|
||||
import { of, tap, throwError } from 'rxjs';
|
||||
import {
|
||||
AddListItemRequest,
|
||||
ApplyListCleanupResponse,
|
||||
CreateListRequest,
|
||||
CreateListWithItemSuggestionsResponse,
|
||||
ListCleanupSuggestionsResponse,
|
||||
ListItemSuggestionsResponse,
|
||||
UpdateListItemRequest,
|
||||
UpdateListRequest,
|
||||
@@ -173,6 +175,34 @@ export class ListsService {
|
||||
);
|
||||
}
|
||||
|
||||
suggestCleanup(listId: string): Observable<ListCleanupSuggestionsResponse> {
|
||||
if (!this.onlineStatus.online()) {
|
||||
return throwError(
|
||||
() => new Error('AI Cleanup ist nur online verfuegbar.'),
|
||||
);
|
||||
}
|
||||
|
||||
return this.http.post<ListCleanupSuggestionsResponse>(
|
||||
`${this.apiUrl}/${listId}/cleanup-suggestions`,
|
||||
{},
|
||||
);
|
||||
}
|
||||
|
||||
applyCleanup(listId: string): Observable<ApplyListCleanupResponse> {
|
||||
if (!this.onlineStatus.online()) {
|
||||
return throwError(
|
||||
() => new Error('AI Cleanup ist nur online verfuegbar.'),
|
||||
);
|
||||
}
|
||||
|
||||
return this.http
|
||||
.post<ApplyListCleanupResponse>(
|
||||
`${this.apiUrl}/${listId}/apply-cleanup`,
|
||||
{},
|
||||
)
|
||||
.pipe(tap((response) => this.upsertCachedList(response.list)));
|
||||
}
|
||||
|
||||
createTemplateFromList(listId: string): Observable<ListTemplate> {
|
||||
if (!this.onlineStatus.online()) {
|
||||
return throwError(
|
||||
|
||||
Reference in New Issue
Block a user