Merge branch 'refactor/code'

This commit is contained in:
liyasthomas
2021-06-29 17:07:46 +05:30
13 changed files with 99 additions and 726 deletions

View File

@@ -57,7 +57,6 @@
</template>
<script>
import { getSettingSubject } from "~/newstore/settings"
import * as teamUtils from "~/helpers/teams/utils"
import {
saveRESTRequestAs,
@@ -90,52 +89,6 @@ export default {
picked: null,
}
},
subscriptions() {
return {
SYNC_COLLECTIONS: getSettingSubject("syncCollections"),
}
},
computed: {
folders() {
const collections = this.$store.state.postwoman.collections
const collectionIndex = this.$data.requestData.collectionIndex
const userSelectedAnyCollection = collectionIndex !== undefined
if (!userSelectedAnyCollection) return []
const noCollectionAvailable = collections[collectionIndex] !== undefined
if (!noCollectionAvailable) return []
return getFolderNames(collections[collectionIndex].folders, [])
},
requests() {
const collections = this.$store.state.postwoman.collections
const collectionIndex = this.$data.requestData.collectionIndex
const folderName = this.$data.requestData.folderName
const userSelectedAnyCollection = collectionIndex !== undefined
if (!userSelectedAnyCollection) {
return []
}
const userSelectedAnyFolder =
folderName !== undefined && folderName !== ""
if (userSelectedAnyFolder) {
const collection = collections[collectionIndex]
const folder = findFolder(folderName, collection)
return folder.requests
} else {
const collection = collections[collectionIndex]
const noCollectionAvailable = collection !== undefined
if (!noCollectionAvailable) {
return []
}
return collection.requests
}
},
},
watch: {
"requestData.collectionIndex": function resetFolderAndRequestIndex() {
// if user has chosen some folder, than selected other collection, which doesn't have any folders
@@ -238,36 +191,4 @@ export default {
},
},
}
function getFolderNames(folders, namesList, folderName = "") {
if (folders.length) {
folders.forEach((folder) => {
namesList.push(folderName + folder.name)
if (folder.folders && folder.folders.length) {
getFolderNames(folder.folders, namesList, folder.name + "/")
}
})
}
return namesList
}
function findFolder(folderName, currentFolder) {
let selectedFolder
let result
if (folderName === currentFolder.name) {
return currentFolder
}
for (let i = 0; i < currentFolder.folders.length; i++) {
selectedFolder = currentFolder.folders[i]
result = findFolder(folderName, selectedFolder)
if (result !== false) {
return result
}
}
return false
}
</script>

View File

