refactor: lint
This commit is contained in:
@@ -37,6 +37,8 @@ module.exports = {
|
|||||||
],
|
],
|
||||||
"vue/singleline-html-element-content-newline": "off",
|
"vue/singleline-html-element-content-newline": "off",
|
||||||
"vue/multiline-html-element-content-newline": "off",
|
"vue/multiline-html-element-content-newline": "off",
|
||||||
|
"vue/require-default-prop": "warn",
|
||||||
|
"vue/require-prop-types": "warn",
|
||||||
"prettier/prettier": ["warn", { semi: false }],
|
"prettier/prettier": ["warn", { semi: false }],
|
||||||
"import/no-named-as-default": "off",
|
"import/no-named-as-default": "off",
|
||||||
"no-undef": "off",
|
"no-undef": "off",
|
||||||
|
|||||||
@@ -12,15 +12,20 @@
|
|||||||
</div>
|
</div>
|
||||||
<div slot="body" class="flex flex-col">
|
<div slot="body" class="flex flex-col">
|
||||||
<label for="selectLabel">{{ $t("token_req_name") }}</label>
|
<label for="selectLabel">{{ $t("token_req_name") }}</label>
|
||||||
<input type="text" id="selectLabel" v-model="requestData.name" @keyup.enter="saveRequestAs" />
|
<input
|
||||||
|
id="selectLabel"
|
||||||
|
v-model="requestData.name"
|
||||||
|
type="text"
|
||||||
|
@keyup.enter="saveRequestAs"
|
||||||
|
/>
|
||||||
<label for="selectLabel">Select location</label>
|
<label for="selectLabel">Select location</label>
|
||||||
<!-- <input readonly :value="path" /> -->
|
<!-- <input readonly :value="path" /> -->
|
||||||
<Collections
|
<Collections
|
||||||
|
:picked="picked"
|
||||||
|
:save-request="true"
|
||||||
@select="onSelect"
|
@select="onSelect"
|
||||||
@update-collection="collectionsType.type = $event"
|
@update-collection="collectionsType.type = $event"
|
||||||
@update-coll-type="onUpdateCollType"
|
@update-coll-type="onUpdateCollType"
|
||||||
:picked="picked"
|
|
||||||
:saveRequest="true"
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div slot="footer">
|
<div slot="footer">
|
||||||
@@ -42,12 +47,12 @@
|
|||||||
<script>
|
<script>
|
||||||
import { fb } from "~/helpers/fb"
|
import { fb } from "~/helpers/fb"
|
||||||
import { getSettingSubject } from "~/newstore/settings"
|
import { getSettingSubject } from "~/newstore/settings"
|
||||||
import * as team_utils from "~/helpers/teams/utils"
|
import * as teamUtils from "~/helpers/teams/utils"
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
show: Boolean,
|
show: Boolean,
|
||||||
editingRequest: Object,
|
editingRequest: { type: Object, default: () => {} },
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@@ -71,20 +76,6 @@ export default {
|
|||||||
SYNC_COLLECTIONS: getSettingSubject("syncCollections"),
|
SYNC_COLLECTIONS: getSettingSubject("syncCollections"),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
|
||||||
"requestData.collectionIndex": function resetFolderAndRequestIndex() {
|
|
||||||
// if user has chosen some folder, than selected other collection, which doesn't have any folders
|
|
||||||
// than `requestUpdateData.folderName` won't be reseted
|
|
||||||
this.$data.requestData.folderName = undefined
|
|
||||||
this.$data.requestData.requestIndex = undefined
|
|
||||||
},
|
|
||||||
"requestData.folderName": function resetRequestIndex() {
|
|
||||||
this.$data.requestData.requestIndex = undefined
|
|
||||||
},
|
|
||||||
editingRequest({ name }) {
|
|
||||||
this.$data.requestData.name = name || this.$data.defaultRequestName
|
|
||||||
},
|
|
||||||
},
|
|
||||||
computed: {
|
computed: {
|
||||||
folders() {
|
folders() {
|
||||||
const collections = this.$store.state.postwoman.collections
|
const collections = this.$store.state.postwoman.collections
|
||||||
@@ -107,7 +98,8 @@ export default {
|
|||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
|
|
||||||
const userSelectedAnyFolder = folderName !== undefined && folderName !== ""
|
const userSelectedAnyFolder =
|
||||||
|
folderName !== undefined && folderName !== ""
|
||||||
|
|
||||||
if (userSelectedAnyFolder) {
|
if (userSelectedAnyFolder) {
|
||||||
const collection = collections[collectionIndex]
|
const collection = collections[collectionIndex]
|
||||||
@@ -125,6 +117,20 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
watch: {
|
||||||
|
"requestData.collectionIndex": function resetFolderAndRequestIndex() {
|
||||||
|
// if user has chosen some folder, than selected other collection, which doesn't have any folders
|
||||||
|
// than `requestUpdateData.folderName` won't be reseted
|
||||||
|
this.$data.requestData.folderName = undefined
|
||||||
|
this.$data.requestData.requestIndex = undefined
|
||||||
|
},
|
||||||
|
"requestData.folderName": function resetRequestIndex() {
|
||||||
|
this.$data.requestData.requestIndex = undefined
|
||||||
|
},
|
||||||
|
editingRequest({ name }) {
|
||||||
|
this.$data.requestData.name = name || this.$data.defaultRequestName
|
||||||
|
},
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
onUpdateCollType(newCollType) {
|
onUpdateCollType(newCollType) {
|
||||||
this.collectionsType = newCollType
|
this.collectionsType = newCollType
|
||||||
@@ -188,14 +194,14 @@ export default {
|
|||||||
|
|
||||||
this.syncCollections()
|
this.syncCollections()
|
||||||
} else if (this.picked.pickedType === "teams-request") {
|
} else if (this.picked.pickedType === "teams-request") {
|
||||||
team_utils.overwriteRequestTeams(
|
teamUtils.overwriteRequestTeams(
|
||||||
this.$apollo,
|
this.$apollo,
|
||||||
JSON.stringify(requestUpdated),
|
JSON.stringify(requestUpdated),
|
||||||
requestUpdated.name,
|
requestUpdated.name,
|
||||||
this.picked.requestID
|
this.picked.requestID
|
||||||
)
|
)
|
||||||
} else if (this.picked.pickedType === "teams-folder") {
|
} else if (this.picked.pickedType === "teams-folder") {
|
||||||
team_utils.saveRequestAsTeams(
|
teamUtils.saveRequestAsTeams(
|
||||||
this.$apollo,
|
this.$apollo,
|
||||||
JSON.stringify(requestUpdated),
|
JSON.stringify(requestUpdated),
|
||||||
requestUpdated.name,
|
requestUpdated.name,
|
||||||
@@ -203,7 +209,7 @@ export default {
|
|||||||
this.picked.folderID
|
this.picked.folderID
|
||||||
)
|
)
|
||||||
} else if (this.picked.pickedType === "teams-collection") {
|
} else if (this.picked.pickedType === "teams-collection") {
|
||||||
team_utils.saveRequestAsTeams(
|
teamUtils.saveRequestAsTeams(
|
||||||
this.$apollo,
|
this.$apollo,
|
||||||
JSON.stringify(requestUpdated),
|
JSON.stringify(requestUpdated),
|
||||||
requestUpdated.name,
|
requestUpdated.name,
|
||||||
|
|||||||
@@ -1,15 +1,23 @@
|
|||||||
<template>
|
<template>
|
||||||
<AppSection class="yellow" :label="$t('collections')" ref="collections" no-legend>
|
<AppSection
|
||||||
|
ref="collections"
|
||||||
|
class="yellow"
|
||||||
|
:label="$t('collections')"
|
||||||
|
no-legend
|
||||||
|
>
|
||||||
<div class="show-on-large-screen">
|
<div class="show-on-large-screen">
|
||||||
<input
|
<input
|
||||||
|
v-model="filterText"
|
||||||
aria-label="Search"
|
aria-label="Search"
|
||||||
type="search"
|
type="search"
|
||||||
:placeholder="$t('search')"
|
:placeholder="$t('search')"
|
||||||
v-model="filterText"
|
|
||||||
class="rounded-t-lg"
|
class="rounded-t-lg"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<CollectionsGraphqlAdd :show="showModalAdd" @hide-modal="displayModalAdd(false)" />
|
<CollectionsGraphqlAdd
|
||||||
|
:show="showModalAdd"
|
||||||
|
@hide-modal="displayModalAdd(false)"
|
||||||
|
/>
|
||||||
<CollectionsGraphqlEdit
|
<CollectionsGraphqlEdit
|
||||||
:show="showModalEdit"
|
:show="showModalEdit"
|
||||||
:editing-collection="editingCollection"
|
:editing-collection="editingCollection"
|
||||||
@@ -53,17 +61,21 @@
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<p v-if="collections.length === 0" class="info">
|
<p v-if="collections.length === 0" class="info">
|
||||||
<i class="material-icons">help_outline</i> {{ $t("create_new_collection") }}
|
<i class="material-icons">help_outline</i>
|
||||||
|
{{ $t("create_new_collection") }}
|
||||||
</p>
|
</p>
|
||||||
<div class="virtual-list">
|
<div class="virtual-list">
|
||||||
<ul class="flex-col">
|
<ul class="flex-col">
|
||||||
<li v-for="(collection, index) in filteredCollections" :key="collection.name">
|
<li
|
||||||
|
v-for="(collection, index) in filteredCollections"
|
||||||
|
:key="collection.name"
|
||||||
|
>
|
||||||
<CollectionsGraphqlCollection
|
<CollectionsGraphqlCollection
|
||||||
:name="collection.name"
|
:name="collection.name"
|
||||||
:collection-index="index"
|
:collection-index="index"
|
||||||
:collection="collection"
|
:collection="collection"
|
||||||
:doc="doc"
|
:doc="doc"
|
||||||
:isFiltered="filterText.length > 0"
|
:is-filtered="filterText.length > 0"
|
||||||
@edit-collection="editCollection(collection, index)"
|
@edit-collection="editCollection(collection, index)"
|
||||||
@add-folder="addFolder($event)"
|
@add-folder="addFolder($event)"
|
||||||
@edit-folder="editFolder($event)"
|
@edit-folder="editFolder($event)"
|
||||||
@@ -74,17 +86,13 @@
|
|||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<p v-if="filterText && filteredCollections.length === 0" class="info">
|
<p v-if="filterText && filteredCollections.length === 0" class="info">
|
||||||
<i class="material-icons">not_interested</i> {{ $t("nothing_found") }} "{{ filterText }}"
|
<i class="material-icons">not_interested</i> {{ $t("nothing_found") }} "{{
|
||||||
|
filterText
|
||||||
|
}}"
|
||||||
</p>
|
</p>
|
||||||
</AppSection>
|
</AppSection>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
.virtual-list {
|
|
||||||
max-height: calc(100vh - 270px);
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { fb } from "~/helpers/fb"
|
import { fb } from "~/helpers/fb"
|
||||||
|
|
||||||
@@ -128,15 +136,16 @@ export default {
|
|||||||
const filterText = this.filterText.toLowerCase()
|
const filterText = this.filterText.toLowerCase()
|
||||||
const filteredCollections = []
|
const filteredCollections = []
|
||||||
|
|
||||||
for (let collection of collections) {
|
for (const collection of collections) {
|
||||||
const filteredRequests = []
|
const filteredRequests = []
|
||||||
const filteredFolders = []
|
const filteredFolders = []
|
||||||
for (let request of collection.requests) {
|
for (const request of collection.requests) {
|
||||||
if (request.name.toLowerCase().includes(filterText)) filteredRequests.push(request)
|
if (request.name.toLowerCase().includes(filterText))
|
||||||
|
filteredRequests.push(request)
|
||||||
}
|
}
|
||||||
for (let folder of collection.folders) {
|
for (const folder of collection.folders) {
|
||||||
const filteredFolderRequests = []
|
const filteredFolderRequests = []
|
||||||
for (let request of folder.requests) {
|
for (const request of folder.requests) {
|
||||||
if (request.name.toLowerCase().includes(filterText))
|
if (request.name.toLowerCase().includes(filterText))
|
||||||
filteredFolderRequests.push(request)
|
filteredFolderRequests.push(request)
|
||||||
}
|
}
|
||||||
@@ -158,7 +167,7 @@ export default {
|
|||||||
return filteredCollections
|
return filteredCollections
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
async mounted() {
|
mounted() {
|
||||||
this._keyListener = function (e) {
|
this._keyListener = function (e) {
|
||||||
if (e.key === "Escape") {
|
if (e.key === "Escape") {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
@@ -173,6 +182,9 @@ export default {
|
|||||||
}
|
}
|
||||||
document.addEventListener("keydown", this._keyListener.bind(this))
|
document.addEventListener("keydown", this._keyListener.bind(this))
|
||||||
},
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
document.removeEventListener("keydown", this._keyListener)
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
displayModalAdd(shouldDisplay) {
|
displayModalAdd(shouldDisplay) {
|
||||||
this.showModalAdd = shouldDisplay
|
this.showModalAdd = shouldDisplay
|
||||||
@@ -232,7 +244,13 @@ export default {
|
|||||||
this.syncCollections()
|
this.syncCollections()
|
||||||
},
|
},
|
||||||
editRequest(payload) {
|
editRequest(payload) {
|
||||||
const { collectionIndex, folderIndex, folderName, request, requestIndex } = payload
|
const {
|
||||||
|
collectionIndex,
|
||||||
|
folderIndex,
|
||||||
|
folderName,
|
||||||
|
request,
|
||||||
|
requestIndex,
|
||||||
|
} = payload
|
||||||
this.$data.editingCollectionIndex = collectionIndex
|
this.$data.editingCollectionIndex = collectionIndex
|
||||||
this.$data.editingFolderIndex = folderIndex
|
this.$data.editingFolderIndex = folderIndex
|
||||||
this.$data.editingFolderName = folderName
|
this.$data.editingFolderName = folderName
|
||||||
@@ -253,15 +271,20 @@ export default {
|
|||||||
if (fb.currentUser !== null && fb.currentSettings[0]) {
|
if (fb.currentUser !== null && fb.currentSettings[0]) {
|
||||||
if (fb.currentSettings[0].value) {
|
if (fb.currentSettings[0].value) {
|
||||||
fb.writeCollections(
|
fb.writeCollections(
|
||||||
JSON.parse(JSON.stringify(this.$store.state.postwoman.collectionsGraphql)),
|
JSON.parse(
|
||||||
|
JSON.stringify(this.$store.state.postwoman.collectionsGraphql)
|
||||||
|
),
|
||||||
"collectionsGraphql"
|
"collectionsGraphql"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
beforeDestroy() {
|
|
||||||
document.removeEventListener("keydown", this._keyListener)
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.virtual-list {
|
||||||
|
max-height: calc(100vh - 270px);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
<template>
|
<template>
|
||||||
<AppSection :label="$t('collections')" ref="collections" no-legend>
|
<AppSection ref="collections" :label="$t('collections')" no-legend>
|
||||||
<div class="show-on-large-screen">
|
<div class="show-on-large-screen">
|
||||||
<input
|
<input
|
||||||
|
v-if="!saveRequest"
|
||||||
|
v-model="filterText"
|
||||||
aria-label="Search"
|
aria-label="Search"
|
||||||
type="search"
|
type="search"
|
||||||
:placeholder="$t('search')"
|
:placeholder="$t('search')"
|
||||||
v-if="!saveRequest"
|
|
||||||
v-model="filterText"
|
|
||||||
class="rounded-t-lg"
|
class="rounded-t-lg"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<CollectionsChooseType
|
<CollectionsChooseType
|
||||||
:collectionsType="collectionsType"
|
:collections-type="collectionsType"
|
||||||
:show="showTeamCollections"
|
:show="showTeamCollections"
|
||||||
:doc="doc"
|
:doc="doc"
|
||||||
@update-collection-type="updateCollectionType"
|
@update-collection-type="updateCollectionType"
|
||||||
@@ -48,7 +48,7 @@
|
|||||||
/>
|
/>
|
||||||
<CollectionsImportExport
|
<CollectionsImportExport
|
||||||
:show="showModalImportExport"
|
:show="showModalImportExport"
|
||||||
:collectionsType="collectionsType"
|
:collections-type="collectionsType"
|
||||||
@hide-modal="displayModalImportExport(false)"
|
@hide-modal="displayModalImportExport(false)"
|
||||||
@update-team-collections="updateTeamCollections"
|
@update-team-collections="updateTeamCollections"
|
||||||
/>
|
/>
|
||||||
@@ -61,22 +61,27 @@
|
|||||||
!saveRequest
|
!saveRequest
|
||||||
"
|
"
|
||||||
class="icon"
|
class="icon"
|
||||||
@click="displayModalAdd(true)"
|
|
||||||
disabled
|
disabled
|
||||||
|
@click="displayModalAdd(true)"
|
||||||
>
|
>
|
||||||
<i class="material-icons">add</i>
|
<i class="material-icons">add</i>
|
||||||
<div v-tooltip.left="$t('disable_new_collection')">
|
<div v-tooltip.left="$t('disable_new_collection')">
|
||||||
<span>{{ $t("new") }}</span>
|
<span>{{ $t("new") }}</span>
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
<button v-else-if="!saveRequest" class="icon" @click="displayModalAdd(true)">
|
<button
|
||||||
|
v-else-if="!saveRequest"
|
||||||
|
class="icon"
|
||||||
|
@click="displayModalAdd(true)"
|
||||||
|
>
|
||||||
<i class="material-icons">add</i>
|
<i class="material-icons">add</i>
|
||||||
<span>{{ $t("new") }}</span>
|
<span>{{ $t("new") }}</span>
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
v-if="!saveRequest"
|
v-if="!saveRequest"
|
||||||
:disabled="
|
:disabled="
|
||||||
collectionsType.type == 'team-collections' && collectionsType.selectedTeam == undefined
|
collectionsType.type == 'team-collections' &&
|
||||||
|
collectionsType.selectedTeam == undefined
|
||||||
"
|
"
|
||||||
class="icon"
|
class="icon"
|
||||||
@click="displayModalImportExport(true)"
|
@click="displayModalImportExport(true)"
|
||||||
@@ -85,11 +90,15 @@
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<p v-if="collections.length === 0" class="info">
|
<p v-if="collections.length === 0" class="info">
|
||||||
<i class="material-icons">help_outline</i> {{ $t("create_new_collection") }}
|
<i class="material-icons">help_outline</i>
|
||||||
|
{{ $t("create_new_collection") }}
|
||||||
</p>
|
</p>
|
||||||
<div class="virtual-list">
|
<div class="virtual-list">
|
||||||
<ul class="flex-col">
|
<ul class="flex-col">
|
||||||
<li v-for="(collection, index) in filteredCollections" :key="collection.name">
|
<li
|
||||||
|
v-for="(collection, index) in filteredCollections"
|
||||||
|
:key="collection.name"
|
||||||
|
>
|
||||||
<component
|
<component
|
||||||
:is="
|
:is="
|
||||||
collectionsType.type == 'my-collections'
|
collectionsType.type == 'my-collections'
|
||||||
@@ -100,10 +109,10 @@
|
|||||||
:collection-index="index"
|
:collection-index="index"
|
||||||
:collection="collection"
|
:collection="collection"
|
||||||
:doc="doc"
|
:doc="doc"
|
||||||
:isFiltered="filterText.length > 0"
|
:is-filtered="filterText.length > 0"
|
||||||
:selected="selected.some((coll) => coll == collection)"
|
:selected="selected.some((coll) => coll == collection)"
|
||||||
:saveRequest="saveRequest"
|
:save-request="saveRequest"
|
||||||
:collectionsType="collectionsType"
|
:collections-type="collectionsType"
|
||||||
:picked="picked"
|
:picked="picked"
|
||||||
@edit-collection="editCollection(collection, index)"
|
@edit-collection="editCollection(collection, index)"
|
||||||
@add-folder="addFolder($event)"
|
@add-folder="addFolder($event)"
|
||||||
@@ -112,25 +121,6 @@
|
|||||||
@update-team-collections="updateTeamCollections"
|
@update-team-collections="updateTeamCollections"
|
||||||
@select-collection="$emit('use-collection', collection)"
|
@select-collection="$emit('use-collection', collection)"
|
||||||
@unselect-collection="$emit('remove-collection', collection)"
|
@unselect-collection="$emit('remove-collection', collection)"
|
||||||
@select-folder="
|
|
||||||
$emit('select-folder', {
|
|
||||||
folderName:
|
|
||||||
(collectionsType.type == 'my-collections' ? collection.name : collection.title) +
|
|
||||||
'/' +
|
|
||||||
$event.name,
|
|
||||||
collectionIndex: collectionsType.type == 'my-collections' ? index : $event.id,
|
|
||||||
reqIdx: $event.reqIdx,
|
|
||||||
collectionsType: collectionsType,
|
|
||||||
folderId: $event.id,
|
|
||||||
})
|
|
||||||
if (collectionsType.type == 'my-collections') {
|
|
||||||
if ($event.folderPath) {
|
|
||||||
picked = $event.folderPath
|
|
||||||
} else picked = index
|
|
||||||
} else {
|
|
||||||
picked = $event.id
|
|
||||||
}
|
|
||||||
"
|
|
||||||
@select="$emit('select', $event)"
|
@select="$emit('select', $event)"
|
||||||
@expand-collection="expandCollection"
|
@expand-collection="expandCollection"
|
||||||
@remove-collection="removeCollection"
|
@remove-collection="removeCollection"
|
||||||
@@ -140,31 +130,27 @@
|
|||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<p v-if="filterText && filteredCollections.length === 0" class="info">
|
<p v-if="filterText && filteredCollections.length === 0" class="info">
|
||||||
<i class="material-icons">not_interested</i> {{ $t("nothing_found") }} "{{ filterText }}"
|
<i class="material-icons">not_interested</i> {{ $t("nothing_found") }} "{{
|
||||||
|
filterText
|
||||||
|
}}"
|
||||||
</p>
|
</p>
|
||||||
</AppSection>
|
</AppSection>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
.virtual-list {
|
|
||||||
max-height: calc(100vh - 270px);
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import gql from "graphql-tag"
|
||||||
|
import cloneDeep from "lodash/cloneDeep"
|
||||||
import { fb } from "~/helpers/fb"
|
import { fb } from "~/helpers/fb"
|
||||||
import { getSettingSubject } from "~/newstore/settings"
|
import { getSettingSubject } from "~/newstore/settings"
|
||||||
import gql from "graphql-tag"
|
|
||||||
import TeamCollectionAdapter from "~/helpers/teams/TeamCollectionAdapter"
|
import TeamCollectionAdapter from "~/helpers/teams/TeamCollectionAdapter"
|
||||||
import * as team_utils from "~/helpers/teams/utils"
|
import * as teamUtils from "~/helpers/teams/utils"
|
||||||
import cloneDeep from "lodash/cloneDeep"
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
doc: Boolean,
|
doc: Boolean,
|
||||||
selected: { type: Array, default: () => [] },
|
selected: { type: Array, default: () => [] },
|
||||||
saveRequest: Boolean,
|
saveRequest: Boolean,
|
||||||
picked: Object,
|
picked: { type: Object, default: () => {} },
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@@ -196,20 +182,12 @@ export default {
|
|||||||
SYNC_COLLECTIONS: getSettingSubject("syncCollections"),
|
SYNC_COLLECTIONS: getSettingSubject("syncCollections"),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
|
||||||
"collectionsType.type": function emitstuff() {
|
|
||||||
this.$emit("update-collection", this.$data.collectionsType.type)
|
|
||||||
},
|
|
||||||
"collectionsType.selectedTeam": function (value) {
|
|
||||||
if (value?.id) this.teamCollectionAdapter.changeTeamID(value.id)
|
|
||||||
},
|
|
||||||
},
|
|
||||||
computed: {
|
computed: {
|
||||||
showTeamCollections() {
|
showTeamCollections() {
|
||||||
if (fb.currentUser == null) {
|
if (fb.currentUser == null) {
|
||||||
this.collectionsType.type = "my-collections"
|
return false
|
||||||
}
|
}
|
||||||
return fb.currentUser !== null
|
return true
|
||||||
},
|
},
|
||||||
collections() {
|
collections() {
|
||||||
return fb.currentUser !== null
|
return fb.currentUser !== null
|
||||||
@@ -218,9 +196,11 @@ export default {
|
|||||||
},
|
},
|
||||||
filteredCollections() {
|
filteredCollections() {
|
||||||
let collections = null
|
let collections = null
|
||||||
if (this.collectionsType.type == "my-collections") {
|
if (this.collectionsType.type === "my-collections") {
|
||||||
collections =
|
collections =
|
||||||
fb.currentUser !== null ? fb.currentCollections : this.$store.state.postwoman.collections
|
fb.currentUser !== null
|
||||||
|
? fb.currentCollections
|
||||||
|
: this.$store.state.postwoman.collections
|
||||||
} else {
|
} else {
|
||||||
collections = this.teamCollectionsNew
|
collections = this.teamCollectionsNew
|
||||||
}
|
}
|
||||||
@@ -229,24 +209,25 @@ export default {
|
|||||||
return collections
|
return collections
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.collectionsType.type == "team-collections") {
|
if (this.collectionsType.type === "team-collections") {
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
|
|
||||||
const filterText = this.filterText.toLowerCase()
|
const filterText = this.filterText.toLowerCase()
|
||||||
const filteredCollections = []
|
const filteredCollections = []
|
||||||
|
|
||||||
for (let collection of collections) {
|
for (const collection of collections) {
|
||||||
const filteredRequests = []
|
const filteredRequests = []
|
||||||
const filteredFolders = []
|
const filteredFolders = []
|
||||||
for (let request of collection.requests) {
|
for (const request of collection.requests) {
|
||||||
if (request.name.toLowerCase().includes(filterText)) filteredRequests.push(request)
|
if (request.name.toLowerCase().includes(filterText))
|
||||||
|
filteredRequests.push(request)
|
||||||
}
|
}
|
||||||
for (let folder of this.collectionsType.type === "team-collections"
|
for (const folder of this.collectionsType.type === "team-collections"
|
||||||
? collection.children
|
? collection.children
|
||||||
: collection.folders) {
|
: collection.folders) {
|
||||||
const filteredFolderRequests = []
|
const filteredFolderRequests = []
|
||||||
for (let request of folder.requests) {
|
for (const request of folder.requests) {
|
||||||
if (request.name.toLowerCase().includes(filterText))
|
if (request.name.toLowerCase().includes(filterText))
|
||||||
filteredFolderRequests.push(request)
|
filteredFolderRequests.push(request)
|
||||||
}
|
}
|
||||||
@@ -271,7 +252,15 @@ export default {
|
|||||||
return filteredCollections
|
return filteredCollections
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
async mounted() {
|
watch: {
|
||||||
|
"collectionsType.type": function emitstuff() {
|
||||||
|
this.$emit("update-collection", this.$data.collectionsType.type)
|
||||||
|
},
|
||||||
|
"collectionsType.selectedTeam"(value) {
|
||||||
|
if (value?.id) this.teamCollectionAdapter.changeTeamID(value.id)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
this._keyListener = function (e) {
|
this._keyListener = function (e) {
|
||||||
if (e.key === "Escape") {
|
if (e.key === "Escape") {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
@@ -290,6 +279,9 @@ export default {
|
|||||||
this.teamCollectionsNew = cloneDeep(colls)
|
this.teamCollectionsNew = cloneDeep(colls)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
document.removeEventListener("keydown", this._keyListener)
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
updateTeamCollections() {
|
updateTeamCollections() {
|
||||||
// TODO: Remove this at some point
|
// TODO: Remove this at some point
|
||||||
@@ -319,8 +311,12 @@ export default {
|
|||||||
this.collectionsType.type === "team-collections" &&
|
this.collectionsType.type === "team-collections" &&
|
||||||
this.collectionsType.selectedTeam.myRole !== "VIEWER"
|
this.collectionsType.selectedTeam.myRole !== "VIEWER"
|
||||||
) {
|
) {
|
||||||
team_utils
|
teamUtils
|
||||||
.createNewRootCollection(this.$apollo, name, this.collectionsType.selectedTeam.id)
|
.createNewRootCollection(
|
||||||
|
this.$apollo,
|
||||||
|
name,
|
||||||
|
this.collectionsType.selectedTeam.id
|
||||||
|
)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
this.$toast.success(this.$t("collection_added"), {
|
this.$toast.success(this.$t("collection_added"), {
|
||||||
icon: "done",
|
icon: "done",
|
||||||
@@ -356,7 +352,7 @@ export default {
|
|||||||
this.collectionsType.type === "team-collections" &&
|
this.collectionsType.type === "team-collections" &&
|
||||||
this.collectionsType.selectedTeam.myRole !== "VIEWER"
|
this.collectionsType.selectedTeam.myRole !== "VIEWER"
|
||||||
) {
|
) {
|
||||||
team_utils
|
teamUtils
|
||||||
.renameCollection(this.$apollo, newName, this.editingCollection.id)
|
.renameCollection(this.$apollo, newName, this.editingCollection.id)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
// TODO: $t translations ?
|
// TODO: $t translations ?
|
||||||
@@ -375,20 +371,20 @@ export default {
|
|||||||
},
|
},
|
||||||
// Intended to be called by CollectionEditFolder modal submit event
|
// Intended to be called by CollectionEditFolder modal submit event
|
||||||
updateEditingFolder(name) {
|
updateEditingFolder(name) {
|
||||||
if (this.collectionsType.type == "my-collections") {
|
if (this.collectionsType.type === "my-collections") {
|
||||||
this.$store.commit("postwoman/editFolder", {
|
this.$store.commit("postwoman/editFolder", {
|
||||||
collectionIndex: this.editingCollectionIndex,
|
collectionIndex: this.editingCollectionIndex,
|
||||||
folder: { ...this.editingFolder, name: name },
|
folder: { ...this.editingFolder, name },
|
||||||
folderIndex: this.editingFolderIndex,
|
folderIndex: this.editingFolderIndex,
|
||||||
folderName: this.editingFolder.name,
|
folderName: this.editingFolder.name,
|
||||||
flag: "rest",
|
flag: "rest",
|
||||||
})
|
})
|
||||||
this.syncCollections()
|
this.syncCollections()
|
||||||
} else if (
|
} else if (
|
||||||
this.collectionsType.type == "team-collections" &&
|
this.collectionsType.type === "team-collections" &&
|
||||||
this.collectionsType.selectedTeam.myRole !== "VIEWER"
|
this.collectionsType.selectedTeam.myRole !== "VIEWER"
|
||||||
) {
|
) {
|
||||||
team_utils
|
teamUtils
|
||||||
.renameCollection(this.$apollo, name, this.editingFolder.id)
|
.renameCollection(this.$apollo, name, this.editingFolder.id)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
// Result
|
// Result
|
||||||
@@ -414,7 +410,7 @@ export default {
|
|||||||
name: requestUpdateData.name || this.editingRequest.name,
|
name: requestUpdateData.name || this.editingRequest.name,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.collectionsType.type == "my-collections") {
|
if (this.collectionsType.type === "my-collections") {
|
||||||
this.$store.commit("postwoman/editRequest", {
|
this.$store.commit("postwoman/editRequest", {
|
||||||
requestCollectionIndex: this.editingCollectionIndex,
|
requestCollectionIndex: this.editingCollectionIndex,
|
||||||
requestFolderName: this.editingFolderName,
|
requestFolderName: this.editingFolderName,
|
||||||
@@ -428,9 +424,14 @@ export default {
|
|||||||
this.collectionsType.type === "team-collections" &&
|
this.collectionsType.type === "team-collections" &&
|
||||||
this.collectionsType.selectedTeam.myRole !== "VIEWER"
|
this.collectionsType.selectedTeam.myRole !== "VIEWER"
|
||||||
) {
|
) {
|
||||||
let requestName = requestUpdateData.name || this.editingRequest.name
|
const requestName = requestUpdateData.name || this.editingRequest.name
|
||||||
team_utils
|
teamUtils
|
||||||
.updateRequest(this.$apollo, requestUpdated, requestName, this.editingRequestIndex)
|
.updateRequest(
|
||||||
|
this.$apollo,
|
||||||
|
requestUpdated,
|
||||||
|
requestName,
|
||||||
|
this.editingRequestIndex
|
||||||
|
)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
this.$toast.success("Request Renamed", {
|
this.$toast.success("Request Renamed", {
|
||||||
icon: "done",
|
icon: "done",
|
||||||
@@ -489,12 +490,18 @@ export default {
|
|||||||
})
|
})
|
||||||
this.syncCollections()
|
this.syncCollections()
|
||||||
} else if (this.collectionsType.type === "team-collections") {
|
} else if (this.collectionsType.type === "team-collections") {
|
||||||
if (this.collectionsType.selectedTeam.myRole != "VIEWER") {
|
if (this.collectionsType.selectedTeam.myRole !== "VIEWER") {
|
||||||
this.$apollo
|
this.$apollo
|
||||||
.mutate({
|
.mutate({
|
||||||
mutation: gql`
|
mutation: gql`
|
||||||
mutation CreateChildCollection($childTitle: String!, $collectionID: String!) {
|
mutation CreateChildCollection(
|
||||||
createChildCollection(childTitle: $childTitle, collectionID: $collectionID) {
|
$childTitle: String!
|
||||||
|
$collectionID: String!
|
||||||
|
) {
|
||||||
|
createChildCollection(
|
||||||
|
childTitle: $childTitle
|
||||||
|
collectionID: $collectionID
|
||||||
|
) {
|
||||||
id
|
id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -540,7 +547,13 @@ export default {
|
|||||||
this.syncCollections()
|
this.syncCollections()
|
||||||
},
|
},
|
||||||
editRequest(payload) {
|
editRequest(payload) {
|
||||||
const { collectionIndex, folderIndex, folderName, request, requestIndex } = payload
|
const {
|
||||||
|
collectionIndex,
|
||||||
|
folderIndex,
|
||||||
|
folderName,
|
||||||
|
request,
|
||||||
|
requestIndex,
|
||||||
|
} = payload
|
||||||
this.$data.editingCollectionIndex = collectionIndex
|
this.$data.editingCollectionIndex = collectionIndex
|
||||||
this.$data.editingFolderIndex = folderIndex
|
this.$data.editingFolderIndex = folderIndex
|
||||||
this.$data.editingFolderName = folderName
|
this.$data.editingFolderName = folderName
|
||||||
@@ -570,17 +583,17 @@ export default {
|
|||||||
this.teamCollectionAdapter.expandCollection(collectionID)
|
this.teamCollectionAdapter.expandCollection(collectionID)
|
||||||
},
|
},
|
||||||
removeCollection({ collectionsType, collectionIndex, collectionID }) {
|
removeCollection({ collectionsType, collectionIndex, collectionID }) {
|
||||||
if (collectionsType.type == "my-collections") {
|
if (collectionsType.type === "my-collections") {
|
||||||
this.$store.commit("postwoman/removeCollection", {
|
this.$store.commit("postwoman/removeCollection", {
|
||||||
collectionIndex: collectionIndex,
|
collectionIndex,
|
||||||
flag: "rest",
|
flag: "rest",
|
||||||
})
|
})
|
||||||
this.$toast.error(this.$t("deleted"), {
|
this.$toast.error(this.$t("deleted"), {
|
||||||
icon: "delete",
|
icon: "delete",
|
||||||
})
|
})
|
||||||
this.syncCollections()
|
this.syncCollections()
|
||||||
} else if (collectionsType.type == "team-collections") {
|
} else if (collectionsType.type === "team-collections") {
|
||||||
if (collectionsType.selectedTeam.myRole != "VIEWER") {
|
if (collectionsType.selectedTeam.myRole !== "VIEWER") {
|
||||||
this.$apollo
|
this.$apollo
|
||||||
.mutate({
|
.mutate({
|
||||||
// Query
|
// Query
|
||||||
@@ -591,10 +604,10 @@ export default {
|
|||||||
`,
|
`,
|
||||||
// Parameters
|
// Parameters
|
||||||
variables: {
|
variables: {
|
||||||
collectionID: collectionID,
|
collectionID,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.then((data) => {
|
.then(() => {
|
||||||
// Result
|
// Result
|
||||||
this.$toast.success(this.$t("deleted"), {
|
this.$toast.success(this.$t("deleted"), {
|
||||||
icon: "delete",
|
icon: "delete",
|
||||||
@@ -611,21 +624,21 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
removeRequest({ collectionIndex, folderName, requestIndex }) {
|
removeRequest({ collectionIndex, folderName, requestIndex }) {
|
||||||
if (this.collectionsType.type == "my-collections") {
|
if (this.collectionsType.type === "my-collections") {
|
||||||
this.$store.commit("postwoman/removeRequest", {
|
this.$store.commit("postwoman/removeRequest", {
|
||||||
collectionIndex: collectionIndex,
|
collectionIndex,
|
||||||
folderName: folderName,
|
folderName,
|
||||||
requestIndex: requestIndex,
|
requestIndex,
|
||||||
flag: "rest",
|
flag: "rest",
|
||||||
})
|
})
|
||||||
this.$toast.error(this.$t("deleted"), {
|
this.$toast.error(this.$t("deleted"), {
|
||||||
icon: "delete",
|
icon: "delete",
|
||||||
})
|
})
|
||||||
this.syncCollections()
|
this.syncCollections()
|
||||||
} else if (this.collectionsType.type == "team-collections") {
|
} else if (this.collectionsType.type === "team-collections") {
|
||||||
team_utils
|
teamUtils
|
||||||
.deleteRequest(this.$apollo, requestIndex)
|
.deleteRequest(this.$apollo, requestIndex)
|
||||||
.then((data) => {
|
.then(() => {
|
||||||
// Result
|
// Result
|
||||||
this.$toast.success(this.$t("deleted"), {
|
this.$toast.success(this.$t("deleted"), {
|
||||||
icon: "delete",
|
icon: "delete",
|
||||||
@@ -641,8 +654,11 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
beforeDestroy() {
|
|
||||||
document.removeEventListener("keydown", this._keyListener)
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.virtual-list {
|
||||||
|
max-height: calc(100vh - 270px);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
:class="['row-wrapper transition duration-150 ease-in-out', { 'bg-bgDarkColor': dragging }]"
|
:class="[
|
||||||
|
'row-wrapper transition duration-150 ease-in-out',
|
||||||
|
{ 'bg-bgDarkColor': dragging },
|
||||||
|
]"
|
||||||
@dragover.prevent
|
@dragover.prevent
|
||||||
@drop.prevent="dropEvent"
|
@drop.prevent="dropEvent"
|
||||||
@dragover="dragging = true"
|
@dragover="dragging = true"
|
||||||
@@ -10,10 +13,16 @@
|
|||||||
@dragend="dragging = false"
|
@dragend="dragging = false"
|
||||||
>
|
>
|
||||||
<button class="icon" @click="toggleShowChildren">
|
<button class="icon" @click="toggleShowChildren">
|
||||||
<i class="material-icons" v-show="!showChildren && !isFiltered">arrow_right</i>
|
<i v-show="!showChildren && !isFiltered" class="material-icons"
|
||||||
<i class="material-icons" v-show="showChildren || isFiltered">arrow_drop_down</i>
|
>arrow_right</i
|
||||||
|
>
|
||||||
|
<i v-show="showChildren || isFiltered" class="material-icons"
|
||||||
|
>arrow_drop_down</i
|
||||||
|
>
|
||||||
|
|
||||||
<i v-if="isSelected" class="text-green-400 material-icons">check_circle</i>
|
<i v-if="isSelected" class="text-green-400 material-icons"
|
||||||
|
>check_circle</i
|
||||||
|
>
|
||||||
|
|
||||||
<i v-else class="material-icons">folder</i>
|
<i v-else class="material-icons">folder</i>
|
||||||
<span>{{ collection.name }}</span>
|
<span>{{ collection.name }}</span>
|
||||||
@@ -21,43 +30,56 @@
|
|||||||
<div>
|
<div>
|
||||||
<button
|
<button
|
||||||
v-if="doc && !selected"
|
v-if="doc && !selected"
|
||||||
|
v-tooltip.left="$t('import')"
|
||||||
class="icon"
|
class="icon"
|
||||||
@click="$emit('select-collection')"
|
@click="$emit('select-collection')"
|
||||||
v-tooltip.left="$t('import')"
|
|
||||||
>
|
>
|
||||||
<i class="material-icons">check_box_outline_blank</i>
|
<i class="material-icons">check_box_outline_blank</i>
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
v-if="doc && selected"
|
v-if="doc && selected"
|
||||||
|
v-tooltip.left="$t('delete')"
|
||||||
class="icon"
|
class="icon"
|
||||||
@click="$emit('unselect-collection')"
|
@click="$emit('unselect-collection')"
|
||||||
v-tooltip.left="$t('delete')"
|
|
||||||
>
|
>
|
||||||
<i class="material-icons">check_box</i>
|
<i class="material-icons">check_box</i>
|
||||||
</button>
|
</button>
|
||||||
<v-popover v-if="!saveRequest">
|
<v-popover v-if="!saveRequest">
|
||||||
<button class="tooltip-target icon" v-tooltip.left="$t('more')">
|
<button v-tooltip.left="$t('more')" class="tooltip-target icon">
|
||||||
<i class="material-icons">more_vert</i>
|
<i class="material-icons">more_vert</i>
|
||||||
</button>
|
</button>
|
||||||
<template slot="popover">
|
<template slot="popover">
|
||||||
<div>
|
<div>
|
||||||
<button
|
<button
|
||||||
class="icon"
|
|
||||||
@click="$emit('add-folder', { folder: collection, path: `${collectionIndex}` })"
|
|
||||||
v-close-popover
|
v-close-popover
|
||||||
|
class="icon"
|
||||||
|
@click="
|
||||||
|
$emit('add-folder', {
|
||||||
|
folder: collection,
|
||||||
|
path: `${collectionIndex}`,
|
||||||
|
})
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<i class="material-icons">create_new_folder</i>
|
<i class="material-icons">create_new_folder</i>
|
||||||
<span>{{ $t("new_folder") }}</span>
|
<span>{{ $t("new_folder") }}</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<button class="icon" @click="$emit('edit-collection')" v-close-popover>
|
<button
|
||||||
|
v-close-popover
|
||||||
|
class="icon"
|
||||||
|
@click="$emit('edit-collection')"
|
||||||
|
>
|
||||||
<i class="material-icons">create</i>
|
<i class="material-icons">create</i>
|
||||||
<span>{{ $t("edit") }}</span>
|
<span>{{ $t("edit") }}</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<button class="icon" @click="confirmRemove = true" v-close-popover>
|
<button
|
||||||
|
v-close-popover
|
||||||
|
class="icon"
|
||||||
|
@click="confirmRemove = true"
|
||||||
|
>
|
||||||
<i class="material-icons">delete</i>
|
<i class="material-icons">delete</i>
|
||||||
<span>{{ $t("delete") }}</span>
|
<span>{{ $t("delete") }}</span>
|
||||||
</button>
|
</button>
|
||||||
@@ -79,9 +101,9 @@
|
|||||||
:folder-path="`${collectionIndex}/${index}`"
|
:folder-path="`${collectionIndex}/${index}`"
|
||||||
:collection-index="collectionIndex"
|
:collection-index="collectionIndex"
|
||||||
:doc="doc"
|
:doc="doc"
|
||||||
:saveRequest="saveRequest"
|
:save-request="saveRequest"
|
||||||
:collectionsType="collectionsType"
|
:collections-type="collectionsType"
|
||||||
:isFiltered="isFiltered"
|
:is-filtered="isFiltered"
|
||||||
:picked="picked"
|
:picked="picked"
|
||||||
@add-folder="$emit('add-folder', $event)"
|
@add-folder="$emit('add-folder', $event)"
|
||||||
@edit-folder="$emit('edit-folder', $event)"
|
@edit-folder="$emit('edit-folder', $event)"
|
||||||
@@ -105,8 +127,8 @@
|
|||||||
:folder-path="collectionIndex.toString()"
|
:folder-path="collectionIndex.toString()"
|
||||||
:request-index="index"
|
:request-index="index"
|
||||||
:doc="doc"
|
:doc="doc"
|
||||||
:saveRequest="saveRequest"
|
:save-request="saveRequest"
|
||||||
:collectionsType="collectionsType"
|
:collections-type="collectionsType"
|
||||||
:picked="picked"
|
:picked="picked"
|
||||||
@edit-request="editRequest($event)"
|
@edit-request="editRequest($event)"
|
||||||
@select="$emit('select', $event)"
|
@select="$emit('select', $event)"
|
||||||
@@ -117,13 +139,16 @@
|
|||||||
<ul>
|
<ul>
|
||||||
<li
|
<li
|
||||||
v-if="
|
v-if="
|
||||||
(collection.folders == undefined || collection.folders.length === 0) &&
|
(collection.folders == undefined ||
|
||||||
(collection.requests == undefined || collection.requests.length === 0)
|
collection.folders.length === 0) &&
|
||||||
|
(collection.requests == undefined ||
|
||||||
|
collection.requests.length === 0)
|
||||||
"
|
"
|
||||||
class="flex ml-8 border-l border-brdColor"
|
class="flex ml-8 border-l border-brdColor"
|
||||||
>
|
>
|
||||||
<p class="info">
|
<p class="info">
|
||||||
<i class="material-icons">not_interested</i> {{ $t("collection_empty") }}
|
<i class="material-icons">not_interested</i>
|
||||||
|
{{ $t("collection_empty") }}
|
||||||
</p>
|
</p>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
@@ -143,14 +168,14 @@ import { getSettingSubject } from "~/newstore/settings"
|
|||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
collectionIndex: Number,
|
collectionIndex: { type: Number, default: null },
|
||||||
collection: Object,
|
collection: { type: Object, default: () => {} },
|
||||||
doc: Boolean,
|
doc: Boolean,
|
||||||
isFiltered: Boolean,
|
isFiltered: Boolean,
|
||||||
selected: Boolean,
|
selected: Boolean,
|
||||||
saveRequest: Boolean,
|
saveRequest: Boolean,
|
||||||
collectionsType: Object,
|
collectionsType: { type: Object, default: () => {} },
|
||||||
picked: Object,
|
picked: { type: Object, default: () => {} },
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
:class="['row-wrapper transition duration-150 ease-in-out', { 'bg-bgDarkColor': dragging }]"
|
:class="[
|
||||||
|
'row-wrapper transition duration-150 ease-in-out',
|
||||||
|
{ 'bg-bgDarkColor': dragging },
|
||||||
|
]"
|
||||||
@dragover.prevent
|
@dragover.prevent
|
||||||
@drop.prevent="dropEvent"
|
@drop.prevent="dropEvent"
|
||||||
@dragover="dragging = true"
|
@dragover="dragging = true"
|
||||||
@@ -11,23 +14,29 @@
|
|||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<button class="icon" @click="toggleShowChildren">
|
<button class="icon" @click="toggleShowChildren">
|
||||||
<i class="material-icons" v-show="!showChildren && !isFiltered">arrow_right</i>
|
<i v-show="!showChildren && !isFiltered" class="material-icons"
|
||||||
<i class="material-icons" v-show="showChildren || isFiltered">arrow_drop_down</i>
|
>arrow_right</i
|
||||||
<i v-if="isSelected" class="text-green-400 material-icons">check_circle</i>
|
>
|
||||||
|
<i v-show="showChildren || isFiltered" class="material-icons"
|
||||||
|
>arrow_drop_down</i
|
||||||
|
>
|
||||||
|
<i v-if="isSelected" class="text-green-400 material-icons"
|
||||||
|
>check_circle</i
|
||||||
|
>
|
||||||
<i v-else class="material-icons">folder_open</i>
|
<i v-else class="material-icons">folder_open</i>
|
||||||
<span>{{ folder.name ? folder.name : folder.title }}</span>
|
<span>{{ folder.name ? folder.name : folder.title }}</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<v-popover v-if="!saveRequest">
|
<v-popover v-if="!saveRequest">
|
||||||
<button class="tooltip-target icon" v-tooltip.left="$t('more')">
|
<button v-tooltip.left="$t('more')" class="tooltip-target icon">
|
||||||
<i class="material-icons">more_vert</i>
|
<i class="material-icons">more_vert</i>
|
||||||
</button>
|
</button>
|
||||||
<template slot="popover">
|
<template slot="popover">
|
||||||
<div>
|
<div>
|
||||||
<button
|
<button
|
||||||
|
v-close-popover
|
||||||
class="icon"
|
class="icon"
|
||||||
@click="$emit('add-folder', { folder, path: folderPath })"
|
@click="$emit('add-folder', { folder, path: folderPath })"
|
||||||
v-close-popover
|
|
||||||
>
|
>
|
||||||
<i class="material-icons">create_new_folder</i>
|
<i class="material-icons">create_new_folder</i>
|
||||||
<span>{{ $t("new_folder") }}</span>
|
<span>{{ $t("new_folder") }}</span>
|
||||||
@@ -35,16 +44,18 @@
|
|||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<button
|
<button
|
||||||
class="icon"
|
|
||||||
@click="$emit('edit-folder', { folder, folderIndex, collectionIndex })"
|
|
||||||
v-close-popover
|
v-close-popover
|
||||||
|
class="icon"
|
||||||
|
@click="
|
||||||
|
$emit('edit-folder', { folder, folderIndex, collectionIndex })
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<i class="material-icons">edit</i>
|
<i class="material-icons">edit</i>
|
||||||
<span>{{ $t("edit") }}</span>
|
<span>{{ $t("edit") }}</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<button class="icon" @click="confirmRemove = true" v-close-popover>
|
<button v-close-popover class="icon" @click="confirmRemove = true">
|
||||||
<i class="material-icons">delete</i>
|
<i class="material-icons">delete</i>
|
||||||
<span>{{ $t("delete") }}</span>
|
<span>{{ $t("delete") }}</span>
|
||||||
</button>
|
</button>
|
||||||
@@ -64,8 +75,8 @@
|
|||||||
:folder-index="subFolderIndex"
|
:folder-index="subFolderIndex"
|
||||||
:collection-index="collectionIndex"
|
:collection-index="collectionIndex"
|
||||||
:doc="doc"
|
:doc="doc"
|
||||||
:saveRequest="saveRequest"
|
:save-request="saveRequest"
|
||||||
:collectionsType="collectionsType"
|
:collections-type="collectionsType"
|
||||||
:folder-path="`${folderPath}/${subFolderIndex}`"
|
:folder-path="`${folderPath}/${subFolderIndex}`"
|
||||||
:picked="picked"
|
:picked="picked"
|
||||||
@add-folder="$emit('add-folder', $event)"
|
@add-folder="$emit('add-folder', $event)"
|
||||||
@@ -92,8 +103,8 @@
|
|||||||
:folder-path="folderPath"
|
:folder-path="folderPath"
|
||||||
:doc="doc"
|
:doc="doc"
|
||||||
:picked="picked"
|
:picked="picked"
|
||||||
:saveRequest="saveRequest"
|
:save-request="saveRequest"
|
||||||
:collectionsType="collectionsType"
|
:collections-type="collectionsType"
|
||||||
@edit-request="$emit('edit-request', $event)"
|
@edit-request="$emit('edit-request', $event)"
|
||||||
@select="$emit('select', $event)"
|
@select="$emit('select', $event)"
|
||||||
@remove-request="removeRequest"
|
@remove-request="removeRequest"
|
||||||
@@ -109,7 +120,10 @@
|
|||||||
"
|
"
|
||||||
>
|
>
|
||||||
<li class="flex ml-8 border-l border-brdColor">
|
<li class="flex ml-8 border-l border-brdColor">
|
||||||
<p class="info"><i class="material-icons">not_interested</i> {{ $t("folder_empty") }}</p>
|
<p class="info">
|
||||||
|
<i class="material-icons">not_interested</i>
|
||||||
|
{{ $t("folder_empty") }}
|
||||||
|
</p>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
@@ -127,17 +141,17 @@ import { fb } from "~/helpers/fb"
|
|||||||
import { getSettingSubject } from "~/newstore/settings"
|
import { getSettingSubject } from "~/newstore/settings"
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "folder",
|
name: "Folder",
|
||||||
props: {
|
props: {
|
||||||
folder: Object,
|
folder: { type: Object, default: () => {} },
|
||||||
folderIndex: Number,
|
folderIndex: { type: Number, default: null },
|
||||||
collectionIndex: Number,
|
collectionIndex: { type: Number, default: null },
|
||||||
folderPath: String,
|
folderPath: { type: String, default: null },
|
||||||
doc: Boolean,
|
doc: Boolean,
|
||||||
saveRequest: Boolean,
|
saveRequest: Boolean,
|
||||||
isFiltered: Boolean,
|
isFiltered: Boolean,
|
||||||
collectionsType: Object,
|
collectionsType: { type: Object, default: () => {} },
|
||||||
picked: Object,
|
picked: { type: Object, default: () => {} },
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
:class="['row-wrapper transition duration-150 ease-in-out', { 'bg-bgDarkColor': dragging }]"
|
:class="[
|
||||||
|
'row-wrapper transition duration-150 ease-in-out',
|
||||||
|
{ 'bg-bgDarkColor': dragging },
|
||||||
|
]"
|
||||||
draggable="true"
|
draggable="true"
|
||||||
@dragstart="dragStart"
|
@dragstart="dragStart"
|
||||||
@dragover.stop
|
@dragover.stop
|
||||||
@@ -10,23 +13,28 @@
|
|||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<button
|
<button
|
||||||
|
v-tooltip="!doc ? $t('use_request') : ''"
|
||||||
class="icon"
|
class="icon"
|
||||||
@click="!doc ? selectRequest() : {}"
|
@click="!doc ? selectRequest() : {}"
|
||||||
v-tooltip="!doc ? $t('use_request') : ''"
|
|
||||||
>
|
>
|
||||||
<i v-if="isSelected" class="mx-3 text-green-400 material-icons">check_circle</i>
|
<i v-if="isSelected" class="mx-3 text-green-400 material-icons"
|
||||||
|
>check_circle</i
|
||||||
|
>
|
||||||
|
|
||||||
<span v-else :class="getRequestLabelColor(request.method)">{{ request.method }}</span>
|
<span v-else :class="getRequestLabelColor(request.method)">{{
|
||||||
|
request.method
|
||||||
|
}}</span>
|
||||||
<span>{{ request.name }}</span>
|
<span>{{ request.name }}</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<v-popover v-if="!saveRequest">
|
<v-popover v-if="!saveRequest">
|
||||||
<button class="tooltip-target icon" v-tooltip="$t('more')">
|
<button v-tooltip="$t('more')" class="tooltip-target icon">
|
||||||
<i class="material-icons">more_vert</i>
|
<i class="material-icons">more_vert</i>
|
||||||
</button>
|
</button>
|
||||||
<template slot="popover">
|
<template slot="popover">
|
||||||
<div>
|
<div>
|
||||||
<button
|
<button
|
||||||
|
v-close-popover
|
||||||
class="icon"
|
class="icon"
|
||||||
@click="
|
@click="
|
||||||
$emit('edit-request', {
|
$emit('edit-request', {
|
||||||
@@ -37,14 +45,13 @@
|
|||||||
requestIndex,
|
requestIndex,
|
||||||
})
|
})
|
||||||
"
|
"
|
||||||
v-close-popover
|
|
||||||
>
|
>
|
||||||
<i class="material-icons">edit</i>
|
<i class="material-icons">edit</i>
|
||||||
<span>{{ $t("edit") }}</span>
|
<span>{{ $t("edit") }}</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<button class="icon" @click="confirmRemove = true" v-close-popover>
|
<button v-close-popover class="icon" @click="confirmRemove = true">
|
||||||
<i class="material-icons">delete</i>
|
<i class="material-icons">delete</i>
|
||||||
<span>{{ $t("delete") }}</span>
|
<span>{{ $t("delete") }}</span>
|
||||||
</button>
|
</button>
|
||||||
@@ -64,26 +71,17 @@
|
|||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
request: Object,
|
request: { type: Object, default: () => {} },
|
||||||
collectionIndex: Number,
|
collectionIndex: { type: Number, default: null },
|
||||||
folderIndex: Number,
|
folderIndex: { type: Number, default: null },
|
||||||
folderName: String,
|
folderName: { type: String, default: null },
|
||||||
|
// eslint-disable-next-line vue/require-default-prop
|
||||||
requestIndex: [Number, String],
|
requestIndex: [Number, String],
|
||||||
doc: Boolean,
|
doc: Boolean,
|
||||||
saveRequest: Boolean,
|
saveRequest: Boolean,
|
||||||
collectionsType: Object,
|
collectionsType: { type: Object, default: () => {} },
|
||||||
folderPath: String,
|
folderPath: { type: String, default: null },
|
||||||
picked: Object,
|
picked: { type: Object, default: () => {} },
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
isSelected() {
|
|
||||||
return (
|
|
||||||
this.picked &&
|
|
||||||
this.picked.pickedType === "my-request" &&
|
|
||||||
this.picked.folderPath === this.folderPath &&
|
|
||||||
this.picked.requestIndex === this.requestIndex
|
|
||||||
)
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@@ -98,6 +96,16 @@ export default {
|
|||||||
confirmRemove: false,
|
confirmRemove: false,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
isSelected() {
|
||||||
|
return (
|
||||||
|
this.picked &&
|
||||||
|
this.picked.pickedType === "my-request" &&
|
||||||
|
this.picked.folderPath === this.folderPath &&
|
||||||
|
this.picked.requestIndex === this.requestIndex
|
||||||
|
)
|
||||||
|
},
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
selectRequest() {
|
selectRequest() {
|
||||||
if (this.$props.saveRequest)
|
if (this.$props.saveRequest)
|
||||||
@@ -110,7 +118,8 @@ export default {
|
|||||||
requestIndex: this.requestIndex,
|
requestIndex: this.requestIndex,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
else this.$store.commit("postwoman/selectRequest", { request: this.request })
|
else
|
||||||
|
this.$store.commit("postwoman/selectRequest", { request: this.request })
|
||||||
},
|
},
|
||||||
dragStart({ dataTransfer }) {
|
dragStart({ dataTransfer }) {
|
||||||
this.dragging = !this.dragging
|
this.dragging = !this.dragging
|
||||||
@@ -127,7 +136,10 @@ export default {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
getRequestLabelColor(method) {
|
getRequestLabelColor(method) {
|
||||||
return this.requestMethodLabels[method.toLowerCase()] || this.requestMethodLabels.default
|
return (
|
||||||
|
this.requestMethodLabels[method.toLowerCase()] ||
|
||||||
|
this.requestMethodLabels.default
|
||||||
|
)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,10 +2,16 @@
|
|||||||
<div>
|
<div>
|
||||||
<div class="transition duration-150 ease-in-out row-wrapper">
|
<div class="transition duration-150 ease-in-out row-wrapper">
|
||||||
<button class="icon" @click="toggleShowChildren">
|
<button class="icon" @click="toggleShowChildren">
|
||||||
<i class="material-icons" v-show="!showChildren && !isFiltered">arrow_right</i>
|
<i v-show="!showChildren && !isFiltered" class="material-icons"
|
||||||
<i class="material-icons" v-show="showChildren || isFiltered">arrow_drop_down</i>
|
>arrow_right</i
|
||||||
|
>
|
||||||
|
<i v-show="showChildren || isFiltered" class="material-icons"
|
||||||
|
>arrow_drop_down</i
|
||||||
|
>
|
||||||
|
|
||||||
<i v-if="isSelected" class="text-green-400 material-icons">check_circle</i>
|
<i v-if="isSelected" class="text-green-400 material-icons"
|
||||||
|
>check_circle</i
|
||||||
|
>
|
||||||
|
|
||||||
<i v-else class="material-icons">folder</i>
|
<i v-else class="material-icons">folder</i>
|
||||||
<span>{{ collection.title }}</span>
|
<span>{{ collection.title }}</span>
|
||||||
@@ -13,25 +19,25 @@
|
|||||||
<div>
|
<div>
|
||||||
<button
|
<button
|
||||||
v-if="doc && !selected"
|
v-if="doc && !selected"
|
||||||
|
v-tooltip.left="$t('import')"
|
||||||
class="icon"
|
class="icon"
|
||||||
@click="$emit('select-collection')"
|
@click="$emit('select-collection')"
|
||||||
v-tooltip.left="$t('import')"
|
|
||||||
>
|
>
|
||||||
<i class="material-icons">check_box_outline_blank</i>
|
<i class="material-icons">check_box_outline_blank</i>
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
v-if="doc && selected"
|
v-if="doc && selected"
|
||||||
|
v-tooltip.left="$t('delete')"
|
||||||
class="icon"
|
class="icon"
|
||||||
@click="$emit('unselect-collection')"
|
@click="$emit('unselect-collection')"
|
||||||
v-tooltip.left="$t('delete')"
|
|
||||||
>
|
>
|
||||||
<i class="material-icons">check_box</i>
|
<i class="material-icons">check_box</i>
|
||||||
</button>
|
</button>
|
||||||
<v-popover v-if="!saveRequest">
|
<v-popover v-if="!saveRequest">
|
||||||
<button
|
<button
|
||||||
v-if="collectionsType.selectedTeam.myRole !== 'VIEWER'"
|
v-if="collectionsType.selectedTeam.myRole !== 'VIEWER'"
|
||||||
class="tooltip-target icon"
|
|
||||||
v-tooltip.left="$t('more')"
|
v-tooltip.left="$t('more')"
|
||||||
|
class="tooltip-target icon"
|
||||||
>
|
>
|
||||||
<i class="material-icons">more_vert</i>
|
<i class="material-icons">more_vert</i>
|
||||||
</button>
|
</button>
|
||||||
@@ -39,9 +45,14 @@
|
|||||||
<div>
|
<div>
|
||||||
<button
|
<button
|
||||||
v-if="collectionsType.selectedTeam.myRole !== 'VIEWER'"
|
v-if="collectionsType.selectedTeam.myRole !== 'VIEWER'"
|
||||||
class="icon"
|
|
||||||
@click="$emit('add-folder', { folder: collection, path: `${collectionIndex}` })"
|
|
||||||
v-close-popover
|
v-close-popover
|
||||||
|
class="icon"
|
||||||
|
@click="
|
||||||
|
$emit('add-folder', {
|
||||||
|
folder: collection,
|
||||||
|
path: `${collectionIndex}`,
|
||||||
|
})
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<i class="material-icons">create_new_folder</i>
|
<i class="material-icons">create_new_folder</i>
|
||||||
<span>{{ $t("new_folder") }}</span>
|
<span>{{ $t("new_folder") }}</span>
|
||||||
@@ -50,9 +61,9 @@
|
|||||||
<div>
|
<div>
|
||||||
<button
|
<button
|
||||||
v-if="collectionsType.selectedTeam.myRole !== 'VIEWER'"
|
v-if="collectionsType.selectedTeam.myRole !== 'VIEWER'"
|
||||||
|
v-close-popover
|
||||||
class="icon"
|
class="icon"
|
||||||
@click="$emit('edit-collection')"
|
@click="$emit('edit-collection')"
|
||||||
v-close-popover
|
|
||||||
>
|
>
|
||||||
<i class="material-icons">create</i>
|
<i class="material-icons">create</i>
|
||||||
<span>{{ $t("edit") }}</span>
|
<span>{{ $t("edit") }}</span>
|
||||||
@@ -61,9 +72,9 @@
|
|||||||
<div>
|
<div>
|
||||||
<button
|
<button
|
||||||
v-if="collectionsType.selectedTeam.myRole !== 'VIEWER'"
|
v-if="collectionsType.selectedTeam.myRole !== 'VIEWER'"
|
||||||
|
v-close-popover
|
||||||
class="icon"
|
class="icon"
|
||||||
@click="confirmRemove = true"
|
@click="confirmRemove = true"
|
||||||
v-close-popover
|
|
||||||
>
|
>
|
||||||
<i class="material-icons">delete</i>
|
<i class="material-icons">delete</i>
|
||||||
<span>{{ $t("delete") }}</span>
|
<span>{{ $t("delete") }}</span>
|
||||||
@@ -86,9 +97,9 @@
|
|||||||
:folder-path="`${collectionIndex}/${index}`"
|
:folder-path="`${collectionIndex}/${index}`"
|
||||||
:collection-index="collectionIndex"
|
:collection-index="collectionIndex"
|
||||||
:doc="doc"
|
:doc="doc"
|
||||||
:saveRequest="saveRequest"
|
:save-request="saveRequest"
|
||||||
:collectionsType="collectionsType"
|
:collections-type="collectionsType"
|
||||||
:isFiltered="isFiltered"
|
:is-filtered="isFiltered"
|
||||||
:picked="picked"
|
:picked="picked"
|
||||||
@add-folder="$emit('add-folder', $event)"
|
@add-folder="$emit('add-folder', $event)"
|
||||||
@edit-folder="$emit('edit-folder', $event)"
|
@edit-folder="$emit('edit-folder', $event)"
|
||||||
@@ -112,8 +123,8 @@
|
|||||||
:folder-name="collection.name"
|
:folder-name="collection.name"
|
||||||
:request-index="request.id"
|
:request-index="request.id"
|
||||||
:doc="doc"
|
:doc="doc"
|
||||||
:saveRequest="saveRequest"
|
:save-request="saveRequest"
|
||||||
:collectionsType="collectionsType"
|
:collections-type="collectionsType"
|
||||||
:picked="picked"
|
:picked="picked"
|
||||||
@edit-request="editRequest($event)"
|
@edit-request="editRequest($event)"
|
||||||
@select="$emit('select', $event)"
|
@select="$emit('select', $event)"
|
||||||
@@ -124,13 +135,16 @@
|
|||||||
<ul>
|
<ul>
|
||||||
<li
|
<li
|
||||||
v-if="
|
v-if="
|
||||||
(collection.children == undefined || collection.children.length === 0) &&
|
(collection.children == undefined ||
|
||||||
(collection.requests == undefined || collection.requests.length === 0)
|
collection.children.length === 0) &&
|
||||||
|
(collection.requests == undefined ||
|
||||||
|
collection.requests.length === 0)
|
||||||
"
|
"
|
||||||
class="flex ml-8 border-l border-brdColor"
|
class="flex ml-8 border-l border-brdColor"
|
||||||
>
|
>
|
||||||
<p class="info">
|
<p class="info">
|
||||||
<i class="material-icons">not_interested</i> {{ $t("collection_empty") }}
|
<i class="material-icons">not_interested</i>
|
||||||
|
{{ $t("collection_empty") }}
|
||||||
</p>
|
</p>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
@@ -147,14 +161,14 @@
|
|||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
collectionIndex: Number,
|
collectionIndex: { type: Number, default: null },
|
||||||
collection: Object,
|
collection: { type: Object, default: () => {} },
|
||||||
doc: Boolean,
|
doc: Boolean,
|
||||||
isFiltered: Boolean,
|
isFiltered: Boolean,
|
||||||
selected: Boolean,
|
selected: Boolean,
|
||||||
saveRequest: Boolean,
|
saveRequest: Boolean,
|
||||||
collectionsType: Object,
|
collectionsType: { type: Object, default: () => {} },
|
||||||
picked: Object,
|
picked: { type: Object, default: () => {} },
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -3,10 +3,16 @@
|
|||||||
<div class="transition duration-150 ease-in-out row-wrapper">
|
<div class="transition duration-150 ease-in-out row-wrapper">
|
||||||
<div>
|
<div>
|
||||||
<button class="icon" @click="toggleShowChildren">
|
<button class="icon" @click="toggleShowChildren">
|
||||||
<i class="material-icons" v-show="!showChildren && !isFiltered">arrow_right</i>
|
<i v-show="!showChildren && !isFiltered" class="material-icons"
|
||||||
<i class="material-icons" v-show="showChildren || isFiltered">arrow_drop_down</i>
|
>arrow_right</i
|
||||||
|
>
|
||||||
|
<i v-show="showChildren || isFiltered" class="material-icons"
|
||||||
|
>arrow_drop_down</i
|
||||||
|
>
|
||||||
|
|
||||||
<i v-if="isSelected" class="text-green-400 material-icons">check_circle</i>
|
<i v-if="isSelected" class="text-green-400 material-icons"
|
||||||
|
>check_circle</i
|
||||||
|
>
|
||||||
|
|
||||||
<i v-else class="material-icons">folder_open</i>
|
<i v-else class="material-icons">folder_open</i>
|
||||||
<span>{{ folder.name ? folder.name : folder.title }}</span>
|
<span>{{ folder.name ? folder.name : folder.title }}</span>
|
||||||
@@ -15,8 +21,8 @@
|
|||||||
<v-popover v-if="!saveRequest">
|
<v-popover v-if="!saveRequest">
|
||||||
<button
|
<button
|
||||||
v-if="collectionsType.selectedTeam.myRole !== 'VIEWER'"
|
v-if="collectionsType.selectedTeam.myRole !== 'VIEWER'"
|
||||||
class="tooltip-target icon"
|
|
||||||
v-tooltip.left="$t('more')"
|
v-tooltip.left="$t('more')"
|
||||||
|
class="tooltip-target icon"
|
||||||
>
|
>
|
||||||
<i class="material-icons">more_vert</i>
|
<i class="material-icons">more_vert</i>
|
||||||
</button>
|
</button>
|
||||||
@@ -24,9 +30,9 @@
|
|||||||
<div>
|
<div>
|
||||||
<button
|
<button
|
||||||
v-if="collectionsType.selectedTeam.myRole !== 'VIEWER'"
|
v-if="collectionsType.selectedTeam.myRole !== 'VIEWER'"
|
||||||
|
v-close-popover
|
||||||
class="icon"
|
class="icon"
|
||||||
@click="$emit('add-folder', { folder, path: folderPath })"
|
@click="$emit('add-folder', { folder, path: folderPath })"
|
||||||
v-close-popover
|
|
||||||
>
|
>
|
||||||
<i class="material-icons">create_new_folder</i>
|
<i class="material-icons">create_new_folder</i>
|
||||||
<span>{{ $t("new_folder") }}</span>
|
<span>{{ $t("new_folder") }}</span>
|
||||||
@@ -35,9 +41,11 @@
|
|||||||
<div>
|
<div>
|
||||||
<button
|
<button
|
||||||
v-if="collectionsType.selectedTeam.myRole !== 'VIEWER'"
|
v-if="collectionsType.selectedTeam.myRole !== 'VIEWER'"
|
||||||
class="icon"
|
|
||||||
@click="$emit('edit-folder', { folder, folderIndex, collectionIndex })"
|
|
||||||
v-close-popover
|
v-close-popover
|
||||||
|
class="icon"
|
||||||
|
@click="
|
||||||
|
$emit('edit-folder', { folder, folderIndex, collectionIndex })
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<i class="material-icons">edit</i>
|
<i class="material-icons">edit</i>
|
||||||
<span>{{ $t("edit") }}</span>
|
<span>{{ $t("edit") }}</span>
|
||||||
@@ -46,9 +54,9 @@
|
|||||||
<div>
|
<div>
|
||||||
<button
|
<button
|
||||||
v-if="collectionsType.selectedTeam.myRole !== 'VIEWER'"
|
v-if="collectionsType.selectedTeam.myRole !== 'VIEWER'"
|
||||||
|
v-close-popover
|
||||||
class="icon"
|
class="icon"
|
||||||
@click="confirmRemove = true"
|
@click="confirmRemove = true"
|
||||||
v-close-popover
|
|
||||||
>
|
>
|
||||||
<i class="material-icons">delete</i>
|
<i class="material-icons">delete</i>
|
||||||
<span>{{ $t("delete") }}</span>
|
<span>{{ $t("delete") }}</span>
|
||||||
@@ -69,8 +77,8 @@
|
|||||||
:folder-index="subFolderIndex"
|
:folder-index="subFolderIndex"
|
||||||
:collection-index="collectionIndex"
|
:collection-index="collectionIndex"
|
||||||
:doc="doc"
|
:doc="doc"
|
||||||
:saveRequest="saveRequest"
|
:save-request="saveRequest"
|
||||||
:collectionsType="collectionsType"
|
:collections-type="collectionsType"
|
||||||
:folder-path="`${folderPath}/${subFolderIndex}`"
|
:folder-path="`${folderPath}/${subFolderIndex}`"
|
||||||
:picked="picked"
|
:picked="picked"
|
||||||
@add-folder="$emit('add-folder', $event)"
|
@add-folder="$emit('add-folder', $event)"
|
||||||
@@ -96,8 +104,8 @@
|
|||||||
:folder-name="folder.name"
|
:folder-name="folder.name"
|
||||||
:request-index="request.id"
|
:request-index="request.id"
|
||||||
:doc="doc"
|
:doc="doc"
|
||||||
:saveRequest="saveRequest"
|
:save-request="saveRequest"
|
||||||
:collectionsType="collectionsType"
|
:collections-type="collectionsType"
|
||||||
:picked="picked"
|
:picked="picked"
|
||||||
@edit-request="$emit('edit-request', $event)"
|
@edit-request="$emit('edit-request', $event)"
|
||||||
@select="$emit('select', $event)"
|
@select="$emit('select', $event)"
|
||||||
@@ -112,7 +120,10 @@
|
|||||||
"
|
"
|
||||||
>
|
>
|
||||||
<li class="flex ml-8 border-l border-brdColor">
|
<li class="flex ml-8 border-l border-brdColor">
|
||||||
<p class="info"><i class="material-icons">not_interested</i> {{ $t("folder_empty") }}</p>
|
<p class="info">
|
||||||
|
<i class="material-icons">not_interested</i>
|
||||||
|
{{ $t("folder_empty") }}
|
||||||
|
</p>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
@@ -126,20 +137,20 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import * as team_utils from "~/helpers/teams/utils"
|
import * as teamUtils from "~/helpers/teams/utils"
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "folder",
|
name: "Folder",
|
||||||
props: {
|
props: {
|
||||||
folder: Object,
|
folder: { type: Object, default: () => {} },
|
||||||
folderIndex: Number,
|
folderIndex: { type: Number, default: null },
|
||||||
collectionIndex: Number,
|
collectionIndex: { type: Number, default: null },
|
||||||
folderPath: String,
|
folderPath: { type: String, default: null },
|
||||||
doc: Boolean,
|
doc: Boolean,
|
||||||
saveRequest: Boolean,
|
saveRequest: Boolean,
|
||||||
isFiltered: Boolean,
|
isFiltered: Boolean,
|
||||||
collectionsType: Object,
|
collectionsType: { type: Object, default: () => {} },
|
||||||
picked: Object,
|
picked: { type: Object, default: () => {} },
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@@ -172,10 +183,10 @@ export default {
|
|||||||
this.showChildren = !this.showChildren
|
this.showChildren = !this.showChildren
|
||||||
},
|
},
|
||||||
removeFolder() {
|
removeFolder() {
|
||||||
if (this.collectionsType.selectedTeam.myRole != "VIEWER") {
|
if (this.collectionsType.selectedTeam.myRole !== "VIEWER") {
|
||||||
team_utils
|
teamUtils
|
||||||
.deleteCollection(this.$apollo, this.folder.id)
|
.deleteCollection(this.$apollo, this.folder.id)
|
||||||
.then((data) => {
|
.then(() => {
|
||||||
// Result
|
// Result
|
||||||
this.$toast.success(this.$t("deleted"), {
|
this.$toast.success(this.$t("deleted"), {
|
||||||
icon: "delete",
|
icon: "delete",
|
||||||
|
|||||||
@@ -3,27 +3,32 @@
|
|||||||
<div class="transition duration-150 ease-in-out row-wrapper">
|
<div class="transition duration-150 ease-in-out row-wrapper">
|
||||||
<div>
|
<div>
|
||||||
<button
|
<button
|
||||||
|
v-tooltip="!doc ? $t('use_request') : ''"
|
||||||
class="icon"
|
class="icon"
|
||||||
@click="!doc ? selectRequest() : {}"
|
@click="!doc ? selectRequest() : {}"
|
||||||
v-tooltip="!doc ? $t('use_request') : ''"
|
|
||||||
>
|
>
|
||||||
<i v-if="isSelected" class="mx-3 text-green-400 material-icons">check_circle</i>
|
<i v-if="isSelected" class="mx-3 text-green-400 material-icons"
|
||||||
|
>check_circle</i
|
||||||
|
>
|
||||||
|
|
||||||
<span v-else :class="getRequestLabelColor(request.method)">{{ request.method }}</span>
|
<span v-else :class="getRequestLabelColor(request.method)">{{
|
||||||
|
request.method
|
||||||
|
}}</span>
|
||||||
<span>{{ request.name }}</span>
|
<span>{{ request.name }}</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<v-popover v-if="!saveRequest">
|
<v-popover v-if="!saveRequest">
|
||||||
<button
|
<button
|
||||||
v-if="collectionsType.selectedTeam.myRole !== 'VIEWER'"
|
v-if="collectionsType.selectedTeam.myRole !== 'VIEWER'"
|
||||||
class="tooltip-target icon"
|
|
||||||
v-tooltip="$t('more')"
|
v-tooltip="$t('more')"
|
||||||
|
class="tooltip-target icon"
|
||||||
>
|
>
|
||||||
<i class="material-icons">more_vert</i>
|
<i class="material-icons">more_vert</i>
|
||||||
</button>
|
</button>
|
||||||
<template slot="popover">
|
<template slot="popover">
|
||||||
<div>
|
<div>
|
||||||
<button
|
<button
|
||||||
|
v-close-popover
|
||||||
class="icon"
|
class="icon"
|
||||||
@click="
|
@click="
|
||||||
$emit('edit-request', {
|
$emit('edit-request', {
|
||||||
@@ -34,14 +39,13 @@
|
|||||||
requestIndex,
|
requestIndex,
|
||||||
})
|
})
|
||||||
"
|
"
|
||||||
v-close-popover
|
|
||||||
>
|
>
|
||||||
<i class="material-icons">edit</i>
|
<i class="material-icons">edit</i>
|
||||||
<span>{{ $t("edit") }}</span>
|
<span>{{ $t("edit") }}</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<button class="icon" @click="confirmRemove = true" v-close-popover>
|
<button v-close-popover class="icon" @click="confirmRemove = true">
|
||||||
<i class="material-icons">delete</i>
|
<i class="material-icons">delete</i>
|
||||||
<span>{{ $t("delete") }}</span>
|
<span>{{ $t("delete") }}</span>
|
||||||
</button>
|
</button>
|
||||||
@@ -61,15 +65,16 @@
|
|||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
request: Object,
|
request: { type: Object, default: () => {} },
|
||||||
collectionIndex: Number,
|
collectionIndex: { type: Number, default: null },
|
||||||
folderIndex: Number,
|
folderIndex: { type: Number, default: null },
|
||||||
folderName: String,
|
folderName: { type: String, default: null },
|
||||||
|
// eslint-disable-next-line vue/require-default-prop
|
||||||
requestIndex: [Number, String],
|
requestIndex: [Number, String],
|
||||||
doc: Boolean,
|
doc: Boolean,
|
||||||
saveRequest: Boolean,
|
saveRequest: Boolean,
|
||||||
collectionsType: Object,
|
collectionsType: { type: Object, default: () => {} },
|
||||||
picked: Object,
|
picked: { type: Object, default: () => {} },
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@@ -102,7 +107,8 @@ export default {
|
|||||||
requestID: this.requestIndex,
|
requestID: this.requestIndex,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
else this.$store.commit("postwoman/selectRequest", { request: this.request })
|
else
|
||||||
|
this.$store.commit("postwoman/selectRequest", { request: this.request })
|
||||||
},
|
},
|
||||||
removeRequest() {
|
removeRequest() {
|
||||||
this.$emit("remove-request", {
|
this.$emit("remove-request", {
|
||||||
@@ -112,7 +118,10 @@ export default {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
getRequestLabelColor(method) {
|
getRequestLabelColor(method) {
|
||||||
return this.requestMethodLabels[method.toLowerCase()] || this.requestMethodLabels.default
|
return (
|
||||||
|
this.requestMethodLabels[method.toLowerCase()] ||
|
||||||
|
this.requestMethodLabels.default
|
||||||
|
)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,17 +6,24 @@
|
|||||||
(
|
(
|
||||||
<span v-for="(field, index) in fieldArgs" :key="index">
|
<span v-for="(field, index) in fieldArgs" :key="index">
|
||||||
{{ field.name }}:
|
{{ field.name }}:
|
||||||
<GraphqlTypeLink :gqlType="field.type" :jumpTypeCallback="jumpTypeCallback" />
|
<GraphqlTypeLink
|
||||||
|
:gql-type="field.type"
|
||||||
|
:jump-type-callback="jumpTypeCallback"
|
||||||
|
/>
|
||||||
<span v-if="index !== fieldArgs.length - 1"> , </span>
|
<span v-if="index !== fieldArgs.length - 1"> , </span>
|
||||||
</span>
|
</span>
|
||||||
) </span
|
) </span
|
||||||
>:
|
>:
|
||||||
<GraphqlTypeLink :gqlType="gqlField.type" :jumpTypeCallback="jumpTypeCallback" />
|
<GraphqlTypeLink
|
||||||
|
:gql-type="gqlField.type"
|
||||||
|
:jump-type-callback="jumpTypeCallback"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-2 text-fgLightColor field-desc" v-if="gqlField.description">
|
<div v-if="gqlField.description" class="mt-2 text-fgLightColor field-desc">
|
||||||
{{ gqlField.description }}
|
{{ gqlField.description }}
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
|
v-if="gqlField.isDeprecated"
|
||||||
class="
|
class="
|
||||||
inline-block
|
inline-block
|
||||||
px-4
|
px-4
|
||||||
@@ -29,7 +36,6 @@
|
|||||||
rounded-lg
|
rounded-lg
|
||||||
field-deprecated
|
field-deprecated
|
||||||
"
|
"
|
||||||
v-if="gqlField.isDeprecated"
|
|
||||||
>
|
>
|
||||||
{{ $t("deprecated") }}
|
{{ $t("deprecated") }}
|
||||||
</div>
|
</div>
|
||||||
@@ -38,8 +44,14 @@
|
|||||||
<div class="px-4 border-l-2 border-acColor">
|
<div class="px-4 border-l-2 border-acColor">
|
||||||
<div v-for="(field, index) in fieldArgs" :key="index">
|
<div v-for="(field, index) in fieldArgs" :key="index">
|
||||||
{{ field.name }}:
|
{{ field.name }}:
|
||||||
<GraphqlTypeLink :gqlType="field.type" :jumpTypeCallback="jumpTypeCallback" />
|
<GraphqlTypeLink
|
||||||
<div class="mt-2 text-fgLightColor field-desc" v-if="field.description">
|
:gql-type="field.type"
|
||||||
|
:jump-type-callback="jumpTypeCallback"
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
v-if="field.description"
|
||||||
|
class="mt-2 text-fgLightColor field-desc"
|
||||||
|
>
|
||||||
{{ field.description }}
|
{{ field.description }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -48,18 +60,11 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
.field-highlighted {
|
|
||||||
@apply border-b-2;
|
|
||||||
@apply border-acColor;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
gqlField: Object,
|
gqlField: { type: Object, default: () => {} },
|
||||||
jumpTypeCallback: Function,
|
jumpTypeCallback: { type: Function, default: () => {} },
|
||||||
isHighlighted: { type: Boolean, default: false },
|
isHighlighted: { type: Boolean, default: false },
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@@ -73,3 +78,10 @@ export default {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.field-highlighted {
|
||||||
|
@apply border-b-2;
|
||||||
|
@apply border-acColor;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -4,27 +4,15 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
.show-if-initialized {
|
|
||||||
&.initialized {
|
|
||||||
@apply opacity-100;
|
|
||||||
}
|
|
||||||
|
|
||||||
& > * {
|
|
||||||
@apply transition-none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import ace from "ace-builds"
|
import ace from "ace-builds"
|
||||||
import "ace-builds/webpack-resolver"
|
import "ace-builds/webpack-resolver"
|
||||||
import "ace-builds/src-noconflict/ext-language_tools"
|
import "ace-builds/src-noconflict/ext-language_tools"
|
||||||
import "ace-builds/src-noconflict/mode-graphqlschema"
|
import "ace-builds/src-noconflict/mode-graphqlschema"
|
||||||
import { defineGQLLanguageMode } from "~/helpers/syntax/gqlQueryLangMode"
|
|
||||||
|
|
||||||
import * as gql from "graphql"
|
import * as gql from "graphql"
|
||||||
import { getAutocompleteSuggestions } from "graphql-language-service-interface"
|
import { getAutocompleteSuggestions } from "graphql-language-service-interface"
|
||||||
|
import { defineGQLLanguageMode } from "~/helpers/syntax/gqlQueryLangMode"
|
||||||
import debounce from "~/helpers/utils/debounce"
|
import debounce from "~/helpers/utils/debounce"
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@@ -44,7 +32,7 @@ export default {
|
|||||||
},
|
},
|
||||||
options: {
|
options: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: {},
|
default: () => {},
|
||||||
},
|
},
|
||||||
styles: {
|
styles: {
|
||||||
type: String,
|
type: String,
|
||||||
@@ -84,7 +72,7 @@ export default {
|
|||||||
mounted() {
|
mounted() {
|
||||||
defineGQLLanguageMode(ace)
|
defineGQLLanguageMode(ace)
|
||||||
|
|
||||||
let langTools = ace.require("ace/ext/language_tools")
|
const langTools = ace.require("ace/ext/language_tools")
|
||||||
|
|
||||||
const editor = ace.edit(this.$refs.editor, {
|
const editor = ace.edit(this.$refs.editor, {
|
||||||
mode: `ace/mode/gql-query`,
|
mode: `ace/mode/gql-query`,
|
||||||
@@ -108,12 +96,22 @@ export default {
|
|||||||
})
|
})
|
||||||
|
|
||||||
const completer = {
|
const completer = {
|
||||||
getCompletions: (editor, _session, { row, column }, _prefix, callback) => {
|
getCompletions: (
|
||||||
|
editor,
|
||||||
|
_session,
|
||||||
|
{ row, column },
|
||||||
|
_prefix,
|
||||||
|
callback
|
||||||
|
) => {
|
||||||
if (this.validationSchema) {
|
if (this.validationSchema) {
|
||||||
const completions = getAutocompleteSuggestions(this.validationSchema, editor.getValue(), {
|
const completions = getAutocompleteSuggestions(
|
||||||
line: row,
|
this.validationSchema,
|
||||||
character: column,
|
editor.getValue(),
|
||||||
})
|
{
|
||||||
|
line: row,
|
||||||
|
character: column,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
callback(
|
callback(
|
||||||
null,
|
null,
|
||||||
@@ -165,10 +163,14 @@ export default {
|
|||||||
this.parseContents(this.value)
|
this.parseContents(this.value)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
beforeDestroy() {
|
||||||
|
this.editor.destroy()
|
||||||
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
prettifyQuery() {
|
prettifyQuery() {
|
||||||
try {
|
try {
|
||||||
this.value = gql.print(gql.parse(this.editor.getValue()))
|
this.$emit("update-query", gql.print(gql.parse(this.editor.getValue())))
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.$toast.error(`${this.$t("gql_prettify_invalid_query")}`, {
|
this.$toast.error(`${this.$t("gql_prettify_invalid_query")}`, {
|
||||||
icon: "error",
|
icon: "error",
|
||||||
@@ -180,9 +182,12 @@ export default {
|
|||||||
if (this.theme) {
|
if (this.theme) {
|
||||||
return this.theme
|
return this.theme
|
||||||
}
|
}
|
||||||
const strip = (str) => str.replace(/#/g, "").replace(/ /g, "").replace(/"/g, "")
|
const strip = (str) =>
|
||||||
|
str.replace(/#/g, "").replace(/ /g, "").replace(/"/g, "")
|
||||||
return strip(
|
return strip(
|
||||||
window.getComputedStyle(document.documentElement).getPropertyValue("--editor-theme")
|
window
|
||||||
|
.getComputedStyle(document.documentElement)
|
||||||
|
.getPropertyValue("--editor-theme")
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -198,12 +203,14 @@ export default {
|
|||||||
|
|
||||||
if (this.validationSchema) {
|
if (this.validationSchema) {
|
||||||
this.editor.session.setAnnotations(
|
this.editor.session.setAnnotations(
|
||||||
gql.validate(this.validationSchema, doc).map(({ locations, message }) => ({
|
gql
|
||||||
row: locations[0].line - 1,
|
.validate(this.validationSchema, doc)
|
||||||
column: locations[0].column - 1,
|
.map(({ locations, message }) => ({
|
||||||
text: message,
|
row: locations[0].line - 1,
|
||||||
type: "error",
|
column: locations[0].column - 1,
|
||||||
}))
|
text: message,
|
||||||
|
type: "error",
|
||||||
|
}))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -221,9 +228,17 @@ export default {
|
|||||||
}
|
}
|
||||||
}, 2000),
|
}, 2000),
|
||||||
},
|
},
|
||||||
|
|
||||||
beforeDestroy() {
|
|
||||||
this.editor.destroy()
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.show-if-initialized {
|
||||||
|
&.initialized {
|
||||||
|
@apply opacity-100;
|
||||||
|
}
|
||||||
|
|
||||||
|
& > * {
|
||||||
|
@apply transition-none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -1,65 +1,79 @@
|
|||||||
<template>
|
<template>
|
||||||
<div :id="`type_${gqlType.name}`" class="p-2 m-2">
|
<div :id="`type_${gqlType.name}`" class="p-2 m-2">
|
||||||
<div class="font-bold type-title" :class="{ 'type-highlighted': isHighlighted }">
|
<div
|
||||||
|
class="font-bold type-title"
|
||||||
|
:class="{ 'type-highlighted': isHighlighted }"
|
||||||
|
>
|
||||||
<span v-if="isInput" class="font-normal text-acColor">input </span>
|
<span v-if="isInput" class="font-normal text-acColor">input </span>
|
||||||
<span v-else-if="isInterface" class="font-normal text-acColor">interface </span>
|
<span v-else-if="isInterface" class="font-normal text-acColor"
|
||||||
|
>interface
|
||||||
|
</span>
|
||||||
<span v-else-if="isEnum" class="font-normal text-acColor">enum </span>
|
<span v-else-if="isEnum" class="font-normal text-acColor">enum </span>
|
||||||
{{ gqlType.name }}
|
{{ gqlType.name }}
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-2 text-fgLightColor type-desc" v-if="gqlType.description">
|
<div v-if="gqlType.description" class="mt-2 text-fgLightColor type-desc">
|
||||||
{{ gqlType.description }}
|
{{ gqlType.description }}
|
||||||
</div>
|
</div>
|
||||||
<div v-if="interfaces.length > 0" class="mb-2">
|
<div v-if="interfaces.length > 0" class="mb-2">
|
||||||
<h5>{{ $t("interfaces") }}</h5>
|
<h5>{{ $t("interfaces") }}</h5>
|
||||||
<div v-for="gqlInterface in interfaces" :key="gqlInterface.name" class="m-2 ml-4">
|
<div
|
||||||
<GraphqlTypeLink :gqlType="gqlInterface" :jumpTypeCallback="jumpTypeCallback" />
|
v-for="gqlInterface in interfaces"
|
||||||
|
:key="gqlInterface.name"
|
||||||
|
class="m-2 ml-4"
|
||||||
|
>
|
||||||
|
<GraphqlTypeLink
|
||||||
|
:gql-type="gqlInterface"
|
||||||
|
:jump-type-callback="jumpTypeCallback"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="children.length > 0" class="mb-2">
|
<div v-if="children.length > 0" class="mb-2">
|
||||||
<h5>{{ $t("children") }}</h5>
|
<h5>{{ $t("children") }}</h5>
|
||||||
<div v-for="child in children" :key="child.name" class="m-2 ml-4">
|
<div v-for="child in children" :key="child.name" class="m-2 ml-4">
|
||||||
<GraphqlTypeLink :gqlType="child" :jumpTypeCallback="jumpTypeCallback" />
|
<GraphqlTypeLink
|
||||||
|
:gql-type="child"
|
||||||
|
:jump-type-callback="jumpTypeCallback"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="gqlType.getFields">
|
<div v-if="gqlType.getFields">
|
||||||
<h5>{{ $t("fields") }}</h5>
|
<h5>{{ $t("fields") }}</h5>
|
||||||
<div v-for="field in gqlType.getFields()" :key="field.name">
|
<div v-for="field in gqlType.getFields()" :key="field.name">
|
||||||
<GraphqlField
|
<GraphqlField
|
||||||
:gqlField="field"
|
:gql-field="field"
|
||||||
:isHighlighted="isFieldHighlighted({ field })"
|
:is-highlighted="isFieldHighlighted({ field })"
|
||||||
:jumpTypeCallback="jumpTypeCallback"
|
:jump-type-callback="jumpTypeCallback"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="isEnum">
|
<div v-if="isEnum">
|
||||||
<h5>{{ $t("values") }}</h5>
|
<h5>{{ $t("values") }}</h5>
|
||||||
<div :key="value.name" v-for="value in gqlType.getValues()" class="m-4" v-text="value.name" />
|
<div
|
||||||
|
v-for="value in gqlType.getValues()"
|
||||||
|
:key="value.name"
|
||||||
|
class="m-4"
|
||||||
|
v-text="value.name"
|
||||||
|
></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
.type-highlighted {
|
|
||||||
@apply text-acColor;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { GraphQLEnumType, GraphQLInputObjectType, GraphQLInterfaceType } from "graphql"
|
import {
|
||||||
|
GraphQLEnumType,
|
||||||
|
GraphQLInputObjectType,
|
||||||
|
GraphQLInterfaceType,
|
||||||
|
} from "graphql"
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
|
// eslint-disable-next-line vue/require-default-prop, vue/require-prop-types
|
||||||
gqlType: {},
|
gqlType: {},
|
||||||
gqlTypes: Array,
|
gqlTypes: { type: Array, default: () => [] },
|
||||||
jumpTypeCallback: Function,
|
jumpTypeCallback: { type: Function, default: () => {} },
|
||||||
isHighlighted: { type: Boolean, default: false },
|
isHighlighted: { type: Boolean, default: false },
|
||||||
highlightedFields: { type: Array, default: () => [] },
|
highlightedFields: { type: Array, default: () => [] },
|
||||||
},
|
},
|
||||||
methods: {
|
|
||||||
isFieldHighlighted({ field }) {
|
|
||||||
return !!this.highlightedFields.find(({ name }) => name === field.name)
|
|
||||||
},
|
|
||||||
},
|
|
||||||
computed: {
|
computed: {
|
||||||
isInput() {
|
isInput() {
|
||||||
return this.gqlType instanceof GraphQLInputObjectType
|
return this.gqlType instanceof GraphQLInputObjectType
|
||||||
@@ -75,9 +89,21 @@ export default {
|
|||||||
},
|
},
|
||||||
children() {
|
children() {
|
||||||
return this.gqlTypes.filter(
|
return this.gqlTypes.filter(
|
||||||
(type) => type.getInterfaces && type.getInterfaces().includes(this.gqlType)
|
(type) =>
|
||||||
|
type.getInterfaces && type.getInterfaces().includes(this.gqlType)
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
methods: {
|
||||||
|
isFieldHighlighted({ field }) {
|
||||||
|
return !!this.highlightedFields.find(({ name }) => name === field.name)
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.type-highlighted {
|
||||||
|
@apply text-acColor;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
<template>
|
<template>
|
||||||
<AppSection icon="history" :label="$t('history')" ref="history" no-legend>
|
<AppSection ref="history" icon="history" :label="$t('history')" no-legend>
|
||||||
<div class="show-on-large-screen">
|
<div class="show-on-large-screen">
|
||||||
<input
|
<input
|
||||||
|
v-model="filterText"
|
||||||
aria-label="Search"
|
aria-label="Search"
|
||||||
type="search"
|
type="search"
|
||||||
:placeholder="$t('search')"
|
:placeholder="$t('search')"
|
||||||
v-model="filterText"
|
|
||||||
class="rounded-t-lg"
|
class="rounded-t-lg"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -16,9 +16,9 @@
|
|||||||
<ul v-for="(entry, index) in filteredHistory" :key="`entry-${index}`">
|
<ul v-for="(entry, index) in filteredHistory" :key="`entry-${index}`">
|
||||||
<HistoryRestCard
|
<HistoryRestCard
|
||||||
v-if="page == 'rest'"
|
v-if="page == 'rest'"
|
||||||
:entry="entry"
|
|
||||||
:id="index"
|
:id="index"
|
||||||
:showMore="showMore"
|
:entry="entry"
|
||||||
|
:show-more="showMore"
|
||||||
@toggle-star="toggleStar(entry)"
|
@toggle-star="toggleStar(entry)"
|
||||||
@delete-entry="deleteHistory(entry)"
|
@delete-entry="deleteHistory(entry)"
|
||||||
@use-entry="useHistory(entry)"
|
@use-entry="useHistory(entry)"
|
||||||
@@ -26,21 +26,24 @@
|
|||||||
<HistoryGraphqlCard
|
<HistoryGraphqlCard
|
||||||
v-if="page == 'graphql'"
|
v-if="page == 'graphql'"
|
||||||
:entry="entry"
|
:entry="entry"
|
||||||
:showMore="showMore"
|
:show-more="showMore"
|
||||||
@toggle-star="toggleStar(entry)"
|
@toggle-star="toggleStar(entry)"
|
||||||
@delete-entry="deleteHistory(entry)"
|
@delete-entry="deleteHistory(entry)"
|
||||||
@use-entry="useHistory(entry)"
|
@use-entry="useHistory(entry)"
|
||||||
/>
|
/>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<p :class="{ hidden: filteredHistory.length != 0 || history.length === 0 }" class="info">
|
<p
|
||||||
|
:class="{ hidden: filteredHistory.length != 0 || history.length === 0 }"
|
||||||
|
class="info"
|
||||||
|
>
|
||||||
{{ $t("nothing_found") }} "{{ filterText }}"
|
{{ $t("nothing_found") }} "{{ filterText }}"
|
||||||
</p>
|
</p>
|
||||||
<p v-if="history.length === 0" class="info">
|
<p v-if="history.length === 0" class="info">
|
||||||
<i class="material-icons">schedule</i> {{ $t("history_empty") }}
|
<i class="material-icons">schedule</i> {{ $t("history_empty") }}
|
||||||
</p>
|
</p>
|
||||||
<div v-if="history.length !== 0" class="rounded-b-lg bg-bgDarkColor">
|
<div v-if="history.length !== 0" class="rounded-b-lg bg-bgDarkColor">
|
||||||
<div class="row-wrapper" v-if="!isClearingHistory">
|
<div v-if="!isClearingHistory" class="row-wrapper">
|
||||||
<button
|
<button
|
||||||
data-testid="clear_history"
|
data-testid="clear_history"
|
||||||
class="icon"
|
class="icon"
|
||||||
@@ -60,22 +63,24 @@
|
|||||||
</i>
|
</i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="row-wrapper" v-else>
|
<div v-else class="row-wrapper">
|
||||||
<p class="info"><i class="material-icons">help_outline</i> {{ $t("are_you_sure") }}</p>
|
<p class="info">
|
||||||
|
<i class="material-icons">help_outline</i> {{ $t("are_you_sure") }}
|
||||||
|
</p>
|
||||||
<div>
|
<div>
|
||||||
<button
|
<button
|
||||||
|
v-tooltip="$t('yes')"
|
||||||
data-testid="confirm_clear_history"
|
data-testid="confirm_clear_history"
|
||||||
class="icon"
|
class="icon"
|
||||||
@click="clearHistory"
|
@click="clearHistory"
|
||||||
v-tooltip="$t('yes')"
|
|
||||||
>
|
>
|
||||||
<i class="material-icons">done</i>
|
<i class="material-icons">done</i>
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
|
v-tooltip="$t('no')"
|
||||||
data-testid="reject_clear_history"
|
data-testid="reject_clear_history"
|
||||||
class="icon"
|
class="icon"
|
||||||
@click="disableHistoryClearing"
|
@click="disableHistoryClearing"
|
||||||
v-tooltip="$t('no')"
|
|
||||||
>
|
>
|
||||||
<i class="material-icons">close</i>
|
<i class="material-icons">close</i>
|
||||||
</button>
|
</button>
|
||||||
@@ -85,6 +90,134 @@
|
|||||||
</AppSection>
|
</AppSection>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { fb } from "~/helpers/fb"
|
||||||
|
|
||||||
|
const updateOnLocalStorage = (propertyName, property) =>
|
||||||
|
window.localStorage.setItem(propertyName, JSON.stringify(property))
|
||||||
|
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
page: { type: String, default: null },
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
history:
|
||||||
|
fb.currentUser !== null
|
||||||
|
? this.page === "rest"
|
||||||
|
? fb.currentHistory
|
||||||
|
: fb.currentGraphqlHistory
|
||||||
|
: JSON.parse(
|
||||||
|
window.localStorage.getItem(
|
||||||
|
this.page === "rest" ? "history" : "graphqlHistory"
|
||||||
|
)
|
||||||
|
) || [],
|
||||||
|
filterText: "",
|
||||||
|
showFilter: false,
|
||||||
|
isClearingHistory: false,
|
||||||
|
showMore: false,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
filteredHistory() {
|
||||||
|
const filteringHistory =
|
||||||
|
fb.currentUser !== null
|
||||||
|
? this.page === "rest"
|
||||||
|
? fb.currentHistory
|
||||||
|
: fb.currentGraphqlHistory
|
||||||
|
: JSON.parse(
|
||||||
|
window.localStorage.getItem(
|
||||||
|
this.page === "rest" ? "history" : "graphqlHistory"
|
||||||
|
)
|
||||||
|
) || []
|
||||||
|
return filteringHistory.filter((entry) => {
|
||||||
|
const filterText = this.filterText.toLowerCase()
|
||||||
|
return Object.keys(entry).some((key) => {
|
||||||
|
let value = entry[key]
|
||||||
|
value = typeof value !== "string" ? value.toString() : value
|
||||||
|
return value.toLowerCase().includes(filterText)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
async clearHistory() {
|
||||||
|
if (fb.currentUser !== null) {
|
||||||
|
this.page === "rest"
|
||||||
|
? await fb.clearHistory()
|
||||||
|
: await fb.clearGraphqlHistory()
|
||||||
|
}
|
||||||
|
this.history = []
|
||||||
|
this.filterText = ""
|
||||||
|
this.disableHistoryClearing()
|
||||||
|
updateOnLocalStorage(
|
||||||
|
this.page === "rest" ? "history" : "graphqlHistory",
|
||||||
|
this.history
|
||||||
|
)
|
||||||
|
this.$toast.error(this.$t("history_deleted"), {
|
||||||
|
icon: "delete",
|
||||||
|
})
|
||||||
|
},
|
||||||
|
useHistory(entry) {
|
||||||
|
this.$emit("useHistory", entry)
|
||||||
|
},
|
||||||
|
async deleteHistory(entry) {
|
||||||
|
if (this.history.length === 0) {
|
||||||
|
this.filterText = ""
|
||||||
|
}
|
||||||
|
if (fb.currentUser !== null) {
|
||||||
|
await (this.page === "rest"
|
||||||
|
? fb.deleteHistory(entry)
|
||||||
|
: fb.deleteGraphqlHistory(entry))
|
||||||
|
this.history = fb.currentHistory
|
||||||
|
updateOnLocalStorage(
|
||||||
|
this.page === "rest" ? "history" : "graphqlHistory",
|
||||||
|
this.history
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
this.history.splice(this.history.indexOf(entry), 1)
|
||||||
|
updateOnLocalStorage(
|
||||||
|
this.page === "rest" ? "history" : "graphqlHistory",
|
||||||
|
this.history
|
||||||
|
)
|
||||||
|
}
|
||||||
|
this.$toast.error(this.$t("deleted"), {
|
||||||
|
icon: "delete",
|
||||||
|
})
|
||||||
|
},
|
||||||
|
addEntry(entry) {
|
||||||
|
this.history.push(entry)
|
||||||
|
updateOnLocalStorage(
|
||||||
|
this.page === "rest" ? "history" : "graphqlHistory",
|
||||||
|
this.history
|
||||||
|
)
|
||||||
|
},
|
||||||
|
enableHistoryClearing() {
|
||||||
|
if (!this.history || !this.history.length) return
|
||||||
|
this.isClearingHistory = true
|
||||||
|
},
|
||||||
|
disableHistoryClearing() {
|
||||||
|
this.isClearingHistory = false
|
||||||
|
},
|
||||||
|
toggleCollapse() {
|
||||||
|
this.showMore = !this.showMore
|
||||||
|
},
|
||||||
|
async toggleStar(entry) {
|
||||||
|
if (fb.currentUser !== null) {
|
||||||
|
this.page === "rest"
|
||||||
|
? await fb.toggleStar(entry, !entry.star)
|
||||||
|
: await fb.toggleGraphqlHistoryStar(entry, !entry.star)
|
||||||
|
}
|
||||||
|
entry.star = !entry.star
|
||||||
|
updateOnLocalStorage(
|
||||||
|
this.page === "rest" ? "history" : "graphqlHistory",
|
||||||
|
this.history
|
||||||
|
)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.virtual-list {
|
.virtual-list {
|
||||||
max-height: calc(100vh - 270px);
|
max-height: calc(100vh - 270px);
|
||||||
@@ -105,106 +238,3 @@ ol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<script>
|
|
||||||
import { fb } from "~/helpers/fb"
|
|
||||||
|
|
||||||
const updateOnLocalStorage = (propertyName, property) =>
|
|
||||||
window.localStorage.setItem(propertyName, JSON.stringify(property))
|
|
||||||
|
|
||||||
export default {
|
|
||||||
props: {
|
|
||||||
page: String,
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
history:
|
|
||||||
fb.currentUser !== null
|
|
||||||
? fb.currentHistory
|
|
||||||
: JSON.parse(
|
|
||||||
window.localStorage.getItem(this.page == "rest" ? "history" : "graphqlHistory")
|
|
||||||
) || [],
|
|
||||||
filterText: "",
|
|
||||||
showFilter: false,
|
|
||||||
isClearingHistory: false,
|
|
||||||
showMore: false,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
filteredHistory() {
|
|
||||||
this.history =
|
|
||||||
fb.currentUser !== null
|
|
||||||
? this.page == "rest"
|
|
||||||
? fb.currentHistory
|
|
||||||
: fb.currentGraphqlHistory
|
|
||||||
: JSON.parse(
|
|
||||||
window.localStorage.getItem(this.page == "rest" ? "history" : "graphqlHistory")
|
|
||||||
) || []
|
|
||||||
return this.history.filter((entry) => {
|
|
||||||
const filterText = this.filterText.toLowerCase()
|
|
||||||
return Object.keys(entry).some((key) => {
|
|
||||||
let value = entry[key]
|
|
||||||
value = typeof value !== "string" ? value.toString() : value
|
|
||||||
return value.toLowerCase().includes(filterText)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
},
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
async clearHistory() {
|
|
||||||
if (fb.currentUser !== null) {
|
|
||||||
this.page == "rest" ? await fb.clearHistory() : await fb.clearGraphqlHistory()
|
|
||||||
}
|
|
||||||
this.history = []
|
|
||||||
this.filterText = ""
|
|
||||||
this.disableHistoryClearing()
|
|
||||||
updateOnLocalStorage(this.page == "rest" ? "history" : "graphqlHistory", this.history)
|
|
||||||
this.$toast.error(this.$t("history_deleted"), {
|
|
||||||
icon: "delete",
|
|
||||||
})
|
|
||||||
},
|
|
||||||
useHistory(entry) {
|
|
||||||
this.$emit("useHistory", entry)
|
|
||||||
},
|
|
||||||
async deleteHistory(entry) {
|
|
||||||
if (this.history.length === 0) {
|
|
||||||
this.filterText = ""
|
|
||||||
}
|
|
||||||
if (fb.currentUser !== null) {
|
|
||||||
await (this.page == "rest" ? fb.deleteHistory(entry) : fb.deleteGraphqlHistory(entry))
|
|
||||||
this.history = fb.currentHistory
|
|
||||||
updateOnLocalStorage(this.page == "rest" ? "history" : "graphqlHistory", this.history)
|
|
||||||
} else {
|
|
||||||
this.history.splice(this.history.indexOf(entry), 1)
|
|
||||||
updateOnLocalStorage(this.page == "rest" ? "history" : "graphqlHistory", this.history)
|
|
||||||
}
|
|
||||||
this.$toast.error(this.$t("deleted"), {
|
|
||||||
icon: "delete",
|
|
||||||
})
|
|
||||||
},
|
|
||||||
addEntry(entry) {
|
|
||||||
this.history.push(entry)
|
|
||||||
updateOnLocalStorage(this.page == "rest" ? "history" : "graphqlHistory", this.history)
|
|
||||||
},
|
|
||||||
enableHistoryClearing() {
|
|
||||||
if (!this.history || !this.history.length) return
|
|
||||||
this.isClearingHistory = true
|
|
||||||
},
|
|
||||||
disableHistoryClearing() {
|
|
||||||
this.isClearingHistory = false
|
|
||||||
},
|
|
||||||
toggleCollapse() {
|
|
||||||
this.showMore = !this.showMore
|
|
||||||
},
|
|
||||||
async toggleStar(entry) {
|
|
||||||
if (fb.currentUser !== null) {
|
|
||||||
this.page == "rest"
|
|
||||||
? await fb.toggleStar(entry, !entry.star)
|
|
||||||
: await fb.toggleGraphqlHistoryStar(entry, !entry.star)
|
|
||||||
}
|
|
||||||
entry.star = !entry.star
|
|
||||||
updateOnLocalStorage(this.page == "rest" ? "history" : "graphqlHistory", this.history)
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ const styles = {
|
|||||||
// TODO: probably have to use a more global state for `test`
|
// TODO: probably have to use a more global state for `test`
|
||||||
|
|
||||||
export default function runTestScriptWithVariables(script, variables) {
|
export default function runTestScriptWithVariables(script, variables) {
|
||||||
let pw = {
|
const pw = {
|
||||||
_errors: [],
|
_errors: [],
|
||||||
_testReports: [],
|
_testReports: [],
|
||||||
_report: "",
|
_report: "",
|
||||||
@@ -29,6 +29,7 @@ export default function runTestScriptWithVariables(script, variables) {
|
|||||||
Object.assign(pw, variables)
|
Object.assign(pw, variables)
|
||||||
|
|
||||||
// run pre-request script within this function so that it has access to the pw object.
|
// run pre-request script within this function so that it has access to the pw object.
|
||||||
|
// eslint-disable-next-line no-new-func
|
||||||
new Function("pw", script)(pw)
|
new Function("pw", script)(pw)
|
||||||
//
|
//
|
||||||
const testReports = pw._testReports.map((item) => {
|
const testReports = pw._testReports.map((item) => {
|
||||||
@@ -80,6 +81,7 @@ class Expectation {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_fmtNot(message) {
|
_fmtNot(message) {
|
||||||
// given a string with "(not)" in it, replaces with "not" or "", depending if the expectation is expecting the positive or inverse (this._not)
|
// given a string with "(not)" in it, replaces with "not" or "", depending if the expectation is expecting the positive or inverse (this._not)
|
||||||
if (this.not === true) {
|
if (this.not === true) {
|
||||||
@@ -88,62 +90,102 @@ class Expectation {
|
|||||||
return message.replace("(not)", "")
|
return message.replace("(not)", "")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_fail(message) {
|
_fail(message) {
|
||||||
return this._testReports.push({ result: FAIL, message })
|
return this._testReports.push({ result: FAIL, message })
|
||||||
}
|
}
|
||||||
|
|
||||||
_pass() {
|
_pass() {
|
||||||
return this._testReports.push({ result: PASS })
|
return this._testReports.push({ result: PASS })
|
||||||
}
|
}
|
||||||
|
|
||||||
// TEST METHODS DEFINED BELOW
|
// TEST METHODS DEFINED BELOW
|
||||||
// these are the usual methods that would follow expect(...)
|
// these are the usual methods that would follow expect(...)
|
||||||
toBe(value) {
|
toBe(value) {
|
||||||
return this._satisfies(value)
|
return this._satisfies(value)
|
||||||
? this._pass()
|
|
||||||
: this._fail(this._fmtNot(`Expected ${this.expectValue} (not)to be ${value}`))
|
|
||||||
}
|
|
||||||
toHaveProperty(value) {
|
|
||||||
return this._satisfies(Object.prototype.hasOwnProperty.call(this.expectValue, value), true)
|
|
||||||
? this._pass()
|
? this._pass()
|
||||||
: this._fail(
|
: this._fail(
|
||||||
this._fmtNot(`Expected object ${this.expectValue} to (not)have property ${value}`)
|
this._fmtNot(`Expected ${this.expectValue} (not)to be ${value}`)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
toHaveProperty(value) {
|
||||||
|
return this._satisfies(
|
||||||
|
Object.prototype.hasOwnProperty.call(this.expectValue, value),
|
||||||
|
true
|
||||||
|
)
|
||||||
|
? this._pass()
|
||||||
|
: this._fail(
|
||||||
|
this._fmtNot(
|
||||||
|
`Expected object ${this.expectValue} to (not)have property ${value}`
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
toBeLevel2xx() {
|
toBeLevel2xx() {
|
||||||
const code = parseInt(this.expectValue, 10)
|
const code = parseInt(this.expectValue, 10)
|
||||||
if (Number.isNaN(code)) {
|
if (Number.isNaN(code)) {
|
||||||
return this._fail(`Expected 200-level status but could not parse value ${this.expectValue}`)
|
return this._fail(
|
||||||
|
`Expected 200-level status but could not parse value ${this.expectValue}`
|
||||||
|
)
|
||||||
}
|
}
|
||||||
return this._satisfies(code >= 200 && code < 300, true)
|
return this._satisfies(code >= 200 && code < 300, true)
|
||||||
? this._pass()
|
? this._pass()
|
||||||
: this._fail(this._fmtNot(`Expected ${this.expectValue} to (not)be 200-level status`))
|
: this._fail(
|
||||||
|
this._fmtNot(
|
||||||
|
`Expected ${this.expectValue} to (not)be 200-level status`
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
toBeLevel3xx() {
|
toBeLevel3xx() {
|
||||||
const code = parseInt(this.expectValue, 10)
|
const code = parseInt(this.expectValue, 10)
|
||||||
if (Number.isNaN(code)) {
|
if (Number.isNaN(code)) {
|
||||||
return this._fail(`Expected 300-level status but could not parse value ${this.expectValue}`)
|
return this._fail(
|
||||||
|
`Expected 300-level status but could not parse value ${this.expectValue}`
|
||||||
|
)
|
||||||
}
|
}
|
||||||
return this._satisfies(code >= 300 && code < 400, true)
|
return this._satisfies(code >= 300 && code < 400, true)
|
||||||
? this._pass()
|
? this._pass()
|
||||||
: this._fail(this._fmtNot(`Expected ${this.expectValue} to (not)be 300-level status`))
|
: this._fail(
|
||||||
|
this._fmtNot(
|
||||||
|
`Expected ${this.expectValue} to (not)be 300-level status`
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
toBeLevel4xx() {
|
toBeLevel4xx() {
|
||||||
const code = parseInt(this.expectValue, 10)
|
const code = parseInt(this.expectValue, 10)
|
||||||
if (Number.isNaN(code)) {
|
if (Number.isNaN(code)) {
|
||||||
return this._fail(`Expected 400-level status but could not parse value ${this.expectValue}`)
|
return this._fail(
|
||||||
|
`Expected 400-level status but could not parse value ${this.expectValue}`
|
||||||
|
)
|
||||||
}
|
}
|
||||||
return this._satisfies(code >= 400 && code < 500, true)
|
return this._satisfies(code >= 400 && code < 500, true)
|
||||||
? this._pass()
|
? this._pass()
|
||||||
: this._fail(this._fmtNot(`Expected ${this.expectValue} to (not)be 400-level status`))
|
: this._fail(
|
||||||
|
this._fmtNot(
|
||||||
|
`Expected ${this.expectValue} to (not)be 400-level status`
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
toBeLevel5xx() {
|
toBeLevel5xx() {
|
||||||
const code = parseInt(this.expectValue, 10)
|
const code = parseInt(this.expectValue, 10)
|
||||||
if (Number.isNaN(code)) {
|
if (Number.isNaN(code)) {
|
||||||
return this._fail(`Expected 500-level status but could not parse value ${this.expectValue}`)
|
return this._fail(
|
||||||
|
`Expected 500-level status but could not parse value ${this.expectValue}`
|
||||||
|
)
|
||||||
}
|
}
|
||||||
return this._satisfies(code >= 500 && code < 600, true)
|
return this._satisfies(code >= 500 && code < 600, true)
|
||||||
? this._pass()
|
? this._pass()
|
||||||
: this._fail(this._fmtNot(`Expected ${this.expectValue} to (not)be 500-level status`))
|
: this._fail(
|
||||||
|
this._fmtNot(
|
||||||
|
`Expected ${this.expectValue} to (not)be 500-level status`
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
toHaveLength(expectedLength) {
|
toHaveLength(expectedLength) {
|
||||||
const actualLength = this.expectValue.length
|
const actualLength = this.expectValue.length
|
||||||
return this._satisfies(actualLength, expectedLength)
|
return this._satisfies(actualLength, expectedLength)
|
||||||
@@ -154,6 +196,7 @@ class Expectation {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
toBeType(expectedType) {
|
toBeType(expectedType) {
|
||||||
const actualType = typeof this.expectValue
|
const actualType = typeof this.expectValue
|
||||||
if (
|
if (
|
||||||
@@ -177,7 +220,9 @@ class Expectation {
|
|||||||
return this._satisfies(actualType, expectedType)
|
return this._satisfies(actualType, expectedType)
|
||||||
? this._pass()
|
? this._pass()
|
||||||
: this._fail(
|
: this._fail(
|
||||||
this._fmtNot(`Expected type to be "${expectedType}" but actual type was "${actualType}"`)
|
this._fmtNot(
|
||||||
|
`Expected type to be "${expectedType}" but actual type was "${actualType}"`
|
||||||
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
export default function getEnvironmentVariablesFromScript(script) {
|
export default function getEnvironmentVariablesFromScript(script) {
|
||||||
let _variables = {}
|
const _variables = {}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// the pw object is the proxy by which pre-request scripts can pass variables to the request.
|
// the pw object is the proxy by which pre-request scripts can pass variables to the request.
|
||||||
// for security and control purposes, this is the only way a pre-request script should modify variables.
|
// for security and control purposes, this is the only way a pre-request script should modify variables.
|
||||||
let pw = {
|
const pw = {
|
||||||
environment: {
|
environment: {
|
||||||
set: (key, value) => (_variables[key] = value),
|
set: (key, value) => (_variables[key] = value),
|
||||||
},
|
},
|
||||||
@@ -15,6 +15,7 @@ export default function getEnvironmentVariablesFromScript(script) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// run pre-request script within this function so that it has access to the pw object.
|
// run pre-request script within this function so that it has access to the pw object.
|
||||||
|
// eslint-disable-next-line no-new-func
|
||||||
new Function("pw", script)(pw)
|
new Function("pw", script)(pw)
|
||||||
} catch (_e) {}
|
} catch (_e) {}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import { ApolloClient } from "@apollo/client/core"
|
|
||||||
import gql from "graphql-tag"
|
import gql from "graphql-tag"
|
||||||
import { BehaviorSubject } from "rxjs"
|
import { BehaviorSubject } from "rxjs"
|
||||||
|
|
||||||
@@ -95,7 +94,9 @@ export async function getLiveTeamMembersList(apollo, teamID) {
|
|||||||
})
|
})
|
||||||
.subscribe(({ data }) => {
|
.subscribe(({ data }) => {
|
||||||
subject.next(
|
subject.next(
|
||||||
subject.value.filter((member) => member.user.uid !== data.teamMemberAdded.user.uid)
|
subject.value.filter(
|
||||||
|
(member) => member.user.uid !== data.teamMemberAdded.user.uid
|
||||||
|
)
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -112,22 +113,22 @@ export async function getLiveTeamMembersList(apollo, teamID) {
|
|||||||
return subject
|
return subject
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function createTeam(apollo, name) {
|
export function createTeam(apollo, name) {
|
||||||
return apollo.mutate({
|
return apollo.mutate({
|
||||||
mutation: gql`
|
mutation: gql`
|
||||||
mutation($name: String!) {
|
mutation ($name: String!) {
|
||||||
createTeam(name: $name) {
|
createTeam(name: $name) {
|
||||||
name
|
name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
variables: {
|
variables: {
|
||||||
name: name,
|
name,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function addTeamMemberByEmail(apollo, userRole, userEmail, teamID) {
|
export function addTeamMemberByEmail(apollo, userRole, userEmail, teamID) {
|
||||||
return apollo.mutate({
|
return apollo.mutate({
|
||||||
mutation: gql`
|
mutation: gql`
|
||||||
mutation addTeamMemberByEmail(
|
mutation addTeamMemberByEmail(
|
||||||
@@ -135,20 +136,24 @@ export async function addTeamMemberByEmail(apollo, userRole, userEmail, teamID)
|
|||||||
$userEmail: String!
|
$userEmail: String!
|
||||||
$teamID: String!
|
$teamID: String!
|
||||||
) {
|
) {
|
||||||
addTeamMemberByEmail(userRole: $userRole, userEmail: $userEmail, teamID: $teamID) {
|
addTeamMemberByEmail(
|
||||||
|
userRole: $userRole
|
||||||
|
userEmail: $userEmail
|
||||||
|
teamID: $teamID
|
||||||
|
) {
|
||||||
role
|
role
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
variables: {
|
variables: {
|
||||||
userRole: userRole,
|
userRole,
|
||||||
userEmail: userEmail,
|
userEmail,
|
||||||
teamID: teamID,
|
teamID,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function updateTeamMemberRole(apollo, userID, newRole, teamID) {
|
export function updateTeamMemberRole(apollo, userID, newRole, teamID) {
|
||||||
return apollo.mutate({
|
return apollo.mutate({
|
||||||
mutation: gql`
|
mutation: gql`
|
||||||
mutation updateTeamMemberRole(
|
mutation updateTeamMemberRole(
|
||||||
@@ -156,20 +161,24 @@ export async function updateTeamMemberRole(apollo, userID, newRole, teamID) {
|
|||||||
$userUid: String!
|
$userUid: String!
|
||||||
$teamID: String!
|
$teamID: String!
|
||||||
) {
|
) {
|
||||||
updateTeamMemberRole(newRole: $newRole, userUid: $userUid, teamID: $teamID) {
|
updateTeamMemberRole(
|
||||||
|
newRole: $newRole
|
||||||
|
userUid: $userUid
|
||||||
|
teamID: $teamID
|
||||||
|
) {
|
||||||
role
|
role
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
variables: {
|
variables: {
|
||||||
newRole: newRole,
|
newRole,
|
||||||
userUid: userID,
|
userUid: userID,
|
||||||
teamID: teamID,
|
teamID,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function renameTeam(apollo, name, teamID) {
|
export function renameTeam(apollo, name, teamID) {
|
||||||
return apollo.mutate({
|
return apollo.mutate({
|
||||||
mutation: gql`
|
mutation: gql`
|
||||||
mutation renameTeam($newName: String!, $teamID: String!) {
|
mutation renameTeam($newName: String!, $teamID: String!) {
|
||||||
@@ -180,12 +189,12 @@ export async function renameTeam(apollo, name, teamID) {
|
|||||||
`,
|
`,
|
||||||
variables: {
|
variables: {
|
||||||
newName: name,
|
newName: name,
|
||||||
teamID: teamID,
|
teamID,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function removeTeamMember(apollo, userID, teamID) {
|
export function removeTeamMember(apollo, userID, teamID) {
|
||||||
return apollo.mutate({
|
return apollo.mutate({
|
||||||
mutation: gql`
|
mutation: gql`
|
||||||
mutation removeTeamMember($userUid: String!, $teamID: String!) {
|
mutation removeTeamMember($userUid: String!, $teamID: String!) {
|
||||||
@@ -194,47 +203,47 @@ export async function removeTeamMember(apollo, userID, teamID) {
|
|||||||
`,
|
`,
|
||||||
variables: {
|
variables: {
|
||||||
userUid: userID,
|
userUid: userID,
|
||||||
teamID: teamID,
|
teamID,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function deleteTeam(apollo, teamID) {
|
export async function deleteTeam(apollo, teamID) {
|
||||||
let response = undefined
|
let response
|
||||||
while (true) {
|
while (true) {
|
||||||
response = await apollo.mutate({
|
response = await apollo.mutate({
|
||||||
mutation: gql`
|
mutation: gql`
|
||||||
mutation($teamID: String!) {
|
mutation ($teamID: String!) {
|
||||||
deleteTeam(teamID: $teamID)
|
deleteTeam(teamID: $teamID)
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
variables: {
|
variables: {
|
||||||
teamID: teamID,
|
teamID,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
if (response != undefined) break
|
if (response !== undefined) break
|
||||||
}
|
}
|
||||||
return response
|
return response
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function exitTeam(apollo, teamID) {
|
export function exitTeam(apollo, teamID) {
|
||||||
apollo.mutate({
|
apollo.mutate({
|
||||||
mutation: gql`
|
mutation: gql`
|
||||||
mutation($teamID: String!) {
|
mutation ($teamID: String!) {
|
||||||
leaveTeam(teamID: $teamID)
|
leaveTeam(teamID: $teamID)
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
variables: {
|
variables: {
|
||||||
teamID: teamID,
|
teamID,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function rootCollectionsOfTeam(apollo, teamID) {
|
export async function rootCollectionsOfTeam(apollo, teamID) {
|
||||||
var collections = []
|
const collections = []
|
||||||
var cursor = ""
|
let cursor = ""
|
||||||
while (true) {
|
while (true) {
|
||||||
var response = await apollo.query({
|
const response = await apollo.query({
|
||||||
query: gql`
|
query: gql`
|
||||||
query rootCollectionsOfTeam($teamID: String!, $cursor: String!) {
|
query rootCollectionsOfTeam($teamID: String!, $cursor: String!) {
|
||||||
rootCollectionsOfTeam(teamID: $teamID, cursor: $cursor) {
|
rootCollectionsOfTeam(teamID: $teamID, cursor: $cursor) {
|
||||||
@@ -244,12 +253,12 @@ export async function rootCollectionsOfTeam(apollo, teamID) {
|
|||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
variables: {
|
variables: {
|
||||||
teamID: teamID,
|
teamID,
|
||||||
cursor: cursor,
|
cursor,
|
||||||
},
|
},
|
||||||
fetchPolicy: "no-cache",
|
fetchPolicy: "no-cache",
|
||||||
})
|
})
|
||||||
if (response.data.rootCollectionsOfTeam.length == 0) break
|
if (response.data.rootCollectionsOfTeam.length === 0) break
|
||||||
response.data.rootCollectionsOfTeam.forEach((collection) => {
|
response.data.rootCollectionsOfTeam.forEach((collection) => {
|
||||||
collections.push(collection)
|
collections.push(collection)
|
||||||
})
|
})
|
||||||
@@ -259,8 +268,8 @@ export async function rootCollectionsOfTeam(apollo, teamID) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function getCollectionChildren(apollo, collectionID) {
|
export async function getCollectionChildren(apollo, collectionID) {
|
||||||
var children = []
|
const children = []
|
||||||
var response = await apollo.query({
|
const response = await apollo.query({
|
||||||
query: gql`
|
query: gql`
|
||||||
query getCollectionChildren($collectionID: String!) {
|
query getCollectionChildren($collectionID: String!) {
|
||||||
collection(collectionID: $collectionID) {
|
collection(collectionID: $collectionID) {
|
||||||
@@ -272,7 +281,7 @@ export async function getCollectionChildren(apollo, collectionID) {
|
|||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
variables: {
|
variables: {
|
||||||
collectionID: collectionID,
|
collectionID,
|
||||||
},
|
},
|
||||||
fetchPolicy: "no-cache",
|
fetchPolicy: "no-cache",
|
||||||
})
|
})
|
||||||
@@ -283,10 +292,10 @@ export async function getCollectionChildren(apollo, collectionID) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function getCollectionRequests(apollo, collectionID) {
|
export async function getCollectionRequests(apollo, collectionID) {
|
||||||
var requests = []
|
const requests = []
|
||||||
var cursor = ""
|
let cursor = ""
|
||||||
while (true) {
|
while (true) {
|
||||||
var response = await apollo.query({
|
const response = await apollo.query({
|
||||||
query: gql`
|
query: gql`
|
||||||
query getCollectionRequests($collectionID: String!, $cursor: String) {
|
query getCollectionRequests($collectionID: String!, $cursor: String) {
|
||||||
requestsInCollection(collectionID: $collectionID, cursor: $cursor) {
|
requestsInCollection(collectionID: $collectionID, cursor: $cursor) {
|
||||||
@@ -297,8 +306,8 @@ export async function getCollectionRequests(apollo, collectionID) {
|
|||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
variables: {
|
variables: {
|
||||||
collectionID: collectionID,
|
collectionID,
|
||||||
cursor: cursor,
|
cursor,
|
||||||
},
|
},
|
||||||
fetchPolicy: "no-cache",
|
fetchPolicy: "no-cache",
|
||||||
})
|
})
|
||||||
@@ -316,11 +325,11 @@ export async function getCollectionRequests(apollo, collectionID) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function renameCollection(apollo, title, id) {
|
export async function renameCollection(apollo, title, id) {
|
||||||
let response = undefined
|
let response
|
||||||
while (true) {
|
while (true) {
|
||||||
response = await apollo.mutate({
|
response = await apollo.mutate({
|
||||||
mutation: gql`
|
mutation: gql`
|
||||||
mutation($newTitle: String!, $collectionID: String!) {
|
mutation ($newTitle: String!, $collectionID: String!) {
|
||||||
renameCollection(newTitle: $newTitle, collectionID: $collectionID) {
|
renameCollection(newTitle: $newTitle, collectionID: $collectionID) {
|
||||||
id
|
id
|
||||||
}
|
}
|
||||||
@@ -331,17 +340,17 @@ export async function renameCollection(apollo, title, id) {
|
|||||||
collectionID: id,
|
collectionID: id,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
if (response != undefined) break
|
if (response !== undefined) break
|
||||||
}
|
}
|
||||||
return response
|
return response
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function updateRequest(apollo, request, requestName, requestID) {
|
export async function updateRequest(apollo, request, requestName, requestID) {
|
||||||
let response = undefined
|
let response
|
||||||
while (true) {
|
while (true) {
|
||||||
response = await apollo.mutate({
|
response = await apollo.mutate({
|
||||||
mutation: gql`
|
mutation: gql`
|
||||||
mutation($data: UpdateTeamRequestInput!, $requestID: String!) {
|
mutation ($data: UpdateTeamRequestInput!, $requestID: String!) {
|
||||||
updateRequest(data: $data, requestID: $requestID) {
|
updateRequest(data: $data, requestID: $requestID) {
|
||||||
id
|
id
|
||||||
}
|
}
|
||||||
@@ -352,21 +361,24 @@ export async function updateRequest(apollo, request, requestName, requestID) {
|
|||||||
request: JSON.stringify(request),
|
request: JSON.stringify(request),
|
||||||
title: requestName,
|
title: requestName,
|
||||||
},
|
},
|
||||||
requestID: requestID,
|
requestID,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
if (response != undefined) break
|
if (response !== undefined) break
|
||||||
}
|
}
|
||||||
return response
|
return response
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function addChildCollection(apollo, title, id) {
|
export async function addChildCollection(apollo, title, id) {
|
||||||
let response = undefined
|
let response
|
||||||
while (true) {
|
while (true) {
|
||||||
response = await apollo.mutate({
|
response = await apollo.mutate({
|
||||||
mutation: gql`
|
mutation: gql`
|
||||||
mutation($childTitle: String!, $collectionID: String!) {
|
mutation ($childTitle: String!, $collectionID: String!) {
|
||||||
createChildCollection(childTitle: $childTitle, collectionID: $collectionID) {
|
createChildCollection(
|
||||||
|
childTitle: $childTitle
|
||||||
|
collectionID: $collectionID
|
||||||
|
) {
|
||||||
id
|
id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -376,17 +388,17 @@ export async function addChildCollection(apollo, title, id) {
|
|||||||
collectionID: id,
|
collectionID: id,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
if (response != undefined) break
|
if (response !== undefined) break
|
||||||
}
|
}
|
||||||
return response
|
return response
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function deleteCollection(apollo, id) {
|
export async function deleteCollection(apollo, id) {
|
||||||
let response = undefined
|
let response
|
||||||
while (true) {
|
while (true) {
|
||||||
response = await apollo.mutate({
|
response = await apollo.mutate({
|
||||||
mutation: gql`
|
mutation: gql`
|
||||||
mutation($collectionID: String!) {
|
mutation ($collectionID: String!) {
|
||||||
deleteCollection(collectionID: $collectionID)
|
deleteCollection(collectionID: $collectionID)
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
@@ -394,54 +406,60 @@ export async function deleteCollection(apollo, id) {
|
|||||||
collectionID: id,
|
collectionID: id,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
if (response != undefined) break
|
if (response !== undefined) break
|
||||||
}
|
}
|
||||||
return response
|
return response
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function deleteRequest(apollo, requestID) {
|
export async function deleteRequest(apollo, requestID) {
|
||||||
let response = undefined
|
let response
|
||||||
while (true) {
|
while (true) {
|
||||||
response = await apollo.mutate({
|
response = await apollo.mutate({
|
||||||
mutation: gql`
|
mutation: gql`
|
||||||
mutation($requestID: String!) {
|
mutation ($requestID: String!) {
|
||||||
deleteRequest(requestID: $requestID)
|
deleteRequest(requestID: $requestID)
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
variables: {
|
variables: {
|
||||||
requestID: requestID,
|
requestID,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
if (response != undefined) break
|
if (response !== undefined) break
|
||||||
}
|
}
|
||||||
return response
|
return response
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function createNewRootCollection(apollo, title, id) {
|
export async function createNewRootCollection(apollo, title, id) {
|
||||||
let response = undefined
|
let response
|
||||||
while (true) {
|
while (true) {
|
||||||
response = await apollo.mutate({
|
response = await apollo.mutate({
|
||||||
mutation: gql`
|
mutation: gql`
|
||||||
mutation($title: String!, $teamID: String!) {
|
mutation ($title: String!, $teamID: String!) {
|
||||||
createRootCollection(title: $title, teamID: $teamID) {
|
createRootCollection(title: $title, teamID: $teamID) {
|
||||||
id
|
id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
variables: {
|
variables: {
|
||||||
title: title,
|
title,
|
||||||
teamID: id,
|
teamID: id,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
if (response != undefined) break
|
if (response !== undefined) break
|
||||||
}
|
}
|
||||||
return response
|
return response
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function saveRequestAsTeams(apollo, request, title, teamID, collectionID) {
|
export async function saveRequestAsTeams(
|
||||||
|
apollo,
|
||||||
|
request,
|
||||||
|
title,
|
||||||
|
teamID,
|
||||||
|
collectionID
|
||||||
|
) {
|
||||||
await apollo.mutate({
|
await apollo.mutate({
|
||||||
mutation: gql`
|
mutation: gql`
|
||||||
mutation($data: CreateTeamRequestInput!, $collectionID: String!) {
|
mutation ($data: CreateTeamRequestInput!, $collectionID: String!) {
|
||||||
createRequestInCollection(data: $data, collectionID: $collectionID) {
|
createRequestInCollection(data: $data, collectionID: $collectionID) {
|
||||||
collection {
|
collection {
|
||||||
id
|
id
|
||||||
@@ -454,11 +472,11 @@ export async function saveRequestAsTeams(apollo, request, title, teamID, collect
|
|||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
variables: {
|
variables: {
|
||||||
collectionID: collectionID,
|
collectionID,
|
||||||
data: {
|
data: {
|
||||||
teamID: teamID,
|
teamID,
|
||||||
title: title,
|
title,
|
||||||
request: request,
|
request,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
@@ -467,7 +485,10 @@ export async function saveRequestAsTeams(apollo, request, title, teamID, collect
|
|||||||
export async function overwriteRequestTeams(apollo, request, title, requestID) {
|
export async function overwriteRequestTeams(apollo, request, title, requestID) {
|
||||||
await apollo.mutate({
|
await apollo.mutate({
|
||||||
mutation: gql`
|
mutation: gql`
|
||||||
mutation updateRequest($data: UpdateTeamRequestInput!, $requestID: String!) {
|
mutation updateRequest(
|
||||||
|
$data: UpdateTeamRequestInput!
|
||||||
|
$requestID: String!
|
||||||
|
) {
|
||||||
updateRequest(data: $data, requestID: $requestID) {
|
updateRequest(data: $data, requestID: $requestID) {
|
||||||
id
|
id
|
||||||
title
|
title
|
||||||
@@ -475,20 +496,26 @@ export async function overwriteRequestTeams(apollo, request, title, requestID) {
|
|||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
variables: {
|
variables: {
|
||||||
requestID: requestID,
|
requestID,
|
||||||
data: {
|
data: {
|
||||||
request: request,
|
request,
|
||||||
title: title,
|
title,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function importFromMyCollections(apollo, collectionID, teamID) {
|
export async function importFromMyCollections(apollo, collectionID, teamID) {
|
||||||
let response = await apollo.mutate({
|
const response = await apollo.mutate({
|
||||||
mutation: gql`
|
mutation: gql`
|
||||||
mutation importFromMyCollections($fbCollectionPath: String!, $teamID: String!) {
|
mutation importFromMyCollections(
|
||||||
importCollectionFromUserFirestore(fbCollectionPath: $fbCollectionPath, teamID: $teamID) {
|
$fbCollectionPath: String!
|
||||||
|
$teamID: String!
|
||||||
|
) {
|
||||||
|
importCollectionFromUserFirestore(
|
||||||
|
fbCollectionPath: $fbCollectionPath
|
||||||
|
teamID: $teamID
|
||||||
|
) {
|
||||||
id
|
id
|
||||||
title
|
title
|
||||||
}
|
}
|
||||||
@@ -496,14 +523,14 @@ export async function importFromMyCollections(apollo, collectionID, teamID) {
|
|||||||
`,
|
`,
|
||||||
variables: {
|
variables: {
|
||||||
fbCollectionPath: collectionID,
|
fbCollectionPath: collectionID,
|
||||||
teamID: teamID,
|
teamID,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
return response.data != null
|
return response.data != null
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function importFromJSON(apollo, collections, teamID) {
|
export async function importFromJSON(apollo, collections, teamID) {
|
||||||
let response = await apollo.mutate({
|
const response = await apollo.mutate({
|
||||||
mutation: gql`
|
mutation: gql`
|
||||||
mutation importFromJSON($jsonString: String!, $teamID: String!) {
|
mutation importFromJSON($jsonString: String!, $teamID: String!) {
|
||||||
importCollectionsFromJSON(jsonString: $jsonString, teamID: $teamID)
|
importCollectionsFromJSON(jsonString: $jsonString, teamID: $teamID)
|
||||||
@@ -511,14 +538,14 @@ export async function importFromJSON(apollo, collections, teamID) {
|
|||||||
`,
|
`,
|
||||||
variables: {
|
variables: {
|
||||||
jsonString: JSON.stringify(collections),
|
jsonString: JSON.stringify(collections),
|
||||||
teamID: teamID,
|
teamID,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
return response.data != null
|
return response.data != null
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function replaceWithJSON(apollo, collections, teamID) {
|
export async function replaceWithJSON(apollo, collections, teamID) {
|
||||||
let response = await apollo.mutate({
|
const response = await apollo.mutate({
|
||||||
mutation: gql`
|
mutation: gql`
|
||||||
mutation replaceWithJSON($jsonString: String!, $teamID: String!) {
|
mutation replaceWithJSON($jsonString: String!, $teamID: String!) {
|
||||||
replaceCollectionsWithJSON(jsonString: $jsonString, teamID: $teamID)
|
replaceCollectionsWithJSON(jsonString: $jsonString, teamID: $teamID)
|
||||||
@@ -526,21 +553,21 @@ export async function replaceWithJSON(apollo, collections, teamID) {
|
|||||||
`,
|
`,
|
||||||
variables: {
|
variables: {
|
||||||
jsonString: JSON.stringify(collections),
|
jsonString: JSON.stringify(collections),
|
||||||
teamID: teamID,
|
teamID,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
return response.data != null
|
return response.data != null
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function exportAsJSON(apollo, teamID) {
|
export async function exportAsJSON(apollo, teamID) {
|
||||||
let response = await apollo.query({
|
const response = await apollo.query({
|
||||||
query: gql`
|
query: gql`
|
||||||
query exportAsJSON($teamID: String!) {
|
query exportAsJSON($teamID: String!) {
|
||||||
exportCollectionsToJSON(teamID: $teamID)
|
exportCollectionsToJSON(teamID: $teamID)
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
variables: {
|
variables: {
|
||||||
teamID: teamID,
|
teamID,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
return response.data.exportCollectionsToJSON
|
return response.data.exportCollectionsToJSON
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ describe("debounce", () => {
|
|||||||
expect(fn).not.toHaveBeenCalled()
|
expect(fn).not.toHaveBeenCalled()
|
||||||
})
|
})
|
||||||
|
|
||||||
test("calls the function after the given timeout", async () => {
|
test("calls the function after the given timeout", () => {
|
||||||
const fn = jest.fn()
|
const fn = jest.fn()
|
||||||
|
|
||||||
jest.useFakeTimers()
|
jest.useFakeTimers()
|
||||||
@@ -24,7 +24,7 @@ describe("debounce", () => {
|
|||||||
expect(setTimeout).toHaveBeenCalledWith(expect.any(Function), 100)
|
expect(setTimeout).toHaveBeenCalledWith(expect.any(Function), 100)
|
||||||
})
|
})
|
||||||
|
|
||||||
test("calls the function only one time within the timeframe", async () => {
|
test("calls the function only one time within the timeframe", () => {
|
||||||
const fn = jest.fn()
|
const fn = jest.fn()
|
||||||
|
|
||||||
const debFunc = debounce(fn, 1000)
|
const debFunc = debounce(fn, 1000)
|
||||||
|
|||||||
@@ -3,6 +3,10 @@ import { map } from "rxjs/operators"
|
|||||||
import assign from "lodash/assign"
|
import assign from "lodash/assign"
|
||||||
import clone from "lodash/clone"
|
import clone from "lodash/clone"
|
||||||
|
|
||||||
|
export type Dispatchers<StoreType> = {
|
||||||
|
[key: string]: (currentVal: StoreType, payload: any) => Partial<StoreType>
|
||||||
|
}
|
||||||
|
|
||||||
type Dispatch<
|
type Dispatch<
|
||||||
StoreType,
|
StoreType,
|
||||||
DispatchersType extends Dispatchers<StoreType>,
|
DispatchersType extends Dispatchers<StoreType>,
|
||||||
@@ -12,21 +16,26 @@ type Dispatch<
|
|||||||
payload: any
|
payload: any
|
||||||
}
|
}
|
||||||
|
|
||||||
export type Dispatchers<StoreType> = {
|
export default class DispatchingStore<
|
||||||
[key: string]: (currentVal: StoreType, payload: any) => Partial<StoreType>
|
StoreType,
|
||||||
}
|
DispatchersType extends Dispatchers<StoreType>
|
||||||
|
> {
|
||||||
export default class DispatchingStore<StoreType, DispatchersType extends Dispatchers<StoreType>> {
|
|
||||||
#state$: BehaviorSubject<StoreType>
|
#state$: BehaviorSubject<StoreType>
|
||||||
#dispatchers: Dispatchers<StoreType>
|
#dispatchers: Dispatchers<StoreType>
|
||||||
#dispatches$: Subject<Dispatch<StoreType, DispatchersType, keyof DispatchersType>> = new Subject()
|
#dispatches$: Subject<
|
||||||
|
Dispatch<StoreType, DispatchersType, keyof DispatchersType>
|
||||||
|
> = new Subject()
|
||||||
|
|
||||||
constructor(initialValue: StoreType, dispatchers: DispatchersType) {
|
constructor(initialValue: StoreType, dispatchers: DispatchersType) {
|
||||||
this.#state$ = new BehaviorSubject(initialValue)
|
this.#state$ = new BehaviorSubject(initialValue)
|
||||||
this.#dispatchers = dispatchers
|
this.#dispatchers = dispatchers
|
||||||
|
|
||||||
this.#dispatches$
|
this.#dispatches$
|
||||||
.pipe(map(({ dispatcher, payload }) => this.#dispatchers[dispatcher](this.value, payload)))
|
.pipe(
|
||||||
|
map(({ dispatcher, payload }) =>
|
||||||
|
this.#dispatchers[dispatcher](this.value, payload)
|
||||||
|
)
|
||||||
|
)
|
||||||
.subscribe((val) => {
|
.subscribe((val) => {
|
||||||
const data = clone(this.value)
|
const data = clone(this.value)
|
||||||
assign(data, val)
|
assign(data, val)
|
||||||
@@ -47,8 +56,12 @@ export default class DispatchingStore<StoreType, DispatchersType extends Dispatc
|
|||||||
return this.#dispatches$
|
return this.#dispatches$
|
||||||
}
|
}
|
||||||
|
|
||||||
dispatch({ dispatcher, payload }: Dispatch<StoreType, DispatchersType, keyof DispatchersType>) {
|
dispatch({
|
||||||
if (!this.#dispatchers[dispatcher]) throw new Error(`Undefined dispatch type '${dispatcher}'`)
|
dispatcher,
|
||||||
|
payload,
|
||||||
|
}: Dispatch<StoreType, DispatchersType, keyof DispatchersType>) {
|
||||||
|
if (!this.#dispatchers[dispatcher])
|
||||||
|
throw new Error(`Undefined dispatch type '${dispatcher}'`)
|
||||||
|
|
||||||
this.#dispatches$.next({ dispatcher, payload })
|
this.#dispatches$.next({ dispatcher, payload })
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,18 +2,18 @@
|
|||||||
<div class="page">
|
<div class="page">
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<div class="page-columns inner-left">
|
<div class="page-columns inner-left">
|
||||||
<AppSection :label="$t('endpoint')" ref="endpoint" no-legend>
|
<AppSection ref="endpoint" :label="$t('endpoint')" no-legend>
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
<label for="url">{{ $t("url") }}</label>
|
<label for="url">{{ $t("url") }}</label>
|
||||||
<input
|
<input
|
||||||
id="url"
|
id="url"
|
||||||
type="url"
|
|
||||||
v-model="url"
|
v-model="url"
|
||||||
|
type="url"
|
||||||
spellcheck="false"
|
spellcheck="false"
|
||||||
@keyup.enter="onPollSchemaClick()"
|
|
||||||
class="md:rounded-bl-lg"
|
class="md:rounded-bl-lg"
|
||||||
:placeholder="$t('url')"
|
:placeholder="$t('url')"
|
||||||
|
@keyup.enter="onPollSchemaClick()"
|
||||||
/>
|
/>
|
||||||
</li>
|
</li>
|
||||||
<div>
|
<div>
|
||||||
@@ -22,8 +22,8 @@
|
|||||||
<button
|
<button
|
||||||
id="get"
|
id="get"
|
||||||
name="get"
|
name="get"
|
||||||
@click="onPollSchemaClick"
|
|
||||||
class="rounded-b-lg md:rounded-bl-none md:rounded-br-lg"
|
class="rounded-b-lg md:rounded-bl-none md:rounded-br-lg"
|
||||||
|
@click="onPollSchemaClick"
|
||||||
>
|
>
|
||||||
{{ !isPollingSchema ? $t("connect") : $t("disconnect") }}
|
{{ !isPollingSchema ? $t("connect") : $t("disconnect") }}
|
||||||
<span
|
<span
|
||||||
@@ -37,7 +37,7 @@
|
|||||||
</ul>
|
</ul>
|
||||||
</AppSection>
|
</AppSection>
|
||||||
|
|
||||||
<AppSection :label="$t('headers')" ref="headers" no-legend>
|
<AppSection ref="headers" :label="$t('headers')" no-legend>
|
||||||
<div class="flex flex-col">
|
<div class="flex flex-col">
|
||||||
<label>{{ $t("headers") }}</label>
|
<label>{{ $t("headers") }}</label>
|
||||||
<ul v-if="headers.length !== 0">
|
<ul v-if="headers.length !== 0">
|
||||||
@@ -45,7 +45,11 @@
|
|||||||
<div class="row-wrapper">
|
<div class="row-wrapper">
|
||||||
<label for="headerList">{{ $t("header_list") }}</label>
|
<label for="headerList">{{ $t("header_list") }}</label>
|
||||||
<div>
|
<div>
|
||||||
<button class="icon" @click="headers = []" v-tooltip.bottom="$t('clear')">
|
<button
|
||||||
|
v-tooltip.bottom="$t('clear')"
|
||||||
|
class="icon"
|
||||||
|
@click="headers = []"
|
||||||
|
>
|
||||||
<i class="material-icons">clear_all</i>
|
<i class="material-icons">clear_all</i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -71,13 +75,13 @@
|
|||||||
:source="commonHeaders"
|
:source="commonHeaders"
|
||||||
:spellcheck="false"
|
:spellcheck="false"
|
||||||
:value="header.key"
|
:value="header.key"
|
||||||
|
autofocus
|
||||||
@input="
|
@input="
|
||||||
$store.commit('setGQLHeaderKey', {
|
$store.commit('setGQLHeaderKey', {
|
||||||
index,
|
index,
|
||||||
value: $event,
|
value: $event,
|
||||||
})
|
})
|
||||||
"
|
"
|
||||||
autofocus
|
|
||||||
/>
|
/>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
@@ -85,25 +89,18 @@
|
|||||||
:placeholder="$t('value_count', { count: index + 1 })"
|
:placeholder="$t('value_count', { count: index + 1 })"
|
||||||
:name="`value ${index}`"
|
:name="`value ${index}`"
|
||||||
:value="header.value"
|
:value="header.value"
|
||||||
|
autofocus
|
||||||
@change="
|
@change="
|
||||||
$store.commit('setGQLHeaderValue', {
|
$store.commit('setGQLHeaderValue', {
|
||||||
index,
|
index,
|
||||||
value: $event.target.value,
|
value: $event.target.value,
|
||||||
})
|
})
|
||||||
"
|
"
|
||||||
autofocus
|
|
||||||
/>
|
/>
|
||||||
</li>
|
</li>
|
||||||
<div>
|
<div>
|
||||||
<li>
|
<li>
|
||||||
<button
|
<button
|
||||||
class="icon"
|
|
||||||
@click="
|
|
||||||
$store.commit('setActiveGQLHeader', {
|
|
||||||
index,
|
|
||||||
value: header.hasOwnProperty('active') ? !header.active : false,
|
|
||||||
})
|
|
||||||
"
|
|
||||||
v-tooltip.bottom="{
|
v-tooltip.bottom="{
|
||||||
content: header.hasOwnProperty('active')
|
content: header.hasOwnProperty('active')
|
||||||
? header.active
|
? header.active
|
||||||
@@ -111,6 +108,15 @@
|
|||||||
: $t('turn_on')
|
: $t('turn_on')
|
||||||
: $t('turn_off'),
|
: $t('turn_off'),
|
||||||
}"
|
}"
|
||||||
|
class="icon"
|
||||||
|
@click="
|
||||||
|
$store.commit('setActiveGQLHeader', {
|
||||||
|
index,
|
||||||
|
value: header.hasOwnProperty('active')
|
||||||
|
? !header.active
|
||||||
|
: false,
|
||||||
|
})
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<i class="material-icons">
|
<i class="material-icons">
|
||||||
{{
|
{{
|
||||||
@@ -127,9 +133,9 @@
|
|||||||
<div>
|
<div>
|
||||||
<li>
|
<li>
|
||||||
<button
|
<button
|
||||||
|
v-tooltip.bottom="$t('delete')"
|
||||||
class="icon"
|
class="icon"
|
||||||
@click="removeRequestHeader(index)"
|
@click="removeRequestHeader(index)"
|
||||||
v-tooltip.bottom="$t('delete')"
|
|
||||||
>
|
>
|
||||||
<i class="material-icons">delete</i>
|
<i class="material-icons">delete</i>
|
||||||
</button>
|
</button>
|
||||||
@@ -147,35 +153,37 @@
|
|||||||
</div>
|
</div>
|
||||||
</AppSection>
|
</AppSection>
|
||||||
|
|
||||||
<AppSection :label="$t('schema')" ref="schema" no-legend>
|
<AppSection ref="schema" :label="$t('schema')" no-legend>
|
||||||
<div class="row-wrapper">
|
<div class="row-wrapper">
|
||||||
<label>{{ $t("schema") }}</label>
|
<label>{{ $t("schema") }}</label>
|
||||||
<div v-if="schema">
|
<div v-if="schema">
|
||||||
<button
|
<button
|
||||||
class="icon"
|
|
||||||
@click="ToggleExpandResponse"
|
|
||||||
ref="ToggleExpandResponse"
|
ref="ToggleExpandResponse"
|
||||||
v-tooltip="{
|
v-tooltip="{
|
||||||
content: !expandResponse ? $t('expand_response') : $t('collapse_response'),
|
content: !expandResponse
|
||||||
|
? $t('expand_response')
|
||||||
|
: $t('collapse_response'),
|
||||||
}"
|
}"
|
||||||
|
class="icon"
|
||||||
|
@click="ToggleExpandResponse"
|
||||||
>
|
>
|
||||||
<i class="material-icons">
|
<i class="material-icons">
|
||||||
{{ !expandResponse ? "unfold_more" : "unfold_less" }}
|
{{ !expandResponse ? "unfold_more" : "unfold_less" }}
|
||||||
</i>
|
</i>
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
class="icon"
|
|
||||||
@click="downloadSchema"
|
|
||||||
ref="downloadSchema"
|
ref="downloadSchema"
|
||||||
v-tooltip="$t('download_file')"
|
v-tooltip="$t('download_file')"
|
||||||
|
class="icon"
|
||||||
|
@click="downloadSchema"
|
||||||
>
|
>
|
||||||
<i class="material-icons">save_alt</i>
|
<i class="material-icons">save_alt</i>
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
class="icon"
|
|
||||||
ref="copySchemaCode"
|
ref="copySchemaCode"
|
||||||
@click="copySchema"
|
|
||||||
v-tooltip="$t('copy_schema')"
|
v-tooltip="$t('copy_schema')"
|
||||||
|
class="icon"
|
||||||
|
@click="copySchema"
|
||||||
>
|
>
|
||||||
<i class="material-icons">content_copy</i>
|
<i class="material-icons">content_copy</i>
|
||||||
</button>
|
</button>
|
||||||
@@ -198,45 +206,47 @@
|
|||||||
/>
|
/>
|
||||||
<input
|
<input
|
||||||
v-else
|
v-else
|
||||||
|
ref="status"
|
||||||
class="rounded-b-lg missing-data-response"
|
class="rounded-b-lg missing-data-response"
|
||||||
:value="$t('waiting_receive_schema')"
|
:value="$t('waiting_receive_schema')"
|
||||||
ref="status"
|
|
||||||
name="status"
|
name="status"
|
||||||
readonly
|
readonly
|
||||||
type="text"
|
type="text"
|
||||||
/>
|
/>
|
||||||
</AppSection>
|
</AppSection>
|
||||||
|
|
||||||
<AppSection :label="$t('query')" ref="query" no-legend>
|
<AppSection ref="query" :label="$t('query')" no-legend>
|
||||||
<div class="row-wrapper gqlRunQuery">
|
<div class="row-wrapper gqlRunQuery">
|
||||||
<label for="gqlQuery">{{ $t("query") }}</label>
|
<label for="gqlQuery">{{ $t("query") }}</label>
|
||||||
<div>
|
<div>
|
||||||
<button
|
<button
|
||||||
|
v-tooltip.bottom="
|
||||||
|
`${$t('run_query')} (${getSpecialKey()}-Enter)`
|
||||||
|
"
|
||||||
@click="runQuery()"
|
@click="runQuery()"
|
||||||
v-tooltip.bottom="`${$t('run_query')} (${getSpecialKey()}-Enter)`"
|
|
||||||
>
|
>
|
||||||
<i class="material-icons">play_arrow</i>
|
<i class="material-icons">play_arrow</i>
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
class="icon"
|
|
||||||
@click="copyQuery"
|
|
||||||
ref="copyQueryButton"
|
ref="copyQueryButton"
|
||||||
v-tooltip="$t('copy_query')"
|
v-tooltip="$t('copy_query')"
|
||||||
|
class="icon"
|
||||||
|
@click="copyQuery"
|
||||||
>
|
>
|
||||||
<i class="material-icons">content_copy</i>
|
<i class="material-icons">content_copy</i>
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
|
v-tooltip="`${$t('prettify_query')} (${getSpecialKey()}-P)`"
|
||||||
class="icon"
|
class="icon"
|
||||||
@click="doPrettifyQuery"
|
@click="doPrettifyQuery"
|
||||||
v-tooltip="`${$t('prettify_query')} (${getSpecialKey()}-P)`"
|
|
||||||
>
|
>
|
||||||
<i class="material-icons">photo_filter</i>
|
<i class="material-icons">photo_filter</i>
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
class="icon"
|
|
||||||
@click="saveRequest"
|
|
||||||
ref="saveRequest"
|
ref="saveRequest"
|
||||||
v-tooltip.bottom="$t('save_to_collections')"
|
v-tooltip.bottom="$t('save_to_collections')"
|
||||||
|
class="icon"
|
||||||
|
@click="saveRequest"
|
||||||
>
|
>
|
||||||
<i class="material-icons">create_new_folder</i>
|
<i class="material-icons">create_new_folder</i>
|
||||||
</button>
|
</button>
|
||||||
@@ -245,7 +255,8 @@
|
|||||||
<GraphqlQueryEditor
|
<GraphqlQueryEditor
|
||||||
ref="queryEditor"
|
ref="queryEditor"
|
||||||
v-model="gqlQueryString"
|
v-model="gqlQueryString"
|
||||||
:onRunGQLQuery="runQuery"
|
styles="rounded-b-lg"
|
||||||
|
:on-run-g-q-l-query="runQuery"
|
||||||
:options="{
|
:options="{
|
||||||
maxLines: responseBodyMaxLines,
|
maxLines: responseBodyMaxLines,
|
||||||
minLines: 10,
|
minLines: 10,
|
||||||
@@ -254,11 +265,11 @@
|
|||||||
showPrintMargin: false,
|
showPrintMargin: false,
|
||||||
useWorker: false,
|
useWorker: false,
|
||||||
}"
|
}"
|
||||||
styles="rounded-b-lg"
|
@update-query="updateQuery"
|
||||||
/>
|
/>
|
||||||
</AppSection>
|
</AppSection>
|
||||||
|
|
||||||
<AppSection :label="$t('variables')" ref="variables" no-legend>
|
<AppSection ref="variables" :label="$t('variables')" no-legend>
|
||||||
<div class="flex flex-col">
|
<div class="flex flex-col">
|
||||||
<label>{{ $t("variables") }}</label>
|
<label>{{ $t("variables") }}</label>
|
||||||
<SmartAceEditor
|
<SmartAceEditor
|
||||||
@@ -277,27 +288,27 @@
|
|||||||
</div>
|
</div>
|
||||||
</AppSection>
|
</AppSection>
|
||||||
|
|
||||||
<AppSection :label="$t('response')" ref="response" no-legend>
|
<AppSection ref="response" :label="$t('response')" no-legend>
|
||||||
<div class="flex flex-col">
|
<div class="flex flex-col">
|
||||||
<label>{{ $t("response") }}</label>
|
<label>{{ $t("response") }}</label>
|
||||||
<div class="row-wrapper">
|
<div class="row-wrapper">
|
||||||
<label for="responseField">{{ $t("response_body") }}</label>
|
<label for="responseField">{{ $t("response_body") }}</label>
|
||||||
<div>
|
<div>
|
||||||
<button
|
<button
|
||||||
|
v-if="response"
|
||||||
|
ref="downloadResponse"
|
||||||
|
v-tooltip="$t('download_file')"
|
||||||
class="icon"
|
class="icon"
|
||||||
@click="downloadResponse"
|
@click="downloadResponse"
|
||||||
ref="downloadResponse"
|
|
||||||
v-if="response"
|
|
||||||
v-tooltip="$t('download_file')"
|
|
||||||
>
|
>
|
||||||
<i class="material-icons">save_alt</i>
|
<i class="material-icons">save_alt</i>
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
|
v-if="response"
|
||||||
|
ref="copyResponseButton"
|
||||||
|
v-tooltip="$t('copy_response')"
|
||||||
class="icon"
|
class="icon"
|
||||||
@click="copyResponse"
|
@click="copyResponse"
|
||||||
ref="copyResponseButton"
|
|
||||||
v-if="response"
|
|
||||||
v-tooltip="$t('copy_response')"
|
|
||||||
>
|
>
|
||||||
<i class="material-icons">content_copy</i>
|
<i class="material-icons">content_copy</i>
|
||||||
</button>
|
</button>
|
||||||
@@ -321,9 +332,9 @@
|
|||||||
/>
|
/>
|
||||||
<input
|
<input
|
||||||
v-else
|
v-else
|
||||||
|
ref="status"
|
||||||
class="rounded-b-lg missing-data-response"
|
class="rounded-b-lg missing-data-response"
|
||||||
:value="$t('waiting_receive_response')"
|
:value="$t('waiting_receive_response')"
|
||||||
ref="status"
|
|
||||||
name="status"
|
name="status"
|
||||||
readonly
|
readonly
|
||||||
type="text"
|
type="text"
|
||||||
@@ -335,12 +346,12 @@
|
|||||||
<aside class="sticky-inner inner-right lg:max-w-md">
|
<aside class="sticky-inner inner-right lg:max-w-md">
|
||||||
<SmartTabs>
|
<SmartTabs>
|
||||||
<SmartTab :id="'docs'" :label="`Docs`" :selected="true">
|
<SmartTab :id="'docs'" :label="`Docs`" :selected="true">
|
||||||
<AppSection :label="$t('docs')" ref="docs" no-legend>
|
<AppSection ref="docs" :label="$t('docs')" no-legend>
|
||||||
<section class="flex-col">
|
<section class="flex-col">
|
||||||
<input
|
<input
|
||||||
|
v-model="graphqlFieldsFilterText"
|
||||||
type="text"
|
type="text"
|
||||||
:placeholder="$t('search')"
|
:placeholder="$t('search')"
|
||||||
v-model="graphqlFieldsFilterText"
|
|
||||||
class="rounded-t-lg"
|
class="rounded-t-lg"
|
||||||
/>
|
/>
|
||||||
<SmartTabs ref="gqlTabs" styles="m-4">
|
<SmartTabs ref="gqlTabs" styles="m-4">
|
||||||
@@ -351,8 +362,14 @@
|
|||||||
:label="$t('queries')"
|
:label="$t('queries')"
|
||||||
:selected="true"
|
:selected="true"
|
||||||
>
|
>
|
||||||
<div v-for="field in filteredQueryFields" :key="field.name">
|
<div
|
||||||
<GraphqlField :gqlField="field" :jumpTypeCallback="handleJumpToType" />
|
v-for="field in filteredQueryFields"
|
||||||
|
:key="field.name"
|
||||||
|
>
|
||||||
|
<GraphqlField
|
||||||
|
:gql-field="field"
|
||||||
|
:jump-type-callback="handleJumpToType"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</SmartTab>
|
</SmartTab>
|
||||||
|
|
||||||
@@ -361,8 +378,14 @@
|
|||||||
:id="'mutations'"
|
:id="'mutations'"
|
||||||
:label="$t('mutations')"
|
:label="$t('mutations')"
|
||||||
>
|
>
|
||||||
<div v-for="field in filteredMutationFields" :key="field.name">
|
<div
|
||||||
<GraphqlField :gqlField="field" :jumpTypeCallback="handleJumpToType" />
|
v-for="field in filteredMutationFields"
|
||||||
|
:key="field.name"
|
||||||
|
>
|
||||||
|
<GraphqlField
|
||||||
|
:gql-field="field"
|
||||||
|
:jump-type-callback="handleJumpToType"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</SmartTab>
|
</SmartTab>
|
||||||
|
|
||||||
@@ -371,24 +394,37 @@
|
|||||||
:id="'subscriptions'"
|
:id="'subscriptions'"
|
||||||
:label="$t('subscriptions')"
|
:label="$t('subscriptions')"
|
||||||
>
|
>
|
||||||
<div v-for="field in filteredSubscriptionFields" :key="field.name">
|
<div
|
||||||
<GraphqlField :gqlField="field" :jumpTypeCallback="handleJumpToType" />
|
v-for="field in filteredSubscriptionFields"
|
||||||
|
:key="field.name"
|
||||||
|
>
|
||||||
|
<GraphqlField
|
||||||
|
:gql-field="field"
|
||||||
|
:jump-type-callback="handleJumpToType"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</SmartTab>
|
</SmartTab>
|
||||||
|
|
||||||
<SmartTab
|
<SmartTab
|
||||||
v-if="graphqlTypes.length > 0"
|
v-if="graphqlTypes.length > 0"
|
||||||
:id="'types'"
|
:id="'types'"
|
||||||
:label="$t('types')"
|
|
||||||
ref="typesTab"
|
ref="typesTab"
|
||||||
|
:label="$t('types')"
|
||||||
>
|
>
|
||||||
<div v-for="type in filteredGraphqlTypes" :key="type.name">
|
<div
|
||||||
|
v-for="type in filteredGraphqlTypes"
|
||||||
|
:key="type.name"
|
||||||
|
>
|
||||||
<GraphqlType
|
<GraphqlType
|
||||||
:gqlType="type"
|
:gql-type="type"
|
||||||
:gqlTypes="graphqlTypes"
|
:gql-types="graphqlTypes"
|
||||||
:isHighlighted="isGqlTypeHighlighted({ gqlType: type })"
|
:is-highlighted="
|
||||||
:highlightedFields="getGqlTypeHighlightedFields({ gqlType: type })"
|
isGqlTypeHighlighted({ gqlType: type })
|
||||||
:jumpTypeCallback="handleJumpToType"
|
"
|
||||||
|
:highlighted-fields="
|
||||||
|
getGqlTypeHighlightedFields({ gqlType: type })
|
||||||
|
"
|
||||||
|
:jump-type-callback="handleJumpToType"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</SmartTab>
|
</SmartTab>
|
||||||
@@ -411,9 +447,9 @@
|
|||||||
|
|
||||||
<SmartTab :id="'history'" :label="$t('history')">
|
<SmartTab :id="'history'" :label="$t('history')">
|
||||||
<History
|
<History
|
||||||
@useHistory="handleUseHistory"
|
|
||||||
ref="graphqlHistoryComponent"
|
ref="graphqlHistoryComponent"
|
||||||
:page="'graphql'"
|
:page="'graphql'"
|
||||||
|
@useHistory="handleUseHistory"
|
||||||
/>
|
/>
|
||||||
</SmartTab>
|
</SmartTab>
|
||||||
|
|
||||||
@@ -433,23 +469,12 @@
|
|||||||
</div>
|
</div>
|
||||||
<CollectionsGraphqlSaveRequest
|
<CollectionsGraphqlSaveRequest
|
||||||
:show="showSaveRequestModal"
|
:show="showSaveRequestModal"
|
||||||
@hide-modal="hideRequestModal"
|
|
||||||
:editing-request="editRequest"
|
:editing-request="editRequest"
|
||||||
|
@hide-modal="hideRequestModal"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
.gqlTabs {
|
|
||||||
max-height: calc(100vh - 192px);
|
|
||||||
position: relative;
|
|
||||||
@apply overflow-auto;
|
|
||||||
}
|
|
||||||
.gqlRunQuery {
|
|
||||||
@apply mb-8;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import * as gql from "graphql"
|
import * as gql from "graphql"
|
||||||
import { commonHeaders } from "~/helpers/headers"
|
import { commonHeaders } from "~/helpers/headers"
|
||||||
@@ -459,6 +484,12 @@ import { getSettingSubject } from "~/newstore/settings"
|
|||||||
import { fb } from "~/helpers/fb"
|
import { fb } from "~/helpers/fb"
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
beforeRouteLeave(_to, _from, next) {
|
||||||
|
this.isPollingSchema = false
|
||||||
|
if (this.timeoutSubscription) clearTimeout(this.timeoutSubscription)
|
||||||
|
|
||||||
|
next()
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
commonHeaders,
|
commonHeaders,
|
||||||
@@ -484,14 +515,10 @@ export default {
|
|||||||
SCROLL_INTO_ENABLED: getSettingSubject("SCROLL_INTO_ENABLED"),
|
SCROLL_INTO_ENABLED: getSettingSubject("SCROLL_INTO_ENABLED"),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
head() {
|
||||||
selectedRequest(newValue) {
|
return {
|
||||||
if (!newValue) return
|
title: `GraphQL • Hoppscotch`,
|
||||||
this.url = newValue.url
|
}
|
||||||
this.gqlQueryString = newValue.query
|
|
||||||
this.headers = newValue.headers
|
|
||||||
this.variableString = newValue.variables
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
selectedRequest() {
|
selectedRequest() {
|
||||||
@@ -576,18 +603,26 @@ 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() {
|
mounted() {
|
||||||
if (this.$store.state.gql.schemaIntrospection && this.$store.state.gql.schema) {
|
if (
|
||||||
const gqlSchema = gql.buildClientSchema(JSON.parse(this.$store.state.gql.schemaIntrospection))
|
this.$store.state.gql.schemaIntrospection &&
|
||||||
|
this.$store.state.gql.schema
|
||||||
|
) {
|
||||||
|
const gqlSchema = gql.buildClientSchema(
|
||||||
|
JSON.parse(this.$store.state.gql.schemaIntrospection)
|
||||||
|
)
|
||||||
this.getDocsFromSchema(gqlSchema)
|
this.getDocsFromSchema(gqlSchema)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
beforeRouteLeave(_to, _from, next) {
|
|
||||||
this.isPollingSchema = false
|
|
||||||
if (this.timeoutSubscription) clearTimeout(this.timeoutSubscription)
|
|
||||||
|
|
||||||
next()
|
|
||||||
},
|
|
||||||
methods: {
|
methods: {
|
||||||
hideRequestModal() {
|
hideRequestModal() {
|
||||||
this.showSaveRequestModal = false
|
this.showSaveRequestModal = false
|
||||||
@@ -641,7 +676,9 @@ export default {
|
|||||||
const isFilterTextFoundInDescription = graphqlFieldObject.description
|
const isFilterTextFoundInDescription = graphqlFieldObject.description
|
||||||
? graphqlFieldObject.description.toLowerCase().includes(normalizedText)
|
? graphqlFieldObject.description.toLowerCase().includes(normalizedText)
|
||||||
: false
|
: false
|
||||||
const isFilterTextFoundInName = graphqlFieldObject.name.toLowerCase().includes(normalizedText)
|
const isFilterTextFoundInName = graphqlFieldObject.name
|
||||||
|
.toLowerCase()
|
||||||
|
.includes(normalizedText)
|
||||||
|
|
||||||
return isFilterTextFoundInDescription || isFilterTextFoundInName
|
return isFilterTextFoundInDescription || isFilterTextFoundInName
|
||||||
},
|
},
|
||||||
@@ -649,7 +686,10 @@ export default {
|
|||||||
if (!filterText) return fields
|
if (!filterText) return fields
|
||||||
|
|
||||||
return fields.filter((field) =>
|
return fields.filter((field) =>
|
||||||
this.isTextFoundInGraphqlFieldObject({ text: filterText, graphqlFieldObject: field })
|
this.isTextFoundInGraphqlFieldObject({
|
||||||
|
text: filterText,
|
||||||
|
graphqlFieldObject: field,
|
||||||
|
})
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
getFilteredGraphqlTypes({ filterText, types }) {
|
getFilteredGraphqlTypes({ filterText, types }) {
|
||||||
@@ -665,12 +705,13 @@ export default {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
const isFilterTextMatchingAtLeastOneField = Object.values(type._fields || {}).some(
|
const isFilterTextMatchingAtLeastOneField = Object.values(
|
||||||
(field) =>
|
type._fields || {}
|
||||||
this.isTextFoundInGraphqlFieldObject({
|
).some((field) =>
|
||||||
text: filterText,
|
this.isTextFoundInGraphqlFieldObject({
|
||||||
graphqlFieldObject: field,
|
text: filterText,
|
||||||
})
|
graphqlFieldObject: field,
|
||||||
|
})
|
||||||
)
|
)
|
||||||
|
|
||||||
return isFilterTextMatchingAtLeastOneField
|
return isFilterTextMatchingAtLeastOneField
|
||||||
@@ -709,7 +750,10 @@ export default {
|
|||||||
this.$toast.success(this.$t("copied_to_clipboard"), {
|
this.$toast.success(this.$t("copied_to_clipboard"), {
|
||||||
icon: "done",
|
icon: "done",
|
||||||
})
|
})
|
||||||
setTimeout(() => (this.$refs.copySchemaCode.innerHTML = this.copyButton), 1000)
|
setTimeout(
|
||||||
|
() => (this.$refs.copySchemaCode.innerHTML = this.copyButton),
|
||||||
|
1000
|
||||||
|
)
|
||||||
},
|
},
|
||||||
copyQuery() {
|
copyQuery() {
|
||||||
this.$refs.copyQueryButton.innerHTML = this.doneButton
|
this.$refs.copyQueryButton.innerHTML = this.doneButton
|
||||||
@@ -722,7 +766,10 @@ export default {
|
|||||||
this.$toast.success(this.$t("copied_to_clipboard"), {
|
this.$toast.success(this.$t("copied_to_clipboard"), {
|
||||||
icon: "done",
|
icon: "done",
|
||||||
})
|
})
|
||||||
setTimeout(() => (this.$refs.copyQueryButton.innerHTML = this.copyButton), 1000)
|
setTimeout(
|
||||||
|
() => (this.$refs.copyQueryButton.innerHTML = this.copyButton),
|
||||||
|
1000
|
||||||
|
)
|
||||||
},
|
},
|
||||||
copyResponse() {
|
copyResponse() {
|
||||||
this.$refs.copyResponseButton.innerHTML = this.doneButton
|
this.$refs.copyResponseButton.innerHTML = this.doneButton
|
||||||
@@ -735,7 +782,10 @@ export default {
|
|||||||
this.$toast.success(this.$t("copied_to_clipboard"), {
|
this.$toast.success(this.$t("copied_to_clipboard"), {
|
||||||
icon: "done",
|
icon: "done",
|
||||||
})
|
})
|
||||||
setTimeout(() => (this.$refs.copyResponseButton.innerHTML = this.copyButton), 1000)
|
setTimeout(
|
||||||
|
() => (this.$refs.copyResponseButton.innerHTML = this.copyButton),
|
||||||
|
1000
|
||||||
|
)
|
||||||
},
|
},
|
||||||
async runQuery() {
|
async runQuery() {
|
||||||
const startTime = Date.now()
|
const startTime = Date.now()
|
||||||
@@ -748,14 +798,18 @@ export default {
|
|||||||
if (this.SCROLL_INTO_ENABLED) this.scrollInto("response")
|
if (this.SCROLL_INTO_ENABLED) this.scrollInto("response")
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let headers = {}
|
const headers = {}
|
||||||
this.headers
|
this.headers
|
||||||
.filter((item) => (item.hasOwnProperty("active") ? item.active == true : true))
|
.filter((item) =>
|
||||||
|
Object.prototype.hasOwnProperty.call(item, "active")
|
||||||
|
? item.active === true
|
||||||
|
: true
|
||||||
|
)
|
||||||
.forEach(({ key, value }) => {
|
.forEach(({ key, value }) => {
|
||||||
headers[key] = value
|
headers[key] = value
|
||||||
})
|
})
|
||||||
|
|
||||||
let variables = JSON.parse(this.variableString || "{}")
|
const variables = JSON.parse(this.variableString || "{}")
|
||||||
|
|
||||||
const gqlQueryString = this.gqlQueryString
|
const gqlQueryString = this.gqlQueryString
|
||||||
|
|
||||||
@@ -778,7 +832,9 @@ export default {
|
|||||||
const res = await sendNetworkRequest(reqOptions)
|
const res = await sendNetworkRequest(reqOptions)
|
||||||
|
|
||||||
// HACK: Temporary trailing null character issue from the extension fix
|
// HACK: Temporary trailing null character issue from the extension fix
|
||||||
const responseText = new TextDecoder("utf-8").decode(res.data).replace(/\0+$/, "")
|
const responseText = new TextDecoder("utf-8")
|
||||||
|
.decode(res.data)
|
||||||
|
.replace(/\0+$/, "")
|
||||||
|
|
||||||
this.response = JSON.stringify(JSON.parse(responseText), null, 2)
|
this.response = JSON.stringify(JSON.parse(responseText), null, 2)
|
||||||
|
|
||||||
@@ -846,17 +902,23 @@ export default {
|
|||||||
const typeMap = schema.getTypeMap()
|
const typeMap = schema.getTypeMap()
|
||||||
const types = []
|
const types = []
|
||||||
|
|
||||||
const queryTypeName = schema.getQueryType() ? schema.getQueryType().name : ""
|
const queryTypeName = schema.getQueryType()
|
||||||
const mutationTypeName = schema.getMutationType() ? schema.getMutationType().name : ""
|
? schema.getQueryType().name
|
||||||
|
: ""
|
||||||
|
const mutationTypeName = schema.getMutationType()
|
||||||
|
? schema.getMutationType().name
|
||||||
|
: ""
|
||||||
const subscriptionTypeName = schema.getSubscriptionType()
|
const subscriptionTypeName = schema.getSubscriptionType()
|
||||||
? schema.getSubscriptionType().name
|
? schema.getSubscriptionType().name
|
||||||
: ""
|
: ""
|
||||||
|
|
||||||
for (const typeName in typeMap) {
|
for (const typeName in typeMap) {
|
||||||
let type = typeMap[typeName]
|
const type = typeMap[typeName]
|
||||||
if (
|
if (
|
||||||
!type.name.startsWith("__") &&
|
!type.name.startsWith("__") &&
|
||||||
![queryTypeName, mutationTypeName, subscriptionTypeName].includes(type.name) &&
|
![queryTypeName, mutationTypeName, subscriptionTypeName].includes(
|
||||||
|
type.name
|
||||||
|
) &&
|
||||||
(type instanceof gql.GraphQLObjectType ||
|
(type instanceof gql.GraphQLObjectType ||
|
||||||
type instanceof gql.GraphQLInputObjectType ||
|
type instanceof gql.GraphQLInputObjectType ||
|
||||||
type instanceof gql.GraphQLEnumType ||
|
type instanceof gql.GraphQLEnumType ||
|
||||||
@@ -887,9 +949,13 @@ export default {
|
|||||||
query: gql.getIntrospectionQuery(),
|
query: gql.getIntrospectionQuery(),
|
||||||
})
|
})
|
||||||
|
|
||||||
let headers = {}
|
const headers = {}
|
||||||
this.headers
|
this.headers
|
||||||
.filter((item) => (item.hasOwnProperty("active") ? item.active == true : true))
|
.filter((item) =>
|
||||||
|
Object.prototype.hasOwnProperty.call(item, "active")
|
||||||
|
? item.active === true
|
||||||
|
: true
|
||||||
|
)
|
||||||
.forEach(({ key, value }) => {
|
.forEach(({ key, value }) => {
|
||||||
headers[key] = value
|
headers[key] = value
|
||||||
})
|
})
|
||||||
@@ -907,7 +973,9 @@ export default {
|
|||||||
const data = await sendNetworkRequest(reqOptions, this.$store)
|
const data = await sendNetworkRequest(reqOptions, this.$store)
|
||||||
|
|
||||||
// HACK : Temporary trailing null character issue from the extension fix
|
// HACK : Temporary trailing null character issue from the extension fix
|
||||||
const response = new TextDecoder("utf-8").decode(data.data).replace(/\0+$/, "")
|
const response = new TextDecoder("utf-8")
|
||||||
|
.decode(data.data)
|
||||||
|
.replace(/\0+$/, "")
|
||||||
const introspectResponse = JSON.parse(response)
|
const introspectResponse = JSON.parse(response)
|
||||||
|
|
||||||
const schema = gql.buildClientSchema(introspectResponse.data)
|
const schema = gql.buildClientSchema(introspectResponse.data)
|
||||||
@@ -926,13 +994,16 @@ export default {
|
|||||||
this.$refs.queryEditor.setValidationSchema(schema)
|
this.$refs.queryEditor.setValidationSchema(schema)
|
||||||
this.$nuxt.$loading.finish()
|
this.$nuxt.$loading.finish()
|
||||||
|
|
||||||
if (this.isPollingSchema) this.timeoutSubscription = setTimeout(this.pollSchema, 7000)
|
if (this.isPollingSchema)
|
||||||
|
this.timeoutSubscription = setTimeout(this.pollSchema, 7000)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.$nuxt.$loading.finish()
|
this.$nuxt.$loading.finish()
|
||||||
|
|
||||||
this.schema = `${error}. ${this.$t("check_console_details")}`
|
this.schema = `${error}. ${this.$t("check_console_details")}`
|
||||||
this.$toast.error(
|
this.$toast.error(
|
||||||
`${this.$t("graphql_introspect_failed")} ${this.$t("check_graphql_valid")}`,
|
`${this.$t("graphql_introspect_failed")} ${this.$t(
|
||||||
|
"check_graphql_valid"
|
||||||
|
)}`,
|
||||||
{
|
{
|
||||||
icon: "error",
|
icon: "error",
|
||||||
}
|
}
|
||||||
@@ -959,9 +1030,13 @@ export default {
|
|||||||
query: gql.getIntrospectionQuery(),
|
query: gql.getIntrospectionQuery(),
|
||||||
})
|
})
|
||||||
|
|
||||||
let headers = {}
|
const headers = {}
|
||||||
this.headers
|
this.headers
|
||||||
.filter((item) => (item.hasOwnProperty("active") ? item.active == true : true))
|
.filter((item) =>
|
||||||
|
Object.prototype.hasOwnProperty.call(item, "active")
|
||||||
|
? item.active === true
|
||||||
|
: true
|
||||||
|
)
|
||||||
.forEach(({ key, value }) => {
|
.forEach(({ key, value }) => {
|
||||||
headers[key] = value
|
headers[key] = value
|
||||||
})
|
})
|
||||||
@@ -979,7 +1054,9 @@ export default {
|
|||||||
const data = await sendNetworkRequest(reqOptions, this.$store)
|
const data = await sendNetworkRequest(reqOptions, this.$store)
|
||||||
|
|
||||||
// HACK : Temporary trailing null character issue from the extension fix
|
// HACK : Temporary trailing null character issue from the extension fix
|
||||||
const response = new TextDecoder("utf-8").decode(data.data).replace(/\0+$/, "")
|
const response = new TextDecoder("utf-8")
|
||||||
|
.decode(data.data)
|
||||||
|
.replace(/\0+$/, "")
|
||||||
const introspectResponse = JSON.parse(response)
|
const introspectResponse = JSON.parse(response)
|
||||||
|
|
||||||
const schema = gql.buildClientSchema(introspectResponse.data)
|
const schema = gql.buildClientSchema(introspectResponse.data)
|
||||||
@@ -1006,7 +1083,9 @@ export default {
|
|||||||
|
|
||||||
this.schema = `${error}. ${this.$t("check_console_details")}`
|
this.schema = `${error}. ${this.$t("check_console_details")}`
|
||||||
this.$toast.error(
|
this.$toast.error(
|
||||||
`${this.$t("graphql_introspect_failed")} ${this.$t("check_graphql_valid")}`,
|
`${this.$t("graphql_introspect_failed")} ${this.$t(
|
||||||
|
"check_graphql_valid"
|
||||||
|
)}`,
|
||||||
{
|
{
|
||||||
icon: "error",
|
icon: "error",
|
||||||
}
|
}
|
||||||
@@ -1016,7 +1095,8 @@ export default {
|
|||||||
},
|
},
|
||||||
ToggleExpandResponse() {
|
ToggleExpandResponse() {
|
||||||
this.expandResponse = !this.expandResponse
|
this.expandResponse = !this.expandResponse
|
||||||
this.responseBodyMaxLines = this.responseBodyMaxLines == Infinity ? 16 : Infinity
|
this.responseBodyMaxLines =
|
||||||
|
this.responseBodyMaxLines === Infinity ? 16 : Infinity
|
||||||
},
|
},
|
||||||
downloadResponse() {
|
downloadResponse() {
|
||||||
const dataToWrite = this.response
|
const dataToWrite = this.response
|
||||||
@@ -1056,7 +1136,7 @@ export default {
|
|||||||
this.$refs.downloadSchema.innerHTML = this.downloadButton
|
this.$refs.downloadSchema.innerHTML = this.downloadButton
|
||||||
}, 1000)
|
}, 1000)
|
||||||
},
|
},
|
||||||
addRequestHeader(index) {
|
addRequestHeader() {
|
||||||
this.$store.commit("addGQLHeader", {
|
this.$store.commit("addGQLHeader", {
|
||||||
key: "",
|
key: "",
|
||||||
value: "",
|
value: "",
|
||||||
@@ -1073,7 +1153,7 @@ export default {
|
|||||||
action: {
|
action: {
|
||||||
text: this.$t("undo"),
|
text: this.$t("undo"),
|
||||||
duration: 4000,
|
duration: 4000,
|
||||||
onClick: (e, toastObject) => {
|
onClick: (_, toastObject) => {
|
||||||
this.headers = oldHeaders
|
this.headers = oldHeaders
|
||||||
toastObject.remove()
|
toastObject.remove()
|
||||||
},
|
},
|
||||||
@@ -1085,11 +1165,20 @@ export default {
|
|||||||
behavior: "smooth",
|
behavior: "smooth",
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
},
|
updateQuery(updatedQuery) {
|
||||||
head() {
|
this.gqlQueryString = updatedQuery
|
||||||
return {
|
},
|
||||||
title: `GraphQL • Hoppscotch`,
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.gqlTabs {
|
||||||
|
max-height: calc(100vh - 192px);
|
||||||
|
position: relative;
|
||||||
|
@apply overflow-auto;
|
||||||
|
}
|
||||||
|
.gqlRunQuery {
|
||||||
|
@apply mb-8;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user