feat: ui for new importer

This commit is contained in:
liyasthomas
2022-01-14 20:40:54 +05:30
parent 67934fd19a
commit e323b4355e
12 changed files with 116 additions and 50 deletions

View File

@@ -33,7 +33,7 @@
<i class="material-icons">check_circle</i>
</span>
<span>
{{ t("import.json_description") }}
{{ t(`${step.metadata.caption}`) }}
</span>
</p>
<p class="flex flex-col ml-10">
@@ -59,7 +59,7 @@
<i class="material-icons">check_circle</i>
</span>
<span>
{{ t("import.gist_description") }}
{{ t(`${step.metadata.caption}`) }}
</span>
</p>
<p class="flex flex-col ml-10">
@@ -77,23 +77,13 @@
>
<div class="select-wrapper">
<select
v-model="mySelectedCollectionID"
type="text"
autocomplete="off"
class="select"
autofocus
@change="
($event) => {
mySelectedCollectionID = $event.target.value
}
"
>
<option
:key="undefined"
:value="undefined"
hidden
disabled
selected
>
<option :key="undefined" :value="undefined" disabled selected>
{{ t("collection.select") }}
</option>
<option
@@ -112,6 +102,7 @@
:label="t('import.title')"
:disabled="enableImportButton"
class="mx-2"
:loading="importingMyCollections"
@click.native="finishImport"
/>
</div>
@@ -119,7 +110,7 @@
<SmartExpand>
<template #body>
<SmartItem
v-for="(importer, index) in RESTCollectionImporters"
v-for="(importer, index) in importerModules"
:key="`importer-${index}`"
:svg="importer.icon"
:label="t(`${importer.name}`)"
@@ -182,8 +173,14 @@ import {
} from "~/helpers/utils/composables"
import { currentUser$ } from "~/helpers/fb/auth"
import * as teamUtils from "~/helpers/teams/utils"
import { appendRESTCollections, restCollections$ } from "~/newstore/collections"
import {
appendRESTCollections,
Collection,
restCollections$,
} from "~/newstore/collections"
import { RESTCollectionImporters } from "~/helpers/import-export/import/importers"
import { HoppRESTRequest } from "~/../hoppscotch-data/dist"
import { StepReturnValue } from "~/helpers/import-export/steps"
const props = defineProps<{
show: boolean
@@ -210,7 +207,7 @@ const currentUser = useReadonlyStream(currentUser$, null)
// Template refs
const mode = ref("import_export")
const mySelectedCollectionID = ref(undefined)
const mySelectedCollectionID = ref<undefined | number>(undefined)
const collectionJson = ref("")
const inputChooseFileToImportFrom = ref<HTMLInputElement | any>()
const inputChooseGistToImportFrom = ref<string>("")
@@ -278,30 +275,39 @@ const hideModal = () => {
emit("hide-modal")
}
const stepResults = ref<string[]>([])
const stepResults = ref<StepReturnValue[]>([])
// const importFromMyCollections = () => {
// if (props.collectionsType.type !== "team-collections") return
watch(mySelectedCollectionID, (newValue) => {
if (newValue === undefined) return
stepResults.value = []
stepResults.value.push(newValue)
})
// teamUtils
// .importFromMyCollections(
// apolloClient,
// mySelectedCollectionID.value,
// props.collectionsType.selectedTeam.id
// )
// .then((success) => {
// if (success) {
// fileImported()
// emit("update-team-collections")
// } else {
// failedImport()
// }
// })
// .catch((e) => {
// console.error(e)
// failedImport()
// })
// }
const importingMyCollections = ref(false)
const importToTeams = async (content: Collection<HoppRESTRequest>) => {
importingMyCollections.value = true
if (props.collectionsType.type !== "team-collections") return
await teamUtils
.importFromJSON(
apolloClient,
content,
props.collectionsType.selectedTeam.id
)
.then((status) => {
if (status) {
emit("update-team-collections")
} else {
console.error(status)
}
})
.catch((e) => {
console.error(e)
})
.finally(() => {
importingMyCollections.value = false
})
}
const exportJSON = () => {
getJSONCollection()
@@ -323,13 +329,18 @@ const exportJSON = () => {
}, 1000)
}
const importerModules = computed(() =>
RESTCollectionImporters.filter(
(i) => i.applicableTo?.includes(props.collectionsType.type) ?? true
)
)
const importerType = ref<number | null>(null)
const importerModule = computed(() =>
importerType.value !== null
? RESTCollectionImporters[importerType.value]
: null
importerType.value !== null ? importerModules.value[importerType.value] : null
)
const importerSteps = computed(() => importerModule.value?.steps ?? null)
const finishImport = async () => {
@@ -343,8 +354,13 @@ const importerAction = async (stepResults: any[]) => {
failedImport()
console.error("error", result.left)
} else if (E.isRight(result)) {
appendRESTCollections(result.right)
fileImported()
if (props.collectionsType.type === "team-collections") {
importToTeams(result.right)
fileImported()
} else {
appendRESTCollections(result.right)
fileImported()
}
}
}
@@ -362,6 +378,7 @@ watch(inputChooseGistToImportFrom, (v) => {
})
const onFileChange = () => {
stepResults.value = []
if (!inputChooseFileToImportFrom.value[0]) {
hasFile.value = false
return

View File

@@ -29,12 +29,13 @@ const fetchGist = (url: string): TO.TaskOption<Collection<HoppRESTRequest>> =>
)
export default defineImporter({
name: "import.gist",
name: "import.from_gist",
icon: "github",
steps: [
step({
stepName: "URL_IMPORT",
metadata: {
caption: "import.from_gist_description",
placeholder: "import.gist_url",
},
}),

View File

@@ -6,12 +6,13 @@ import { defineImporter, IMPORTER_INVALID_FILE_FORMAT } from "."
import { translateToNewRESTCollection } from "~/newstore/collections"
export default defineImporter({
name: "import.json",
name: "import.from_json",
icon: "folder-plus",
steps: [
step({
stepName: "FILE_IMPORT",
metadata: {
caption: "import.from_json_description",
acceptedFileTypes: "application/json",
},
}),

View File

@@ -3,6 +3,7 @@ import OpenAPIImporter from "./openapi"
import PostmanImporter from "./postman"
import InsomniaImporter from "./insomnia"
import GistImporter from "./gist"
import MyCollectionsImporter from "./myCollections"
export const RESTCollectionImporters = [
HoppRESTCollImporter,
@@ -10,4 +11,5 @@ export const RESTCollectionImporters = [
PostmanImporter,
InsomniaImporter,
GistImporter,
MyCollectionsImporter,
] as const

View File

@@ -27,6 +27,11 @@ type HoppImporterDefintion<T, Y, E> = {
*/
icon: string
/**
* Identifier for the importer
*/
applicableTo?: Array<"team-collections" | "my-collections">
/**
* The importer function, It is a Promise because its supposed to be loaded in lazily (dynamic imports ?)
*/
@@ -45,6 +50,7 @@ export const defineImporter = <ReturnType, StepType, Errors>(input: {
name: string
icon: string
importer: HoppImporter<ReturnType, StepType, Errors>
applicableTo?: Array<"team-collections" | "my-collections">
steps: StepType
}) => {
return <HoppImporterDefintion<ReturnType, StepType, Errors>>{

View File

@@ -215,6 +215,7 @@ export default defineImporter({
step({
stepName: "FILE_IMPORT",
metadata: {
caption: "import.from_insomnia_description",
acceptedFileTypes: ".json, .yaml",
},
}),

View File

@@ -0,0 +1,21 @@
import * as TE from "fp-ts/TaskEither"
import * as A from "fp-ts/Array"
import { pipe } from "fp-ts/function"
import { step } from "../steps"
import { defineImporter } from "."
import { getRESTCollection } from "~/newstore/collections"
export default defineImporter({
name: "import.from_my_collections",
icon: "user",
applicableTo: ["team-collections"],
steps: [
step({
stepName: "TARGET_MY_COLLECTION",
metadata: {
caption: "import.from_my_collections_description",
},
}),
] as const,
importer: ([content]) => pipe(content, getRESTCollection, A.of, TE.of),
})

View File

@@ -591,6 +591,7 @@ export default defineImporter({
step({
stepName: "FILE_IMPORT",
metadata: {
caption: "import.from_openapi_description",
acceptedFileTypes: ".json, .yaml, .yml",
},
}),

View File

@@ -236,6 +236,7 @@ export default defineImporter({
step({
stepName: "FILE_IMPORT",
metadata: {
caption: "import.from_postman_description",
acceptedFileTypes: ".json",
},
}),

View File

@@ -6,21 +6,27 @@ export type StepDefinition = {
FILE_IMPORT: {
returnType: string
metadata: {
caption: string
acceptedFileTypes: string
}
} // String content of the file
TARGET_MY_COLLECTION: {
returnType: number
metadata: never
metadata: {
caption: string
}
} // folderPath
URL_IMPORT: {
returnType: string
metadata: {
caption: string
placeholder: string
}
} // String content of the url
}
export type StepReturnValue = StepDefinition[keyof StepDefinition]["returnType"]
/**
* Defines what the data structure of a step
*/

View File

@@ -229,15 +229,20 @@
"collections": "Import collections",
"curl": "Import cURL",
"failed": "Error while importing: format not recognized",
"gist": "Import from Gist",
"gist_description": "Import a Gist",
"from_gist": "Import from Gist",
"from_gist_description": "Import from Gist URL",
"from_insomnia": "Import from Insomnia",
"from_insomnia_description": "Import from Insomnia collection",
"from_my_collections": "Import from My Collections",
"from_my_collections_description": "Import from My Collections file",
"from_openapi": "Import from OpenAPI",
"from_openapi_description": "Import from OpenAPI specification file (YML/JSON)",
"from_postman": "Import from Postman",
"from_postman_description": "Import from Postman collection",
"from_url": "Import from URL",
"from_json": "Import from Hoppscotch",
"from_json_description": "Import from Hoppscotch collection file",
"gist_url": "Enter Gist URL",
"json": "Import from file",
"json_description": "Import collections from a Hoppscotch Collections JSON file",
"title": "Import"
},

View File

@@ -694,6 +694,10 @@ export function removeRESTCollection(collectionIndex: number) {
})
}
export function getRESTCollection(collectionIndex: number) {
return restCollectionStore.value.state[collectionIndex]
}
export function editRESTCollection(
collectionIndex: number,
collection: Collection<HoppRESTRequest>