chore: split url and file importer steps
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<SmartModal
|
<SmartModal
|
||||||
v-if="show"
|
v-if="show"
|
||||||
:title="`${t('modal.import_export')} ${t('modal.collections')}`"
|
:title="`${t('modal.collections')}`"
|
||||||
max-width="sm:max-w-md"
|
max-width="sm:max-w-md"
|
||||||
@close="hideModal"
|
@close="hideModal"
|
||||||
>
|
>
|
||||||
@@ -27,49 +27,72 @@
|
|||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
<template #body>
|
<template #body>
|
||||||
<div v-if="importerType !== null" class="relative flex flex-col px-2">
|
<div v-if="importerType !== null" class="flex flex-col">
|
||||||
<div
|
<div class="relative flex pb-6 flex-col px-2">
|
||||||
class="absolute top-0 w-0.5 bg-primaryDark left-5 -z-1 bottom-1"
|
<div
|
||||||
></div>
|
class="absolute top-0 w-0.5 bg-primaryDark left-5 -z-1 bottom-1"
|
||||||
<div
|
></div>
|
||||||
v-for="(step, index) in importerSteps"
|
<div
|
||||||
:key="`step-${index}`"
|
v-for="(step, index) in importerSteps"
|
||||||
class="flex flex-col space-y-8"
|
:key="`step-${index}`"
|
||||||
>
|
class="flex flex-col space-y-8"
|
||||||
<div v-if="step.name === 'FILE_OR_URL_IMPORT'" class="space-y-4">
|
>
|
||||||
<p class="flex items-center">
|
<div v-if="step.name === 'FILE_IMPORT'" class="space-y-4">
|
||||||
<span
|
<p class="flex items-center">
|
||||||
class="inline-flex items-center justify-center flex-shrink-0 mr-4 rounded-full border-5 border-primary text-secondaryLight"
|
<span
|
||||||
:class="{
|
class="inline-flex items-center justify-center flex-shrink-0 mr-4 rounded-full border-5 border-primary text-secondaryLight"
|
||||||
'text-green-500': hasFile,
|
:class="{
|
||||||
}"
|
'text-green-500': hasFile,
|
||||||
>
|
}"
|
||||||
<i class="material-icons">check_circle</i>
|
>
|
||||||
</span>
|
<i class="material-icons">check_circle</i>
|
||||||
<span>
|
</span>
|
||||||
{{ t("import.json_description") }}
|
<span>
|
||||||
</span>
|
{{ t("import.json_description") }}
|
||||||
</p>
|
</span>
|
||||||
<p class="flex flex-col ml-12">
|
</p>
|
||||||
<input
|
<p class="flex flex-col ml-11">
|
||||||
id="inputChooseFileToImportFrom"
|
<input
|
||||||
ref="inputChooseFileToImportFrom"
|
id="inputChooseFileToImportFrom"
|
||||||
name="inputChooseFileToImportFrom"
|
ref="inputChooseFileToImportFrom"
|
||||||
type="file"
|
name="inputChooseFileToImportFrom"
|
||||||
class="transition cursor-pointer file:transition file:cursor-pointer text-secondaryLight hover:text-secondaryDark file:mr-2 file:py-2 file:px-4 file:rounded file:border-0 file:text-secondary hover:file:text-secondaryDark file:bg-primaryLight hover:file:bg-primaryDark"
|
type="file"
|
||||||
:accept="step.metadata.acceptedFileTypes"
|
class="transition cursor-pointer file:transition file:cursor-pointer text-secondary hover:text-secondaryDark file:mr-2 file:py-2 file:px-4 file:rounded file:border-0 file:text-secondary hover:file:text-secondaryDark file:bg-primaryLight hover:file:bg-primaryDark"
|
||||||
@change="onFileChange"
|
:accept="step.metadata.acceptedFileTypes"
|
||||||
/>
|
@change="onFileChange"
|
||||||
</p>
|
/>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div v-else-if="step.name === 'URL_IMPORT'" class="space-y-4">
|
||||||
|
<p class="flex items-center">
|
||||||
|
<span
|
||||||
|
class="inline-flex items-center justify-center flex-shrink-0 mr-4 rounded-full border-5 border-primary text-secondaryLight"
|
||||||
|
:class="{
|
||||||
|
'text-green-500': hasGist,
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<i class="material-icons">check_circle</i>
|
||||||
|
</span>
|
||||||
|
<span>
|
||||||
|
{{ t("import.gist_description") }}
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
<p class="flex flex-col ml-10">
|
||||||
|
<input
|
||||||
|
v-model="inputChooseGistToImportFrom"
|
||||||
|
type="url"
|
||||||
|
class="input"
|
||||||
|
:placeholder="`${$t('import.gist_url')}`"
|
||||||
|
/>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<ButtonPrimary
|
<ButtonPrimary
|
||||||
:label="t('import.title')"
|
:label="t('import.title')"
|
||||||
class="mt-6"
|
|
||||||
:disabled="enableImportButton"
|
:disabled="enableImportButton"
|
||||||
@click.native="finishImport"
|
@click.native="finishImport"
|
||||||
/>
|
/>
|
||||||
{{ enableImportButton }}
|
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="flex flex-col px-2">
|
<div v-else class="flex flex-col px-2">
|
||||||
<SmartExpand>
|
<SmartExpand>
|
||||||
@@ -81,7 +104,6 @@
|
|||||||
:label="t(`${importer.name}`)"
|
:label="t(`${importer.name}`)"
|
||||||
@click.native="importerType = index"
|
@click.native="importerType = index"
|
||||||
/>
|
/>
|
||||||
---
|
|
||||||
<SmartItem
|
<SmartItem
|
||||||
v-if="collectionsType.type == 'team-collections'"
|
v-if="collectionsType.type == 'team-collections'"
|
||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
@@ -90,16 +112,6 @@
|
|||||||
:label="t('import.from_my_collections')"
|
:label="t('import.from_my_collections')"
|
||||||
@click.native="mode = 'import_from_my_collections'"
|
@click.native="mode = 'import_from_my_collections'"
|
||||||
/>
|
/>
|
||||||
<SmartItem svg="link-2" :label="t('import.from_url')" />
|
|
||||||
<SmartItem
|
|
||||||
svg="github"
|
|
||||||
:label="t('import.from_gist')"
|
|
||||||
@click.native="
|
|
||||||
() => {
|
|
||||||
readCollectionGist()
|
|
||||||
}
|
|
||||||
"
|
|
||||||
/>
|
|
||||||
<hr />
|
<hr />
|
||||||
<SmartItem
|
<SmartItem
|
||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
@@ -191,8 +203,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, ref } from "@nuxtjs/composition-api"
|
import { computed, ref, watch } from "@nuxtjs/composition-api"
|
||||||
// import { HoppRESTRequest, translateToNewRequest } from "@hoppscotch/data"
|
|
||||||
import * as E from "fp-ts/Either"
|
import * as E from "fp-ts/Either"
|
||||||
import { apolloClient } from "~/helpers/apollo"
|
import { apolloClient } from "~/helpers/apollo"
|
||||||
import {
|
import {
|
||||||
@@ -203,14 +214,7 @@ import {
|
|||||||
} from "~/helpers/utils/composables"
|
} from "~/helpers/utils/composables"
|
||||||
import { currentUser$ } from "~/helpers/fb/auth"
|
import { currentUser$ } from "~/helpers/fb/auth"
|
||||||
import * as teamUtils from "~/helpers/teams/utils"
|
import * as teamUtils from "~/helpers/teams/utils"
|
||||||
// import { parseInsomniaCollection } from "~/helpers/utils/parseInsomniaCollection"
|
import { appendRESTCollections, restCollections$ } from "~/newstore/collections"
|
||||||
import {
|
|
||||||
appendRESTCollections,
|
|
||||||
restCollections$,
|
|
||||||
setRESTCollections,
|
|
||||||
// Collection,
|
|
||||||
// makeCollection,
|
|
||||||
} from "~/newstore/collections"
|
|
||||||
import { RESTCollectionImporters } from "~/helpers/import-export/import/importers"
|
import { RESTCollectionImporters } from "~/helpers/import-export/import/importers"
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
@@ -241,7 +245,7 @@ const mode = ref("import_export")
|
|||||||
const mySelectedCollectionID = ref(undefined)
|
const mySelectedCollectionID = ref(undefined)
|
||||||
const collectionJson = ref("")
|
const collectionJson = ref("")
|
||||||
const inputChooseFileToImportFrom = ref<HTMLInputElement | any>()
|
const inputChooseFileToImportFrom = ref<HTMLInputElement | any>()
|
||||||
// const fileName = ref<string>("")
|
const inputChooseGistToImportFrom = ref<string>("")
|
||||||
|
|
||||||
const getJSONCollection = async () => {
|
const getJSONCollection = async () => {
|
||||||
if (props.collectionsType.type === "my-collections") {
|
if (props.collectionsType.type === "my-collections") {
|
||||||
@@ -299,35 +303,6 @@ const failedImport = () => {
|
|||||||
toast.error(t("import.failed").toString())
|
toast.error(t("import.failed").toString())
|
||||||
}
|
}
|
||||||
|
|
||||||
const readCollectionGist = async () => {
|
|
||||||
const gist = prompt(t("import.gist_url").toString())
|
|
||||||
if (!gist) return
|
|
||||||
|
|
||||||
try {
|
|
||||||
const { files } = (await axios.$get(
|
|
||||||
`https://api.github.com/gists/${gist.split("/").pop()}`,
|
|
||||||
{
|
|
||||||
headers: {
|
|
||||||
Accept: "application/vnd.github.v3+json",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
)) as {
|
|
||||||
files: {
|
|
||||||
[fileName: string]: {
|
|
||||||
content: any
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const collections = JSON.parse(Object.values(files)[0].content)
|
|
||||||
setRESTCollections(collections)
|
|
||||||
fileImported()
|
|
||||||
} catch (e) {
|
|
||||||
failedImport()
|
|
||||||
console.error(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const hideModal = () => {
|
const hideModal = () => {
|
||||||
mode.value = "import_export"
|
mode.value = "import_export"
|
||||||
mySelectedCollectionID.value = undefined
|
mySelectedCollectionID.value = undefined
|
||||||
@@ -413,6 +388,18 @@ const importerAction = async (stepResults: any[]) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const hasFile = ref(false)
|
const hasFile = ref(false)
|
||||||
|
const hasGist = ref(false)
|
||||||
|
|
||||||
|
watch(inputChooseGistToImportFrom, (v) => {
|
||||||
|
stepResults.value = []
|
||||||
|
if (v === "") {
|
||||||
|
hasGist.value = false
|
||||||
|
} else {
|
||||||
|
hasGist.value = true
|
||||||
|
stepResults.value.push(inputChooseGistToImportFrom.value)
|
||||||
|
console.log(stepResults.value)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
const onFileChange = () => {
|
const onFileChange = () => {
|
||||||
if (!inputChooseFileToImportFrom.value[0]) return
|
if (!inputChooseFileToImportFrom.value[0]) return
|
||||||
@@ -447,8 +434,11 @@ const enableImportButton = computed(
|
|||||||
)
|
)
|
||||||
|
|
||||||
const resetImport = () => {
|
const resetImport = () => {
|
||||||
stepResults.value = []
|
|
||||||
hasFile.value = false
|
|
||||||
importerType.value = null
|
importerType.value = null
|
||||||
|
stepResults.value = []
|
||||||
|
inputChooseFileToImportFrom.value = ""
|
||||||
|
hasFile.value = false
|
||||||
|
inputChooseGistToImportFrom.value = ""
|
||||||
|
hasGist.value = false
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<SmartModal
|
<SmartModal
|
||||||
v-if="show"
|
v-if="show"
|
||||||
:title="`${t('modal.import_export')} ${t('modal.collections')}`"
|
:title="`${t('modal.collections')}`"
|
||||||
max-width="sm:max-w-md"
|
max-width="sm:max-w-md"
|
||||||
@close="hideModal"
|
@close="hideModal"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<SmartModal
|
<SmartModal
|
||||||
v-if="show"
|
v-if="show"
|
||||||
:title="`${t('modal.import_export')} ${t('environment.title')}`"
|
:title="`${t('environment.title')}`"
|
||||||
max-width="sm:max-w-md"
|
max-width="sm:max-w-md"
|
||||||
@close="hideModal"
|
@close="hideModal"
|
||||||
>
|
>
|
||||||
|
|||||||
41
packages/hoppscotch-app/helpers/import-export/import/gist.ts
Normal file
41
packages/hoppscotch-app/helpers/import-export/import/gist.ts
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
import { pipe } from "fp-ts/function"
|
||||||
|
import * as TE from "fp-ts/TaskEither"
|
||||||
|
import * as E from "fp-ts/Either"
|
||||||
|
import { step } from "../steps"
|
||||||
|
import { defineImporter, IMPORTER_INVALID_FILE_FORMAT } from "."
|
||||||
|
import { translateToNewRESTCollection } from "~/newstore/collections"
|
||||||
|
|
||||||
|
export default defineImporter({
|
||||||
|
name: "import.gist",
|
||||||
|
icon: "github",
|
||||||
|
steps: [
|
||||||
|
step({
|
||||||
|
stepName: "URL_IMPORT",
|
||||||
|
metadata: {
|
||||||
|
placeholder: "import.gist_url",
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
] as const,
|
||||||
|
importer: ([content]) =>
|
||||||
|
pipe(
|
||||||
|
E.tryCatch(
|
||||||
|
async () => {
|
||||||
|
await fetch(
|
||||||
|
`https://api.github.com/gists/${content.split("/").pop()}`,
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
Accept: "application/vnd.github.v3+json",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
).then((files) => {
|
||||||
|
debugger
|
||||||
|
return JSON.parse(Object.values(files)[0].content).map(
|
||||||
|
(coll: any) => translateToNewRESTCollection(coll)
|
||||||
|
)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
() => IMPORTER_INVALID_FILE_FORMAT
|
||||||
|
),
|
||||||
|
TE.fromEither
|
||||||
|
),
|
||||||
|
})
|
||||||
@@ -10,7 +10,7 @@ export default defineImporter({
|
|||||||
icon: "folder-plus",
|
icon: "folder-plus",
|
||||||
steps: [
|
steps: [
|
||||||
step({
|
step({
|
||||||
stepName: "FILE_OR_URL_IMPORT",
|
stepName: "FILE_IMPORT",
|
||||||
metadata: {
|
metadata: {
|
||||||
acceptedFileTypes: "application/json",
|
acceptedFileTypes: "application/json",
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -2,10 +2,12 @@ import HoppRESTCollImporter from "./hopp"
|
|||||||
import OpenAPIImporter from "./openapi"
|
import OpenAPIImporter from "./openapi"
|
||||||
import PostmanImporter from "./postman"
|
import PostmanImporter from "./postman"
|
||||||
import InsomniaImporter from "./insomnia"
|
import InsomniaImporter from "./insomnia"
|
||||||
|
import GistImporter from "./gist"
|
||||||
|
|
||||||
export const RESTCollectionImporters = [
|
export const RESTCollectionImporters = [
|
||||||
HoppRESTCollImporter,
|
HoppRESTCollImporter,
|
||||||
OpenAPIImporter,
|
OpenAPIImporter,
|
||||||
PostmanImporter,
|
PostmanImporter,
|
||||||
InsomniaImporter,
|
InsomniaImporter,
|
||||||
|
GistImporter,
|
||||||
] as const
|
] as const
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ export default defineImporter({
|
|||||||
icon: "insomnia",
|
icon: "insomnia",
|
||||||
steps: [
|
steps: [
|
||||||
step({
|
step({
|
||||||
stepName: "FILE_OR_URL_IMPORT",
|
stepName: "FILE_IMPORT",
|
||||||
metadata: {
|
metadata: {
|
||||||
acceptedFileTypes: ".json",
|
acceptedFileTypes: ".json",
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -589,7 +589,7 @@ export default defineImporter({
|
|||||||
icon: "file",
|
icon: "file",
|
||||||
steps: [
|
steps: [
|
||||||
step({
|
step({
|
||||||
stepName: "FILE_OR_URL_IMPORT",
|
stepName: "FILE_IMPORT",
|
||||||
metadata: {
|
metadata: {
|
||||||
acceptedFileTypes: ".json, .yaml, .yml",
|
acceptedFileTypes: ".json, .yaml, .yml",
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -183,7 +183,7 @@ export default defineImporter({
|
|||||||
icon: "postman",
|
icon: "postman",
|
||||||
steps: [
|
steps: [
|
||||||
step({
|
step({
|
||||||
stepName: "FILE_OR_URL_IMPORT",
|
stepName: "FILE_IMPORT",
|
||||||
metadata: {
|
metadata: {
|
||||||
acceptedFileTypes: ".json",
|
acceptedFileTypes: ".json",
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -3,16 +3,22 @@
|
|||||||
* Add an entry here when you define a step
|
* Add an entry here when you define a step
|
||||||
*/
|
*/
|
||||||
export type StepDefinition = {
|
export type StepDefinition = {
|
||||||
FILE_OR_URL_IMPORT: {
|
FILE_IMPORT: {
|
||||||
returnType: string
|
returnType: string
|
||||||
metadata: {
|
metadata: {
|
||||||
acceptedFileTypes: string
|
acceptedFileTypes: string
|
||||||
}
|
}
|
||||||
} // String content of the file/url
|
} // String content of the file
|
||||||
TARGET_MY_COLLECTION: {
|
TARGET_MY_COLLECTION: {
|
||||||
returnType: number
|
returnType: number
|
||||||
metadata: never
|
metadata: never
|
||||||
} // folderPath
|
} // folderPath
|
||||||
|
URL_IMPORT: {
|
||||||
|
returnType: string
|
||||||
|
metadata: {
|
||||||
|
placeholder: string
|
||||||
|
}
|
||||||
|
} // String content of the url
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -229,7 +229,8 @@
|
|||||||
"collections": "Import collections",
|
"collections": "Import collections",
|
||||||
"curl": "Import cURL",
|
"curl": "Import cURL",
|
||||||
"failed": "Error while importing: format not recognized",
|
"failed": "Error while importing: format not recognized",
|
||||||
"from_gist": "Import from Gist",
|
"gist": "Import from Gist",
|
||||||
|
"gist_description": "Import a Gist",
|
||||||
"from_insomnia": "Import from Insomnia",
|
"from_insomnia": "Import from Insomnia",
|
||||||
"from_my_collections": "Import from My Collections",
|
"from_my_collections": "Import from My Collections",
|
||||||
"from_openapi": "Import from OpenAPI",
|
"from_openapi": "Import from OpenAPI",
|
||||||
|
|||||||
Reference in New Issue
Block a user