123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247 |
- <template>
- <SmartModal
- v-if="show"
- :title="`${$t('modal.import_export')} ${$t('environment.title')}`"
- @close="hideModal"
- >
- <template #actions>
- <span>
- <tippy ref="options" interactive trigger="click" theme="popover" arrow>
- <template #trigger>
- <ButtonSecondary
- v-tippy="{ theme: 'tooltip' }"
- :title="$t('action.more')"
- class="rounded"
- svg="more-vertical"
- />
- </template>
- <SmartItem
- icon="assignment_returned"
- :label="$t('import.from_gist')"
- @click.native="
- readEnvironmentGist
- $refs.options.tippy().hide()
- "
- />
- <span
- v-tippy="{ theme: 'tooltip' }"
- :title="
- !currentUser
- ? $t('export.require_github')
- : currentUser.provider !== 'github.com'
- ? $t('export.require_github')
- : null
- "
- >
- <SmartItem
- :disabled="
- !currentUser
- ? true
- : currentUser.provider !== 'github.com'
- ? true
- : false
- "
- icon="assignment_turned_in"
- :label="$t('export.create_secret_gist')"
- @click.native="
- createEnvironmentGist
- $refs.options.tippy().hide()
- "
- />
- </span>
- </tippy>
- </span>
- </template>
- <template #body>
- <div class="flex flex-col space-y-2">
- <SmartItem
- v-tippy="{ theme: 'tooltip' }"
- :title="$t('action.replace_current')"
- svg="file"
- :label="$t('action.replace_json')"
- @click.native="openDialogChooseFileToReplaceWith"
- />
- <input
- ref="inputChooseFileToReplaceWith"
- class="input"
- type="file"
- accept="application/json"
- @change="replaceWithJSON"
- />
- <SmartItem
- v-tippy="{ theme: 'tooltip' }"
- :title="$t('action.preserve_current')"
- svg="folder-plus"
- :label="$t('import.json')"
- @click.native="openDialogChooseFileToImportFrom"
- />
- <input
- ref="inputChooseFileToImportFrom"
- class="input"
- type="file"
- accept="application/json"
- @change="importFromJSON"
- />
- <SmartItem
- v-tippy="{ theme: 'tooltip' }"
- :title="$t('action.download_file')"
- svg="download"
- :label="$t('export.as_json')"
- @click.native="exportJSON"
- />
- </div>
- </template>
- </SmartModal>
- </template>
- <script>
- import { defineComponent } from "@nuxtjs/composition-api"
- import { currentUser$ } from "~/helpers/fb/auth"
- import { useReadonlyStream } from "~/helpers/utils/composables"
- import {
- environments$,
- replaceEnvironments,
- appendEnvironments,
- } from "~/newstore/environments"
- export default defineComponent({
- props: {
- show: Boolean,
- },
- setup() {
- return {
- environments: useReadonlyStream(environments$, []),
- currentUser: useReadonlyStream(currentUser$, null),
- }
- },
- computed: {
- environmentJson() {
- return JSON.stringify(this.environments, null, 2)
- },
- },
- methods: {
- async createEnvironmentGist() {
- await this.$axios
- .$post(
- "https://api.github.com/gists",
- {
- files: {
- "hoppscotch-environments.json": {
- content: this.environmentJson,
- },
- },
- },
- {
- headers: {
- Authorization: `token ${this.currentUser.accessToken}`,
- Accept: "application/vnd.github.v3+json",
- },
- }
- )
- .then((res) => {
- this.$toast.success(this.$t("export.gist_created"), {
- icon: "done",
- })
- window.open(res.html_url)
- })
- .catch((e) => {
- this.$toast.error(this.$t("error.something_went_wrong"), {
- icon: "error_outline",
- })
- console.error(e)
- })
- },
- async readEnvironmentGist() {
- const gist = prompt(this.$t("import.gist_url"))
- if (!gist) return
- await this.$axios
- .$get(`https://api.github.com/gists/${gist.split("/").pop()}`, {
- headers: {
- Accept: "application/vnd.github.v3+json",
- },
- })
- .then(({ files }) => {
- const environments = JSON.parse(Object.values(files)[0].content)
- replaceEnvironments(environments)
- this.fileImported()
- })
- .catch((e) => {
- this.failedImport()
- console.error(e)
- })
- },
- hideModal() {
- this.$emit("hide-modal")
- },
- openDialogChooseFileToReplaceWith() {
- this.$refs.inputChooseFileToReplaceWith.click()
- },
- openDialogChooseFileToImportFrom() {
- this.$refs.inputChooseFileToImportFrom.click()
- },
- replaceWithJSON() {
- const reader = new FileReader()
- reader.onload = ({ target }) => {
- const content = target.result
- const environments = JSON.parse(content)
- replaceEnvironments(environments)
- }
- reader.readAsText(this.$refs.inputChooseFileToReplaceWith.files[0])
- this.fileImported()
- this.$refs.inputChooseFileToReplaceWith.value = ""
- },
- importFromJSON() {
- const reader = new FileReader()
- reader.onload = ({ target }) => {
- const content = target.result
- const importFileObj = JSON.parse(content)
- if (
- importFileObj._postman_variable_scope === "environment" ||
- importFileObj._postman_variable_scope === "globals"
- ) {
- this.importFromPostman(importFileObj)
- } else {
- this.importFromHoppscotch(importFileObj)
- }
- }
- reader.readAsText(this.$refs.inputChooseFileToImportFrom.files[0])
- this.$refs.inputChooseFileToImportFrom.value = ""
- },
- importFromHoppscotch(environments) {
- appendEnvironments(environments)
- this.fileImported()
- },
- importFromPostman({ name, values }) {
- const environment = { name, variables: [] }
- values.forEach(({ key, value }) =>
- environment.variables.push({ key, value })
- )
- const environments = [environment]
- this.importFromHoppscotch(environments)
- },
- exportJSON() {
- const dataToWrite = this.environmentJson
- const file = new Blob([dataToWrite], { type: "application/json" })
- const a = document.createElement("a")
- const url = URL.createObjectURL(file)
- a.href = url
- // TODO get uri from meta
- a.download = `${url.split("/").pop().split("#")[0].split("?")[0]}`
- document.body.appendChild(a)
- a.click()
- this.$toast.success(this.$t("state.download_started"), {
- icon: "downloading",
- })
- setTimeout(() => {
- document.body.removeChild(a)
- URL.revokeObjectURL(url)
- }, 1000)
- },
- fileImported() {
- this.$toast.success(this.$t("state.file_imported"), {
- icon: "folder_shared",
- })
- },
- },
- })
- </script>
|