feat(planner): add isLoading prop to SwapSuggestionList — disables Pick buttons during PATCH
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -11,6 +11,7 @@
|
||||
replacingMeta,
|
||||
recipes,
|
||||
currentWeekRecipeIds,
|
||||
isLoading = false,
|
||||
onpick,
|
||||
oncancel
|
||||
}: {
|
||||
@@ -18,6 +19,7 @@
|
||||
replacingMeta?: string;
|
||||
recipes: Recipe[];
|
||||
currentWeekRecipeIds: Set<string>;
|
||||
isLoading?: boolean;
|
||||
onpick: (recipeId: string, recipeName: string) => void;
|
||||
oncancel?: () => void;
|
||||
} = $props();
|
||||
@@ -97,7 +99,8 @@
|
||||
<button
|
||||
type="button"
|
||||
onclick={() => onpick(recipe.id, recipe.name)}
|
||||
style="background: none; border: none; cursor: pointer; font-size: 11px; font-weight: 500; color: var(--green); font-family: var(--font-sans); flex-shrink: 0;"
|
||||
disabled={isLoading}
|
||||
style="background: none; border: none; cursor: {isLoading ? 'default' : 'pointer'}; font-size: 11px; font-weight: 500; color: var(--green); font-family: var(--font-sans); flex-shrink: 0; opacity: {isLoading ? '0.4' : '1'};"
|
||||
>
|
||||
Wählen
|
||||
</button>
|
||||
|
||||
@@ -74,6 +74,18 @@ describe('SwapSuggestionList', () => {
|
||||
expect(screen.getByTestId('swap-empty-state')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('disables all Wählen buttons when isLoading is true', () => {
|
||||
render(SwapSuggestionList, { props: { ...baseProps, isLoading: true } });
|
||||
const buttons = screen.getAllByRole('button', { name: /Wählen/i });
|
||||
buttons.forEach((btn) => expect((btn as HTMLButtonElement).disabled).toBe(true));
|
||||
});
|
||||
|
||||
it('Wählen buttons are enabled when isLoading is false', () => {
|
||||
render(SwapSuggestionList, { props: { ...baseProps, isLoading: false } });
|
||||
const buttons = screen.getAllByRole('button', { name: /Wählen/i });
|
||||
buttons.forEach((btn) => expect((btn as HTMLButtonElement).disabled).toBe(false));
|
||||
});
|
||||
|
||||
it('renders optional Abbrechen button when oncancel provided', () => {
|
||||
render(SwapSuggestionList, { props: { ...baseProps, oncancel: vi.fn() } });
|
||||
expect(screen.getByRole('button', { name: /Abbrechen/i })).toBeTruthy();
|
||||
|
||||
@@ -61,6 +61,7 @@
|
||||
let pickerOpen = $state(false);
|
||||
let actionSheetOpen = $state(false);
|
||||
let swapSheetOpen = $state(false);
|
||||
let swapLoading = $state(false);
|
||||
|
||||
// Recipes already in any slot this week — used for ⚠ overlap warnings
|
||||
let currentWeekRecipeIds = $derived(
|
||||
@@ -139,8 +140,10 @@
|
||||
}
|
||||
|
||||
async function handleSwapPick(recipeId: string, recipeName: string) {
|
||||
swapSheetOpen = false;
|
||||
swapLoading = true;
|
||||
await handleRecipePick(recipeId, recipeName);
|
||||
swapSheetOpen = false;
|
||||
swapLoading = false;
|
||||
}
|
||||
|
||||
function closePanelToIdle() {
|
||||
@@ -306,6 +309,7 @@
|
||||
replacingMeta={replacingMeta || undefined}
|
||||
recipes={sortedRecipes}
|
||||
{currentWeekRecipeIds}
|
||||
isLoading={swapLoading}
|
||||
onpick={handleSwapPick}
|
||||
oncancel={() => (swapSheetOpen = false)}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user