Skip to content

Commit a52b04c

Browse files
committed
Handled edge case
1 parent 3d1f055 commit a52b04c

File tree

4 files changed

+95
-2
lines changed

4 files changed

+95
-2
lines changed

src/lib/components/v2/projects/datasets/DatasetImagesTable.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -385,7 +385,7 @@
385385
body: JSON.stringify(params)
386386
}
387387
);
388-
if (firstLoad) {
388+
if (firstLoad && !runWorkflowModal) {
389389
showTable = imagePage.total_count > 0;
390390
firstLoad = false;
391391
} else {

src/lib/components/v2/workflow/RunWorkflowModal.svelte

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@
282282
...task.type_filters
283283
}
284284
};
285-
const response = await fetch(
285+
let response = await fetch(
286286
`/api/v2/project/${dataset.project_id}/dataset/${dataset.id}/images/query?page=1&page_size=10`,
287287
{
288288
method: 'POST',
@@ -299,6 +299,26 @@
299299
imagePage = await response.json();
300300
hasImages =
301301
/** @type {import('fractal-components/types/api').ImagePage} */ (imagePage).total_count > 0;
302+
if (!hasImages) {
303+
// Verify if dataset without filters has images
304+
let response = await fetch(
305+
`/api/v2/project/${dataset.project_id}/dataset/${dataset.id}/images/query?page=1&page_size=10`,
306+
{
307+
method: 'POST',
308+
headers,
309+
credentials: 'include',
310+
body: JSON.stringify({})
311+
}
312+
);
313+
if (!response.ok) {
314+
modal.displayErrorAlert(await getAlertErrorFromResponse(response));
315+
datasetImagesLoading = false;
316+
return;
317+
}
318+
/** @type {import('fractal-components/types/api').ImagePage} */
319+
const result = await response.json();
320+
hasImages = result.total_count > 0;
321+
}
302322
datasetImagesLoading = false;
303323
await tick();
304324
datasetImagesTable?.load();

tests/v2/images.spec.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ test('Dataset images [v2]', async ({ page, project }) => {
2222
await page.getByRole('link', { name: 'test-dataset' }).click();
2323
await page.waitForURL(/\/v2\/projects\/\d+\/datasets\/\d+/);
2424
await expect(page.getByText('No entries in the image list yet')).toBeVisible();
25+
await expect(page.getByRole('button', { name: 'Apply' })).not.toBeVisible();
2526
});
2627

2728
await test.step('Create an image without filters', async () => {
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import { selectSlimSelect, waitModalClosed, waitPageLoading } from '../utils.js';
2+
import { createImage } from './image_utils.js';
3+
import { expect, test } from './workflow_fixture.js';
4+
5+
test('Image list visibility in run workflow modal', async ({ page, workflow }) => {
6+
await page.waitForURL(workflow.url);
7+
await waitPageLoading(page);
8+
9+
await page.goto(`/v2/projects/${workflow.projectId}`);
10+
await waitPageLoading(page);
11+
12+
const modal = page.locator('.modal.show');
13+
const randomPath = `/tmp/${Math.random().toString(36).substring(7)}`;
14+
15+
await test.step('Create test dataset', async () => {
16+
const createDatasetButton = page.getByRole('button', { name: 'Create new dataset' });
17+
await createDatasetButton.click();
18+
await modal.waitFor();
19+
await modal.getByRole('textbox', { name: 'Dataset Name' }).fill('test-dataset');
20+
await modal.getByRole('textbox', { name: 'Zarr dir' }).fill(randomPath);
21+
await modal.getByRole('button', { name: 'Save' }).click();
22+
await waitModalClosed(page);
23+
});
24+
25+
await test.step('Open workflow page and verify that image list is not displayed', async () => {
26+
await page.goto(workflow.url);
27+
await waitPageLoading(page);
28+
await workflow.addTask('generic_task');
29+
await page.getByRole('button', { name: 'Run workflow' }).click();
30+
await modal.waitFor();
31+
await expect(modal.getByText('Image list')).not.toBeVisible();
32+
});
33+
34+
await test.step('Add images to the dataset', async () => {
35+
await page.goto(`/v2/projects/${workflow.projectId}`);
36+
await waitPageLoading(page);
37+
await page.getByRole('link', { name: 'test-dataset' }).click();
38+
await waitPageLoading(page);
39+
await createImage(page, `${randomPath}/img1`, { a1: 'v1' });
40+
await createImage(page, `${randomPath}/img2`, { a2: 'v2' });
41+
});
42+
43+
await test.step('Add dataset filters that exclude all images', async () => {
44+
await page.getByText('Current selection').click();
45+
await expect(page.getByText(/Total results: 2/)).toBeVisible();
46+
await selectSlimSelect(page, page.getByLabel('Selector for attribute a1'), 'v1');
47+
await page.getByRole('button', { name: 'Apply' }).click();
48+
await selectSlimSelect(page, page.getByLabel('Selector for attribute a2'), 'v2');
49+
await page.getByRole('button', { name: 'Apply' }).click();
50+
await expect(page.getByText(/Total results: 0/)).toBeVisible();
51+
await page.getByRole('button', { name: 'Save' }).click();
52+
await modal.getByRole('button', { name: 'Confirm' }).click();
53+
await waitModalClosed(page);
54+
await expect(page.getByRole('button', { name: 'Save' })).toBeDisabled();
55+
});
56+
57+
await test.step('Open workflow page and verify that image list is displayed and table is empty', async () => {
58+
await page.goto(workflow.url);
59+
await waitPageLoading(page);
60+
await page.getByRole('button', { name: 'Run workflow' }).click();
61+
await modal.waitFor();
62+
await expect(modal.getByRole('button', { name: 'Image list' })).toBeVisible();
63+
await modal.getByRole('button', { name: 'Image list' }).click();
64+
await expect(modal.getByText(/Total results: 0/)).toBeVisible();
65+
});
66+
67+
await test.step('Deselect filter and check result', async () => {
68+
await modal.locator('.ss-deselect').first().click();
69+
await modal.getByRole('button', { name: 'Apply' }).click();
70+
await expect(modal.getByText(/Total results: 1/)).toBeVisible();
71+
});
72+
});

0 commit comments

Comments
 (0)