chore: update steps ui
This commit is contained in:
@@ -27,35 +27,43 @@
|
|||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
<template #body>
|
<template #body>
|
||||||
<div v-if="importerType > 0" class="flex flex-col px-2">
|
<div v-if="importerType > 0" class="relative flex flex-col px-2">
|
||||||
<div v-for="(step, index) in importerSteps" :key="`step-${index}`">
|
<div
|
||||||
<div
|
class="absolute top-0 w-0.5 bg-primaryDark left-5 -z-1 bottom-1"
|
||||||
v-if="step.name === 'FILE_OR_URL_IMPORT'"
|
></div>
|
||||||
class="flex space-y-4 flex-col"
|
<div
|
||||||
>
|
v-for="(step, index) in importerSteps"
|
||||||
<p>{{ t("import.json_description") }}</p>
|
:key="`step-${index}`"
|
||||||
<label
|
class="flex flex-col space-y-8"
|
||||||
for="inputChooseFileToImportFrom"
|
>
|
||||||
class="cursor-pointer text-secondary hover:text-secondaryDark focus-visible:text-secondaryDark border border-divider hover:border-dividerDark focus-visible:border-dividerDark rounded px-4 font-semibold py-2 transition inline-flex items-center justify-center whitespace-nowrap focus:outline-none"
|
<div v-if="step.name === 'FILE_OR_URL_IMPORT'" class="space-y-4">
|
||||||
>
|
<p class="flex items-center">
|
||||||
<SmartIcon class="svg-icons mr-2" name="upload" />
|
<span
|
||||||
{{ fileName || t("action.choose_file") }}
|
class="inline-flex items-center justify-center flex-shrink-0 mr-4 rounded-full border-5 border-primary text-secondaryLight"
|
||||||
</label>
|
>
|
||||||
<input
|
<i class="material-icons">check_circle</i>
|
||||||
id="inputChooseFileToImportFrom"
|
</span>
|
||||||
ref="inputChooseFileToImportFrom"
|
<span>
|
||||||
name="inputChooseFileToImportFrom"
|
{{ t("import.json_description") }}
|
||||||
class="input"
|
</span>
|
||||||
type="file"
|
</p>
|
||||||
:accept="step.metadata.acceptedFileTypes"
|
<p class="flex flex-col ml-12">
|
||||||
@change="importFromJSON"
|
<input
|
||||||
/>
|
id="inputChooseFileToImportFrom"
|
||||||
<ButtonPrimary
|
ref="inputChooseFileToImportFrom"
|
||||||
:label="t('import.title')"
|
name="inputChooseFileToImportFrom"
|
||||||
@click.native="finishImport"
|
type="file"
|
||||||
/>
|
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"
|
||||||
|
:accept="step.metadata.acceptedFileTypes"
|
||||||
|
/>
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<ButtonPrimary
|
||||||
|
:label="t('import.title')"
|
||||||
|
class="mt-6"
|
||||||
|
@click.native="finishImport"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="flex flex-col px-2">
|
<div v-else class="flex flex-col px-2">
|
||||||
<SmartExpand>
|
<SmartExpand>
|
||||||
@@ -178,7 +186,7 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref } from "@nuxtjs/composition-api"
|
import { ref } from "@nuxtjs/composition-api"
|
||||||
import { HoppRESTRequest, translateToNewRequest } from "@hoppscotch/data"
|
// 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 {
|
||||||
@@ -189,13 +197,13 @@ 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 { parseInsomniaCollection } from "~/helpers/utils/parseInsomniaCollection"
|
||||||
import {
|
import {
|
||||||
appendRESTCollections,
|
appendRESTCollections,
|
||||||
restCollections$,
|
restCollections$,
|
||||||
setRESTCollections,
|
setRESTCollections,
|
||||||
Collection,
|
// Collection,
|
||||||
makeCollection,
|
// makeCollection,
|
||||||
} from "~/newstore/collections"
|
} from "~/newstore/collections"
|
||||||
import { RESTCollectionImporters } from "~/helpers/import-export/import/importers"
|
import { RESTCollectionImporters } from "~/helpers/import-export/import/importers"
|
||||||
|
|
||||||
@@ -227,7 +235,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 fileName = ref<string>("")
|
||||||
|
|
||||||
const getJSONCollection = async () => {
|
const getJSONCollection = async () => {
|
||||||
if (props.collectionsType.type === "my-collections") {
|
if (props.collectionsType.type === "my-collections") {
|
||||||
@@ -322,253 +330,6 @@ const hideModal = () => {
|
|||||||
|
|
||||||
const stepsValue = ref<string[]>([])
|
const stepsValue = ref<string[]>([])
|
||||||
|
|
||||||
const hasFolder = (item: { item?: any }) => {
|
|
||||||
return Object.prototype.hasOwnProperty.call(item, "item")
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: I don't even know what is going on here :/
|
|
||||||
type PostmanCollection = {
|
|
||||||
info?: {
|
|
||||||
name: string
|
|
||||||
}
|
|
||||||
name: string
|
|
||||||
item: {
|
|
||||||
name: string
|
|
||||||
request: any
|
|
||||||
item?: any
|
|
||||||
}[]
|
|
||||||
folders?: any
|
|
||||||
}
|
|
||||||
|
|
||||||
const parsePostmanCollection = ({ info, name, item }: PostmanCollection) => {
|
|
||||||
const hoppscotchCollection: Collection<HoppRESTRequest> = makeCollection({
|
|
||||||
name: "",
|
|
||||||
folders: [],
|
|
||||||
requests: [],
|
|
||||||
})
|
|
||||||
|
|
||||||
hoppscotchCollection.name = info ? info.name : name
|
|
||||||
|
|
||||||
if (item && item.length > 0) {
|
|
||||||
for (const collectionItem of item) {
|
|
||||||
if (collectionItem.request) {
|
|
||||||
if (
|
|
||||||
Object.prototype.hasOwnProperty.call(hoppscotchCollection, "folders")
|
|
||||||
) {
|
|
||||||
hoppscotchCollection.name = info ? info.name : name
|
|
||||||
hoppscotchCollection.requests.push(
|
|
||||||
parsePostmanRequest(collectionItem)
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
hoppscotchCollection.name = name || ""
|
|
||||||
hoppscotchCollection.requests.push(
|
|
||||||
parsePostmanRequest(collectionItem)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
} else if (hasFolder(collectionItem)) {
|
|
||||||
hoppscotchCollection.folders.push(
|
|
||||||
parsePostmanCollection(collectionItem as any)
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
hoppscotchCollection.requests.push(parsePostmanRequest(collectionItem))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return hoppscotchCollection
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Rewrite
|
|
||||||
const parsePostmanRequest = ({
|
|
||||||
name,
|
|
||||||
request,
|
|
||||||
}: {
|
|
||||||
name: string
|
|
||||||
request: any
|
|
||||||
}) => {
|
|
||||||
const pwRequest = {
|
|
||||||
url: "",
|
|
||||||
path: "",
|
|
||||||
method: "",
|
|
||||||
auth: "",
|
|
||||||
httpUser: "",
|
|
||||||
httpPassword: "",
|
|
||||||
passwordFieldType: "password",
|
|
||||||
bearerToken: "",
|
|
||||||
headers: [] as { name?: string; type?: string }[],
|
|
||||||
params: [] as { disabled?: boolean }[],
|
|
||||||
bodyParams: [] as { type?: string }[],
|
|
||||||
body: {
|
|
||||||
body: "",
|
|
||||||
contentType: "application/json",
|
|
||||||
},
|
|
||||||
rawParams: "",
|
|
||||||
rawInput: false,
|
|
||||||
contentType: "",
|
|
||||||
requestType: "",
|
|
||||||
name: "",
|
|
||||||
}
|
|
||||||
|
|
||||||
pwRequest.name = name
|
|
||||||
if (request.url) {
|
|
||||||
const requestObjectUrl = request.url.raw.match(
|
|
||||||
/^(.+:\/\/[^/]+|{[^/]+})(\/[^?]+|).*$/
|
|
||||||
)
|
|
||||||
if (requestObjectUrl) {
|
|
||||||
pwRequest.url = requestObjectUrl[1]
|
|
||||||
pwRequest.path = requestObjectUrl[2] ? requestObjectUrl[2] : ""
|
|
||||||
} else {
|
|
||||||
pwRequest.url = request.url.raw
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pwRequest.method = request.method
|
|
||||||
const itemAuth = request.auth ? request.auth : ""
|
|
||||||
const authType = itemAuth ? itemAuth.type : ""
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (authType === "basic") {
|
|
||||||
pwRequest.auth = "Basic Auth"
|
|
||||||
pwRequest.httpUser =
|
|
||||||
itemAuth.basic[0].key === "username"
|
|
||||||
? itemAuth.basic[0].value
|
|
||||||
: itemAuth.basic[1].value
|
|
||||||
pwRequest.httpPassword =
|
|
||||||
itemAuth.basic[0].key === "password"
|
|
||||||
? itemAuth.basic[0].value
|
|
||||||
: itemAuth.basic[1].value
|
|
||||||
} else if (authType === "oauth2") {
|
|
||||||
pwRequest.auth = "OAuth 2.0"
|
|
||||||
pwRequest.bearerToken =
|
|
||||||
itemAuth.oauth2[0].key === "accessToken"
|
|
||||||
? itemAuth.oauth2[0].value
|
|
||||||
: itemAuth.oauth2[1].value
|
|
||||||
} else if (authType === "bearer") {
|
|
||||||
pwRequest.auth = "Bearer Token"
|
|
||||||
pwRequest.bearerToken = itemAuth.bearer[0].value
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error(error)
|
|
||||||
}
|
|
||||||
|
|
||||||
const requestObjectHeaders = request.header
|
|
||||||
if (requestObjectHeaders) {
|
|
||||||
pwRequest.headers = requestObjectHeaders
|
|
||||||
for (const header of pwRequest.headers) {
|
|
||||||
delete header.name
|
|
||||||
delete header.type
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (request.url) {
|
|
||||||
const requestObjectParams = request.url.query
|
|
||||||
if (requestObjectParams) {
|
|
||||||
pwRequest.params = requestObjectParams
|
|
||||||
for (const param of pwRequest.params) {
|
|
||||||
delete param.disabled
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (request.body) {
|
|
||||||
if (request.body.mode === "urlencoded") {
|
|
||||||
const params = request.body.urlencoded
|
|
||||||
pwRequest.bodyParams = params || []
|
|
||||||
for (const param of pwRequest.bodyParams) {
|
|
||||||
delete param.type
|
|
||||||
}
|
|
||||||
} else if (request.body.mode === "raw") {
|
|
||||||
pwRequest.rawInput = true
|
|
||||||
pwRequest.rawParams = request.body.raw
|
|
||||||
try {
|
|
||||||
const body = JSON.parse(request.body.raw)
|
|
||||||
pwRequest.body.body = JSON.stringify(body, null, 2)
|
|
||||||
} catch (error) {
|
|
||||||
console.error(error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return translateToNewRequest(pwRequest)
|
|
||||||
}
|
|
||||||
|
|
||||||
const isInsomniaCollection = (collection: any) => {
|
|
||||||
if (typeof collection === "object") {
|
|
||||||
return (
|
|
||||||
Object.prototype.hasOwnProperty.call(collection, "__export_source") &&
|
|
||||||
collection.__export_source.includes("insomnia")
|
|
||||||
)
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
const importFromJSON = () => {
|
|
||||||
if (!inputChooseFileToImportFrom.value[0]) return
|
|
||||||
|
|
||||||
if (
|
|
||||||
!inputChooseFileToImportFrom.value[0].files ||
|
|
||||||
inputChooseFileToImportFrom.value[0].files.length === 0
|
|
||||||
) {
|
|
||||||
inputChooseFileToImportFrom.value[0].value = ""
|
|
||||||
toast.show(t("action.choose_file").toString())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
fileName.value = inputChooseFileToImportFrom.value[0].files[0].name
|
|
||||||
|
|
||||||
const reader = new FileReader()
|
|
||||||
|
|
||||||
reader.onload = ({ target }) => {
|
|
||||||
let content = target!.result as string | null
|
|
||||||
|
|
||||||
if (!content) {
|
|
||||||
toast.show(t("action.choose_file").toString())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
let collections = JSON.parse(content)
|
|
||||||
stepsValue.value.push(content)
|
|
||||||
|
|
||||||
if (isInsomniaCollection(collections)) {
|
|
||||||
collections = parseInsomniaCollection(content)
|
|
||||||
content = JSON.stringify(collections)
|
|
||||||
}
|
|
||||||
if (collections[0]) {
|
|
||||||
const [name, folders, requests] = Object.keys(collections[0])
|
|
||||||
if (name === "name" && folders === "folders" && requests === "requests") {
|
|
||||||
// Do nothing
|
|
||||||
}
|
|
||||||
} else if (collections.info && collections.info.schema.includes("v2.1.0")) {
|
|
||||||
// replace the variables, postman uses {{var}}, Hoppscotch uses <<var>>
|
|
||||||
collections = JSON.parse(content.replaceAll(/{{([a-z]+)}}/gi, "<<$1>>"))
|
|
||||||
collections = [parsePostmanCollection(collections)]
|
|
||||||
} else {
|
|
||||||
failedImport()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (props.collectionsType.type === "team-collections") {
|
|
||||||
teamUtils
|
|
||||||
.importFromJSON(
|
|
||||||
apolloClient,
|
|
||||||
collections,
|
|
||||||
props.collectionsType.selectedTeam.id
|
|
||||||
)
|
|
||||||
.then((status) => {
|
|
||||||
if (status) {
|
|
||||||
emit("update-team-collections")
|
|
||||||
fileImported()
|
|
||||||
} else {
|
|
||||||
failedImport()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch((e) => {
|
|
||||||
console.error(e)
|
|
||||||
failedImport()
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
fileImported()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
reader.readAsText(inputChooseFileToImportFrom.value[0].files[0])
|
|
||||||
inputChooseFileToImportFrom.value[0].value = ""
|
|
||||||
}
|
|
||||||
|
|
||||||
const importFromMyCollections = () => {
|
const importFromMyCollections = () => {
|
||||||
if (props.collectionsType.type !== "team-collections") return
|
if (props.collectionsType.type !== "team-collections") return
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user