fix: implement fetch generation counter to handle concurrent refreshes in ScrollingList
Some checks failed
Chore App Build, Test, and Push Docker Images / build-and-push (push) Has been cancelled
Some checks failed
Chore App Build, Test, and Push Docker Images / build-and-push (push) Has been cancelled
- Added a fetch generation counter to the fetchItems method to discard stale results from concurrent fetches. - Updated the loading state management to ensure it only updates if the fetch is the latest. - Enhanced the refresh method to prevent stale data from being rendered when multiple refreshes occur. - Added a test case to verify that stale fetches are discarded correctly when concurrent refreshes happen. - Fixed CSS for mobile banners to prevent overflow and adjusted font sizes for better visibility. - Resolved issues with task icons disappearing when extending time on overdue chores by ensuring only one fetch is active at a time.
This commit is contained in:
@@ -74,6 +74,15 @@ test.describe('Chore activation', () => {
|
||||
await request.put(`/api/child/${childId}/set-tasks`, {
|
||||
data: { task_ids: [kindId], type: 'kindness' },
|
||||
})
|
||||
// Add a schedule so COMPLETED status persists after trigger
|
||||
await request.put(`/api/child/${childId}/task/${choreId}/schedule`, {
|
||||
data: {
|
||||
mode: 'interval',
|
||||
interval_days: 1,
|
||||
anchor_date: new Date().toISOString().slice(0, 10),
|
||||
interval_has_deadline: false,
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
test.afterAll(async ({ request }) => {
|
||||
|
||||
@@ -66,7 +66,7 @@ test.describe('Chore assignment', () => {
|
||||
await expect(page.getByRole('button', { name: 'Assign Chores' })).toBeVisible()
|
||||
|
||||
await page.getByRole('button', { name: 'Assign Chores' }).click()
|
||||
await page.waitForURL(new RegExp(`/parent/${childId}/assign-chores$`))
|
||||
await page.waitForURL(new RegExp(`/parent/${childId}/assign-chores(\\?|$)`))
|
||||
|
||||
await expect(page.getByRole('heading', { name: 'Assign Chores' })).toBeVisible()
|
||||
|
||||
@@ -83,7 +83,7 @@ test.describe('Chore assignment', () => {
|
||||
test('Select chores and submit — items appear in ParentView chores section', async ({ page }) => {
|
||||
await page.goto(`/parent/${childId}`)
|
||||
await page.getByRole('button', { name: 'Assign Chores' }).click()
|
||||
await page.waitForURL(new RegExp(`/parent/${childId}/assign-chores$`))
|
||||
await page.waitForURL(new RegExp(`/parent/${childId}/assign-chores(\\?|$)`))
|
||||
await expect(page.getByRole('heading', { name: 'Assign Chores' })).toBeVisible()
|
||||
|
||||
// Select two chores
|
||||
@@ -126,7 +126,7 @@ test.describe('Chore assignment', () => {
|
||||
test('Uncheck all chores and submit — items are removed from ParentView', async ({ page }) => {
|
||||
await page.goto(`/parent/${childId}`)
|
||||
await page.getByRole('button', { name: 'Assign Chores' }).click()
|
||||
await page.waitForURL(new RegExp(`/parent/${childId}/assign-chores$`))
|
||||
await page.waitForURL(new RegExp(`/parent/${childId}/assign-chores(\\?|$)`))
|
||||
await expect(page.getByRole('heading', { name: 'Assign Chores' })).toBeVisible()
|
||||
|
||||
// Uncheck the two previously assigned chores
|
||||
@@ -151,7 +151,7 @@ test.describe('Chore assignment', () => {
|
||||
test('Cancel does not persist selection changes', async ({ page }) => {
|
||||
await page.goto(`/parent/${childId}`)
|
||||
await page.getByRole('button', { name: 'Assign Chores' }).click()
|
||||
await page.waitForURL(new RegExp(`/parent/${childId}/assign-chores$`))
|
||||
await page.waitForURL(new RegExp(`/parent/${childId}/assign-chores(\\?|$)`))
|
||||
await expect(page.getByRole('heading', { name: 'Assign Chores' })).toBeVisible()
|
||||
|
||||
// Check an item
|
||||
|
||||
@@ -56,7 +56,7 @@ test.describe('Kindness act assignment', () => {
|
||||
await expect(page.getByRole('button', { name: 'Assign Kindness Acts' })).toBeVisible()
|
||||
|
||||
await page.getByRole('button', { name: 'Assign Kindness Acts' }).click()
|
||||
await page.waitForURL(new RegExp(`/parent/${childId}/assign-kindness$`))
|
||||
await page.waitForURL(new RegExp(`/parent/${childId}/assign-kindness(\\?|$)`))
|
||||
|
||||
await expect(page.getByRole('heading', { name: 'Assign Kindness Acts' })).toBeVisible()
|
||||
|
||||
@@ -72,7 +72,7 @@ test.describe('Kindness act assignment', () => {
|
||||
test('Select a kindness act and submit — item appears in ParentView', async ({ page }) => {
|
||||
await page.goto(`/parent/${childId}`)
|
||||
await page.getByRole('button', { name: 'Assign Kindness Acts' }).click()
|
||||
await page.waitForURL(new RegExp(`/parent/${childId}/assign-kindness$`))
|
||||
await page.waitForURL(new RegExp(`/parent/${childId}/assign-kindness(\\?|$)`))
|
||||
await expect(page.getByRole('heading', { name: 'Assign Kindness Acts' })).toBeVisible()
|
||||
|
||||
await page.getByText(KIND1_NAME, { exact: true }).click()
|
||||
@@ -101,7 +101,7 @@ test.describe('Kindness act assignment', () => {
|
||||
}) => {
|
||||
await page.goto(`/parent/${childId}`)
|
||||
await page.getByRole('button', { name: 'Assign Kindness Acts' }).click()
|
||||
await page.waitForURL(new RegExp(`/parent/${childId}/assign-kindness$`))
|
||||
await page.waitForURL(new RegExp(`/parent/${childId}/assign-kindness(\\?|$)`))
|
||||
await expect(page.getByRole('heading', { name: 'Assign Kindness Acts' })).toBeVisible()
|
||||
|
||||
// Uncheck the previously assigned item
|
||||
@@ -120,7 +120,7 @@ test.describe('Kindness act assignment', () => {
|
||||
test('Cancel does not persist selection changes', async ({ page }) => {
|
||||
await page.goto(`/parent/${childId}`)
|
||||
await page.getByRole('button', { name: 'Assign Kindness Acts' }).click()
|
||||
await page.waitForURL(new RegExp(`/parent/${childId}/assign-kindness$`))
|
||||
await page.waitForURL(new RegExp(`/parent/${childId}/assign-kindness(\\?|$)`))
|
||||
await expect(page.getByRole('heading', { name: 'Assign Kindness Acts' })).toBeVisible()
|
||||
|
||||
// Check the item
|
||||
|
||||
@@ -66,7 +66,7 @@ test.describe('Penalty assignment', () => {
|
||||
await expect(page.getByRole('button', { name: 'Assign Penalties' })).toBeVisible()
|
||||
|
||||
await page.getByRole('button', { name: 'Assign Penalties' }).click()
|
||||
await page.waitForURL(new RegExp(`/parent/${childId}/assign-penalties$`))
|
||||
await page.waitForURL(new RegExp(`/parent/${childId}/assign-penalties(\\?|$)`))
|
||||
|
||||
await expect(page.getByRole('heading', { name: 'Assign Penalties' })).toBeVisible()
|
||||
|
||||
@@ -85,7 +85,7 @@ test.describe('Penalty assignment', () => {
|
||||
}) => {
|
||||
await page.goto(`/parent/${childId}`)
|
||||
await page.getByRole('button', { name: 'Assign Penalties' }).click()
|
||||
await page.waitForURL(new RegExp(`/parent/${childId}/assign-penalties$`))
|
||||
await page.waitForURL(new RegExp(`/parent/${childId}/assign-penalties(\\?|$)`))
|
||||
await expect(page.getByRole('heading', { name: 'Assign Penalties' })).toBeVisible()
|
||||
|
||||
// Select two penalties
|
||||
@@ -128,7 +128,7 @@ test.describe('Penalty assignment', () => {
|
||||
test('Uncheck all penalties and submit — items are removed from ParentView', async ({ page }) => {
|
||||
await page.goto(`/parent/${childId}`)
|
||||
await page.getByRole('button', { name: 'Assign Penalties' }).click()
|
||||
await page.waitForURL(new RegExp(`/parent/${childId}/assign-penalties$`))
|
||||
await page.waitForURL(new RegExp(`/parent/${childId}/assign-penalties(\\?|$)`))
|
||||
await expect(page.getByRole('heading', { name: 'Assign Penalties' })).toBeVisible()
|
||||
|
||||
// Uncheck the previously assigned penalties
|
||||
@@ -153,7 +153,7 @@ test.describe('Penalty assignment', () => {
|
||||
test('Cancel does not persist selection changes', async ({ page }) => {
|
||||
await page.goto(`/parent/${childId}`)
|
||||
await page.getByRole('button', { name: 'Assign Penalties' }).click()
|
||||
await page.waitForURL(new RegExp(`/parent/${childId}/assign-penalties$`))
|
||||
await page.waitForURL(new RegExp(`/parent/${childId}/assign-penalties(\\?|$)`))
|
||||
await expect(page.getByRole('heading', { name: 'Assign Penalties' })).toBeVisible()
|
||||
|
||||
// Check an item
|
||||
|
||||
@@ -62,7 +62,7 @@ test.describe('Reward assignment', () => {
|
||||
await expect(page.getByRole('button', { name: 'Assign Rewards' })).toBeVisible()
|
||||
|
||||
await page.getByRole('button', { name: 'Assign Rewards' }).click()
|
||||
await page.waitForURL(new RegExp(`/parent/${childId}/assign-rewards$`))
|
||||
await page.waitForURL(new RegExp(`/parent/${childId}/assign-rewards(\\?|$)`))
|
||||
|
||||
await expect(page.getByRole('heading', { name: 'Assign Rewards' })).toBeVisible()
|
||||
|
||||
@@ -81,7 +81,7 @@ test.describe('Reward assignment', () => {
|
||||
}) => {
|
||||
await page.goto(`/parent/${childId}`)
|
||||
await page.getByRole('button', { name: 'Assign Rewards' }).click()
|
||||
await page.waitForURL(new RegExp(`/parent/${childId}/assign-rewards$`))
|
||||
await page.waitForURL(new RegExp(`/parent/${childId}/assign-rewards(\\?|$)`))
|
||||
await expect(page.getByRole('heading', { name: 'Assign Rewards' })).toBeVisible()
|
||||
|
||||
// Select two rewards
|
||||
@@ -124,7 +124,7 @@ test.describe('Reward assignment', () => {
|
||||
test('Uncheck all rewards and submit — items are removed from ParentView', async ({ page }) => {
|
||||
await page.goto(`/parent/${childId}`)
|
||||
await page.getByRole('button', { name: 'Assign Rewards' }).click()
|
||||
await page.waitForURL(new RegExp(`/parent/${childId}/assign-rewards$`))
|
||||
await page.waitForURL(new RegExp(`/parent/${childId}/assign-rewards(\\?|$)`))
|
||||
await expect(page.getByRole('heading', { name: 'Assign Rewards' })).toBeVisible()
|
||||
|
||||
// Uncheck the previously assigned rewards
|
||||
@@ -149,7 +149,7 @@ test.describe('Reward assignment', () => {
|
||||
test('Cancel does not persist selection changes', async ({ page }) => {
|
||||
await page.goto(`/parent/${childId}`)
|
||||
await page.getByRole('button', { name: 'Assign Rewards' }).click()
|
||||
await page.waitForURL(new RegExp(`/parent/${childId}/assign-rewards$`))
|
||||
await page.waitForURL(new RegExp(`/parent/${childId}/assign-rewards(\\?|$)`))
|
||||
await expect(page.getByRole('heading', { name: 'Assign Rewards' })).toBeVisible()
|
||||
|
||||
// Check an item
|
||||
|
||||
@@ -70,6 +70,15 @@ test.describe('Chore reset', () => {
|
||||
await request.put(`/api/child/${childId}/set-tasks`, {
|
||||
data: { task_ids: [helperKindId], type: 'kindness' },
|
||||
})
|
||||
// Add a schedule so COMPLETED status persists after trigger
|
||||
await request.put(`/api/child/${childId}/task/${choreId}/schedule`, {
|
||||
data: {
|
||||
mode: 'interval',
|
||||
interval_days: 1,
|
||||
anchor_date: new Date().toISOString().slice(0, 10),
|
||||
interval_has_deadline: false,
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
test.afterAll(async ({ request }) => {
|
||||
|
||||
Reference in New Issue
Block a user