diff --git a/web-common/src/features/entity-management/WatchResourcesClient.ts b/web-common/src/features/entity-management/WatchResourcesClient.ts index ac638875f54..891062b6008 100644 --- a/web-common/src/features/entity-management/WatchResourcesClient.ts +++ b/web-common/src/features/entity-management/WatchResourcesClient.ts @@ -21,6 +21,7 @@ import { runtime } from "@rilldata/web-common/runtime-client/runtime-store"; import { WatchRequestClient } from "@rilldata/web-common/runtime-client/watch-request-client"; import { get } from "svelte/store"; import { connectorExplorerStore } from "../connectors/connector-explorer-store"; +import { sourceImportedPath } from "../sources/sources-store"; export class WatchResourcesClient { public readonly client: WatchRequestClient; @@ -181,6 +182,15 @@ export class WatchResourcesClient { // The following invalidations are only needed if the Source/Model has an active table if (!connectorName || !tableName) return; + // If it's a new source, show the "Source imported successfully" modal + const isNewSource = + res.name.kind === ResourceKind.Source && + res.resource.meta.specVersion === "1"; + if (isNewSource) { + const filePath = res.resource?.meta?.filePaths?.[0] as string; + sourceImportedPath.set(filePath); + } + // Invalidate the model partitions query if ((res.name.kind as ResourceKind) === ResourceKind.Model) { void queryClient.invalidateQueries( diff --git a/web-common/src/features/sources/modal/FileDrop.svelte b/web-common/src/features/sources/modal/FileDrop.svelte index a014817b2b6..46cd26b46c6 100644 --- a/web-common/src/features/sources/modal/FileDrop.svelte +++ b/web-common/src/features/sources/modal/FileDrop.svelte @@ -3,9 +3,7 @@ import Overlay from "@rilldata/web-common/components/overlay/Overlay.svelte"; import { getFilePathFromNameAndType } from "@rilldata/web-common/features/entity-management/entity-mappers"; import { EntityType } from "@rilldata/web-common/features/entity-management/types"; - import { checkSourceImported } from "@rilldata/web-common/features/sources/source-imported-utils"; import { createRuntimeServiceUnpackEmpty } from "@rilldata/web-common/runtime-client"; - import { useQueryClient } from "@tanstack/svelte-query"; import { runtime } from "../../../runtime-client/runtime-store"; import { EMPTY_PROJECT_TITLE } from "../../welcome/constants"; import { isProjectInitialized } from "../../welcome/is-project-initialized"; @@ -15,8 +13,6 @@ export let showDropOverlay: boolean; - const queryClient = useQueryClient(); - $: ({ instanceId } = $runtime); const unpackEmptyProject = createRuntimeServiceUnpackEmpty(); @@ -55,7 +51,6 @@ tableName, EntityType.Table, ); - await checkSourceImported(queryClient, newFilePath); await goto(`/files${newFilePath}`); } catch (err) { console.error(err); diff --git a/web-common/src/features/sources/modal/LocalSourceUpload.svelte b/web-common/src/features/sources/modal/LocalSourceUpload.svelte index 14c91c73329..11f4da28460 100644 --- a/web-common/src/features/sources/modal/LocalSourceUpload.svelte +++ b/web-common/src/features/sources/modal/LocalSourceUpload.svelte @@ -7,10 +7,8 @@ openFileUploadDialog, uploadTableFiles, } from "@rilldata/web-common/features/sources/modal/file-upload"; - import { checkSourceImported } from "@rilldata/web-common/features/sources/source-imported-utils"; import { overlay } from "@rilldata/web-common/layout/overlay-store"; import { createRuntimeServiceUnpackEmpty } from "@rilldata/web-common/runtime-client"; - import { useQueryClient } from "@tanstack/svelte-query"; import { createEventDispatcher } from "svelte"; import { runtime } from "../../../runtime-client/runtime-store"; import { EMPTY_PROJECT_TITLE } from "../../welcome/constants"; @@ -19,7 +17,6 @@ import { createSource } from "./createSource"; const dispatch = createEventDispatcher(); - const queryClient = useQueryClient(); $: ({ instanceId } = $runtime); @@ -55,7 +52,6 @@ tableName, EntityType.Table, ); - await checkSourceImported(queryClient, newFilePath); await goto(`/files${newFilePath}`); } catch (err) { console.error(err); diff --git a/web-common/src/features/sources/modal/submitAddDataForm.ts b/web-common/src/features/sources/modal/submitAddDataForm.ts index c37324729f0..d357648d87d 100644 --- a/web-common/src/features/sources/modal/submitAddDataForm.ts +++ b/web-common/src/features/sources/modal/submitAddDataForm.ts @@ -1,6 +1,5 @@ import { goto, invalidate } from "$app/navigation"; import { getScreenNameFromPage } from "@rilldata/web-common/features/file-explorer/telemetry"; -import { checkSourceImported } from "@rilldata/web-common/features/sources/source-imported-utils"; import type { QueryClient } from "@tanstack/query-core"; import { get } from "svelte/store"; import { behaviourEvent } from "../../../metrics/initMetrics"; @@ -116,8 +115,6 @@ export async function submitAddDataForm( createOnly: false, }); - await checkSourceImported(queryClient, newSourceFilePath); - await goto(`/files/${newSourceFilePath}`); return; diff --git a/web-common/src/features/sources/source-imported-utils.ts b/web-common/src/features/sources/source-imported-utils.ts deleted file mode 100644 index 2057ef4670c..00000000000 --- a/web-common/src/features/sources/source-imported-utils.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { fileArtifacts } from "@rilldata/web-common/features/entity-management/file-artifacts"; -import { sourceImportedPath } from "@rilldata/web-common/features/sources/sources-store"; -import { V1ReconcileStatus } from "@rilldata/web-common/runtime-client"; -import { runtime } from "@rilldata/web-common/runtime-client/runtime-store"; -import type { QueryClient } from "@tanstack/svelte-query"; -import { derived, get } from "svelte/store"; - -export async function checkSourceImported( - queryClient: QueryClient, - filePath: string, -) { - const lastUpdatedOn = - fileArtifacts.getFileArtifact(filePath).lastStateUpdatedOn; - if (lastUpdatedOn) return; // For now only show for fresh sources - - waitForResourceUpdate(queryClient, get(runtime).instanceId, filePath) - .then((success) => { - if (!success) return; - sourceImportedPath.set(filePath); - }) - .catch(console.error); -} - -function waitForResourceUpdate( - queryClient: QueryClient, - instanceId: string, - filePath: string, -) { - return new Promise((resolve) => { - const end = (changed: boolean) => { - unsub?.(); - resolve(changed); - }; - - // eslint-disable-next-line prefer-const - const unsub = sourceImportedStore( - queryClient, - instanceId, - filePath, - ).subscribe(({ done, errored }) => { - if (!done) return; - end(!errored); - }); - }); -} - -/** - * Used while saving to wait until either a resource is created or parse has errored. - */ -function sourceImportedStore( - queryClient: QueryClient, - instanceId: string, - filePath: string, -) { - const artifact = fileArtifacts.getFileArtifact(filePath); - return derived( - [ - artifact.getResource(queryClient, instanceId), - artifact.getAllErrors(queryClient, instanceId), - ], - ([res, errors]) => { - if (res.isFetching) return { done: false, errored: false }; - if ( - (res.isError && (res.error as any).response.status !== 404) || - errors.length > 0 - ) - return { done: true, errored: true }; - - if ( - res.data?.meta?.reconcileStatus !== - V1ReconcileStatus.RECONCILE_STATUS_IDLE - ) - return { done: false, errored: false }; - - return { - done: !!res.data?.source?.state?.table, - errored: false, - }; - }, - ); -}