Merge remote-tracking branch 'upstream/main' into newstate/firebase
This commit is contained in:
11
.github/workflows/codeql-analysis.yml
vendored
11
.github/workflows/codeql-analysis.yml
vendored
@@ -31,15 +31,6 @@ jobs:
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
# We must fetch at least the immediate parents so that if this is
|
||||
# a pull request then we can checkout the head.
|
||||
fetch-depth: 2
|
||||
|
||||
# If this run was triggered by a pull request event, then checkout
|
||||
# the head of the pull request instead of the merge commit.
|
||||
- run: git checkout HEAD^2
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
@@ -47,7 +38,7 @@ jobs:
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||
# By default, queries listed here will override any specified in a config file.
|
||||
# By default, queries listed here will override any specified in a config file.
|
||||
# Prefix the list here with "+" to use these queries and those in the config file.
|
||||
# queries: ./path/to/local/query, your-org/your-repo/queries@main
|
||||
|
||||
|
||||
2
.github/workflows/tests.yml
vendored
2
.github/workflows/tests.yml
vendored
@@ -22,5 +22,5 @@ jobs:
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- run: npm ci
|
||||
- run: npm run build --if-present
|
||||
- run: npm run generate --if-present
|
||||
- run: npm test
|
||||
|
||||
@@ -477,7 +477,7 @@ docker pull hoppscotch/hoppscotch
|
||||
docker build -t hoppscotch/hoppscotch:latest .
|
||||
|
||||
#run
|
||||
docker run -p 3000:3000 hoppscotch/hoppscotch:latest
|
||||
docker run --rm --name hoppscotch -p 3000:3000 hoppscotch/hoppscotch:latest
|
||||
```
|
||||
|
||||
**Legacy container** [](https://hub.docker.com/r/liyasthomas/postwoman)
|
||||
|
||||
@@ -727,11 +727,13 @@ section {
|
||||
}
|
||||
|
||||
.inner-right {
|
||||
--width: 33%;
|
||||
--ml: 1rem;
|
||||
@apply flex;
|
||||
@apply order-2;
|
||||
@apply ml-4;
|
||||
|
||||
width: 33%;
|
||||
margin-left: var(--ml);
|
||||
width: var(--width);
|
||||
}
|
||||
|
||||
@media (max-width: $responsiveWidth) {
|
||||
@@ -770,7 +772,7 @@ section {
|
||||
}
|
||||
|
||||
.inner-right {
|
||||
@apply ml-0;
|
||||
--ml: 0;
|
||||
}
|
||||
|
||||
.toasted-container {
|
||||
|
||||
@@ -189,14 +189,6 @@ export default {
|
||||
}
|
||||
},
|
||||
async mounted() {
|
||||
this._keyListener = function (e) {
|
||||
if (e.key === "Escape") {
|
||||
e.preventDefault()
|
||||
this.showExtensions = this.showShortcuts = this.showSupport = false
|
||||
}
|
||||
}
|
||||
document.addEventListener("keydown", this._keyListener.bind(this))
|
||||
|
||||
// Initializes the PWA code - checks if the app is installed,
|
||||
// etc.
|
||||
this.showInstallPrompt = await intializePwa()
|
||||
@@ -281,9 +273,6 @@ export default {
|
||||
// }, 5000)
|
||||
// }
|
||||
},
|
||||
beforeDestroy() {
|
||||
document.removeEventListener("keydown", this._keyListener)
|
||||
},
|
||||
methods: {
|
||||
nativeShare() {
|
||||
if (navigator.share) {
|
||||
|
||||
@@ -26,7 +26,7 @@ export default Vue.extend({
|
||||
},
|
||||
noLegend: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
default: true,
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
|
||||
@@ -232,6 +232,7 @@ export default {
|
||||
this.hideModal()
|
||||
},
|
||||
hideModal() {
|
||||
this.picked = null
|
||||
this.$emit("hide-modal")
|
||||
},
|
||||
},
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
>
|
||||
<i class="material-icons">topic</i>
|
||||
</button>
|
||||
<v-popover v-if="!savingMode">
|
||||
<v-popover>
|
||||
<button v-tooltip.left="$t('more')" class="tooltip-target icon">
|
||||
<i class="material-icons">more_vert</i>
|
||||
</button>
|
||||
@@ -197,6 +197,14 @@ export default Vue.extend({
|
||||
this.showChildren = !this.showChildren
|
||||
},
|
||||
removeCollection() {
|
||||
// Cancel pick if picked collection is deleted
|
||||
if (
|
||||
this.picked &&
|
||||
this.picked.pickedType === "gql-my-collection" &&
|
||||
this.picked.collectionIndex === this.collectionIndex
|
||||
) {
|
||||
this.$emit("select", { picked: null })
|
||||
}
|
||||
removeGraphqlCollection(this.collectionIndex)
|
||||
|
||||
this.$toast.error(this.$t("deleted").toString(), {
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
<span>{{ folder.name }}</span>
|
||||
</button>
|
||||
</div>
|
||||
<v-popover v-if="!savingMode">
|
||||
<v-popover>
|
||||
<button v-tooltip.left="$t('more')" class="tooltip-target icon">
|
||||
<i class="material-icons">more_vert</i>
|
||||
</button>
|
||||
@@ -181,6 +181,15 @@ export default Vue.extend({
|
||||
this.showChildren = !this.showChildren
|
||||
},
|
||||
removeFolder() {
|
||||
// Cancel pick if the picked folder is deleted
|
||||
if (
|
||||
this.picked &&
|
||||
this.picked.pickedType === "gql-my-folder" &&
|
||||
this.picked.folderPath === this.folderPath
|
||||
) {
|
||||
this.$emit("select", { picked: null })
|
||||
}
|
||||
|
||||
removeGraphqlFolder(this.folderPath)
|
||||
this.$toast.error(this.$t("deleted").toString(), {
|
||||
icon: "delete",
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
<span>{{ request.name }}</span>
|
||||
</button>
|
||||
</div>
|
||||
<v-popover v-if="!savingMode">
|
||||
<v-popover>
|
||||
<button v-tooltip="$t('more')" class="tooltip-target icon">
|
||||
<i class="material-icons">more_vert</i>
|
||||
</button>
|
||||
@@ -122,6 +122,16 @@ export default Vue.extend({
|
||||
dataTransfer.setData("requestIndex", this.requestIndex)
|
||||
},
|
||||
removeRequest() {
|
||||
// Cancel pick if the picked request is deleted
|
||||
if (
|
||||
this.picked &&
|
||||
this.picked.pickedType === "gql-my-request" &&
|
||||
this.picked.folderPath === this.folderPath &&
|
||||
this.picked.requestIndex === this.requestIndex
|
||||
) {
|
||||
this.$emit("select", { picked: null })
|
||||
}
|
||||
|
||||
removeGraphqlRequest(this.folderPath, this.requestIndex)
|
||||
this.$toast.error(this.$t("deleted").toString(), {
|
||||
icon: "delete",
|
||||
|
||||
@@ -1,12 +1,8 @@
|
||||
<template>
|
||||
<AppSection
|
||||
ref="collections"
|
||||
class="yellow"
|
||||
:label="$t('collections')"
|
||||
no-legend
|
||||
>
|
||||
<AppSection ref="collections" :label="$t('collections')">
|
||||
<div class="show-on-large-screen">
|
||||
<input
|
||||
v-if="showCollActions"
|
||||
v-model="filterText"
|
||||
aria-label="Search"
|
||||
type="search"
|
||||
@@ -50,11 +46,7 @@
|
||||
@hide-modal="displayModalImportExport(false)"
|
||||
/>
|
||||
<div class="border-b row-wrapper border-divider">
|
||||
<button
|
||||
v-if="showCollActions"
|
||||
class="icon"
|
||||
@click="displayModalAdd(true)"
|
||||
>
|
||||
<button class="icon" @click="displayModalAdd(true)">
|
||||
<i class="material-icons">add</i>
|
||||
<span>{{ $t("new") }}</span>
|
||||
</button>
|
||||
@@ -178,24 +170,6 @@ export default {
|
||||
return filteredCollections
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this._keyListener = function (e) {
|
||||
if (e.key === "Escape") {
|
||||
e.preventDefault()
|
||||
this.showModalAdd =
|
||||
this.showModalEdit =
|
||||
this.showModalImportExport =
|
||||
this.showModalAddFolder =
|
||||
this.showModalEditFolder =
|
||||
this.showModalEditRequest =
|
||||
false
|
||||
}
|
||||
}
|
||||
document.addEventListener("keydown", this._keyListener.bind(this))
|
||||
},
|
||||
beforeDestroy() {
|
||||
document.removeEventListener("keydown", this._keyListener)
|
||||
},
|
||||
methods: {
|
||||
displayModalAdd(shouldDisplay) {
|
||||
this.showModalAdd = shouldDisplay
|
||||
@@ -250,7 +224,9 @@ export default {
|
||||
folderName,
|
||||
request,
|
||||
requestIndex,
|
||||
folderPath,
|
||||
} = payload
|
||||
this.$data.editingFolderPath = folderPath
|
||||
this.$data.editingCollectionIndex = collectionIndex
|
||||
this.$data.editingFolderIndex = folderIndex
|
||||
this.$data.editingFolderName = folderName
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<AppSection ref="collections" :label="$t('collections')" no-legend>
|
||||
<AppSection ref="collections" :label="$t('collections')">
|
||||
<div class="show-on-large-screen">
|
||||
<input
|
||||
v-if="!saveRequest"
|
||||
@@ -57,8 +57,7 @@
|
||||
v-if="
|
||||
collectionsType.type == 'team-collections' &&
|
||||
(collectionsType.selectedTeam == undefined ||
|
||||
collectionsType.selectedTeam.myRole == 'VIEWER') &&
|
||||
!saveRequest
|
||||
collectionsType.selectedTeam.myRole == 'VIEWER')
|
||||
"
|
||||
class="icon"
|
||||
disabled
|
||||
@@ -69,11 +68,7 @@
|
||||
<span>{{ $t("new") }}</span>
|
||||
</div>
|
||||
</button>
|
||||
<button
|
||||
v-else-if="!saveRequest"
|
||||
class="icon"
|
||||
@click="displayModalAdd(true)"
|
||||
>
|
||||
<button v-else class="icon" @click="displayModalAdd(true)">
|
||||
<i class="material-icons">add</i>
|
||||
<span>{{ $t("new") }}</span>
|
||||
</button>
|
||||
@@ -261,27 +256,10 @@ export default {
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this._keyListener = function (e) {
|
||||
if (e.key === "Escape") {
|
||||
e.preventDefault()
|
||||
this.showModalAdd =
|
||||
this.showModalEdit =
|
||||
this.showModalImportExport =
|
||||
this.showModalAddFolder =
|
||||
this.showModalEditFolder =
|
||||
this.showModalEditRequest =
|
||||
false
|
||||
}
|
||||
}
|
||||
document.addEventListener("keydown", this._keyListener.bind(this))
|
||||
|
||||
this.$subscribeTo(this.teamCollectionAdapter.collections$, (colls) => {
|
||||
this.teamCollectionsNew = cloneDeep(colls)
|
||||
})
|
||||
},
|
||||
beforeDestroy() {
|
||||
document.removeEventListener("keydown", this._keyListener)
|
||||
},
|
||||
methods: {
|
||||
updateTeamCollections() {
|
||||
// TODO: Remove this at some point
|
||||
@@ -554,12 +532,30 @@ export default {
|
||||
},
|
||||
removeCollection({ collectionsType, collectionIndex, collectionID }) {
|
||||
if (collectionsType.type === "my-collections") {
|
||||
// Cancel pick if picked collection is deleted
|
||||
if (
|
||||
this.picked &&
|
||||
this.picked.pickedType === "my-collection" &&
|
||||
this.picked.collectionIndex === collectionIndex
|
||||
) {
|
||||
this.$emit("select", { picked: null })
|
||||
}
|
||||
|
||||
removeRESTCollection(collectionIndex)
|
||||
|
||||
this.$toast.error(this.$t("deleted"), {
|
||||
icon: "delete",
|
||||
})
|
||||
} else if (collectionsType.type === "team-collections") {
|
||||
// Cancel pick if picked collection is deleted
|
||||
if (
|
||||
this.picked &&
|
||||
this.picked.pickedType === "teams-collection" &&
|
||||
this.picked.collectionID === collectionID
|
||||
) {
|
||||
this.$emit("select", { picked: null })
|
||||
}
|
||||
|
||||
if (collectionsType.selectedTeam.myRole !== "VIEWER") {
|
||||
this.$apollo
|
||||
.mutate({
|
||||
@@ -592,12 +588,30 @@ export default {
|
||||
},
|
||||
removeRequest({ requestIndex, folderPath }) {
|
||||
if (this.collectionsType.type === "my-collections") {
|
||||
// Cancel pick if the picked item is being deleted
|
||||
if (
|
||||
this.picked &&
|
||||
this.picked.pickedType === "my-request" &&
|
||||
this.picked.folderPath === folderPath &&
|
||||
this.picked.requestIndex === requestIndex
|
||||
) {
|
||||
this.$emit("select", { picked: null })
|
||||
}
|
||||
removeRESTRequest(folderPath, requestIndex)
|
||||
|
||||
this.$toast.error(this.$t("deleted"), {
|
||||
icon: "delete",
|
||||
})
|
||||
} else if (this.collectionsType.type === "team-collections") {
|
||||
// Cancel pick if the picked item is being deleted
|
||||
if (
|
||||
this.picked &&
|
||||
this.picked.pickedType === "teams-request" &&
|
||||
this.picked.requestID === requestIndex
|
||||
) {
|
||||
this.$emit("select", { picked: null })
|
||||
}
|
||||
|
||||
teamUtils
|
||||
.deleteRequest(this.$apollo, requestIndex)
|
||||
.then(() => {
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
>
|
||||
<i class="material-icons">check_box</i>
|
||||
</button>
|
||||
<v-popover v-if="!saveRequest">
|
||||
<v-popover>
|
||||
<button v-tooltip.left="$t('more')" class="tooltip-target icon">
|
||||
<i class="material-icons">more_vert</i>
|
||||
</button>
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
<span>{{ folder.name ? folder.name : folder.title }}</span>
|
||||
</button>
|
||||
</div>
|
||||
<v-popover v-if="!saveRequest">
|
||||
<v-popover>
|
||||
<button v-tooltip.left="$t('more')" class="tooltip-target icon">
|
||||
<i class="material-icons">more_vert</i>
|
||||
</button>
|
||||
@@ -193,6 +193,15 @@ export default {
|
||||
this.showChildren = !this.showChildren
|
||||
},
|
||||
removeFolder() {
|
||||
// TODO: Bubble it up ?
|
||||
// Cancel pick if picked folder was deleted
|
||||
if (
|
||||
this.picked &&
|
||||
this.picked.pickedType === "my-folder" &&
|
||||
this.picked.folderPath === this.folderPath
|
||||
) {
|
||||
this.$emit("select", { picked: null })
|
||||
}
|
||||
removeRESTFolder(this.folderPath)
|
||||
|
||||
this.$toast.error(this.$t("deleted"), {
|
||||
@@ -206,6 +215,16 @@ export default {
|
||||
moveRESTRequest(folderPath, requestIndex, this.folderPath)
|
||||
},
|
||||
removeRequest({ requestIndex }) {
|
||||
// TODO: Bubble it up to root ?
|
||||
// Cancel pick if the picked item is being deleted
|
||||
if (
|
||||
this.picked &&
|
||||
this.picked.pickedType === "my-request" &&
|
||||
this.picked.folderPath === this.folderPath &&
|
||||
this.picked.requestIndex === requestIndex
|
||||
) {
|
||||
this.$emit("select", { picked: null })
|
||||
}
|
||||
removeRESTRequest(this.folderPath, requestIndex)
|
||||
},
|
||||
},
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
<span>{{ request.name }}</span>
|
||||
</button>
|
||||
</div>
|
||||
<v-popover v-if="!saveRequest">
|
||||
<v-popover>
|
||||
<button v-tooltip="$t('more')" class="tooltip-target icon">
|
||||
<i class="material-icons">more_vert</i>
|
||||
</button>
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
>
|
||||
<i class="material-icons">check_box</i>
|
||||
</button>
|
||||
<v-popover v-if="!saveRequest">
|
||||
<v-popover>
|
||||
<button
|
||||
v-if="collectionsType.selectedTeam.myRole !== 'VIEWER'"
|
||||
v-tooltip.left="$t('more')"
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
<span>{{ folder.name ? folder.name : folder.title }}</span>
|
||||
</button>
|
||||
</div>
|
||||
<v-popover v-if="!saveRequest">
|
||||
<v-popover>
|
||||
<button
|
||||
v-if="collectionsType.selectedTeam.myRole !== 'VIEWER'"
|
||||
v-tooltip.left="$t('more')"
|
||||
@@ -189,6 +189,15 @@ export default {
|
||||
},
|
||||
removeFolder() {
|
||||
if (this.collectionsType.selectedTeam.myRole !== "VIEWER") {
|
||||
// Cancel pick if picked collection folder was deleted
|
||||
if (
|
||||
this.picked &&
|
||||
this.picked.pickedType === "teams-folder" &&
|
||||
this.picked.folderID === this.folder.id
|
||||
) {
|
||||
this.$emit("select", { picked: null })
|
||||
}
|
||||
|
||||
teamUtils
|
||||
.deleteCollection(this.$apollo, this.folder.id)
|
||||
.then(() => {
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<span>{{ request.name }}</span>
|
||||
</button>
|
||||
</div>
|
||||
<v-popover v-if="!saveRequest">
|
||||
<v-popover>
|
||||
<button
|
||||
v-if="collectionsType.selectedTeam.myRole !== 'VIEWER'"
|
||||
v-tooltip="$t('more')"
|
||||
|
||||
@@ -1,10 +1,5 @@
|
||||
<template>
|
||||
<AppSection
|
||||
ref="environments"
|
||||
icon="history"
|
||||
:label="$t('environments')"
|
||||
no-legend
|
||||
>
|
||||
<AppSection ref="environments" :label="$t('environments')">
|
||||
<div class="show-on-large-screen">
|
||||
<span class="select-wrapper">
|
||||
<select
|
||||
@@ -103,21 +98,6 @@ export default {
|
||||
setCurrentEnvironment(val)
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this._keyListener = function (e) {
|
||||
if (e.key === "Escape") {
|
||||
e.preventDefault()
|
||||
this.showModalImportExport =
|
||||
this.showModalAdd =
|
||||
this.showModalEdit =
|
||||
false
|
||||
}
|
||||
}
|
||||
document.addEventListener("keydown", this._keyListener.bind(this))
|
||||
},
|
||||
beforeDestroy() {
|
||||
document.removeEventListener("keydown", this._keyListener)
|
||||
},
|
||||
methods: {
|
||||
displayModalAdd(shouldDisplay) {
|
||||
this.showModalAdd = shouldDisplay
|
||||
|
||||
@@ -90,17 +90,6 @@ export default {
|
||||
this.$subscribeTo(currentUser$, (user) => {
|
||||
if (user) this.hideModal()
|
||||
})
|
||||
|
||||
this._keyListener = function (e) {
|
||||
if (e.key === "Escape") {
|
||||
e.preventDefault()
|
||||
this.hideModal()
|
||||
}
|
||||
}
|
||||
document.addEventListener("keydown", this._keyListener.bind(this))
|
||||
},
|
||||
beforeDestroy() {
|
||||
document.removeEventListener("keydown", this._keyListener)
|
||||
},
|
||||
methods: {
|
||||
async signInWithEmail() {
|
||||
|
||||
@@ -9,7 +9,8 @@
|
||||
readonly
|
||||
:value="entry.url"
|
||||
:placeholder="$t('empty_req_name')"
|
||||
class="bg-transparent"
|
||||
class="cursor-pointer text-sm bg-transparent"
|
||||
@click="$emit('use-entry')"
|
||||
/>
|
||||
</li>
|
||||
<button
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<AppSection ref="history" icon="history" :label="$t('history')" no-legend>
|
||||
<AppSection ref="history" :label="$t('history')">
|
||||
<div class="show-on-large-screen">
|
||||
<input
|
||||
v-model="filterText"
|
||||
|
||||
@@ -2,9 +2,10 @@
|
||||
<div>
|
||||
<div class="show-on-large-screen">
|
||||
<span
|
||||
class="p-2 m-2 truncate"
|
||||
class="p-2 m-2 truncate inline-flex cursor-pointer items-center text-sm"
|
||||
:class="entryStatus.className"
|
||||
:style="{ '--status-code': entry.status }"
|
||||
@click="$emit('use-entry')"
|
||||
>
|
||||
{{ `${entry.method} \xA0 • \xA0 ${entry.status}` }}
|
||||
</span>
|
||||
@@ -15,7 +16,8 @@
|
||||
readonly
|
||||
:value="entry.name"
|
||||
:placeholder="$t('empty_req_name')"
|
||||
class="bg-transparent"
|
||||
class="cursor-pointer text-sm bg-transparent"
|
||||
@click="$emit('use-entry')"
|
||||
/>
|
||||
</li>
|
||||
<span>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<AppSection ref="headers" label="Headers" no-legend>
|
||||
<AppSection ref="headers" label="Headers">
|
||||
<ul v-if="headers.length !== 0">
|
||||
<li>
|
||||
<div class="row-wrapper">
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<AppSection ref="parameters" label="Parameters" no-legend>
|
||||
<AppSection ref="parameters" label="Parameters">
|
||||
<ul v-if="params.length !== 0">
|
||||
<li>
|
||||
<div class="row-wrapper">
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<AppSection id="response" ref="response" :label="$t('response')" no-legend>
|
||||
<AppSection id="response" ref="response" :label="$t('response')">
|
||||
<HttpResponseMeta :response="response" :active="active" />
|
||||
<div v-if="response.body && response.body !== $t('loading')">
|
||||
<LensesResponseBodyRenderer :response="response" />
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div>
|
||||
<AppSection :label="$t('request')" no-legend>
|
||||
<AppSection :label="$t('request')">
|
||||
<ul>
|
||||
<li>
|
||||
<label for="mqtt-url">{{ $t("url") }}</label>
|
||||
@@ -34,7 +34,7 @@
|
||||
</ul>
|
||||
</AppSection>
|
||||
|
||||
<AppSection :label="$t('communication')" no-legend>
|
||||
<AppSection :label="$t('communication')">
|
||||
<ul>
|
||||
<li>
|
||||
<RealtimeLog :title="$t('log')" :log="log" />
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div>
|
||||
<AppSection ref="request" :label="$t('request')" no-legend>
|
||||
<AppSection ref="request" :label="$t('request')">
|
||||
<ul>
|
||||
<li>
|
||||
<label for="socketio-url">{{ $t("url") }}</label>
|
||||
@@ -43,12 +43,7 @@
|
||||
</ul>
|
||||
</AppSection>
|
||||
|
||||
<AppSection
|
||||
id="response"
|
||||
ref="response"
|
||||
:label="$t('communication')"
|
||||
no-legend
|
||||
>
|
||||
<AppSection id="response" ref="response" :label="$t('communication')">
|
||||
<ul>
|
||||
<li>
|
||||
<RealtimeLog :title="$t('log')" :log="communication.log" />
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div>
|
||||
<AppSection ref="request" :label="$t('request')" no-legend>
|
||||
<AppSection ref="request" :label="$t('request')">
|
||||
<ul>
|
||||
<li>
|
||||
<label for="server">{{ $t("server") }}</label>
|
||||
@@ -36,12 +36,7 @@
|
||||
</ul>
|
||||
</AppSection>
|
||||
|
||||
<AppSection
|
||||
id="response"
|
||||
ref="response"
|
||||
:label="$t('communication')"
|
||||
no-legend
|
||||
>
|
||||
<AppSection id="response" ref="response" :label="$t('communication')">
|
||||
<ul>
|
||||
<li>
|
||||
<RealtimeLog :title="$t('events')" :log="events.log" />
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div>
|
||||
<AppSection ref="request" :label="$t('request')" no-legend>
|
||||
<AppSection ref="request" :label="$t('request')">
|
||||
<ul>
|
||||
<li>
|
||||
<label for="websocket-url">{{ $t("url") }}</label>
|
||||
@@ -10,7 +10,6 @@
|
||||
type="url"
|
||||
spellcheck="false"
|
||||
:class="{ error: !urlValid }"
|
||||
class="md:rounded-bl-lg"
|
||||
:placeholder="$t('url')"
|
||||
@keyup.enter="urlValid ? toggleConnection() : null"
|
||||
/>
|
||||
@@ -22,7 +21,6 @@
|
||||
id="connect"
|
||||
:disabled="!urlValid"
|
||||
name="connect"
|
||||
class="rounded-b-lg md:rounded-bl-none md:rounded-br-lg"
|
||||
@click="toggleConnection"
|
||||
>
|
||||
{{ !connectionState ? $t("connect") : $t("disconnect") }}
|
||||
@@ -35,14 +33,86 @@
|
||||
</li>
|
||||
</div>
|
||||
</ul>
|
||||
<ul>
|
||||
<li>
|
||||
<div class="row-wrapper">
|
||||
<label>{{ $t("protocols") }}</label>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
<ul
|
||||
v-for="(protocol, index) of protocols"
|
||||
:key="`protocol-${index}`"
|
||||
:class="{ 'border-t': index == 0 }"
|
||||
class="
|
||||
border-b border-dashed
|
||||
divide-y
|
||||
md:divide-x
|
||||
border-divider
|
||||
divide-dashed divide-divider
|
||||
md:divide-y-0
|
||||
"
|
||||
>
|
||||
<li>
|
||||
<input
|
||||
v-model="protocol.value"
|
||||
:placeholder="$t('protocol_count', { count: index + 1 })"
|
||||
name="message"
|
||||
type="text"
|
||||
/>
|
||||
</li>
|
||||
<div>
|
||||
<li>
|
||||
<button
|
||||
v-tooltip.bottom="{
|
||||
content: protocol.hasOwnProperty('active')
|
||||
? protocol.active
|
||||
? $t('turn_off')
|
||||
: $t('turn_on')
|
||||
: $t('turn_off'),
|
||||
}"
|
||||
class="icon"
|
||||
@click="
|
||||
protocol.active = protocol.hasOwnProperty('active')
|
||||
? !protocol.active
|
||||
: false
|
||||
"
|
||||
>
|
||||
<i class="material-icons">
|
||||
{{
|
||||
protocol.hasOwnProperty("active")
|
||||
? protocol.active
|
||||
? "check_box"
|
||||
: "check_box_outline_blank"
|
||||
: "check_box"
|
||||
}}
|
||||
</i>
|
||||
</button>
|
||||
</li>
|
||||
</div>
|
||||
<div>
|
||||
<li>
|
||||
<button
|
||||
v-tooltip.bottom="$t('delete')"
|
||||
class="icon"
|
||||
@click="deleteProtocol({ index })"
|
||||
>
|
||||
<i class="material-icons">delete</i>
|
||||
</button>
|
||||
</li>
|
||||
</div>
|
||||
</ul>
|
||||
<ul>
|
||||
<li>
|
||||
<button class="icon" @click="addProtocol">
|
||||
<i class="material-icons">add</i>
|
||||
<span>{{ $t("add_new") }}</span>
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</AppSection>
|
||||
|
||||
<AppSection
|
||||
id="response"
|
||||
ref="response"
|
||||
:label="$t('communication')"
|
||||
no-legend
|
||||
>
|
||||
<AppSection id="response" ref="response" :label="$t('communication')">
|
||||
<ul>
|
||||
<li>
|
||||
<RealtimeLog :title="$t('log')" :log="communication.log" />
|
||||
@@ -100,6 +170,8 @@ export default {
|
||||
input: "",
|
||||
},
|
||||
currentIndex: -1, // index of the message log array to put in input box
|
||||
protocols: [],
|
||||
activeProtocols: [],
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@@ -111,6 +183,18 @@ export default {
|
||||
url() {
|
||||
this.debouncer()
|
||||
},
|
||||
protocols: {
|
||||
handler(newVal) {
|
||||
this.activeProtocols = newVal
|
||||
.filter((item) =>
|
||||
Object.prototype.hasOwnProperty.call(item, "active")
|
||||
? item.active === true
|
||||
: true
|
||||
)
|
||||
.map(({ value }) => value)
|
||||
},
|
||||
deep: true,
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
if (process.browser) {
|
||||
@@ -143,7 +227,7 @@ export default {
|
||||
},
|
||||
]
|
||||
try {
|
||||
this.socket = new WebSocket(this.url)
|
||||
this.socket = new WebSocket(this.url, this.activeProtocols)
|
||||
this.socket.onopen = () => {
|
||||
this.connectionState = true
|
||||
this.communication.log = [
|
||||
@@ -255,6 +339,24 @@ export default {
|
||||
break
|
||||
}
|
||||
},
|
||||
addProtocol() {
|
||||
this.protocols.push({ value: "", active: true })
|
||||
},
|
||||
deleteProtocol({ index }) {
|
||||
const oldProtocols = this.protocols.slice()
|
||||
this.$delete(this.protocols, index)
|
||||
this.$toast.error(this.$t("deleted"), {
|
||||
icon: "delete",
|
||||
action: {
|
||||
text: this.$t("undo"),
|
||||
duration: 4000,
|
||||
onClick: (_, toastObject) => {
|
||||
this.protocols = oldProtocols
|
||||
toastObject.remove()
|
||||
},
|
||||
},
|
||||
})
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -47,18 +47,6 @@ export default {
|
||||
},
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this._keyListener = function (e) {
|
||||
if (e.key === "Escape") {
|
||||
e.preventDefault()
|
||||
this.hideModal()
|
||||
}
|
||||
}
|
||||
document.addEventListener("keydown", this._keyListener.bind(this))
|
||||
},
|
||||
beforeDestroy() {
|
||||
document.removeEventListener("keydown", this._keyListener)
|
||||
},
|
||||
methods: {
|
||||
hideModal() {
|
||||
this.$emit("hide-modal")
|
||||
|
||||
@@ -1,6 +1,13 @@
|
||||
<template>
|
||||
<transition name="modal" appear>
|
||||
<div class="modal-backdrop">
|
||||
<transition name="modal" appear @leave="onTransitionLeaveStart">
|
||||
<div
|
||||
ref="modal"
|
||||
class="modal-backdrop"
|
||||
@touchstart="onBackdropMouseDown"
|
||||
@touchend="onBackdropMouseUp"
|
||||
@mouseup="onBackdropMouseUp"
|
||||
@mousedown="onBackdropMouseDown"
|
||||
>
|
||||
<div class="modal-wrapper">
|
||||
<div class="modal-container">
|
||||
<div class="modal-header">
|
||||
@@ -21,12 +28,86 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
const PORTAL_DOM_ID = "hoppscotch-modal-portal"
|
||||
|
||||
const stack = (() => {
|
||||
const stack = []
|
||||
return {
|
||||
push: stack.push.bind(stack),
|
||||
pop: stack.pop.bind(stack),
|
||||
peek: () => (stack.length === 0 ? undefined : stack[stack.length - 1]),
|
||||
}
|
||||
})()
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
stackId: Math.random(),
|
||||
shouldCloseOnBackdropClick: true,
|
||||
// when transition doesn't fire on unmount, we should manually remove the modal from DOM
|
||||
// (for example, when the parent component of this modal gets destroyed)
|
||||
shouldCleanupDomOnUnmount: true,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
hasFooterSlot() {
|
||||
return !!this.$slots.footer
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
const $portal = this.$getPortal()
|
||||
$portal.appendChild(this.$refs.modal)
|
||||
stack.push(this.stackId)
|
||||
document.addEventListener("keydown", this.onKeyDown)
|
||||
},
|
||||
beforeDestroy() {
|
||||
const $modal = this.$refs.modal
|
||||
if (this.shouldCleanupDomOnUnmount && $modal) {
|
||||
this.$getPortal().removeChild($modal)
|
||||
}
|
||||
stack.pop()
|
||||
document.removeEventListener("keydown", this.onKeyDown)
|
||||
},
|
||||
methods: {
|
||||
close() {
|
||||
this.$emit("close")
|
||||
},
|
||||
onBackdropMouseDown({ target }) {
|
||||
this.shouldCloseOnBackdropClick =
|
||||
!this.checkIfTargetInsideModalContent(target)
|
||||
},
|
||||
onBackdropMouseUp({ target }) {
|
||||
if (
|
||||
this.shouldCloseOnBackdropClick &&
|
||||
!this.checkIfTargetInsideModalContent(target)
|
||||
) {
|
||||
this.close()
|
||||
}
|
||||
this.shouldCloseOnBackdropClick = true
|
||||
},
|
||||
checkIfTargetInsideModalContent($target) {
|
||||
return $target?.closest(".modal-container")
|
||||
},
|
||||
onKeyDown(e) {
|
||||
if (e.key === "Escape" && this.stackId === stack.peek()) {
|
||||
e.preventDefault()
|
||||
this.close()
|
||||
}
|
||||
},
|
||||
onTransitionLeaveStart() {
|
||||
this.shouldCleanupDomOnUnmount = false
|
||||
},
|
||||
$getPortal() {
|
||||
let $el = document.querySelector("#" + PORTAL_DOM_ID)
|
||||
if ($el) {
|
||||
return $el
|
||||
}
|
||||
$el = document.createElement("DIV")
|
||||
$el.id = PORTAL_DOM_ID
|
||||
document.body.appendChild($el)
|
||||
return $el
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
@@ -1,11 +1,5 @@
|
||||
<template>
|
||||
<AppSection
|
||||
ref="teams"
|
||||
class="green"
|
||||
icon="history"
|
||||
:label="$t('teams')"
|
||||
no-legend
|
||||
>
|
||||
<AppSection ref="teams" :label="$t('teams')">
|
||||
<div class="flex flex-col">
|
||||
<label>{{ $t("teams") }}</label>
|
||||
<div v-if="currentUser"></div>
|
||||
|
||||
@@ -1,18 +1,8 @@
|
||||
<template>
|
||||
<transition
|
||||
:appear="appear"
|
||||
name="translate-slide-left"
|
||||
enter-active-class="transition duration-500 transform"
|
||||
enter-class="translate-x-full"
|
||||
enter-to-class="translate-x-0"
|
||||
leave-active-class="transition duration-500 transform"
|
||||
leave-class="translate-x-0"
|
||||
leave-to-class="translate-x-full"
|
||||
>
|
||||
<transition :appear="appear" name="translate-slide-left">
|
||||
<slot></slot>
|
||||
</transition>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
@@ -23,3 +13,26 @@ export default {
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.translate-slide-left {
|
||||
&-enter,
|
||||
&-leave-to {
|
||||
width: 0%;
|
||||
opacity: 0;
|
||||
margin-left: 0;
|
||||
}
|
||||
&-enter-to,
|
||||
&-leave {
|
||||
width: var(--width, 33%);
|
||||
margin-left: var(--ml, 0);
|
||||
opacity: 1;
|
||||
}
|
||||
&-enter-active,
|
||||
&-leave-active {
|
||||
overflow-x: hidden;
|
||||
white-space: nowrap;
|
||||
transition: width 0.5s ease, opacity 0.3s ease, margin-left 0.5s ease;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -336,5 +336,7 @@
|
||||
"we_sent_magic_link": "We sent you a magic link!",
|
||||
"we_sent_magic_link_description": "We sent an email to {email}. It contains a magic link that’ll log you in.",
|
||||
"hide_sidebar": "Hide sidebar",
|
||||
"show_sidebar": "Show sidebar"
|
||||
"show_sidebar": "Show sidebar",
|
||||
"protocols": "Protocols",
|
||||
"protocol_count": "protocol {count}"
|
||||
}
|
||||
|
||||
3986
package-lock.json
generated
3986
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -39,7 +39,7 @@
|
||||
"lodash": "^4.17.21",
|
||||
"mustache": "^4.2.0",
|
||||
"node-interval-tree": "^1.3.3",
|
||||
"nuxt": "^2.15.6",
|
||||
"nuxt": "^2.15.7",
|
||||
"nuxt-i18n": "^6.27.0",
|
||||
"paho-mqtt": "^1.1.0",
|
||||
"rxjs": "^7.1.0",
|
||||
@@ -57,7 +57,7 @@
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.14.5",
|
||||
"@babel/preset-env": "^7.14.5",
|
||||
"@nuxt/types": "^2.15.6",
|
||||
"@nuxt/types": "^2.15.7",
|
||||
"@nuxt/typescript-build": "^2.1.0",
|
||||
"@nuxtjs/color-mode": "^2.0.10",
|
||||
"@nuxtjs/dotenv": "^1.4.1",
|
||||
@@ -70,7 +70,7 @@
|
||||
"@nuxtjs/tailwindcss": "^4.1.3",
|
||||
"@testing-library/jest-dom": "^5.14.1",
|
||||
"@types/lodash": "^4.14.170",
|
||||
"@vue/test-utils": "^1.2.0",
|
||||
"@vue/test-utils": "^1.2.1",
|
||||
"babel-core": "^7.0.0-bridge.0",
|
||||
"babel-jest": "^27.0.2",
|
||||
"eslint": "^7.28.0",
|
||||
@@ -82,7 +82,7 @@
|
||||
"jest": "^27.0.4",
|
||||
"jest-serializer-vue": "^2.0.2",
|
||||
"lint-staged": "^11.0.0",
|
||||
"postcss": "^8.3.2",
|
||||
"postcss": "^8.3.4",
|
||||
"prettier": "^2.3.1",
|
||||
"pretty-quick": "^3.1.0",
|
||||
"raw-loader": "^4.0.2",
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<div class="page">
|
||||
<div class="content">
|
||||
<div class="page-columns inner-left">
|
||||
<AppSection ref="import" :label="$t('import')" no-legend>
|
||||
<AppSection ref="import" :label="$t('import')">
|
||||
<div class="flex flex-col">
|
||||
<label>{{ $t("collection") }}</label>
|
||||
<p class="info">
|
||||
@@ -55,7 +55,7 @@
|
||||
</div>
|
||||
</AppSection>
|
||||
|
||||
<AppSection ref="documentation" :label="$t('documentation')" no-legend>
|
||||
<AppSection ref="documentation" :label="$t('documentation')">
|
||||
<div class="flex flex-col">
|
||||
<label>{{ $t("documentation") }}</label>
|
||||
<p v-if="items.length === 0" class="info">
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<div class="page">
|
||||
<div class="content">
|
||||
<div class="page-columns inner-left">
|
||||
<AppSection ref="endpoint" :label="$t('endpoint')" no-legend>
|
||||
<AppSection ref="endpoint" :label="$t('endpoint')">
|
||||
<ul>
|
||||
<li>
|
||||
<label for="url">{{ $t("url") }}</label>
|
||||
@@ -37,7 +37,7 @@
|
||||
</ul>
|
||||
</AppSection>
|
||||
|
||||
<AppSection ref="headers" :label="$t('headers')" no-legend>
|
||||
<AppSection ref="headers" :label="$t('headers')">
|
||||
<div class="flex flex-col">
|
||||
<label>{{ $t("headers") }}</label>
|
||||
<ul v-if="headers.length !== 0">
|
||||
@@ -150,7 +150,7 @@
|
||||
</div>
|
||||
</AppSection>
|
||||
|
||||
<AppSection ref="schema" :label="$t('schema')" no-legend>
|
||||
<AppSection ref="schema" :label="$t('schema')">
|
||||
<div class="row-wrapper">
|
||||
<label>{{ $t("schema") }}</label>
|
||||
<div v-if="schema">
|
||||
@@ -212,7 +212,7 @@
|
||||
/>
|
||||
</AppSection>
|
||||
|
||||
<AppSection ref="query" :label="$t('query')" no-legend>
|
||||
<AppSection ref="query" :label="$t('query')">
|
||||
<div class="row-wrapper gqlRunQuery">
|
||||
<label for="gqlQuery">{{ $t("query") }}</label>
|
||||
<div>
|
||||
@@ -266,7 +266,7 @@
|
||||
/>
|
||||
</AppSection>
|
||||
|
||||
<AppSection ref="variables" :label="$t('variables')" no-legend>
|
||||
<AppSection ref="variables" :label="$t('variables')">
|
||||
<div class="flex flex-col">
|
||||
<label>{{ $t("variables") }}</label>
|
||||
<SmartAceEditor
|
||||
@@ -285,7 +285,7 @@
|
||||
</div>
|
||||
</AppSection>
|
||||
|
||||
<AppSection ref="response" :label="$t('response')" no-legend>
|
||||
<AppSection ref="response" :label="$t('response')">
|
||||
<div class="flex flex-col">
|
||||
<label>{{ $t("response") }}</label>
|
||||
<div class="row-wrapper">
|
||||
@@ -347,7 +347,7 @@
|
||||
>
|
||||
<SmartTabs>
|
||||
<SmartTab :id="'docs'" :label="`Docs`" :selected="true">
|
||||
<AppSection ref="docs" :label="$t('docs')" no-legend>
|
||||
<AppSection ref="docs" :label="$t('docs')">
|
||||
<section class="flex-col">
|
||||
<input
|
||||
v-model="graphqlFieldsFilterText"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<div class="page">
|
||||
<div class="content">
|
||||
<div class="page-columns inner-left">
|
||||
<AppSection :label="$t('request')" ref="request" no-legend>
|
||||
<AppSection :label="$t('request')" ref="request">
|
||||
<ul>
|
||||
<li class="shrink">
|
||||
<label for="method">{{ $t("method") }}</label>
|
||||
@@ -253,11 +253,7 @@
|
||||
</SmartTab>
|
||||
|
||||
<SmartTab :id="'authentication'" :label="$t('authentication')">
|
||||
<AppSection
|
||||
:label="$t('authentication')"
|
||||
ref="authentication"
|
||||
no-legend
|
||||
>
|
||||
<AppSection :label="$t('authentication')" ref="authentication">
|
||||
<ul>
|
||||
<li>
|
||||
<div class="row-wrapper">
|
||||
@@ -358,7 +354,6 @@
|
||||
|
||||
<AppSection
|
||||
v-if="showTokenRequest"
|
||||
class="red"
|
||||
label="Access Token Request"
|
||||
ref="accessTokenRequest"
|
||||
>
|
||||
@@ -485,10 +480,8 @@
|
||||
>
|
||||
<AppSection
|
||||
v-if="showPreRequestScript"
|
||||
class="orange"
|
||||
:label="$t('pre_request_script')"
|
||||
ref="preRequest"
|
||||
no-legend
|
||||
>
|
||||
<ul>
|
||||
<li>
|
||||
@@ -527,10 +520,8 @@
|
||||
<SmartTab :id="'tests'" :label="$t('tests')">
|
||||
<AppSection
|
||||
v-if="testsEnabled"
|
||||
class="orange"
|
||||
:label="$t('tests')"
|
||||
ref="postRequestTests"
|
||||
no-legend
|
||||
>
|
||||
<ul>
|
||||
<li>
|
||||
@@ -2172,15 +2163,6 @@ export default {
|
||||
e.preventDefault()
|
||||
this.$refs.clearAll.click()
|
||||
}
|
||||
if (e.key === "Escape") {
|
||||
e.preventDefault()
|
||||
this.showCurlImportModal =
|
||||
this.showTokenListModal =
|
||||
this.showTokenRequestList =
|
||||
this.showSaveRequestModal =
|
||||
this.showCodegenModal =
|
||||
false
|
||||
}
|
||||
if ((e.key === "g" || e.key === "G") && e.altKey) {
|
||||
this.method = "GET"
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<Teams />
|
||||
</div>
|
||||
|
||||
<AppSection ref="account" :label="$t('account')" no-legend>
|
||||
<AppSection ref="account" :label="$t('account')">
|
||||
<div class="flex flex-col">
|
||||
<label>{{ $t("account") }}</label>
|
||||
<div v-if="currentUser">
|
||||
@@ -67,7 +67,7 @@
|
||||
</div>
|
||||
</AppSection>
|
||||
|
||||
<AppSection ref="theme" :label="$t('theme')" no-legend>
|
||||
<AppSection ref="theme" :label="$t('theme')">
|
||||
<div class="flex flex-col">
|
||||
<label>{{ $t("theme") }}</label>
|
||||
<SmartColorModePicker />
|
||||
@@ -84,7 +84,7 @@
|
||||
</div>
|
||||
</AppSection>
|
||||
|
||||
<AppSection ref="extensions" :label="$t('extensions')" no-legend>
|
||||
<AppSection ref="extensions" :label="$t('extensions')">
|
||||
<div class="flex flex-col">
|
||||
<label>{{ $t("extensions") }}</label>
|
||||
<div class="row-wrapper">
|
||||
@@ -106,7 +106,7 @@
|
||||
</div>
|
||||
</AppSection>
|
||||
|
||||
<AppSection ref="proxy" :label="$t('proxy')" no-legend>
|
||||
<AppSection ref="proxy" :label="$t('proxy')">
|
||||
<div class="flex flex-col">
|
||||
<label>{{ $t("proxy") }}</label>
|
||||
<div class="row-wrapper">
|
||||
@@ -177,7 +177,7 @@
|
||||
-->
|
||||
</AppSection>
|
||||
|
||||
<AppSection ref="experiments" :label="$t('experiments')" no-legend>
|
||||
<AppSection ref="experiments" :label="$t('experiments')">
|
||||
<div class="flex flex-col">
|
||||
<label>{{ $t("experiments") }}</label>
|
||||
<p class="info">
|
||||
|
||||
Reference in New Issue
Block a user