diff --git a/packages/hoppscotch-common/src/components/collections/ImportExport.vue b/packages/hoppscotch-common/src/components/collections/ImportExport.vue index dc098b53f..4287fde90 100644 --- a/packages/hoppscotch-common/src/components/collections/ImportExport.vue +++ b/packages/hoppscotch-common/src/components/collections/ImportExport.vue @@ -19,30 +19,30 @@ import { UrlSource } from "~/helpers/import-export/import/import-sources/UrlSour import IconFile from "~icons/lucide/file" import { - hoppRESTImporter, - hoppInsomniaImporter, - hoppPostmanImporter, - toTeamsImporter, - hoppOpenAPIImporter, harImporter, + hoppInsomniaImporter, + hoppOpenAPIImporter, + hoppPostmanImporter, + hoppRESTImporter, + toTeamsImporter, } from "~/helpers/import-export/import/importers" import { defineStep } from "~/composables/step-components" +import MyCollectionImport from "~/components/importExport/ImportExportSteps/MyCollectionImport.vue" import { useI18n } from "~/composables/i18n" import { useToast } from "~/composables/toast" import { appendRESTCollections, restCollections$ } from "~/newstore/collections" -import MyCollectionImport from "~/components/importExport/ImportExportSteps/MyCollectionImport.vue" -import IconFolderPlus from "~icons/lucide/folder-plus" -import IconOpenAPI from "~icons/lucide/file" -import IconPostman from "~icons/hopp/postman" import IconInsomnia from "~icons/hopp/insomnia" +import IconPostman from "~icons/hopp/postman" +import IconOpenAPI from "~icons/lucide/file" +import IconFolderPlus from "~icons/lucide/folder-plus" import IconGithub from "~icons/lucide/github" import IconLink from "~icons/lucide/link" -import IconUser from "~icons/lucide/user" import { useReadonlyStream } from "~/composables/stream" +import IconUser from "~icons/lucide/user" import { getTeamCollectionJSON } from "~/helpers/backend/helpers" @@ -53,10 +53,18 @@ import { gistExporter } from "~/helpers/import-export/export/gist" import { myCollectionsExporter } from "~/helpers/import-export/export/myCollections" import { teamCollectionsExporter } from "~/helpers/import-export/export/teamCollections" -import { GistSource } from "~/helpers/import-export/import/import-sources/GistSource" import { ImporterOrExporter } from "~/components/importExport/types" +import { GistSource } from "~/helpers/import-export/import/import-sources/GistSource" import { TeamWorkspace } from "~/services/workspace.service" +const isPostmanImporterInProgress = ref(false) +const isInsomniaImporterInProgress = ref(false) +const isOpenAPIImporterInProgress = ref(false) +const isRESTImporterInProgress = ref(false) +const isPersonalCollectionImporterInProgress = ref(false) +const isHarImporterInProgress = ref(false) +const isGistImporterInProgress = ref(false) + const t = useI18n() const toast = useToast() @@ -92,7 +100,7 @@ const showImportFailedError = () => { const handleImportToStore = async (collections: HoppCollection[]) => { const importResult = props.collectionsType.type === "my-collections" - ? await importToPersonalWorkspace(collections) + ? importToPersonalWorkspace(collections) : await importToTeamsWorkspace(collections) if (E.isRight(importResult)) { @@ -179,10 +187,11 @@ const HoppRESTImporter: ImporterOrExporter = { caption: "import.from_file", acceptedFileTypes: ".json", onImportFromFile: async (content) => { + isRESTImporterInProgress.value = true const res = await hoppRESTImporter(content)() if (E.isRight(res)) { - handleImportToStore(res.right) + await handleImportToStore(res.right) platform.analytics?.logEvent({ type: "HOPP_IMPORT_COLLECTION", @@ -193,7 +202,10 @@ const HoppRESTImporter: ImporterOrExporter = { } else { showImportFailedError() } + + isRESTImporterInProgress.value = false }, + isLoading: isRESTImporterInProgress, }), } @@ -207,8 +219,11 @@ const HoppMyCollectionImporter: ImporterOrExporter = { applicableTo: ["team-workspace"], }, component: defineStep("my_collection_import", MyCollectionImport, () => ({ + loading: isPersonalCollectionImporterInProgress.value, async onImportFromMyCollection(content) { - handleImportToStore([content]) + isPersonalCollectionImporterInProgress.value = true + + await handleImportToStore([content]) // our analytics consider this as an export event, so keeping compatibility with that platform.analytics?.logEvent({ @@ -216,6 +231,8 @@ const HoppMyCollectionImporter: ImporterOrExporter = { exporter: "import_to_teams", platform: "rest", }) + + isPersonalCollectionImporterInProgress.value = false }, })), } @@ -238,10 +255,12 @@ const HoppOpenAPIImporter: ImporterOrExporter = { caption: "import.from_file", acceptedFileTypes: ".json, .yaml, .yml", onImportFromFile: async (content) => { + isOpenAPIImporterInProgress.value = true + const res = await hoppOpenAPIImporter(content)() if (E.isRight(res)) { - handleImportToStore(res.right) + await handleImportToStore(res.right) platform.analytics?.logEvent({ platform: "rest", @@ -252,7 +271,10 @@ const HoppOpenAPIImporter: ImporterOrExporter = { } else { showImportFailedError() } + + isOpenAPIImporterInProgress.value = false }, + isLoading: isOpenAPIImporterInProgress, }), }, { @@ -262,10 +284,12 @@ const HoppOpenAPIImporter: ImporterOrExporter = { step: UrlSource({ caption: "import.from_url", onImportFromURL: async (content) => { + isOpenAPIImporterInProgress.value = true + const res = await hoppOpenAPIImporter([content])() if (E.isRight(res)) { - handleImportToStore(res.right) + await handleImportToStore(res.right) platform.analytics?.logEvent({ platform: "rest", @@ -276,7 +300,10 @@ const HoppOpenAPIImporter: ImporterOrExporter = { } else { showImportFailedError() } + + isOpenAPIImporterInProgress.value = false }, + isLoading: isOpenAPIImporterInProgress, }), }, ], @@ -295,10 +322,12 @@ const HoppPostmanImporter: ImporterOrExporter = { caption: "import.from_file", acceptedFileTypes: ".json", onImportFromFile: async (content) => { + isPostmanImporterInProgress.value = true + const res = await hoppPostmanImporter(content)() if (E.isRight(res)) { - handleImportToStore(res.right) + await handleImportToStore(res.right) platform.analytics?.logEvent({ platform: "rest", @@ -309,7 +338,10 @@ const HoppPostmanImporter: ImporterOrExporter = { } else { showImportFailedError() } + + isPostmanImporterInProgress.value = false }, + isLoading: isPostmanImporterInProgress, }), } @@ -326,10 +358,12 @@ const HoppInsomniaImporter: ImporterOrExporter = { caption: "import.from_file", acceptedFileTypes: ".json", onImportFromFile: async (content) => { + isInsomniaImporterInProgress.value = true + const res = await hoppInsomniaImporter(content)() if (E.isRight(res)) { - handleImportToStore(res.right) + await handleImportToStore(res.right) platform.analytics?.logEvent({ platform: "rest", @@ -340,7 +374,10 @@ const HoppInsomniaImporter: ImporterOrExporter = { } else { showImportFailedError() } + + isInsomniaImporterInProgress.value = false }, + isLoading: isInsomniaImporterInProgress, }), } @@ -361,10 +398,12 @@ const HoppGistImporter: ImporterOrExporter = { return } + isGistImporterInProgress.value = true + const res = await hoppRESTImporter(content.right)() if (E.isRight(res)) { - handleImportToStore(res.right) + await handleImportToStore(res.right) platform.analytics?.logEvent({ platform: "rest", @@ -375,7 +414,10 @@ const HoppGistImporter: ImporterOrExporter = { } else { showImportFailedError() } + + isGistImporterInProgress.value = false }, + isLoading: isGistImporterInProgress, }), } @@ -528,22 +570,26 @@ const HARImporter: ImporterOrExporter = { caption: "import.from_file", acceptedFileTypes: ".har", onImportFromFile: async (content) => { + isHarImporterInProgress.value = true + const res = await harImporter(content) - if (E.isLeft(res)) { + if (E.isRight(res)) { + await handleImportToStore(res.right) + + platform.analytics?.logEvent({ + type: "HOPP_IMPORT_COLLECTION", + importer: "import.from_har", + platform: "rest", + workspaceType: isTeamWorkspace.value ? "team" : "personal", + }) + } else { showImportFailedError() - return } - handleImportToStore(res.right) - - platform.analytics?.logEvent({ - type: "HOPP_IMPORT_COLLECTION", - importer: "import.from_har", - platform: "rest", - workspaceType: isTeamWorkspace.value ? "team" : "personal", - }) + isHarImporterInProgress.value = false }, + isLoading: isHarImporterInProgress, }), } diff --git a/packages/hoppscotch-common/src/components/collections/graphql/ImportExport.vue b/packages/hoppscotch-common/src/components/collections/graphql/ImportExport.vue index a9716c992..b0759eabe 100644 --- a/packages/hoppscotch-common/src/components/collections/graphql/ImportExport.vue +++ b/packages/hoppscotch-common/src/components/collections/graphql/ImportExport.vue @@ -231,7 +231,7 @@ const showImportFailedError = () => { toast.error(t("import.failed")) } -const handleImportToStore = async (gqlCollections: HoppCollection[]) => { +const handleImportToStore = (gqlCollections: HoppCollection[]) => { appendGraphqlCollections(gqlCollections) toast.success(t("state.file_imported")) } diff --git a/packages/hoppscotch-common/src/components/environments/ImportExport.vue b/packages/hoppscotch-common/src/components/environments/ImportExport.vue index 6d7c0a6d5..0f11f6580 100644 --- a/packages/hoppscotch-common/src/components/environments/ImportExport.vue +++ b/packages/hoppscotch-common/src/components/environments/ImportExport.vue @@ -60,6 +60,11 @@ const currentUser = useReadonlyStream( platform.auth.getCurrentUser() ) +const isPostmanImporterInProgress = ref(false) +const isInsomniaImporterInProgress = ref(false) +const isRESTImporterInProgress = ref(false) +const isGistImporterInProgress = ref(false) + const isEnvironmentGistExportInProgress = ref(false) const isTeamEnvironment = computed(() => { @@ -91,23 +96,27 @@ const HoppEnvironmentsImport: ImporterOrExporter = { acceptedFileTypes: "application/json", caption: "import.hoppscotch_environment_description", onImportFromFile: async (environments) => { + isRESTImporterInProgress.value = true + const res = await hoppEnvImporter(environments)() - if (E.isLeft(res)) { + if (E.isRight(res)) { + await handleImportToStore(res.right) + + platform.analytics?.logEvent({ + type: "HOPP_IMPORT_ENVIRONMENT", + platform: "rest", + workspaceType: isTeamEnvironment.value ? "team" : "personal", + }) + + emit("hide-modal") + } else { showImportFailedError() - return } - handleImportToStore(res.right) - - platform.analytics?.logEvent({ - type: "HOPP_IMPORT_ENVIRONMENT", - platform: "rest", - workspaceType: workspaceType.value, - }) - - emit("hide-modal") + isRESTImporterInProgress.value = false }, + isLoading: isRESTImporterInProgress, }), } @@ -124,23 +133,27 @@ const PostmanEnvironmentsImport: ImporterOrExporter = { acceptedFileTypes: "application/json", caption: "import.postman_environment_description", onImportFromFile: async (environments) => { + isPostmanImporterInProgress.value = true + const res = await postmanEnvImporter(environments)() - if (E.isLeft(res)) { + if (E.isRight(res)) { + await handleImportToStore(res.right) + + platform.analytics?.logEvent({ + type: "HOPP_IMPORT_ENVIRONMENT", + platform: "rest", + workspaceType: isTeamEnvironment.value ? "team" : "personal", + }) + + emit("hide-modal") + } else { showImportFailedError() - return } - handleImportToStore(res.right) - - platform.analytics?.logEvent({ - type: "HOPP_IMPORT_ENVIRONMENT", - platform: "rest", - workspaceType: workspaceType.value, - }) - - emit("hide-modal") + isPostmanImporterInProgress.value = false }, + isLoading: isPostmanImporterInProgress, }), } @@ -157,30 +170,34 @@ const insomniaEnvironmentsImport: ImporterOrExporter = { acceptedFileTypes: "application/json", caption: "import.insomnia_environment_description", onImportFromFile: async (environments) => { + isInsomniaImporterInProgress.value = true + const res = await insomniaEnvImporter(environments)() - if (E.isLeft(res)) { + if (E.isRight(res)) { + const globalEnvs = res.right.filter( + (env) => env.name === "Base Environment" + ) + const otherEnvs = res.right.filter( + (env) => env.name !== "Base Environment" + ) + + await handleImportToStore(otherEnvs, globalEnvs) + + platform.analytics?.logEvent({ + type: "HOPP_IMPORT_ENVIRONMENT", + platform: "rest", + workspaceType: isTeamEnvironment.value ? "team" : "personal", + }) + + emit("hide-modal") + } else { showImportFailedError() - return } - const globalEnvs = res.right.filter( - (env) => env.name === "Base Environment" - ) - const otherEnvs = res.right.filter( - (env) => env.name !== "Base Environment" - ) - - handleImportToStore(otherEnvs, globalEnvs) - - platform.analytics?.logEvent({ - type: "HOPP_IMPORT_ENVIRONMENT", - platform: "rest", - workspaceType: workspaceType.value, - }) - - emit("hide-modal") + isInsomniaImporterInProgress.value = false }, + isLoading: isInsomniaImporterInProgress, }), } @@ -201,21 +218,26 @@ const EnvironmentsImportFromGIST: ImporterOrExporter = { return } + isGistImporterInProgress.value = true + const res = await hoppEnvImporter(environments.right)() - if (E.isLeft(res)) { + if (E.isRight(res)) { + await handleImportToStore(res.right) + + platform.analytics?.logEvent({ + type: "HOPP_IMPORT_ENVIRONMENT", + platform: "rest", + workspaceType: isTeamEnvironment.value ? "team" : "personal", + }) + emit("hide-modal") + } else { showImportFailedError() - return } - handleImportToStore(res.right) - platform.analytics?.logEvent({ - type: "HOPP_IMPORT_ENVIRONMENT", - platform: "rest", - workspaceType: workspaceType.value, - }) - emit("hide-modal") + isGistImporterInProgress.value = false }, + isLoading: isGistImporterInProgress, }), } diff --git a/packages/hoppscotch-common/src/components/importExport/ImportExportSteps/FileImport.vue b/packages/hoppscotch-common/src/components/importExport/ImportExportSteps/FileImport.vue index 4750b1a42..ce83fa8b9 100644 --- a/packages/hoppscotch-common/src/components/importExport/ImportExportSteps/FileImport.vue +++ b/packages/hoppscotch-common/src/components/importExport/ImportExportSteps/FileImport.vue @@ -45,9 +45,10 @@

@@ -55,14 +56,20 @@