feat: collection level headers and authorization (#3505)
Co-authored-by: Andrew Bastin <andrewbastin.k@gmail.com>
This commit is contained in:
@@ -32,58 +32,58 @@
|
||||
</HoppSmartModal>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from "vue"
|
||||
<script setup lang="ts">
|
||||
import { ref } from "vue"
|
||||
import { useToast } from "@composables/toast"
|
||||
import { useI18n } from "@composables/i18n"
|
||||
import { HoppGQLRequest, makeCollection } from "@hoppscotch/data"
|
||||
import { makeCollection } from "@hoppscotch/data"
|
||||
import { addGraphqlCollection } from "~/newstore/collections"
|
||||
import { platform } from "~/platform"
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
show: Boolean,
|
||||
},
|
||||
emits: ["hide-modal"],
|
||||
setup() {
|
||||
return {
|
||||
toast: useToast(),
|
||||
t: useI18n(),
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
name: null as string | null,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
addNewCollection() {
|
||||
if (!this.name) {
|
||||
this.toast.error(`${this.t("collection.invalid_name")}`)
|
||||
return
|
||||
}
|
||||
const t = useI18n()
|
||||
const toast = useToast()
|
||||
|
||||
addGraphqlCollection(
|
||||
makeCollection<HoppGQLRequest>({
|
||||
name: this.name,
|
||||
folders: [],
|
||||
requests: [],
|
||||
})
|
||||
)
|
||||
defineProps<{
|
||||
show: boolean
|
||||
}>()
|
||||
|
||||
this.hideModal()
|
||||
const emit = defineEmits<{
|
||||
(e: "hide-modal"): void
|
||||
}>()
|
||||
|
||||
platform.analytics?.logEvent({
|
||||
type: "HOPP_CREATE_COLLECTION",
|
||||
isRootCollection: true,
|
||||
platform: "gql",
|
||||
workspaceType: "personal",
|
||||
})
|
||||
},
|
||||
hideModal() {
|
||||
this.name = null
|
||||
this.$emit("hide-modal")
|
||||
},
|
||||
},
|
||||
})
|
||||
const name = ref<string | null>(null)
|
||||
|
||||
const addNewCollection = () => {
|
||||
if (!name.value) {
|
||||
toast.error(`${t("collection.invalid_name")}`)
|
||||
return
|
||||
}
|
||||
|
||||
addGraphqlCollection(
|
||||
makeCollection({
|
||||
name: name.value,
|
||||
folders: [],
|
||||
requests: [],
|
||||
auth: {
|
||||
authType: "inherit",
|
||||
authActive: true,
|
||||
},
|
||||
headers: [],
|
||||
})
|
||||
)
|
||||
|
||||
hideModal()
|
||||
|
||||
platform.analytics?.logEvent({
|
||||
type: "HOPP_CREATE_COLLECTION",
|
||||
isRootCollection: true,
|
||||
platform: "gql",
|
||||
workspaceType: "personal",
|
||||
})
|
||||
}
|
||||
|
||||
const hideModal = () => {
|
||||
name.value = null
|
||||
emit("hide-modal")
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
v-if="show"
|
||||
dialog
|
||||
:title="t('folder.new')"
|
||||
@close="$emit('hide-modal')"
|
||||
@close="hideModal"
|
||||
>
|
||||
<template #body>
|
||||
<HoppSmartInput
|
||||
@@ -32,47 +32,49 @@
|
||||
</HoppSmartModal>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
<script setup lang="ts">
|
||||
import { ref } from "vue"
|
||||
import { useToast } from "@composables/toast"
|
||||
import { useI18n } from "@composables/i18n"
|
||||
import { defineComponent } from "vue"
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
show: Boolean,
|
||||
folderPath: { type: String, default: null },
|
||||
collectionIndex: { type: Number, default: null },
|
||||
},
|
||||
emits: ["hide-modal", "add-folder"],
|
||||
setup() {
|
||||
return {
|
||||
toast: useToast(),
|
||||
t: useI18n(),
|
||||
const t = useI18n()
|
||||
const toast = useToast()
|
||||
|
||||
const props = defineProps<{
|
||||
show: boolean
|
||||
folderPath?: string
|
||||
collectionIndex: number
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: "hide-modal"): void
|
||||
(
|
||||
e: "add-folder",
|
||||
v: {
|
||||
name: string
|
||||
path: string | undefined
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
name: null,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
addFolder() {
|
||||
if (!this.name) {
|
||||
this.toast.error(`${this.t("folder.name_length_insufficient")}`)
|
||||
return
|
||||
}
|
||||
): void
|
||||
}>()
|
||||
|
||||
this.$emit("add-folder", {
|
||||
name: this.name,
|
||||
path: this.folderPath || `${this.collectionIndex}`,
|
||||
})
|
||||
const name = ref<string | null>(null)
|
||||
|
||||
this.hideModal()
|
||||
},
|
||||
hideModal() {
|
||||
this.name = null
|
||||
this.$emit("hide-modal")
|
||||
},
|
||||
},
|
||||
})
|
||||
const addFolder = () => {
|
||||
if (!name.value) {
|
||||
toast.error(`${t("folder.name_length_insufficient")}`)
|
||||
return
|
||||
}
|
||||
|
||||
emit("add-folder", {
|
||||
name: name.value,
|
||||
path: props.folderPath || `${props.collectionIndex}`,
|
||||
})
|
||||
|
||||
hideModal()
|
||||
}
|
||||
|
||||
const hideModal = () => {
|
||||
name.value = null
|
||||
emit("hide-modal")
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -128,6 +128,21 @@
|
||||
}
|
||||
"
|
||||
/>
|
||||
<HoppSmartItem
|
||||
ref="propertiesAction"
|
||||
:icon="IconSettings2"
|
||||
:label="t('action.properties')"
|
||||
:shortcut="['P']"
|
||||
@click="
|
||||
() => {
|
||||
emit('edit-properties', {
|
||||
collectionIndex: String(collectionIndex),
|
||||
collection: collection,
|
||||
})
|
||||
hide()
|
||||
}
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
</tippy>
|
||||
@@ -155,7 +170,15 @@
|
||||
@edit-folder="$emit('edit-folder', $event)"
|
||||
@edit-request="$emit('edit-request', $event)"
|
||||
@duplicate-request="$emit('duplicate-request', $event)"
|
||||
@edit-properties="
|
||||
$emit('edit-properties', {
|
||||
collectionIndex: `${collectionIndex}/${String(index)}`,
|
||||
collection: folder,
|
||||
})
|
||||
"
|
||||
@select="$emit('select', $event)"
|
||||
@select-request="$emit('select-request', $event)"
|
||||
@drop-request="$emit('drop-request', $event)"
|
||||
/>
|
||||
<CollectionsGraphqlRequest
|
||||
v-for="(request, index) in collection.requests"
|
||||
@@ -171,6 +194,7 @@
|
||||
@edit-request="$emit('edit-request', $event)"
|
||||
@duplicate-request="$emit('duplicate-request', $event)"
|
||||
@select="$emit('select', $event)"
|
||||
@select-request="$emit('select-request', $event)"
|
||||
/>
|
||||
<HoppSmartPlaceholder
|
||||
v-if="
|
||||
@@ -214,25 +238,24 @@ import IconFolderPlus from "~icons/lucide/folder-plus"
|
||||
import IconMoreVertical from "~icons/lucide/more-vertical"
|
||||
import IconEdit from "~icons/lucide/edit"
|
||||
import IconTrash2 from "~icons/lucide/trash-2"
|
||||
import IconSettings2 from "~icons/lucide/settings-2"
|
||||
import { useToast } from "@composables/toast"
|
||||
import { useI18n } from "@composables/i18n"
|
||||
import { useColorMode } from "@composables/theming"
|
||||
import {
|
||||
removeGraphqlCollection,
|
||||
moveGraphqlRequest,
|
||||
} from "~/newstore/collections"
|
||||
import { removeGraphqlCollection } from "~/newstore/collections"
|
||||
import { Picked } from "~/helpers/types/HoppPicked"
|
||||
import { useService } from "dioc/vue"
|
||||
import { GQLTabService } from "~/services/tab/graphql"
|
||||
import { HoppCollection } from "@hoppscotch/data"
|
||||
|
||||
const props = defineProps({
|
||||
picked: { type: Object, default: null },
|
||||
const props = defineProps<{
|
||||
picked: Picked | null
|
||||
// Whether the viewing context is related to picking (activates 'select' events)
|
||||
saveRequest: { type: Boolean, default: false },
|
||||
collectionIndex: { type: Number, default: null },
|
||||
collection: { type: Object, default: () => ({}) },
|
||||
isFiltered: Boolean,
|
||||
})
|
||||
saveRequest: boolean
|
||||
collectionIndex: number | null
|
||||
collection: HoppCollection
|
||||
isFiltered: boolean
|
||||
}>()
|
||||
|
||||
const colorMode = useColorMode()
|
||||
const toast = useToast()
|
||||
@@ -248,7 +271,23 @@ const emit = defineEmits<{
|
||||
(e: "add-request", i: any): void
|
||||
(e: "add-folder", i: any): void
|
||||
(e: "edit-folder", i: any): void
|
||||
(
|
||||
e: "edit-properties",
|
||||
payload: {
|
||||
collectionIndex: string | null
|
||||
collection: HoppCollection
|
||||
}
|
||||
): void
|
||||
(e: "edit-collection"): void
|
||||
(e: "select-request", i: any): void
|
||||
(
|
||||
e: "drop-request",
|
||||
payload: {
|
||||
folderPath: string
|
||||
requestIndex: string
|
||||
collectionIndex: number | null
|
||||
}
|
||||
): void
|
||||
}>()
|
||||
|
||||
// Template refs
|
||||
@@ -324,6 +363,10 @@ const dropEvent = ({ dataTransfer }: any) => {
|
||||
dragging.value = !dragging.value
|
||||
const folderPath = dataTransfer.getData("folderPath")
|
||||
const requestIndex = dataTransfer.getData("requestIndex")
|
||||
moveGraphqlRequest(folderPath, requestIndex, `${props.collectionIndex}`)
|
||||
emit("drop-request", {
|
||||
folderPath,
|
||||
requestIndex,
|
||||
collectionIndex: props.collectionIndex,
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -37,13 +37,14 @@ import { ref, watch } from "vue"
|
||||
import { editGraphqlCollection } from "~/newstore/collections"
|
||||
import { useToast } from "@composables/toast"
|
||||
import { useI18n } from "@composables/i18n"
|
||||
import { HoppCollection } from "@hoppscotch/data"
|
||||
|
||||
const props = defineProps({
|
||||
show: Boolean,
|
||||
editingCollection: { type: Object, default: () => ({}) },
|
||||
editingCollectionIndex: { type: Number, default: null },
|
||||
editingCollectionName: { type: String, default: null },
|
||||
})
|
||||
const props = defineProps<{
|
||||
show: boolean
|
||||
editingCollectionIndex: number | null
|
||||
editingCollection: HoppCollection | null
|
||||
editingCollectionName: string
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: "hide-modal"): void
|
||||
|
||||
@@ -32,52 +32,47 @@
|
||||
</HoppSmartModal>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from "vue"
|
||||
<script setup lang="ts">
|
||||
import { ref, watch } from "vue"
|
||||
import { useI18n } from "@composables/i18n"
|
||||
import { useToast } from "@composables/toast"
|
||||
import { editGraphqlFolder } from "~/newstore/collections"
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
show: Boolean,
|
||||
folder: { type: Object, default: () => ({}) },
|
||||
folderPath: { type: String, default: null },
|
||||
editingFolderName: { type: String, default: null },
|
||||
},
|
||||
emits: ["hide-modal"],
|
||||
setup() {
|
||||
return {
|
||||
toast: useToast(),
|
||||
t: useI18n(),
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
name: "",
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
editingFolderName(val) {
|
||||
this.name = val
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
editFolder() {
|
||||
if (!this.name) {
|
||||
this.toast.error(`${this.t("collection.invalid_name")}`)
|
||||
return
|
||||
}
|
||||
editGraphqlFolder(this.folderPath, {
|
||||
...(this.folder as any),
|
||||
name: this.name,
|
||||
})
|
||||
this.hideModal()
|
||||
},
|
||||
hideModal() {
|
||||
this.name = ""
|
||||
this.$emit("hide-modal")
|
||||
},
|
||||
},
|
||||
})
|
||||
const t = useI18n()
|
||||
const toast = useToast()
|
||||
|
||||
const props = defineProps<{
|
||||
show: boolean
|
||||
folderPath?: string
|
||||
folder: any
|
||||
editingFolderName: string
|
||||
}>()
|
||||
|
||||
const emit = defineEmits(["hide-modal"])
|
||||
|
||||
const name = ref("")
|
||||
|
||||
watch(
|
||||
() => props.editingFolderName,
|
||||
(val) => {
|
||||
name.value = val
|
||||
}
|
||||
)
|
||||
|
||||
const editFolder = () => {
|
||||
if (!name.value) {
|
||||
toast.error(`${t("collection.invalid_name")}`)
|
||||
return
|
||||
}
|
||||
editGraphqlFolder(props.folderPath, {
|
||||
...(props.folder as any),
|
||||
name: name.value,
|
||||
})
|
||||
hideModal()
|
||||
}
|
||||
|
||||
const hideModal = () => {
|
||||
name.value = ""
|
||||
emit("hide-modal")
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -32,61 +32,55 @@
|
||||
</HoppSmartModal>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, PropType } from "vue"
|
||||
<script setup lang="ts">
|
||||
import { ref, watch } from "vue"
|
||||
import { useI18n } from "@composables/i18n"
|
||||
import { useToast } from "@composables/toast"
|
||||
import { HoppGQLRequest } from "@hoppscotch/data"
|
||||
import { editGraphqlRequest } from "~/newstore/collections"
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
show: Boolean,
|
||||
folderPath: { type: String, default: null },
|
||||
request: { type: Object as PropType<HoppGQLRequest>, default: () => ({}) },
|
||||
requestIndex: { type: Number, default: null },
|
||||
editingRequestName: { type: String, default: null },
|
||||
},
|
||||
emits: ["hide-modal"],
|
||||
setup() {
|
||||
return {
|
||||
toast: useToast(),
|
||||
t: useI18n(),
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
requestUpdateData: {
|
||||
name: null as any | null,
|
||||
},
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
editingRequestName(val) {
|
||||
this.requestUpdateData.name = val
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
saveRequest() {
|
||||
if (!this.requestUpdateData.name) {
|
||||
this.toast.error(`${this.t("collection.invalid_name")}`)
|
||||
return
|
||||
}
|
||||
const t = useI18n()
|
||||
const toast = useToast()
|
||||
|
||||
// TODO: Type safety goes brrrr. Proper typing plz
|
||||
const requestUpdated = {
|
||||
...this.$props.request,
|
||||
name: this.$data.requestUpdateData.name || this.$props.request.name,
|
||||
}
|
||||
const props = defineProps<{
|
||||
show: boolean
|
||||
folderPath?: string
|
||||
requestIndex: number | null
|
||||
request: HoppGQLRequest | null
|
||||
editingRequestName: string
|
||||
}>()
|
||||
|
||||
editGraphqlRequest(this.folderPath, this.requestIndex, requestUpdated)
|
||||
const emit = defineEmits<{
|
||||
(e: "hide-modal"): void
|
||||
}>()
|
||||
|
||||
this.hideModal()
|
||||
},
|
||||
hideModal() {
|
||||
this.requestUpdateData = { name: null }
|
||||
this.$emit("hide-modal")
|
||||
},
|
||||
},
|
||||
})
|
||||
const requestUpdateData = ref({ name: null as string | null })
|
||||
|
||||
watch(
|
||||
() => props.editingRequestName,
|
||||
(val) => {
|
||||
requestUpdateData.value.name = val
|
||||
}
|
||||
)
|
||||
|
||||
const saveRequest = () => {
|
||||
if (!requestUpdateData.value.name) {
|
||||
toast.error(`${t("collection.invalid_name")}`)
|
||||
return
|
||||
}
|
||||
|
||||
const requestUpdated = {
|
||||
...(props.request as any),
|
||||
name: requestUpdateData.value.name || (props.request as any).name,
|
||||
}
|
||||
|
||||
editGraphqlRequest(props.folderPath, props.requestIndex, requestUpdated)
|
||||
|
||||
hideModal()
|
||||
}
|
||||
|
||||
const hideModal = () => {
|
||||
requestUpdateData.value = { name: null }
|
||||
emit("hide-modal")
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -10,24 +10,25 @@
|
||||
@dragend="dragging = false"
|
||||
@contextmenu.prevent="options.tippy.show()"
|
||||
>
|
||||
<span
|
||||
class="flex cursor-pointer items-center justify-center px-4"
|
||||
<div
|
||||
class="flex min-w-0 flex-1 items-center justify-center cursor-pointer"
|
||||
@click="toggleShowChildren()"
|
||||
>
|
||||
<component
|
||||
:is="collectionIcon"
|
||||
class="svg-icons"
|
||||
:class="{ 'text-accent': isSelected }"
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
class="flex min-w-0 flex-1 cursor-pointer py-2 pr-2 transition group-hover:text-secondaryDark"
|
||||
@click="toggleShowChildren()"
|
||||
>
|
||||
<span class="truncate" :class="{ 'text-accent': isSelected }">
|
||||
{{ folder.name ? folder.name : folder.title }}
|
||||
<span class="pointer-events-none flex items-center justify-center px-4">
|
||||
<component
|
||||
:is="collectionIcon"
|
||||
class="svg-icons"
|
||||
:class="{ 'text-accent': isSelected }"
|
||||
/>
|
||||
</span>
|
||||
</span>
|
||||
<span
|
||||
class="pointer-events-none flex min-w-0 flex-1 cursor-pointer py-2 pr-2 transition group-hover:text-secondaryDark"
|
||||
>
|
||||
<span class="truncate" :class="{ 'text-accent': isSelected }">
|
||||
{{ folder.name ? folder.name : folder.title }}
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex">
|
||||
<HoppButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
@@ -120,6 +121,21 @@
|
||||
}
|
||||
"
|
||||
/>
|
||||
<HoppSmartItem
|
||||
ref="propertiesAction"
|
||||
:icon="IconSettings2"
|
||||
:label="t('action.properties')"
|
||||
:shortcut="['P']"
|
||||
@click="
|
||||
() => {
|
||||
emit('edit-properties', {
|
||||
collectionIndex: collectionIndex,
|
||||
collection: collection,
|
||||
})
|
||||
hide()
|
||||
}
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
</tippy>
|
||||
@@ -148,7 +164,14 @@
|
||||
@edit-folder="emit('edit-folder', $event)"
|
||||
@edit-request="emit('edit-request', $event)"
|
||||
@duplicate-request="emit('duplicate-request', $event)"
|
||||
@edit-properties="
|
||||
emit('edit-properties', {
|
||||
collectionIndex: `${folderPath}/${String(subFolderIndex)}`,
|
||||
collection: subFolder,
|
||||
})
|
||||
"
|
||||
@select="emit('select', $event)"
|
||||
@select-request="$emit('select-request', $event)"
|
||||
/>
|
||||
<CollectionsGraphqlRequest
|
||||
v-for="(request, index) in folder.requests"
|
||||
@@ -164,6 +187,7 @@
|
||||
@edit-request="emit('edit-request', $event)"
|
||||
@duplicate-request="emit('duplicate-request', $event)"
|
||||
@select="emit('select', $event)"
|
||||
@select-request="$emit('select-request', $event)"
|
||||
/>
|
||||
|
||||
<HoppSmartPlaceholder
|
||||
@@ -197,13 +221,16 @@ import IconMoreVertical from "~icons/lucide/more-vertical"
|
||||
import IconCheckCircle from "~icons/lucide/check-circle"
|
||||
import IconFolder from "~icons/lucide/folder"
|
||||
import IconFolderOpen from "~icons/lucide/folder-open"
|
||||
import IconSettings2 from "~icons/lucide/settings-2"
|
||||
import { useToast } from "@composables/toast"
|
||||
import { useI18n } from "@composables/i18n"
|
||||
import { useColorMode } from "@composables/theming"
|
||||
import { removeGraphqlFolder, moveGraphqlRequest } from "~/newstore/collections"
|
||||
import { removeGraphqlFolder } from "~/newstore/collections"
|
||||
import { computed, ref } from "vue"
|
||||
import { useService } from "dioc/vue"
|
||||
import { GQLTabService } from "~/services/tab/graphql"
|
||||
import { Picked } from "~/helpers/types/HoppPicked"
|
||||
import { HoppCollection } from "@hoppscotch/data"
|
||||
|
||||
const toast = useToast()
|
||||
const t = useI18n()
|
||||
@@ -211,16 +238,16 @@ const colorMode = useColorMode()
|
||||
|
||||
const tabs = useService(GQLTabService)
|
||||
|
||||
const props = defineProps({
|
||||
picked: { type: Object, default: null },
|
||||
const props = defineProps<{
|
||||
picked: Picked
|
||||
// Whether the request is in a selectable mode (activates 'select' event)
|
||||
saveRequest: { type: Boolean, default: false },
|
||||
folder: { type: Object, default: () => ({}) },
|
||||
folderIndex: { type: Number, default: null },
|
||||
collectionIndex: { type: Number, default: null },
|
||||
folderPath: { type: String, default: null },
|
||||
isFiltered: Boolean,
|
||||
})
|
||||
saveRequest: boolean
|
||||
folder: HoppCollection
|
||||
folderIndex: number
|
||||
collectionIndex: number
|
||||
folderPath: string
|
||||
isFiltered: boolean
|
||||
}>()
|
||||
|
||||
const emit = defineEmits([
|
||||
"select",
|
||||
@@ -229,6 +256,9 @@ const emit = defineEmits([
|
||||
"add-folder",
|
||||
"edit-folder",
|
||||
"duplicate-request",
|
||||
"edit-properties",
|
||||
"select-request",
|
||||
"drop-request",
|
||||
])
|
||||
|
||||
// Template refs
|
||||
@@ -303,6 +333,11 @@ const dropEvent = ({ dataTransfer }: any) => {
|
||||
dragging.value = !dragging.value
|
||||
const folderPath = dataTransfer.getData("folderPath")
|
||||
const requestIndex = dataTransfer.getData("requestIndex")
|
||||
moveGraphqlRequest(folderPath, requestIndex, props.folderPath)
|
||||
|
||||
emit("drop-request", {
|
||||
folderPath,
|
||||
requestIndex,
|
||||
collectionIndex: props.folderPath,
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<script setup lang="ts">
|
||||
import { useI18n } from "~/composables/i18n"
|
||||
import { useToast } from "~/composables/toast"
|
||||
import { HoppCollection, HoppGQLRequest } from "@hoppscotch/data"
|
||||
import { HoppCollection } from "@hoppscotch/data"
|
||||
import { ImporterOrExporter } from "~/components/importExport/types"
|
||||
import { FileSource } from "~/helpers/import-export/import/import-sources/FileSource"
|
||||
import { GistSource } from "~/helpers/import-export/import/import-sources/GistSource"
|
||||
@@ -25,13 +25,14 @@ import { useReadonlyStream } from "~/composables/stream"
|
||||
|
||||
import { platform } from "~/platform"
|
||||
import {
|
||||
appendGraphqlCollections,
|
||||
graphqlCollections$,
|
||||
setGraphqlCollections,
|
||||
} from "~/newstore/collections"
|
||||
import { hoppGqlCollectionsImporter } from "~/helpers/import-export/import/hoppGql"
|
||||
import { gqlCollectionsExporter } from "~/helpers/import-export/export/gqlCollections"
|
||||
import { gqlCollectionsGistExporter } from "~/helpers/import-export/export/gqlCollectionsGistExporter"
|
||||
import { computed } from "vue"
|
||||
import { hoppGQLImporter } from "~/helpers/import-export/import/hopp"
|
||||
|
||||
const t = useI18n()
|
||||
const toast = useToast()
|
||||
@@ -60,15 +61,20 @@ const GqlCollectionsHoppImporter: ImporterOrExporter = {
|
||||
showImportFailedError()
|
||||
return
|
||||
}
|
||||
const validatedCollection = await hoppGQLImporter(
|
||||
JSON.stringify(res.right)
|
||||
)()
|
||||
|
||||
handleImportToStore(res.right)
|
||||
if (E.isRight(validatedCollection)) {
|
||||
handleImportToStore(validatedCollection.right)
|
||||
|
||||
platform.analytics?.logEvent({
|
||||
type: "HOPP_IMPORT_COLLECTION",
|
||||
platform: "gql",
|
||||
workspaceType: "personal",
|
||||
importer: "json",
|
||||
})
|
||||
platform.analytics?.logEvent({
|
||||
type: "HOPP_IMPORT_COLLECTION",
|
||||
platform: "gql",
|
||||
workspaceType: "personal",
|
||||
importer: "json",
|
||||
})
|
||||
}
|
||||
|
||||
emit("hide-modal")
|
||||
},
|
||||
@@ -214,11 +220,9 @@ const showImportFailedError = () => {
|
||||
toast.error(t("import.failed"))
|
||||
}
|
||||
|
||||
const handleImportToStore = async (
|
||||
gqlCollections: HoppCollection<HoppGQLRequest>[]
|
||||
) => {
|
||||
setGraphqlCollections(gqlCollections)
|
||||
toast.success(t("import.success"))
|
||||
const handleImportToStore = async (gqlCollections: HoppCollection[]) => {
|
||||
appendGraphqlCollections(gqlCollections)
|
||||
toast.success(t("state.file_imported"))
|
||||
}
|
||||
|
||||
const emit = defineEmits<{
|
||||
|
||||
@@ -9,38 +9,41 @@
|
||||
@dragend="dragging = false"
|
||||
@contextmenu.prevent="options.tippy.show()"
|
||||
>
|
||||
<span
|
||||
class="flex w-16 cursor-pointer items-center justify-center truncate px-2"
|
||||
<div
|
||||
class="pointer-events-auto flex min-w-0 flex-1 cursor-pointer items-center justify-center"
|
||||
@click="selectRequest()"
|
||||
>
|
||||
<component
|
||||
:is="isSelected ? IconCheckCircle : IconFile"
|
||||
class="svg-icons"
|
||||
:class="{ 'text-accent': isSelected }"
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
class="flex min-w-0 flex-1 cursor-pointer items-center py-2 pr-2 transition group-hover:text-secondaryDark"
|
||||
@click="selectRequest()"
|
||||
>
|
||||
<span class="truncate" :class="{ 'text-accent': isSelected }">
|
||||
{{ request.name }}
|
||||
<span
|
||||
class="pointer-events-none flex w-8 items-center justify-center truncate px-6"
|
||||
>
|
||||
<component
|
||||
:is="isSelected ? IconCheckCircle : IconFile"
|
||||
class="svg-icons"
|
||||
:class="{ 'text-accent': isSelected }"
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
v-if="isActive"
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
class="relative mx-3 flex h-1.5 w-1.5 flex-shrink-0"
|
||||
:title="`${t('collection.request_in_use')}`"
|
||||
class="pointer-events-none flex min-w-0 flex-1 items-center py-2 pr-2 transition group-hover:text-secondaryDark"
|
||||
>
|
||||
<span
|
||||
class="absolute inline-flex h-full w-full flex-shrink-0 animate-ping rounded-full bg-green-500 opacity-75"
|
||||
>
|
||||
<span class="truncate" :class="{ 'text-accent': isSelected }">
|
||||
{{ request.name }}
|
||||
</span>
|
||||
<span
|
||||
class="relative inline-flex h-1.5 w-1.5 flex-shrink-0 rounded-full bg-green-500"
|
||||
></span>
|
||||
v-if="isActive"
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
class="relative mx-3 flex h-1.5 w-1.5 flex-shrink-0"
|
||||
:title="`${t('collection.request_in_use')}`"
|
||||
>
|
||||
<span
|
||||
class="absolute inline-flex h-full w-full flex-shrink-0 animate-ping rounded-full bg-green-500 opacity-75"
|
||||
>
|
||||
</span>
|
||||
<span
|
||||
class="relative inline-flex h-1.5 w-1.5 flex-shrink-0 rounded-full bg-green-500"
|
||||
></span>
|
||||
</span>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex">
|
||||
<span>
|
||||
<tippy
|
||||
@@ -134,8 +137,7 @@ import IconTrash2 from "~icons/lucide/trash-2"
|
||||
import { PropType, computed, ref } from "vue"
|
||||
import { useI18n } from "@composables/i18n"
|
||||
import { useToast } from "@composables/toast"
|
||||
import { HoppGQLRequest, makeGQLRequest } from "@hoppscotch/data"
|
||||
import { cloneDeep } from "lodash-es"
|
||||
import { HoppGQLRequest } from "@hoppscotch/data"
|
||||
import { removeGraphqlRequest } from "~/newstore/collections"
|
||||
import { useService } from "dioc/vue"
|
||||
import { GQLTabService } from "~/services/tab/graphql"
|
||||
@@ -175,7 +177,12 @@ const isActive = computed(() => {
|
||||
})
|
||||
|
||||
// TODO: Better types please
|
||||
const emit = defineEmits(["select", "edit-request", "duplicate-request"])
|
||||
const emit = defineEmits([
|
||||
"select",
|
||||
"edit-request",
|
||||
"duplicate-request",
|
||||
"select-request",
|
||||
])
|
||||
|
||||
const dragging = ref(false)
|
||||
const confirmRemove = ref(false)
|
||||
@@ -199,36 +206,11 @@ const selectRequest = () => {
|
||||
if (props.saveRequest) {
|
||||
pick()
|
||||
} else {
|
||||
const possibleTab = tabs.getTabRefWithSaveContext({
|
||||
originLocation: "user-collection",
|
||||
emit("select-request", {
|
||||
request: props.request,
|
||||
folderPath: props.folderPath,
|
||||
requestIndex: props.requestIndex,
|
||||
})
|
||||
|
||||
// Switch to that request if that request is open
|
||||
if (possibleTab) {
|
||||
tabs.setActiveTab(possibleTab.value.id)
|
||||
return
|
||||
}
|
||||
|
||||
tabs.createNewTab({
|
||||
saveContext: {
|
||||
originLocation: "user-collection",
|
||||
folderPath: props.folderPath,
|
||||
requestIndex: props.requestIndex,
|
||||
},
|
||||
request: cloneDeep(
|
||||
makeGQLRequest({
|
||||
name: props.request.name,
|
||||
url: props.request.url,
|
||||
query: props.request.query,
|
||||
headers: props.request.headers,
|
||||
variables: props.request.variables,
|
||||
auth: props.request.auth,
|
||||
})
|
||||
),
|
||||
isDirty: false,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -57,7 +57,10 @@
|
||||
@edit-request="editRequest($event)"
|
||||
@duplicate-request="duplicateRequest($event)"
|
||||
@select-collection="$emit('use-collection', collection)"
|
||||
@edit-properties="editProperties($event)"
|
||||
@select="$emit('select', $event)"
|
||||
@select-request="selectRequest($event)"
|
||||
@drop-request="dropRequest($event)"
|
||||
/>
|
||||
</div>
|
||||
<HoppSmartPlaceholder
|
||||
@@ -142,19 +145,27 @@
|
||||
v-if="showModalImportExport"
|
||||
@hide-modal="displayModalImportExport(false)"
|
||||
/>
|
||||
<CollectionsProperties
|
||||
:show="showModalEditProperties"
|
||||
:editing-properties="editingProperties"
|
||||
@hide-modal="displayModalEditProperties(false)"
|
||||
@set-collection-properties="setCollectionProperties"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
// TODO: TypeScript + Script Setup this :)
|
||||
import { defineComponent } from "vue"
|
||||
import { cloneDeep, clone } from "lodash-es"
|
||||
<script setup lang="ts">
|
||||
import { nextTick, ref } from "vue"
|
||||
import { clone, cloneDeep } from "lodash-es"
|
||||
import {
|
||||
graphqlCollections$,
|
||||
addGraphqlFolder,
|
||||
saveGraphqlRequestAs,
|
||||
cascadeParentCollectionForHeaderAuth,
|
||||
editGraphqlCollection,
|
||||
editGraphqlFolder,
|
||||
moveGraphqlRequest,
|
||||
} from "~/newstore/collections"
|
||||
|
||||
import IconPlus from "~icons/lucide/plus"
|
||||
import IconHelpCircle from "~icons/lucide/help-circle"
|
||||
import IconImport from "~icons/lucide/folder-down"
|
||||
@@ -164,213 +175,448 @@ import { useColorMode } from "@composables/theming"
|
||||
import { platform } from "~/platform"
|
||||
import { useService } from "dioc/vue"
|
||||
import { GQLTabService } from "~/services/tab/graphql"
|
||||
import { computed } from "vue"
|
||||
import {
|
||||
HoppCollection,
|
||||
HoppGQLRequest,
|
||||
makeGQLRequest,
|
||||
} from "@hoppscotch/data"
|
||||
import { Picked } from "~/helpers/types/HoppPicked"
|
||||
import { HoppInheritedProperty } from "~/helpers/types/HoppInheritedProperties"
|
||||
import { updateInheritedPropertiesForAffectedRequests } from "~/helpers/collection/collection"
|
||||
import { useToast } from "~/composables/toast"
|
||||
import { getRequestsByPath } from "~/helpers/collection/request"
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
// Whether to activate the ability to pick items (activates 'select' events)
|
||||
saveRequest: { type: Boolean, default: false },
|
||||
picked: { type: Object, default: null },
|
||||
},
|
||||
emits: ["select", "use-collection"],
|
||||
setup() {
|
||||
const collections = useReadonlyStream(graphqlCollections$, [], "deep")
|
||||
const colorMode = useColorMode()
|
||||
const t = useI18n()
|
||||
const tabs = useService(GQLTabService)
|
||||
const t = useI18n()
|
||||
const toast = useToast()
|
||||
|
||||
return {
|
||||
collections,
|
||||
colorMode,
|
||||
t,
|
||||
tabs,
|
||||
IconPlus,
|
||||
IconHelpCircle,
|
||||
IconImport,
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
showModalAdd: false,
|
||||
showModalEdit: false,
|
||||
showModalImportExport: false,
|
||||
showModalAddRequest: false,
|
||||
showModalAddFolder: false,
|
||||
showModalEditFolder: false,
|
||||
showModalEditRequest: false,
|
||||
editingCollection: undefined,
|
||||
editingCollectionIndex: undefined,
|
||||
editingFolder: undefined,
|
||||
editingFolderName: undefined,
|
||||
editingFolderIndex: undefined,
|
||||
editingFolderPath: undefined,
|
||||
editingRequest: undefined,
|
||||
editingRequestIndex: undefined,
|
||||
filterText: "",
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
filteredCollections() {
|
||||
const collections = clone(this.collections)
|
||||
defineProps<{
|
||||
// Whether to activate the ability to pick items (activates 'select' events)
|
||||
saveRequest: boolean
|
||||
picked: Picked
|
||||
}>()
|
||||
|
||||
if (!this.filterText) return collections
|
||||
const collections = useReadonlyStream(graphqlCollections$, [], "deep")
|
||||
const colorMode = useColorMode()
|
||||
const tabs = useService(GQLTabService)
|
||||
|
||||
const filterText = this.filterText.toLowerCase()
|
||||
const filteredCollections = []
|
||||
const showModalAdd = ref(false)
|
||||
const showModalEdit = ref(false)
|
||||
const showModalImportExport = ref(false)
|
||||
const showModalAddRequest = ref(false)
|
||||
const showModalAddFolder = ref(false)
|
||||
const showModalEditFolder = ref(false)
|
||||
const showModalEditRequest = ref(false)
|
||||
const showModalEditProperties = ref(false)
|
||||
|
||||
for (const collection of collections) {
|
||||
const filteredRequests = []
|
||||
const filteredFolders = []
|
||||
for (const request of collection.requests) {
|
||||
if (request.name.toLowerCase().includes(filterText))
|
||||
filteredRequests.push(request)
|
||||
}
|
||||
for (const folder of collection.folders) {
|
||||
const filteredFolderRequests = []
|
||||
for (const request of folder.requests) {
|
||||
if (request.name.toLowerCase().includes(filterText))
|
||||
filteredFolderRequests.push(request)
|
||||
}
|
||||
if (filteredFolderRequests.length > 0) {
|
||||
const filteredFolder = Object.assign({}, folder)
|
||||
filteredFolder.requests = filteredFolderRequests
|
||||
filteredFolders.push(filteredFolder)
|
||||
}
|
||||
}
|
||||
const editingCollection = ref<HoppCollection | null>(null)
|
||||
const editingCollectionIndex = ref<number | null>(null)
|
||||
const editingFolder = ref<HoppCollection | null>(null)
|
||||
const editingFolderName = ref("")
|
||||
const editingFolderIndex = ref<number | null>(null)
|
||||
const editingFolderPath = ref("")
|
||||
const editingRequest = ref<HoppGQLRequest | null>(null)
|
||||
const editingRequestIndex = ref<number | null>(null)
|
||||
|
||||
if (filteredRequests.length + filteredFolders.length > 0) {
|
||||
const filteredCollection = Object.assign({}, collection)
|
||||
filteredCollection.requests = filteredRequests
|
||||
filteredCollection.folders = filteredFolders
|
||||
filteredCollections.push(filteredCollection)
|
||||
}
|
||||
}
|
||||
|
||||
return filteredCollections
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
displayModalAdd(shouldDisplay) {
|
||||
this.showModalAdd = shouldDisplay
|
||||
},
|
||||
displayModalEdit(shouldDisplay) {
|
||||
this.showModalEdit = shouldDisplay
|
||||
|
||||
if (!shouldDisplay) this.resetSelectedData()
|
||||
},
|
||||
displayModalImportExport(shouldDisplay) {
|
||||
this.showModalImportExport = shouldDisplay
|
||||
},
|
||||
displayModalAddRequest(shouldDisplay) {
|
||||
this.showModalAddRequest = shouldDisplay
|
||||
|
||||
if (!shouldDisplay) this.resetSelectedData()
|
||||
},
|
||||
displayModalAddFolder(shouldDisplay) {
|
||||
this.showModalAddFolder = shouldDisplay
|
||||
|
||||
if (!shouldDisplay) this.resetSelectedData()
|
||||
},
|
||||
displayModalEditFolder(shouldDisplay) {
|
||||
this.showModalEditFolder = shouldDisplay
|
||||
|
||||
if (!shouldDisplay) this.resetSelectedData()
|
||||
},
|
||||
displayModalEditRequest(shouldDisplay) {
|
||||
this.showModalEditRequest = shouldDisplay
|
||||
|
||||
if (!shouldDisplay) this.resetSelectedData()
|
||||
},
|
||||
editCollection(collection, collectionIndex) {
|
||||
this.$data.editingCollection = collection
|
||||
this.$data.editingCollectionIndex = collectionIndex
|
||||
this.displayModalEdit(true)
|
||||
},
|
||||
onAddRequest({ name, path, index }) {
|
||||
const newRequest = {
|
||||
...this.tabs.currentActiveTab.value.document.request,
|
||||
name,
|
||||
}
|
||||
|
||||
saveGraphqlRequestAs(path, newRequest)
|
||||
|
||||
this.tabs.createNewTab({
|
||||
saveContext: {
|
||||
originLocation: "user-collection",
|
||||
folderPath: path,
|
||||
requestIndex: index,
|
||||
},
|
||||
request: newRequest,
|
||||
isDirty: false,
|
||||
})
|
||||
|
||||
platform.analytics?.logEvent({
|
||||
type: "HOPP_SAVE_REQUEST",
|
||||
platform: "gql",
|
||||
createdNow: true,
|
||||
workspaceType: "personal",
|
||||
})
|
||||
|
||||
this.displayModalAddRequest(false)
|
||||
},
|
||||
addRequest(payload) {
|
||||
const { path } = payload
|
||||
this.$data.editingFolderPath = path
|
||||
this.displayModalAddRequest(true)
|
||||
},
|
||||
onAddFolder({ name, path }) {
|
||||
addGraphqlFolder(name, path)
|
||||
|
||||
platform.analytics?.logEvent({
|
||||
type: "HOPP_CREATE_COLLECTION",
|
||||
isRootCollection: false,
|
||||
platform: "gql",
|
||||
workspaceType: "personal",
|
||||
})
|
||||
|
||||
this.displayModalAddFolder(false)
|
||||
},
|
||||
addFolder(payload) {
|
||||
const { path } = payload
|
||||
this.$data.editingFolderPath = path
|
||||
this.displayModalAddFolder(true)
|
||||
},
|
||||
editFolder(payload) {
|
||||
const { folder, folderPath } = payload
|
||||
this.editingFolder = folder
|
||||
this.editingFolderPath = folderPath
|
||||
this.displayModalEditFolder(true)
|
||||
},
|
||||
editRequest(payload) {
|
||||
const {
|
||||
collectionIndex,
|
||||
folderIndex,
|
||||
folderName,
|
||||
request,
|
||||
requestIndex,
|
||||
folderPath,
|
||||
} = payload
|
||||
this.$data.editingFolderPath = folderPath
|
||||
this.$data.editingCollectionIndex = collectionIndex
|
||||
this.$data.editingFolderIndex = folderIndex
|
||||
this.$data.editingFolderName = folderName
|
||||
this.$data.editingRequest = request
|
||||
this.$data.editingRequestIndex = requestIndex
|
||||
this.displayModalEditRequest(true)
|
||||
},
|
||||
resetSelectedData() {
|
||||
this.$data.editingCollection = undefined
|
||||
this.$data.editingCollectionIndex = undefined
|
||||
this.$data.editingFolder = undefined
|
||||
this.$data.editingFolderIndex = undefined
|
||||
this.$data.editingRequest = undefined
|
||||
this.$data.editingRequestIndex = undefined
|
||||
},
|
||||
duplicateRequest({ folderPath, request }) {
|
||||
saveGraphqlRequestAs(folderPath, {
|
||||
...cloneDeep(request),
|
||||
name: `${request.name} - ${this.t("action.duplicate")}`,
|
||||
})
|
||||
},
|
||||
},
|
||||
const editingProperties = ref<{
|
||||
collection: HoppCollection | null
|
||||
isRootCollection: boolean
|
||||
path: string
|
||||
inheritedProperties?: HoppInheritedProperty
|
||||
}>({
|
||||
collection: null,
|
||||
isRootCollection: false,
|
||||
path: "",
|
||||
inheritedProperties: undefined,
|
||||
})
|
||||
|
||||
const filterText = ref("")
|
||||
|
||||
const filteredCollections = computed(() => {
|
||||
const collectionsClone = clone(collections.value)
|
||||
|
||||
if (!filterText.value) return collectionsClone
|
||||
|
||||
const filterTextLower = filterText.value.toLowerCase()
|
||||
const filteredCollections = []
|
||||
|
||||
for (const collection of collectionsClone) {
|
||||
const filteredRequests = []
|
||||
const filteredFolders = []
|
||||
|
||||
for (const request of collection.requests) {
|
||||
if (request.name.toLowerCase().includes(filterTextLower))
|
||||
filteredRequests.push(request)
|
||||
}
|
||||
|
||||
for (const folder of collection.folders) {
|
||||
const filteredFolderRequests = []
|
||||
for (const request of folder.requests) {
|
||||
if (request.name.toLowerCase().includes(filterTextLower))
|
||||
filteredFolderRequests.push(request)
|
||||
}
|
||||
if (filteredFolderRequests.length > 0) {
|
||||
const filteredFolder = { ...folder }
|
||||
filteredFolder.requests = filteredFolderRequests
|
||||
filteredFolders.push(filteredFolder)
|
||||
}
|
||||
}
|
||||
|
||||
if (filteredRequests.length + filteredFolders.length > 0) {
|
||||
const filteredCollection = { ...collection }
|
||||
filteredCollection.requests = filteredRequests
|
||||
filteredCollection.folders = filteredFolders
|
||||
filteredCollections.push(filteredCollection)
|
||||
}
|
||||
}
|
||||
|
||||
return filteredCollections
|
||||
})
|
||||
|
||||
const displayModalAdd = (shouldDisplay: boolean) => {
|
||||
showModalAdd.value = shouldDisplay
|
||||
}
|
||||
|
||||
const displayModalEdit = (shouldDisplay: boolean) => {
|
||||
showModalEdit.value = shouldDisplay
|
||||
|
||||
if (!shouldDisplay) resetSelectedData()
|
||||
}
|
||||
|
||||
const displayModalImportExport = (shouldDisplay: boolean) => {
|
||||
showModalImportExport.value = shouldDisplay
|
||||
}
|
||||
|
||||
const displayModalAddRequest = (shouldDisplay: boolean) => {
|
||||
showModalAddRequest.value = shouldDisplay
|
||||
|
||||
if (!shouldDisplay) resetSelectedData()
|
||||
}
|
||||
|
||||
const displayModalAddFolder = (shouldDisplay: boolean) => {
|
||||
showModalAddFolder.value = shouldDisplay
|
||||
|
||||
if (!shouldDisplay) resetSelectedData()
|
||||
}
|
||||
|
||||
const displayModalEditFolder = (shouldDisplay: boolean) => {
|
||||
showModalEditFolder.value = shouldDisplay
|
||||
|
||||
if (!shouldDisplay) resetSelectedData()
|
||||
}
|
||||
|
||||
const displayModalEditRequest = (shouldDisplay: boolean) => {
|
||||
showModalEditRequest.value = shouldDisplay
|
||||
|
||||
if (!shouldDisplay) resetSelectedData()
|
||||
}
|
||||
|
||||
const displayModalEditProperties = (show: boolean) => {
|
||||
showModalEditProperties.value = show
|
||||
|
||||
if (!show) resetSelectedData()
|
||||
}
|
||||
|
||||
const editCollection = (
|
||||
collection: HoppCollection,
|
||||
collectionIndex: number
|
||||
) => {
|
||||
editingCollection.value = collection
|
||||
editingCollectionIndex.value = collectionIndex
|
||||
displayModalEdit(true)
|
||||
}
|
||||
|
||||
const onAddRequest = ({
|
||||
name,
|
||||
path,
|
||||
index,
|
||||
}: {
|
||||
name: string
|
||||
path: string
|
||||
index: number
|
||||
}) => {
|
||||
const newRequest = {
|
||||
...tabs.currentActiveTab.value.document.request,
|
||||
name,
|
||||
}
|
||||
|
||||
saveGraphqlRequestAs(path, newRequest)
|
||||
|
||||
const { auth, headers } = cascadeParentCollectionForHeaderAuth(
|
||||
path,
|
||||
"graphql"
|
||||
)
|
||||
|
||||
tabs.createNewTab({
|
||||
saveContext: {
|
||||
originLocation: "user-collection",
|
||||
folderPath: path,
|
||||
requestIndex: index,
|
||||
},
|
||||
request: newRequest,
|
||||
isDirty: false,
|
||||
inheritedProperties: {
|
||||
auth,
|
||||
headers,
|
||||
},
|
||||
})
|
||||
|
||||
platform.analytics?.logEvent({
|
||||
type: "HOPP_SAVE_REQUEST",
|
||||
platform: "gql",
|
||||
createdNow: true,
|
||||
workspaceType: "personal",
|
||||
})
|
||||
|
||||
displayModalAddRequest(false)
|
||||
}
|
||||
|
||||
const addRequest = (payload: { path: string }) => {
|
||||
const { path } = payload
|
||||
editingFolderPath.value = path
|
||||
displayModalAddRequest(true)
|
||||
}
|
||||
|
||||
const onAddFolder = ({
|
||||
name,
|
||||
path,
|
||||
}: {
|
||||
name: string
|
||||
path: string | undefined
|
||||
}) => {
|
||||
addGraphqlFolder(name, path ?? "0")
|
||||
|
||||
platform.analytics?.logEvent({
|
||||
type: "HOPP_CREATE_COLLECTION",
|
||||
isRootCollection: false,
|
||||
platform: "gql",
|
||||
workspaceType: "personal",
|
||||
})
|
||||
|
||||
displayModalAddFolder(false)
|
||||
}
|
||||
|
||||
const addFolder = (payload: { path: string }) => {
|
||||
const { path } = payload
|
||||
editingFolderPath.value = path
|
||||
displayModalAddFolder(true)
|
||||
}
|
||||
|
||||
const editFolder = (payload: {
|
||||
folder: HoppCollection
|
||||
folderPath: string
|
||||
}) => {
|
||||
const { folder, folderPath } = payload
|
||||
editingFolder.value = folder
|
||||
editingFolderPath.value = folderPath
|
||||
displayModalEditFolder(true)
|
||||
}
|
||||
|
||||
const editRequest = (payload: {
|
||||
collectionIndex: number
|
||||
folderIndex: number
|
||||
folderName: string
|
||||
request: HoppGQLRequest
|
||||
requestIndex: number
|
||||
folderPath: string
|
||||
}) => {
|
||||
const {
|
||||
collectionIndex,
|
||||
folderIndex,
|
||||
folderName,
|
||||
request,
|
||||
requestIndex,
|
||||
folderPath,
|
||||
} = payload
|
||||
editingFolderPath.value = folderPath
|
||||
editingCollectionIndex.value = collectionIndex
|
||||
editingFolderIndex.value = folderIndex
|
||||
editingFolderName.value = folderName
|
||||
editingRequest.value = request
|
||||
editingRequestIndex.value = requestIndex
|
||||
displayModalEditRequest(true)
|
||||
}
|
||||
|
||||
const duplicateRequest = ({
|
||||
folderPath,
|
||||
request,
|
||||
}: {
|
||||
folderPath: string
|
||||
request: HoppGQLRequest
|
||||
}) => {
|
||||
saveGraphqlRequestAs(folderPath, {
|
||||
...cloneDeep(request),
|
||||
name: `${request.name} - ${t("action.duplicate")}`,
|
||||
})
|
||||
}
|
||||
|
||||
const selectRequest = ({
|
||||
request,
|
||||
folderPath,
|
||||
requestIndex,
|
||||
}: {
|
||||
request: HoppGQLRequest
|
||||
folderPath: string
|
||||
requestIndex: number
|
||||
}) => {
|
||||
const possibleTab = tabs.getTabRefWithSaveContext({
|
||||
originLocation: "user-collection",
|
||||
folderPath: folderPath,
|
||||
requestIndex: requestIndex,
|
||||
})
|
||||
const { auth, headers } = cascadeParentCollectionForHeaderAuth(
|
||||
folderPath,
|
||||
"graphql"
|
||||
)
|
||||
// Switch to that request if that request is open
|
||||
if (possibleTab) {
|
||||
tabs.setActiveTab(possibleTab.value.id)
|
||||
return
|
||||
}
|
||||
|
||||
tabs.createNewTab({
|
||||
saveContext: {
|
||||
originLocation: "user-collection",
|
||||
folderPath: folderPath,
|
||||
requestIndex: requestIndex,
|
||||
},
|
||||
request: cloneDeep(
|
||||
makeGQLRequest({
|
||||
name: request.name,
|
||||
url: request.url,
|
||||
query: request.query,
|
||||
headers: request.headers,
|
||||
variables: request.variables,
|
||||
auth: request.auth,
|
||||
})
|
||||
),
|
||||
isDirty: false,
|
||||
inheritedProperties: {
|
||||
auth,
|
||||
headers,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
const dropRequest = ({
|
||||
folderPath,
|
||||
requestIndex,
|
||||
collectionIndex,
|
||||
}: {
|
||||
folderPath: string
|
||||
requestIndex: number
|
||||
collectionIndex: number
|
||||
}) => {
|
||||
const { auth, headers } = cascadeParentCollectionForHeaderAuth(
|
||||
`${collectionIndex}`,
|
||||
"graphql"
|
||||
)
|
||||
|
||||
const possibleTab = tabs.getTabRefWithSaveContext({
|
||||
originLocation: "user-collection",
|
||||
folderPath,
|
||||
requestIndex: Number(requestIndex),
|
||||
})
|
||||
|
||||
if (possibleTab) {
|
||||
possibleTab.value.document.saveContext = {
|
||||
originLocation: "user-collection",
|
||||
folderPath: `${collectionIndex}`,
|
||||
requestIndex: getRequestsByPath(collections.value, `${collectionIndex}`)
|
||||
.length,
|
||||
}
|
||||
|
||||
possibleTab.value.document.inheritedProperties = {
|
||||
auth,
|
||||
headers,
|
||||
}
|
||||
}
|
||||
|
||||
moveGraphqlRequest(folderPath, requestIndex, `${collectionIndex}`)
|
||||
|
||||
toast.success(`${t("request.moved")}`)
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the collection is already in the root
|
||||
* @param id - path of the collection
|
||||
* @returns boolean - true if the collection is already in the root
|
||||
*/
|
||||
const isAlreadyInRoot = (id: string) => {
|
||||
const indexPath = id.split("/")
|
||||
return indexPath.length === 1
|
||||
}
|
||||
|
||||
const editProperties = ({
|
||||
collectionIndex,
|
||||
collection,
|
||||
}: {
|
||||
collectionIndex: string | null
|
||||
collection: HoppCollection | null
|
||||
}) => {
|
||||
if (collectionIndex === null || collection === null) return
|
||||
|
||||
const parentIndex = collectionIndex.split("/").slice(0, -1).join("/") // remove last folder to get parent folder
|
||||
let inheritedProperties = {}
|
||||
|
||||
if (parentIndex) {
|
||||
const { auth, headers } = cascadeParentCollectionForHeaderAuth(
|
||||
parentIndex,
|
||||
"graphql"
|
||||
)
|
||||
|
||||
inheritedProperties = {
|
||||
auth,
|
||||
headers,
|
||||
} as HoppInheritedProperty
|
||||
}
|
||||
|
||||
editingProperties.value = {
|
||||
collection,
|
||||
isRootCollection: isAlreadyInRoot(collectionIndex),
|
||||
path: collectionIndex,
|
||||
inheritedProperties,
|
||||
}
|
||||
|
||||
displayModalEditProperties(true)
|
||||
}
|
||||
|
||||
const setCollectionProperties = (newCollection: {
|
||||
collection: HoppCollection
|
||||
path: string
|
||||
isRootCollection: boolean
|
||||
}) => {
|
||||
const { collection, path, isRootCollection } = newCollection
|
||||
if (isRootCollection) {
|
||||
editGraphqlCollection(parseInt(path), collection)
|
||||
} else {
|
||||
editGraphqlFolder(path, collection)
|
||||
}
|
||||
|
||||
const { auth, headers } = cascadeParentCollectionForHeaderAuth(
|
||||
path,
|
||||
"graphql"
|
||||
)
|
||||
|
||||
nextTick(() => {
|
||||
updateInheritedPropertiesForAffectedRequests(
|
||||
path,
|
||||
{
|
||||
auth,
|
||||
headers,
|
||||
},
|
||||
"graphql"
|
||||
)
|
||||
})
|
||||
|
||||
displayModalEditProperties(false)
|
||||
}
|
||||
const resetSelectedData = () => {
|
||||
editingCollection.value = null
|
||||
editingCollectionIndex.value = null
|
||||
editingFolder.value = null
|
||||
editingFolderIndex.value = null
|
||||
editingRequest.value = null
|
||||
editingRequestIndex.value = null
|
||||
}
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user