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,
|
replacingMeta,
|
||||||
recipes,
|
recipes,
|
||||||
currentWeekRecipeIds,
|
currentWeekRecipeIds,
|
||||||
|
isLoading = false,
|
||||||
onpick,
|
onpick,
|
||||||
oncancel
|
oncancel
|
||||||
}: {
|
}: {
|
||||||
@@ -18,6 +19,7 @@
|
|||||||
replacingMeta?: string;
|
replacingMeta?: string;
|
||||||
recipes: Recipe[];
|
recipes: Recipe[];
|
||||||
currentWeekRecipeIds: Set<string>;
|
currentWeekRecipeIds: Set<string>;
|
||||||
|
isLoading?: boolean;
|
||||||
onpick: (recipeId: string, recipeName: string) => void;
|
onpick: (recipeId: string, recipeName: string) => void;
|
||||||
oncancel?: () => void;
|
oncancel?: () => void;
|
||||||
} = $props();
|
} = $props();
|
||||||
@@ -97,7 +99,8 @@
|
|||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onclick={() => onpick(recipe.id, recipe.name)}
|
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
|
Wählen
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -74,6 +74,18 @@ describe('SwapSuggestionList', () => {
|
|||||||
expect(screen.getByTestId('swap-empty-state')).toBeTruthy();
|
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', () => {
|
it('renders optional Abbrechen button when oncancel provided', () => {
|
||||||
render(SwapSuggestionList, { props: { ...baseProps, oncancel: vi.fn() } });
|
render(SwapSuggestionList, { props: { ...baseProps, oncancel: vi.fn() } });
|
||||||
expect(screen.getByRole('button', { name: /Abbrechen/i })).toBeTruthy();
|
expect(screen.getByRole('button', { name: /Abbrechen/i })).toBeTruthy();
|
||||||
|
|||||||
@@ -61,6 +61,7 @@
|
|||||||
let pickerOpen = $state(false);
|
let pickerOpen = $state(false);
|
||||||
let actionSheetOpen = $state(false);
|
let actionSheetOpen = $state(false);
|
||||||
let swapSheetOpen = $state(false);
|
let swapSheetOpen = $state(false);
|
||||||
|
let swapLoading = $state(false);
|
||||||
|
|
||||||
// Recipes already in any slot this week — used for ⚠ overlap warnings
|
// Recipes already in any slot this week — used for ⚠ overlap warnings
|
||||||
let currentWeekRecipeIds = $derived(
|
let currentWeekRecipeIds = $derived(
|
||||||
@@ -139,8 +140,10 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function handleSwapPick(recipeId: string, recipeName: string) {
|
async function handleSwapPick(recipeId: string, recipeName: string) {
|
||||||
swapSheetOpen = false;
|
swapLoading = true;
|
||||||
await handleRecipePick(recipeId, recipeName);
|
await handleRecipePick(recipeId, recipeName);
|
||||||
|
swapSheetOpen = false;
|
||||||
|
swapLoading = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function closePanelToIdle() {
|
function closePanelToIdle() {
|
||||||
@@ -306,6 +309,7 @@
|
|||||||
replacingMeta={replacingMeta || undefined}
|
replacingMeta={replacingMeta || undefined}
|
||||||
recipes={sortedRecipes}
|
recipes={sortedRecipes}
|
||||||
{currentWeekRecipeIds}
|
{currentWeekRecipeIds}
|
||||||
|
isLoading={swapLoading}
|
||||||
onpick={handleSwapPick}
|
onpick={handleSwapPick}
|
||||||
oncancel={() => (swapSheetOpen = false)}
|
oncancel={() => (swapSheetOpen = false)}
|
||||||
/>
|
/>
|
||||||
|
|||||||
Reference in New Issue
Block a user