@@ -28,7 +28,7 @@
class="icon button"
@click="clearContent($event)"
>
<i class="material-icons">clear_all</i>
<i class="material-icons">{{ clearIcon }}</i>
</button>
</div>
</div>
@@ -118,7 +118,7 @@ export default Vue.extend({
return {
name: null as string | null,
vars: [] as { key: string; value: string }[],
doneButton: '<i class="material-icons">done</i>',
clearIcon: "clear_all",
}
},
watch: {
@@ -132,17 +132,13 @@ export default Vue.extend({
},
},
methods: {
clearContent({ target }: { target: HTMLElement }) {
clearContent() {
this.vars = []
target.innerHTML = this.doneButton
this.clearIcon = "done"
this.$toast.info(this.$t("cleared").toString(), {
icon: "clear_all",
})
setTimeout(
() => (target.innerHTML = '<i class="material-icons">clear_all</i>'),
1000
)
setTimeout(() => (this.clearIcon = "clear_all"), 1000)
},
addEnvironmentVariable() {
this.vars.push({

View File

@@ -48,7 +48,7 @@
class="icon button"
@click="copyRequestCode"
>
<i class="material-icons">content_copy</i>
<i class="material-icons">{{ copyIcon }}</i>
</button>
</div>
</div>
@@ -84,8 +84,7 @@ export default {
data() {
return {
codegens,
copyButton: '<i class="material-icons">content_copy</i>',
doneButton: '<i class="material-icons">done</i>',
copyIcon: "content_copy",
}
},
computed: {
@@ -106,17 +105,14 @@ export default {
this.$emit("handle-import")
},
copyRequestCode() {
this.$refs.copyRequestCode.innerHTML = this.doneButton
this.$toast.success(this.$t("copied_to_clipboard"), {
icon: "done",
})
this.$refs.generatedCode.editor.selectAll()
this.$refs.generatedCode.editor.focus()
document.execCommand("copy")
setTimeout(
() => (this.$refs.copyRequestCode.innerHTML = this.copyButton),
1000
)
this.copyIcon = "done"
this.$toast.success(this.$t("copied_to_clipboard"), {
icon: "done",
})
setTimeout(() => (this.copyIcon = "content_copy"), 1000)
},
},
}

View File

@@ -12,7 +12,7 @@
class="icon button"
@click="prettifyRequestBody"
>
<i class="material-icons">photo_filter</i>
<i class="material-icons">{{ prettifyIcon }}</i>
</button>
<label for="payload" class="p-0">
<button
@@ -69,7 +69,7 @@ export default {
},
data() {
return {
doneButton: '<i class="material-icons">done</i>',
prettifyIcon: "photo_filter",
}
},
computed: {
@@ -112,9 +112,8 @@ export default {
try {
const jsonObj = JSON.parse(this.rawParamsBody)
this.rawParamsBody = JSON.stringify(jsonObj, null, 2)
const oldIcon = this.$refs.prettifyRequest.innerHTML
this.$refs.prettifyRequest.innerHTML = this.doneButton
setTimeout(() => (this.$refs.prettifyRequest.innerHTML = oldIcon), 1000)
this.prettifyIcon = "done"
setTimeout(() => (this.prettifyIcon = "photo_filter"), 1000)
} catch (e) {
this.$toast.error(`${this.$t("json_prettify_invalid_body")}`, {
icon: "error",

View File

@@ -37,7 +37,7 @@
class="icon button"
@click="downloadResponse"
>
<i class="material-icons">save_alt</i>
<i class="material-icons">{{ downloadIcon }}</i>
</button>
<button
v-if="response.body"
@@ -46,7 +46,7 @@
class="icon button"
@click="copyResponse"
>
<i class="material-icons">content_copy</i>
<i class="material-icons">{{ copyIcon }}</i>
</button>
</div>
</div>
@@ -87,9 +87,8 @@ export default {
return {
expandResponse: false,
responseBodyMaxLines: 16,
doneButton: '<i class="material-icons">done</i>',
downloadButton: '<i class="material-icons">save_alt</i>',
copyButton: '<i class="material-icons">content_copy</i>',
downloadIcon: "save_alt",
copyIcon: "content_copy",
previewEnabled: false,
}
},
@@ -109,21 +108,17 @@ export default {
a.download = `${url.split("/").pop().split("#")[0].split("?")[0]}`
document.body.appendChild(a)
a.click()
this.$refs.downloadResponse.innerHTML = this.doneButton
this.downloadIcon = "done"
this.$toast.success(this.$t("download_started"), {
icon: "done",
})
setTimeout(() => {
document.body.removeChild(a)
window.URL.revokeObjectURL(url)
this.$refs.downloadResponse.innerHTML = this.downloadButton
this.downloadIcon = "save_alt"
}, 1000)
},
copyResponse() {
this.$refs.copyResponse.innerHTML = this.doneButton
this.$toast.success(this.$t("copied_to_clipboard"), {
icon: "done",
})
const aux = document.createElement("textarea")
const copy = this.responseBodyText
aux.innerText = copy
@@ -131,10 +126,11 @@ export default {
aux.select()
document.execCommand("copy")
document.body.removeChild(aux)
setTimeout(
() => (this.$refs.copyResponse.innerHTML = this.copyButton),
1000
)
this.copyIcon = "done"
this.$toast.success(this.$t("copied_to_clipboard"), {
icon: "done",
})
setTimeout(() => (this.copyIcon = "content_copy"), 1000)
},
togglePreview() {
this.previewEnabled = !this.previewEnabled

View File

@@ -10,7 +10,7 @@
class="icon button"
@click="downloadResponse"
>
<i class="material-icons">save_alt</i>
<i class="material-icons">{{ downloadIcon }}</i>
</button>
</div>
</div>
@@ -28,8 +28,7 @@ export default {
data() {
return {
imageSource: "",
doneButton: '<i class="material-icons">done</i>',
downloadButton: '<i class="material-icons">save_alt</i>',
downloadIcon: "save_alt",
}
},
computed: {
@@ -81,14 +80,14 @@ export default {
a.download = `${url.split("/").pop().split("#")[0].split("?")[0]}`
document.body.appendChild(a)
a.click()
this.$refs.downloadResponse.innerHTML = this.doneButton
this.downloadIcon = "done"
this.$toast.success(this.$t("download_started"), {
icon: "done",
})
setTimeout(() => {
document.body.removeChild(a)
window.URL.revokeObjectURL(url)
this.$refs.downloadResponse.innerHTML = this.downloadButton
this.downloadIcon = "save_alt"
}, 1000)
},
},

View File

@@ -25,7 +25,7 @@
class="icon button"
@click="downloadResponse"
>
<i class="material-icons">save_alt</i>
<i class="material-icons">{{ downloadIcon }}</i>
</button>
<button
v-if="response.body"
@@ -34,7 +34,7 @@
class="icon button"
@click="copyResponse"
>
<i class="material-icons">content_copy</i>
<i class="material-icons">{{ copyIcon }}</i>
</button>
</div>
</div>
@@ -71,9 +71,8 @@ export default {
return {
expandResponse: false,
responseBodyMaxLines: 16,
doneButton: '<i class="material-icons">done</i>',
downloadButton: '<i class="material-icons">save_alt</i>',
copyButton: '<i class="material-icons">content_copy</i>',
downloadIcon: "save_alt",
copyIcon: "content_copy",
}
},
computed: {
@@ -115,21 +114,17 @@ export default {
a.download = `${url.split("/").pop().split("#")[0].split("?")[0]}`
document.body.appendChild(a)
a.click()
this.$refs.downloadResponse.innerHTML = this.doneButton
this.downloadIcon = "done"
this.$toast.success(this.$t("download_started"), {
icon: "done",
})
setTimeout(() => {
document.body.removeChild(a)
window.URL.revokeObjectURL(url)
this.$refs.downloadResponse.innerHTML = this.downloadButton
this.downloadIcon = "save_alt"
}, 1000)
},
copyResponse() {
this.$refs.copyResponse.innerHTML = this.doneButton
this.$toast.success(this.$t("copied_to_clipboard"), {
icon: "done",
})
const aux = document.createElement("textarea")
const copy = this.responseBodyText
aux.innerText = copy
@@ -137,10 +132,11 @@ export default {
aux.select()
document.execCommand("copy")
document.body.removeChild(aux)
setTimeout(
() => (this.$refs.copyResponse.innerHTML = this.copyButton),
1000
)
this.copyIcon = "done"
this.$toast.success(this.$t("copied_to_clipboard"), {
icon: "done",
})
setTimeout(() => (this.copyIcon = "content_copy"), 1000)
},
},
}

View File

@@ -25,7 +25,7 @@
class="icon button"
@click="downloadResponse"
>
<i class="material-icons">save_alt</i>
<i class="material-icons">{{ downloadIcon }}</i>
</button>
<button
v-if="response.body"
@@ -34,7 +34,7 @@
class="icon button"
@click="copyResponse"
>
<i class="material-icons">content_copy</i>
<i class="material-icons">{{ copyIcon }}</i>
</button>
</div>
</div>
@@ -70,9 +70,8 @@ export default {
return {
expandResponse: false,
responseBodyMaxLines: 16,
doneButton: '<i class="material-icons">done</i>',
downloadButton: '<i class="material-icons">save_alt</i>',
copyButton: '<i class="material-icons">content_copy</i>',
downloadIcon: "save_alt",
copyIcon: "content_copy",
}
},
computed: {
@@ -106,21 +105,17 @@ export default {
a.download = `${url.split("/").pop().split("#")[0].split("?")[0]}`
document.body.appendChild(a)
a.click()
this.$refs.downloadResponse.innerHTML = this.doneButton
this.downloadIcon = "done"
this.$toast.success(this.$t("download_started"), {
icon: "done",
})
setTimeout(() => {
document.body.removeChild(a)
window.URL.revokeObjectURL(url)
this.$refs.downloadResponse.innerHTML = this.downloadButton
this.downloadIcon = "save_alt"
}, 1000)
},
copyResponse() {
this.$refs.copyResponse.innerHTML = this.doneButton
this.$toast.success(this.$t("copied_to_clipboard"), {
icon: "done",
})
const aux = document.createElement("textarea")
const copy = this.responseBodyText
aux.innerText = copy
@@ -128,10 +123,11 @@ export default {
aux.select()
document.execCommand("copy")
document.body.removeChild(aux)
setTimeout(
() => (this.$refs.copyResponse.innerHTML = this.copyButton),
1000
)
this.copyIcon = "done"
this.$toast.success(this.$t("copied_to_clipboard"), {
icon: "done",
})
setTimeout(() => (this.copyIcon = "content_copy"), 1000)
},
},
}

View File

@@ -25,7 +25,7 @@
class="icon button"
@click="downloadResponse"
>
<i class="material-icons">save_alt</i>
<i class="material-icons">{{ downloadIcon }}</i>
</button>
<button
v-if="response.body"
@@ -34,7 +34,7 @@
class="icon button"
@click="copyResponse"
>
<i class="material-icons">content_copy</i>
<i class="material-icons">{{ copyIcon }}</i>
</button>
</div>
</div>
@@ -69,9 +69,8 @@ export default {
return {
expandResponse: false,
responseBodyMaxLines: 16,
doneButton: '<i class="material-icons">done</i>',
downloadButton: '<i class="material-icons">save_alt</i>',
copyButton: '<i class="material-icons">content_copy</i>',
copyIcon: "content_copy",
downloadIcon: "save_alt",
}
},
computed: {
@@ -97,21 +96,17 @@ export default {
a.download = `${url.split("/").pop().split("#")[0].split("?")[0]}`
document.body.appendChild(a)
a.click()
this.$refs.downloadResponse.innerHTML = this.doneButton
this.downloadIcon = "done"
this.$toast.success(this.$t("download_started"), {
icon: "done",
})
setTimeout(() => {
document.body.removeChild(a)
window.URL.revokeObjectURL(url)
this.$refs.downloadResponse.innerHTML = this.downloadButton
this.downloadIcon = "save_alt"
}, 1000)
},
copyResponse() {
this.$refs.copyResponse.innerHTML = this.doneButton
this.$toast.success(this.$t("copied_to_clipboard"), {
icon: "done",
})
const aux = document.createElement("textarea")
const copy = this.responseBodyText
aux.innerText = copy
@@ -119,10 +114,11 @@ export default {
aux.select()
document.execCommand("copy")
document.body.removeChild(aux)
setTimeout(
() => (this.$refs.copyResponse.innerHTML = this.copyButton),
1000
)
this.copyIcon = "done"
this.$toast.success(this.$t("copied_to_clipboard"), {
icon: "done",
})
setTimeout(() => (this.copyIcon = "content_copy"), 1000)
},
},
}

View File

@@ -179,7 +179,7 @@
class="icon button"
@click="downloadSchema"
>
<i class="material-icons">save_alt</i>
<i class="material-icons">{{ downloadSchemaIcon }}</i>
</button>
<button
ref="copySchemaCode"
@@ -187,7 +187,7 @@
class="icon button"
@click="copySchema"
>
<i class="material-icons">content_copy</i>
<i class="material-icons">{{ copySchemaIcon }}</i>
</button>
</div>
</div>
@@ -236,14 +236,14 @@
class="icon button"
@click="copyQuery"
>
<i class="material-icons">content_copy</i>
<i class="material-icons">{{ copyQueryIcon }}</i>
</button>
<button
v-tooltip="`${$t('prettify_query')} (${getSpecialKey()}-P)`"
class="icon button"
@click="doPrettifyQuery"
>
<i class="material-icons">photo_filter</i>
<i class="material-icons">{{ prettifyIcon }}</i>
</button>
<button
ref="saveRequest"
@@ -304,7 +304,7 @@
class="icon button"
@click="downloadResponse"
>
<i class="material-icons">save_alt</i>
<i class="material-icons">{{ downloadResponseIcon }}</i>
</button>
<button
v-if="response"
@@ -313,7 +313,7 @@
class="icon button"
@click="copyResponse"
>
<i class="material-icons">content_copy</i>
<i class="material-icons">{{ copyResponseIcon }}</i>
</button>
</div>
</div>
@@ -503,9 +503,12 @@ export default {
mutationFields: [],
subscriptionFields: [],
graphqlTypes: [],
copyButton: '<i class="material-icons">content_copy</i>',
downloadButton: '<i class="material-icons">save_alt</i>',
doneButton: '<i class="material-icons">done</i>',
downloadResponseIcon: "save_alt",
downloadSchemaIcon: "save_alt",
copyQueryIcon: "content_copy",
copySchemaIcon: "content_copy",
copyResponseIcon: "content_copy",
prettifyIcon: "photo_filter",
expandResponse: false,
responseBodyMaxLines: 16,
graphqlFieldsFilterText: undefined,
@@ -527,12 +530,6 @@ export default {
}
},
computed: {
selectedRequest() {
return this.$store.state.postwoman.selectedGraphqlRequest
},
editingRequest() {
return this.$store.state.postwoman.editingRequest
},
filteredQueryFields() {
return this.getFilteredGraphqlFields({
filterText: this.graphqlFieldsFilterText,
@@ -609,15 +606,6 @@ export default {
},
},
},
watch: {
selectedRequest(newValue) {
if (!newValue) return
this.url = newValue.url
this.gqlQueryString = newValue.query
this.headers = newValue.headers
this.variableString = newValue.variables
},
},
mounted() {
if (
this.$store.state.gql.schemaIntrospection &&
@@ -726,6 +714,8 @@ export default {
getSpecialKey: getPlatformSpecialKey,
doPrettifyQuery() {
this.$refs.queryEditor.prettifyQuery()
this.prettifyIcon = "done"
setTimeout(() => (this.prettifyIcon = "photo_filter"), 1000)
},
async handleJumpToType(type) {
this.$refs.gqlTabs.selectTab(this.$refs.typesTab)
@@ -746,41 +736,23 @@ export default {
return t
},
copySchema() {
this.$refs.copySchemaCode.innerHTML = this.doneButton
const aux = document.createElement("textarea")
aux.innerText = this.schema
document.body.appendChild(aux)
aux.select()
document.execCommand("copy")
document.body.removeChild(aux)
this.$toast.success(this.$t("copied_to_clipboard"), {
icon: "done",
})
setTimeout(
() => (this.$refs.copySchemaCode.innerHTML = this.copyButton),
1000
)
this.copyToClipboard(this.schema)
this.copySchemaIcon = "done"
setTimeout(() => (this.copySchemaIcon = "content_copy"), 1000)
},
copyQuery() {
this.$refs.copyQueryButton.innerHTML = this.doneButton
const aux = document.createElement("textarea")
aux.innerText = this.gqlQueryString
document.body.appendChild(aux)
aux.select()
document.execCommand("copy")
document.body.removeChild(aux)
this.$toast.success(this.$t("copied_to_clipboard"), {
icon: "done",
})
setTimeout(
() => (this.$refs.copyQueryButton.innerHTML = this.copyButton),
1000
)
this.copyToClipboard(this.gqlQueryString)
this.copyQueryIcon = "done"
setTimeout(() => (this.copyQueryIcon = "content_copy"), 1000)
},
copyResponse() {
this.$refs.copyResponseButton.innerHTML = this.doneButton
this.copyToClipboard(this.response)
this.copyResponseIcon = "done"
setTimeout(() => (this.copyResponseIcon = "content_copy"), 1000)
},
copyToClipboard(content) {
const aux = document.createElement("textarea")
aux.innerText = this.response
aux.innerText = content
document.body.appendChild(aux)
aux.select()
document.execCommand("copy")
@@ -788,10 +760,6 @@ export default {
this.$toast.success(this.$t("copied_to_clipboard"), {
icon: "done",
})
setTimeout(
() => (this.$refs.copyResponseButton.innerHTML = this.copyButton),
1000
)
},
async runQuery() {
const startTime = Date.now()
@@ -1108,14 +1076,14 @@ export default {
a.download = `${url.split("/").pop().split("#")[0].split("?")[0]}`
document.body.appendChild(a)
a.click()
this.$refs.downloadResponse.innerHTML = this.doneButton
this.downloadResponseIcon = "done"
this.$toast.success(this.$t("download_started"), {
icon: "done",
})
setTimeout(() => {
document.body.removeChild(a)
window.URL.revokeObjectURL(url)
this.$refs.downloadResponse.innerHTML = this.downloadButton
this.downloadResponseIcon = "save_alt"
}, 1000)
},
downloadSchema() {
@@ -1127,14 +1095,14 @@ export default {
a.download = `${url.split("/").pop().split("#")[0].split("?")[0]}`
document.body.appendChild(a)
a.click()
this.$refs.downloadSchema.innerHTML = this.doneButton
this.downloadSchemaIcon = "done"
this.$toast.success(this.$t("download_started"), {
icon: "done",
})
setTimeout(() => {
document.body.removeChild(a)
window.URL.revokeObjectURL(url)
this.$refs.downloadSchema.innerHTML = this.downloadButton
this.downloadSchemaIcon = "save_alt"
}, 1000)
},
addRequestHeader() {

View File

@@ -843,9 +843,6 @@ export default {
EXPERIMENTAL_URL_BAR_ENABLED: getSettingSubject(
"EXPERIMENTAL_URL_BAR_ENABLED"
),
SYNC_COLLECTIONS: getSettingSubject("syncCollections"),
SYNC_HISTORY: getSettingSubject("syncHistory"),
}
},
watch: {
@@ -930,10 +927,6 @@ export default {
}
this.name = newValue.name
},
editingRequest(newValue) {
this.editRequest = newValue
this.showSaveRequestModal = true
},
method() {
this.contentType = ["POST", "PUT", "PATCH", "DELETE"].includes(
this.method
@@ -1223,12 +1216,6 @@ export default {
})
},
},
selectedRequest() {
return this.$store.state.postwoman.selectedRequest
},
editingRequest() {
return this.$store.state.postwoman.editingRequest
},
requestName() {
return this.name
},
@@ -1336,12 +1323,6 @@ export default {
},
},
methods: {
checkCollections() {
const checkCollectionAvailability =
this.$store.state.postwoman.collections &&
this.$store.state.postwoman.collections.length > 0
return checkCollectionAvailability
},
scrollInto(view) {
this.$refs[view].$el.scrollIntoView({
behavior: "smooth",
@@ -2005,13 +1986,6 @@ export default {
testScript: this.testsEnabled == true ? this.testScript : null,
name: this.requestName,
}
if (this.selectedRequest.url) {
this.editRequest = Object.assign(
{},
this.selectedRequest,
this.editRequest
)
}
this.showSaveRequestModal = true
},
hideRequestModal() {

View File

@@ -136,7 +136,7 @@
class="icon button"
@click="resetProxy"
>
<i class="material-icons">clear_all</i>
<i class="material-icons">{{ clearIcon }}</i>
</button>
</div>
<input
@@ -227,7 +227,7 @@ export default Vue.extend({
? window.__POSTWOMAN_EXTENSION_HOOK__.getVersion()
: null,
doneButton: '<i class="material-icons">done</i>',
clearIcon: "clear_all",
SYNC_COLLECTIONS: true,
SYNC_ENVIRONMENTS: true,
@@ -309,17 +309,13 @@ export default Vue.extend({
) {
this.applySetting(name, value)
},
resetProxy({ target }: { target: HTMLElement }) {
resetProxy() {
applySetting("PROXY_URL", `https://proxy.hoppscotch.io/`)
target.innerHTML = this.doneButton
this.clearIcon = "done"
this.$toast.info(this.$t("cleared"), {
icon: "clear_all",
})
setTimeout(
() => (target.innerHTML = '<i class="material-icons">clear_all</i>'),
1000
)
setTimeout(() => (this.clearIcon = "clear_all"), 1000)
},
},
})

View File

@@ -1,460 +0,0 @@
import Vue from "vue"
export const SETTINGS_KEYS = [
/**
* Whether or not to enable scrolling to a specified element, when certain
* actions are triggered.
*/
"SCROLL_INTO_ENABLED",
/**
* Whether or not requests should be proxied.
*/
"PROXY_ENABLED",
/**
* The URL of the proxy to connect to for requests.
*/
"PROXY_URL",
/**
* The security key of the proxy.
*/
"PROXY_KEY",
/**
* An array of properties to exclude from the URL.
* e.g. 'auth'
*/
"URL_EXCLUDES",
/**
* A boolean value indicating whether to use the browser extensions
* to run the requests
*/
"EXTENSIONS_ENABLED",
/**
* A boolean value indicating whether to use the URL bar experiments
*/
"EXPERIMENTAL_URL_BAR_ENABLED",
]
export const state = () => ({
settings: {},
editingEnvironment: {},
selectedRequest: {},
selectedGraphqlRequest: {},
editingRequest: {},
})
export const mutations = {
applySetting({ settings }, setting) {
if (
setting === null ||
!(setting instanceof Array) ||
setting.length !== 2
) {
throw new Error(
"You must provide a setting (array in the form [key, value])"
)
}
const [key, value] = setting
// Do not just remove this check.
// Add your settings key to the SETTINGS_KEYS array at the
// top of the file.
// This is to ensure that application settings remain documented.
if (!SETTINGS_KEYS.includes(key)) {
throw new Error(`The settings structure does not include the key ${key}`)
}
settings[key] = value
},
removeVariables({ editingEnvironment }, value) {
editingEnvironment.variables = value
},
setEditingEnvironment(state, value) {
state.editingEnvironment = { ...value }
},
setVariableKey({ editingEnvironment }, { index, value }) {
editingEnvironment.variables[index].key = value
},
setVariableValue({ editingEnvironment }, { index, value }) {
editingEnvironment.variables[index].value = testValue(value)
},
removeVariable({ editingEnvironment }, variables) {
editingEnvironment.variables = variables
},
addVariable({ editingEnvironment }, value) {
editingEnvironment.variables.push(value)
},
replaceEnvironments(state, environments) {
state.environments = environments
},
importAddEnvironments(state, { environments, confirmation }) {
const duplicateEnvironment = environments.some((item) => {
return state.environments.some((item2) => {
return item.name.toLowerCase() === item2.name.toLowerCase()
})
})
if (duplicateEnvironment) {
this.$toast.info("Duplicate environment")
return
}
state.environments = [...state.environments, ...environments]
let index = 0
for (const environment of state.environments) {
environment.environmentIndex = index
index += 1
}
this.$toast.info(confirmation, {
icon: "folder_shared",
})
},
removeEnvironment({ environments }, environmentIndex) {
environments.splice(environmentIndex, 1)
},
saveEnvironment({ environments }, payload) {
const { environment, environmentIndex } = payload
const { name } = environment
const duplicateEnvironment =
environments.length === 1
? false
: environments.some(
(item) =>
item.environmentIndex !== environmentIndex &&
item.name.toLowerCase() === name.toLowerCase()
)
if (duplicateEnvironment) {
this.$toast.info("Duplicate environment")
return
}
environments[environmentIndex] = environment
},
replaceCollections(state, item) {
const collections = item.data
const flag = item.flag
if (flag === "rest") state.collections = collections
else state.collectionsGraphql = collections
},
importCollections(state, item) {
const collections = item.data
const flag = item.flag
if (flag === "rest")
state.collections = [...state.collections, ...collections]
else
state.collectionsGraphql = [...state.collectionsGraphql, ...collections]
let index = 0
for (const collection of collections) {
collection.collectionIndex = index
index += 1
}
},
addNewCollection({ collections, collectionsGraphql }, collection) {
const name = collection.name
const flag = collection.flag
let duplicateCollection = null
if (flag === "rest") {
duplicateCollection = collections.some(
(item) => item.name.toLowerCase() === name.toLowerCase()
)
} else {
duplicateCollection = collectionsGraphql.some(
(item) => item.name.toLowerCase() === name.toLowerCase()
)
}
if (duplicateCollection) {
this.$toast.info("Duplicate collection")
return
}
if (flag === "rest") {
collections.push({
name: "",
folders: [],
requests: [],
...collection,
})
} else {
collectionsGraphql.push({
name: "",
folders: [],
requests: [],
...collection,
})
}
},
removeCollection({ collections, collectionsGraphql }, payload) {
const { collectionIndex, flag } = payload
if (flag === "rest") collections.splice(collectionIndex, 1)
else collectionsGraphql.splice(collectionIndex, 1)
},
editCollection({ collections, collectionsGraphql }, payload) {
const { collection, collectionIndex, flag } = payload
const { name } = collection
let duplicateCollection = null
if (flag === "rest") {
duplicateCollection = collections.some(
(item) => item.name.toLowerCase() === name.toLowerCase()
)
} else {
duplicateCollection = collectionsGraphql.some(
(item) => item.name.toLowerCase() === name.toLowerCase()
)
}
if (duplicateCollection) {
this.$toast.info("Duplicate collection")
return
}
if (flag === "rest") collections[collectionIndex] = collection
else collectionsGraphql[collectionIndex] = collection
},
addFolder({ collections, collectionsGraphql }, payload) {
const { name, path, flag } = payload
const newFolder = {
name,
requests: [],
folders: [],
}
// Walk from collections to destination with the path
const indexPaths = path.split("/").map((x) => parseInt(x))
let target = null
if (flag === "rest") target = collections[indexPaths.shift()]
else target = collectionsGraphql[indexPaths.shift()]
while (indexPaths.length > 0) target = target.folders[indexPaths.shift()]
target.folders.push(newFolder)
},
editFolder({ collections, collectionsGraphql }, payload) {
const { collectionIndex, folder, folderIndex, folderName, flag } = payload
let collection = null
if (flag === "rest") collection = collections[collectionIndex]
else collection = collectionsGraphql[collectionIndex]
const parentFolder = findFolder(folderName, collection, true)
if (parentFolder && parentFolder.folders) {
Vue.set(parentFolder.folders, folderIndex, folder)
}
},
removeFolder({ collections, collectionsGraphql }, payload) {
const { collectionIndex, folderIndex, folderName, flag } = payload
let collection = null
if (flag === "rest") collection = collections[collectionIndex]
else collection = collectionsGraphql[collectionIndex]
const parentFolder = findFolder(folderName, collection, true)
if (parentFolder && parentFolder.folders) {
parentFolder.folders.splice(folderIndex, 1)
}
},
editRequest({ collections, collectionsGraphql }, payload) {
const {
requestCollectionIndex,
requestFolderName,
requestFolderIndex,
requestNew,
requestIndex,
flag,
} = payload
let collection = null
if (flag === "rest") collection = collections[requestCollectionIndex]
else collection = collectionsGraphql[requestCollectionIndex]
if (requestFolderIndex === -1) {
Vue.set(collection.requests, requestIndex, requestNew)
return
}
const folder = findFolder(requestFolderName, collection, false)
Vue.set(folder.requests, requestIndex, requestNew)
},
saveRequestAs({ collections, collectionsGraphql }, payload) {
let { request } = payload
const { collectionIndex, folderName, requestIndex, flag } = payload
if (flag === "rest") {
// Filter out all file inputs
request = {
...request,
bodyParams: request.bodyParams.map((param) =>
param?.value?.[0] instanceof File ? { ...param, value: "" } : param
),
}
}
const specifiedCollection = collectionIndex !== undefined
const specifiedFolder = folderName !== undefined
const specifiedRequest = requestIndex !== undefined
if (specifiedCollection && specifiedFolder && specifiedRequest) {
const folder = findFolder(
folderName,
flag === "rest"
? collections[collectionIndex]
: collectionsGraphql[collectionIndex]
)
Vue.set(folder.requests, requestIndex, request)
} else if (specifiedCollection && specifiedFolder && !specifiedRequest) {
const folder = findFolder(
folderName,
flag === "rest"
? collections[collectionIndex]
: collectionsGraphql[collectionIndex]
)
const requests = folder.requests
const lastRequestIndex = requests.length - 1
Vue.set(requests, lastRequestIndex + 1, request)
} else if (specifiedCollection && !specifiedFolder && specifiedRequest) {
const requests =
flag === "rest"
? collections[collectionIndex].requests
: collectionsGraphql[collectionIndex].requests
Vue.set(requests, requestIndex, request)
} else if (specifiedCollection && !specifiedFolder && !specifiedRequest) {
const requests =
flag === "rest"
? collections[collectionIndex].requests
: collectionsGraphql[collectionIndex].requests
const lastRequestIndex = requests.length - 1
Vue.set(requests, lastRequestIndex + 1, request)
}
},
removeRequest({ collections, collectionsGraphql }, payload) {
const { collectionIndex, folderName, requestIndex, flag } = payload
let collection = null
if (flag === "rest") collection = collections[collectionIndex]
else collection = collectionsGraphql[collectionIndex]
if (collection.name === folderName) {
collection.requests.splice(requestIndex, 1)
return
}
const folder = findFolder(folderName, collection, false)
if (folder) {
folder.requests.splice(requestIndex, 1)
}
},
selectRequest(state, { request }) {
state.selectedRequest = Object.assign({}, request)
},
selectGraphqlRequest(state, { request }) {
state.selectedGraphqlRequest = Object.assign({}, request)
},
moveRequest({ collections, collectionsGraphql }, payload) {
const {
oldCollectionIndex,
newCollectionIndex,
newFolderIndex,
newFolderName,
oldFolderName,
requestIndex,
flag,
} = payload
const isCollection = newFolderIndex === -1
let oldCollection = null
if (flag === "rest") oldCollection = collections[oldCollectionIndex]
else oldCollection = collectionsGraphql[oldCollectionIndex]
let newCollection = null
if (flag === "rest") newCollection = collections[newCollectionIndex]
else newCollection = collectionsGraphql[newCollectionIndex]
const request = findRequest(oldFolderName, oldCollection, requestIndex)
if (isCollection) {
newCollection.requests.push(request)
return
}
if (!isCollection) {
const folder = findFolder(newFolderName, newCollection, false)
if (folder) {
folder.requests.push(request)
}
}
},
}
function testValue(myValue) {
try {
return JSON.parse(myValue)
} catch (ex) {
// Now we know it's a string just leave it as a string value.
return myValue
}
}
function findRequest(folderName, currentFolder, requestIndex) {
let selectedFolder, result
if (folderName === currentFolder.name) {
const request = currentFolder.requests[requestIndex]
currentFolder.requests.splice(requestIndex, 1)
return request
} else {
for (let i = 0; i < currentFolder.folders.length; i += 1) {
selectedFolder = currentFolder.folders[i]
result = findRequest(folderName, selectedFolder, requestIndex)
if (result !== false) {
return result
}
}
return false
}
}
function findFolder(folderName, currentFolder, returnParent, parentFolder) {
let selectedFolder, result
if (folderName === currentFolder.name && returnParent) {
return parentFolder
} else if (folderName === currentFolder.name && !returnParent) {
return currentFolder
} else {
for (let i = 0; i < currentFolder.folders.length; i++) {
selectedFolder = currentFolder.folders[i]
result = findFolder(
folderName,
selectedFolder,
returnParent,
currentFolder
)
if (result !== false) {
return result
}
}
return false
}
}