diff --git a/ui/apps/pixano/src/components/dataset/DatasetExplorer.svelte b/ui/apps/pixano/src/components/dataset/DatasetExplorer.svelte index 1cfb796ec..6fd149cde 100644 --- a/ui/apps/pixano/src/components/dataset/DatasetExplorer.svelte +++ b/ui/apps/pixano/src/components/dataset/DatasetExplorer.svelte @@ -16,6 +16,7 @@ // Imports import { createEventDispatcher, onMount } from "svelte"; + import { Loader2Icon } from "lucide-svelte"; import { LoadingModal, WarningModal } from "@pixano/core/src"; import { Table } from "@pixano/table"; @@ -41,10 +42,16 @@ // Exports export let selectedDataset: DatasetInfo; + let isLoadingTableItems = false; // Page navigation let currentPage: number; let pageSize: number; + $: { + if (selectedDataset.page?.items) { + isLoadingTableItems = false; + } + } datasetTableStore.subscribe((value) => { currentPage = value?.currentPage || DEFAULT_DATASET_TABLE_PAGE; @@ -58,7 +65,7 @@ // Semantic search let search: string = ""; let selectedSearchModel: string | undefined; - const searchModels: Array<string> = []; + const searchModels: string[] = []; if ("embeddings" in selectedDataset.tables) { for (const table of selectedDataset.tables.embeddings) { if (table.type == "search") { @@ -77,86 +84,68 @@ dispatch("selectItem", itemId); } - function loadPage() { - // let res: DatasetItems; - // let query: Record<string, string> = { model: selectedSearchModel as string, search: search }; - - // Load page - // const start = Date.now(); - // if (search == "") { - // // Standard page - // res = await api.getDatasetItems(selectedDataset.id, currentPage, itemsPerPage); - // console.log("DatasetExplorer.loadPage - api.getDatasetItems in", Date.now() - start, "ms"); - // } else { - // // Search page - // loadingResultsModal = true; - // res = await api.searchDatasetItems(selectedDataset.id, query, currentPage, itemsPerPage); - // console.log("DatasetExplorer.loadPage - api.searchDatasetItems in", Date.now() - start, "ms"); - // } - - // Results - loadingResultsModal = false; - // if (res == null) { - // datasetErrorModal = true; - // } else { - // selectedDataset.page = res; - // } - } - function handleClearSearch() { (document.getElementById("sem-search-input") as HTMLInputElement).value = ""; handleSearch(); } function handleGoToFirstPage() { + isLoadingTableItems = true; if (currentPage > 1) { datasetTableStore.update((value) => ({ + ...value, pageSize: value?.pageSize || pageSize, currentPage: 1, })); - loadPage(); } } function handleGoToPreviousPage() { + isLoadingTableItems = true; if (currentPage > 1) { datasetTableStore.update((value) => ({ + ...value, pageSize: value?.pageSize || pageSize, currentPage: currentPage - 1, })); - loadPage(); } } function handleGoToNextPage() { + isLoadingTableItems = true; if ((selectedDataset.page?.total || 1) > currentPage * pageSize) { datasetTableStore.update((value) => ({ + ...value, pageSize: value?.pageSize || pageSize, currentPage: currentPage + 1, })); - loadPage(); } } function handleGoToLastPage() { + isLoadingTableItems = true; if ((selectedDataset.page?.total || 1) > currentPage * pageSize) { datasetTableStore.update((value) => ({ + ...value, pageSize: value?.pageSize || pageSize, currentPage: Math.ceil((selectedDataset.page?.total || 1) / pageSize), })); - loadPage(); } } function handleSearch() { search = (document.getElementById("sem-search-input") as HTMLInputElement).value; - currentPage = 1; - loadPage(); + let query = { model: selectedSearchModel as string, search }; + isLoadingTableItems = true; + datasetTableStore.update((value) => ({ + ...value, + currentPage: 1, + query, + })); } onMount(() => { search = ""; - loadPage(); }); </script> @@ -247,10 +236,16 @@ {/if} </div> </div> - <Table - items={selectedDataset.page.items} - on:selectItem={(event) => handleSelectItem(event.detail)} - /> + {#if isLoadingTableItems} + <div class="flex-grow flex justify-center items-center"> + <Loader2Icon class="animate-spin" /> + </div> + {:else} + <Table + items={selectedDataset.page.items} + on:selectItem={(event) => handleSelectItem(event.detail)} + /> + {/if} </div> <div class="w-full py-5 h-20 flex justify-center items-center text-slate-800"> diff --git a/ui/apps/pixano/src/lib/stores/datasetStores.ts b/ui/apps/pixano/src/lib/stores/datasetStores.ts index 73d0c67be..f76c31aad 100644 --- a/ui/apps/pixano/src/lib/stores/datasetStores.ts +++ b/ui/apps/pixano/src/lib/stores/datasetStores.ts @@ -17,10 +17,23 @@ import { writable } from "svelte/store"; import type { DatasetInfo } from "@pixano/core/src"; +import { + DEFAULT_DATASET_TABLE_PAGE, + DEFAULT_DATASET_TABLE_SIZE, +} from "$lib/constants/pixanoConstants"; import type { DatasetTableStore } from "../types/pixanoTypes"; +const defaultDatasetTableValues: DatasetTableStore = { + currentPage: DEFAULT_DATASET_TABLE_PAGE, + pageSize: DEFAULT_DATASET_TABLE_SIZE, + query: { + model: "", + search: "", + }, +}; + // Exports export const datasetsStore = writable<DatasetInfo[]>(); export const modelsStore = writable<string[]>([]); export const isLoadingNewItemStore = writable<boolean>(false); -export const datasetTableStore = writable<DatasetTableStore>(); +export const datasetTableStore = writable<DatasetTableStore>(defaultDatasetTableValues); diff --git a/ui/apps/pixano/src/lib/types/pixanoTypes.ts b/ui/apps/pixano/src/lib/types/pixanoTypes.ts index df5dd2d6d..fe9108dfb 100644 --- a/ui/apps/pixano/src/lib/types/pixanoTypes.ts +++ b/ui/apps/pixano/src/lib/types/pixanoTypes.ts @@ -1,4 +1,8 @@ export type DatasetTableStore = { currentPage: number; pageSize: number; + query: { + model: string; + search: string; + }; }; diff --git a/ui/apps/pixano/src/routes/+layout.svelte b/ui/apps/pixano/src/routes/+layout.svelte index 9b6f2e04d..2f7a894e0 100644 --- a/ui/apps/pixano/src/routes/+layout.svelte +++ b/ui/apps/pixano/src/routes/+layout.svelte @@ -2,7 +2,7 @@ import { onMount } from "svelte"; import { page } from "$app/stores"; - import type { DatasetInfo } from "@pixano/core/src"; + import type { DatasetInfo, DatasetItems } from "@pixano/core/src"; import { api } from "@pixano/core/src"; import MainHeader from "../components/layout/MainHeader.svelte"; @@ -10,6 +10,7 @@ import { datasetsStore, modelsStore, datasetTableStore } from "../lib/stores/datasetStores"; import "./styles.css"; + import type { DatasetTableStore } from "$lib/types/pixanoTypes"; let datasets: DatasetInfo[] = []; let models: Array<string>; @@ -35,8 +36,18 @@ await handleGetModels(); }); - const getDatasetItems = async (datasetId: string, page?: number, size?: number) => { - const datasetItems = await api.getDatasetItems(datasetId, page, size); + const getDatasetItems = async ( + datasetId: string, + page?: number, + size?: number, + query?: DatasetTableStore["query"], + ) => { + let datasetItems: DatasetItems; + if (query?.search) { + datasetItems = await api.searchDatasetItems(datasetId, query, page, size); + } else { + datasetItems = await api.getDatasetItems(datasetId, page, size); + } datasetsStore.update((value = []) => value.map((dataset) => dataset.id === datasetId ? { ...dataset, page: datasetItems } : dataset, @@ -57,8 +68,8 @@ datasetTableStore.subscribe((value) => { const currentDatasetId = datasets?.find((dataset) => dataset.name === currentDatasetName)?.id; if (currentDatasetId && value) - getDatasetItems(currentDatasetId, value.currentPage, value.pageSize).catch((err) => - console.error(err), + getDatasetItems(currentDatasetId, value.currentPage, value.pageSize, value.query).catch( + (err) => console.error(err), ); }); </script>