feat: added inherit auth-header for personal gql

This commit is contained in:
nivedin
2023-12-04 16:15:10 +05:30
committed by Andrew Bastin
parent ad7b3f05b1
commit fce68de282
19 changed files with 546 additions and 99 deletions

View File

@@ -240,15 +240,14 @@ const saveRequestAs = async () => {
},
}
const { auth, headers, name } = cascaseParentCollectionForHeaderAuth(
`${picked.value.collectionIndex}`
const { auth, headers } = cascaseParentCollectionForHeaderAuth(
`${picked.value.collectionIndex}`,
"rest"
)
RESTTabs.currentActiveTab.value.document.inheritedProperties = {
auth,
headers,
parentId: `${picked.value.collectionIndex}`,
parentName: name,
}
platform.analytics?.logEvent({
@@ -278,15 +277,14 @@ const saveRequestAs = async () => {
},
}
const { auth, headers, name } = cascaseParentCollectionForHeaderAuth(
picked.value.folderPath
const { auth, headers } = cascaseParentCollectionForHeaderAuth(
picked.value.folderPath,
"rest"
)
RESTTabs.currentActiveTab.value.document.inheritedProperties = {
auth,
headers,
parentId: picked.value.folderPath,
parentName: name,
}
platform.analytics?.logEvent({
@@ -317,15 +315,14 @@ const saveRequestAs = async () => {
},
}
const { auth, headers, name } = cascaseParentCollectionForHeaderAuth(
picked.value.folderPath
const { auth, headers } = cascaseParentCollectionForHeaderAuth(
picked.value.folderPath,
"rest"
)
RESTTabs.currentActiveTab.value.document.inheritedProperties = {
auth,
headers,
parentId: picked.value.folderPath,
parentName: name,
}
platform.analytics?.logEvent({
@@ -412,6 +409,16 @@ const saveRequestAs = async () => {
workspaceType: "team",
})
const { auth, headers } = cascaseParentCollectionForHeaderAuth(
picked.value.folderPath,
"graphql"
)
GQLTabs.currentActiveTab.value.document.inheritedProperties = {
auth,
headers,
}
requestSaved()
} else if (picked.value.pickedType === "gql-my-folder") {
// TODO: Check for GQL request ?
@@ -427,6 +434,16 @@ const saveRequestAs = async () => {
workspaceType: "team",
})
const { auth, headers } = cascaseParentCollectionForHeaderAuth(
picked.value.folderPath,
"graphql"
)
GQLTabs.currentActiveTab.value.document.inheritedProperties = {
auth,
headers,
}
requestSaved()
} else if (picked.value.pickedType === "gql-my-collection") {
// TODO: Check for GQL request ?
@@ -442,6 +459,16 @@ const saveRequestAs = async () => {
workspaceType: "team",
})
const { auth, headers } = cascaseParentCollectionForHeaderAuth(
`${picked.value.collectionIndex}`,
"graphql"
)
GQLTabs.currentActiveTab.value.document.inheritedProperties = {
auth,
headers,
}
requestSaved()
}
}

View File

@@ -64,6 +64,11 @@ const addNewCollection = () => {
name: name.value,
folders: [],
requests: [],
auth: {
authType: "inherit",
authActive: true,
},
headers: [],
})
)

View File

@@ -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,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: `${collectionIndex}/${String(index)}`,
collection: folder,
})
"
@select="$emit('select', $event)"
@select-request="$emit('select-request', $event)"
/>
<CollectionsGraphqlRequest
v-for="(request, index) in collection.requests"
@@ -171,6 +193,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,6 +237,7 @@ 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"
@@ -224,15 +248,16 @@ import {
import { Picked } from "~/helpers/types/HoppPicked"
import { useService } from "dioc/vue"
import { GQLTabService } from "~/services/tab/graphql"
import { HoppCollection, HoppGQLRequest } 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<HoppGQLRequest>
isFiltered: boolean
}>()
const colorMode = useColorMode()
const toast = useToast()
@@ -248,7 +273,15 @@ 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<HoppGQLRequest>
}
): void
(e: "edit-collection"): void
(e: "select-request", i: any): void
}>()
// Template refs

View File

@@ -121,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>
@@ -149,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"
@@ -165,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
@@ -198,6 +221,7 @@ 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"
@@ -205,6 +229,8 @@ import { removeGraphqlFolder, moveGraphqlRequest } 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, HoppGQLRequest } from "@hoppscotch/data"
const toast = useToast()
const t = useI18n()
@@ -212,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<HoppGQLRequest>
folderIndex: number
collectionIndex: number
folderPath: string
isFiltered: boolean
}>()
const emit = defineEmits([
"select",
@@ -230,6 +256,8 @@ const emit = defineEmits([
"add-folder",
"edit-folder",
"duplicate-request",
"edit-properties",
"select-request",
])
// Template refs

View File

@@ -178,7 +178,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)
@@ -202,36 +207,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,
})
}
}

View File

@@ -57,7 +57,9 @@
@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)"
/>
</div>
<HoppSmartPlaceholder
@@ -142,16 +144,25 @@
v-if="showModalImportExport"
@hide-modal="displayModalImportExport(false)"
/>
<CollectionsProperties
:show="showModalEditProperties"
:editing-properties="editingProperties"
@hide-modal="displayModalEditProperties(false)"
@set-collection-properties="setCollectionProperties"
/>
</div>
</template>
<script setup lang="ts">
import { ref } from "vue"
import { nextTick, ref } from "vue"
import { clone, cloneDeep } from "lodash-es"
import {
graphqlCollections$,
addGraphqlFolder,
saveGraphqlRequestAs,
cascaseParentCollectionForHeaderAuth,
editGraphqlCollection,
editGraphqlFolder,
} from "~/newstore/collections"
import IconPlus from "~icons/lucide/plus"
import IconHelpCircle from "~icons/lucide/help-circle"
@@ -163,8 +174,14 @@ import { platform } from "~/platform"
import { useService } from "dioc/vue"
import { GQLTabService } from "~/services/tab/graphql"
import { computed } from "vue"
import { HoppCollection, HoppGQLRequest } from "@hoppscotch/data"
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"
const t = useI18n()
@@ -185,6 +202,7 @@ const showModalAddRequest = ref(false)
const showModalAddFolder = ref(false)
const showModalEditFolder = ref(false)
const showModalEditRequest = ref(false)
const showModalEditProperties = ref(false)
const editingCollection = ref<HoppCollection<HoppGQLRequest> | null>(null)
const editingCollectionIndex = ref<number | null>(null)
@@ -195,6 +213,18 @@ const editingFolderPath = ref("")
const editingRequest = ref<HoppGQLRequest | null>(null)
const editingRequestIndex = ref<number | null>(null)
const editingProperties = ref<{
collection: HoppCollection<HoppGQLRequest> | null
isRootCollection: boolean
path: string
inheritedProperties?: HoppInheritedProperty
}>({
collection: null,
isRootCollection: false,
path: "",
inheritedProperties: undefined,
})
const filterText = ref("")
const filteredCollections = computed(() => {
@@ -276,6 +306,12 @@ const displayModalEditRequest = (shouldDisplay: boolean) => {
if (!shouldDisplay) resetSelectedData()
}
const displayModalEditProperties = (show: boolean) => {
showModalEditProperties.value = show
if (!show) resetSelectedData()
}
const editCollection = (
collection: HoppCollection<HoppGQLRequest>,
collectionIndex: number
@@ -302,6 +338,11 @@ const onAddRequest = ({
saveGraphqlRequestAs(path, newRequest)
const { auth, headers } = cascaseParentCollectionForHeaderAuth(
path,
"graphql"
)
tabs.createNewTab({
saveContext: {
originLocation: "user-collection",
@@ -310,6 +351,10 @@ const onAddRequest = ({
},
request: newRequest,
isDirty: false,
inheritedProperties: {
auth,
headers,
},
})
platform.analytics?.logEvent({
@@ -401,6 +446,128 @@ const duplicateRequest = ({
})
}
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 } = cascaseParentCollectionForHeaderAuth(
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,
},
})
}
/**
* 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<HoppGQLRequest> | 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 } = cascaseParentCollectionForHeaderAuth(
parentIndex,
"graphql"
)
inheritedProperties = {
auth,
headers,
} as HoppInheritedProperty
}
editingProperties.value = {
collection,
isRootCollection: isAlreadyInRoot(collectionIndex),
path: collectionIndex,
inheritedProperties,
}
displayModalEditProperties(true)
}
const setCollectionProperties = (newCollection: {
collection: HoppCollection<HoppGQLRequest>
path: string
isRootCollection: boolean
}) => {
const { collection, path, isRootCollection } = newCollection
if (isRootCollection) {
editGraphqlCollection(parseInt(path), collection)
} else {
editGraphqlFolder(path, collection)
}
const { auth, headers } = cascaseParentCollectionForHeaderAuth(
path,
"graphql"
)
nextTick(() => {
updateInheritedPropertiesForAffectedRequests(
path,
{
auth,
headers,
},
"graphql"
)
})
displayModalEditProperties(false)
}
const resetSelectedData = () => {
editingCollection.value = null
editingCollectionIndex.value = null

View File

@@ -679,7 +679,7 @@ const onAddRequest = (requestName: string) => {
if (!path) return
const insertionIndex = saveRESTRequestAs(path, newRequest)
const { auth, headers } = cascaseParentCollectionForHeaderAuth(path)
const { auth, headers } = cascaseParentCollectionForHeaderAuth(path, "rest")
tabs.createNewTab({
request: newRequest,
@@ -1329,7 +1329,10 @@ const selectRequest = (selectedRequest: {
// If there is a request with this save context, switch into it
let possibleTab = null
const { auth, headers } = cascaseParentCollectionForHeaderAuth(folderPath)
const { auth, headers } = cascaseParentCollectionForHeaderAuth(
folderPath,
"rest"
)
if (collectionsType.value.type === "team-collections") {
possibleTab = tabs.getTabRefWithSaveContext({
@@ -1402,7 +1405,8 @@ const dropRequest = (payload: {
if (collectionsType.value.type === "my-collections" && folderPath) {
const { auth, headers } = cascaseParentCollectionForHeaderAuth(
destinationCollectionIndex
destinationCollectionIndex,
"rest"
)
possibleTab = tabs.getTabRefWithSaveContext({
@@ -1595,7 +1599,8 @@ const dropCollection = (payload: {
)
const { auth, headers } = cascaseParentCollectionForHeaderAuth(
`${destinationCollectionIndex}/${totalFoldersOfDestinationCollection}`
`${destinationCollectionIndex}/${totalFoldersOfDestinationCollection}`,
"rest"
)
const inheritedProperty = {
@@ -1605,7 +1610,8 @@ const dropCollection = (payload: {
updateInheritedPropertiesForAffectedRequests(
`${destinationCollectionIndex}/${totalFoldersOfDestinationCollection}`,
inheritedProperty
inheritedProperty,
"rest"
)
draggingToRoot.value = false
@@ -1975,7 +1981,10 @@ const editProperties = (payload: {
let inheritedProperties = {}
if (parentIndex) {
const { auth, headers } = cascaseParentCollectionForHeaderAuth(parentIndex)
const { auth, headers } = cascaseParentCollectionForHeaderAuth(
parentIndex,
"rest"
)
inheritedProperties = {
auth,
@@ -2005,13 +2014,17 @@ const setCollectionProperties = (newCollection: {
editRESTFolder(path, collection)
}
const { auth, headers } = cascaseParentCollectionForHeaderAuth(path)
const { auth, headers } = cascaseParentCollectionForHeaderAuth(path, "rest")
nextTick(() => {
updateInheritedPropertiesForAffectedRequests(path, {
auth,
headers,
})
updateInheritedPropertiesForAffectedRequests(
path,
{
auth,
headers,
},
"rest"
)
})
displayModalEditProperties(false)

View File

@@ -37,6 +37,18 @@
}
"
/>
<HoppSmartItem
v-if="!isRootCollection"
label="Inherit"
:icon="authName === 'Inherit' ? IconCircleDot : IconCircle"
:active="authName === 'Inherit'"
@click="
() => {
auth.authType = 'inherit'
hide()
}
"
/>
<HoppSmartItem
label="Basic Auth"
:icon="authName === 'Basic Auth' ? IconCircleDot : IconCircle"
@@ -149,6 +161,17 @@
/>
</div>
</div>
<div v-if="auth.authType === 'inherit'" class="p-4">
<span v-if="inheritedProperties?.auth">
Inherited
{{ getAuthName(inheritedProperties.auth.inheritedAuth.authType) }}
from Parent Collection {{ inheritedProperties?.auth.parentName }}
</span>
<span v-else>
Please save this request in any collection to inherit the
authorization
</span>
</div>
<div v-if="auth.authType === 'bearer'">
<div class="flex flex-1 border-b border-dividerLight">
<SmartEnvInput
@@ -203,6 +226,8 @@ import { pluckRef } from "@composables/ref"
import { useI18n } from "@composables/i18n"
import { useColorMode } from "@composables/theming"
import { useVModel } from "@vueuse/core"
import { HoppInheritedProperty } from "~/helpers/types/HoppInheritedProperties"
import { onMounted } from "vue"
const t = useI18n()
@@ -210,12 +235,24 @@ const colorMode = useColorMode()
const props = defineProps<{
modelValue: HoppGQLAuth
isCollectionProperty?: boolean
isRootCollection?: boolean
inheritedProperties?: HoppInheritedProperty
}>()
const emit = defineEmits<{
(e: "update:modelValue", value: HoppGQLAuth): void
}>()
onMounted(() => {
if (props.isRootCollection && auth.value.authType === "inherit") {
auth.value = {
authType: "none",
authActive: true,
}
}
})
const auth = useVModel(props, "modelValue", emit)
const AUTH_KEY_NAME = {
@@ -224,12 +261,20 @@ const AUTH_KEY_NAME = {
"oauth-2": "OAuth 2.0",
"api-key": "API key",
none: "None",
inherit: "Inherit",
} as const
const authType = pluckRef(auth, "authType")
const authName = computed(() =>
AUTH_KEY_NAME[authType.value] ? AUTH_KEY_NAME[authType.value] : "None"
)
const getAuthName = (type: HoppGQLAuth["authType"] | undefined) => {
if (!type) return "None"
return AUTH_KEY_NAME[type] ? AUTH_KEY_NAME[type] : "None"
}
const authActive = pluckRef(auth, "authActive")
const clearContent = () => {

View File

@@ -215,6 +215,60 @@
</template>
</draggable>
<draggable
v-model="inheritedProperties"
item-key="id"
animation="250"
handle=".draggable-handle"
draggable=".draggable-content"
ghost-class="cursor-move"
chosen-class="bg-primaryLight"
drag-class="cursor-grabbing"
>
<template #item="{ element: header, index }">
<div
class="draggable-content group flex divide-x divide-dividerLight border-b border-dividerLight"
>
<span>
<HoppButtonSecondary
:icon="IconLock"
class="cursor-auto bg-divider text-secondaryLight opacity-25"
tabindex="-1"
/>
</span>
<SmartEnvInput
v-model="header.header.key"
:placeholder="`${t('count.value', { count: index + 1 })}`"
readonly
/>
<SmartEnvInput
:model-value="
header.source === 'auth' ? mask(header) : header.header.value
"
:placeholder="`${t('count.value', { count: index + 1 })}`"
readonly
/>
<HoppButtonSecondary
v-if="header.source === 'auth'"
v-tippy="{ theme: 'tooltip' }"
:title="t(masking ? 'state.show' : 'state.hide')"
:icon="masking && header.source === 'auth' ? IconEye : IconEyeOff"
@click="toggleMask()"
/>
<span v-else class="aspect-square w-[2.05rem]"></span>
<span>
<HoppButtonSecondary
v-tippy="{ theme: 'tooltip' }"
:icon="IconInfo"
:title="`This header is inherited from Parent Collection ${
header.inheritedFrom ?? ''
}`"
/>
</span>
</div>
</template>
</draggable>
<HoppSmartPlaceholder
v-if="workingHeaders.length === 0"
:src="`/images/states/${colorMode.value}/add_category.svg`"
@@ -247,7 +301,7 @@ import IconArrowUpRight from "~icons/lucide/arrow-up-right"
import IconLock from "~icons/lucide/lock"
import IconEye from "~icons/lucide/eye"
import IconEyeOff from "~icons/lucide/eye-off"
import IconInfo from "~icons/lucide/info"
import { computed, reactive, ref, watch } from "vue"
import * as E from "fp-ts/Either"
import * as O from "fp-ts/Option"
@@ -272,13 +326,18 @@ import { objRemoveKey } from "~/helpers/functional/object"
import { useVModel } from "@vueuse/core"
import { HoppGQLHeader } from "~/helpers/graphql"
import { throwError } from "~/helpers/functional/error"
import { HoppInheritedProperty } from "~/helpers/types/HoppInheritedProperties"
const colorMode = useColorMode()
const t = useI18n()
const toast = useToast()
// v-model integration with props and emit
const props = defineProps<{ modelValue: HoppGQLRequest }>()
const props = defineProps<{
modelValue: HoppGQLRequest
isCollectionProperty?: boolean
inheritedProperties?: HoppInheritedProperty
}>()
const emit = defineEmits<{
(e: "update:modelValue", value: HoppGQLRequest): void
@@ -565,6 +624,64 @@ const computedHeaders = computed(() =>
}))
)
const inheritedProperties = computed(() => {
if (!props.inheritedProperties?.auth || !props.inheritedProperties.headers)
return []
//filter out headers that are already in the request headers
const inheritedHeaders = props.inheritedProperties.headers.filter(
(header) =>
!request.value.headers.some(
(requestHeader) => requestHeader.key === header.key
)
)
const headers = inheritedHeaders.map((header, index) => ({
inheritedFrom: props.inheritedProperties?.headers[index].parentName,
source: "headers",
id: `header-${index}`,
header: {
key: header.inheritedHeader?.key,
value: header.inheritedHeader?.value,
active: header.inheritedHeader?.active,
},
}))
let auth = [] as {
inheritedFrom: string
source: "auth"
id: string
header: {
key: string
value: string
active: boolean
}
}[]
const computedAuthHeader = getComputedAuthHeaders(
request.value,
props.inheritedProperties.auth.inheritedAuth
)[0]
if (
computedAuthHeader &&
request.value.auth.authType === "inherit" &&
request.value.auth.authActive
) {
auth = [
{
inheritedFrom: props.inheritedProperties?.auth.parentName,
source: "auth",
id: `header-auth`,
header: computedAuthHeader,
},
]
}
return [...headers, ...auth]
})
const masking = ref(true)
const toggleMask = () => {

View File

@@ -34,10 +34,16 @@
:label="`${t('tab.headers')}`"
:info="activeGQLHeadersCount === 0 ? null : `${activeGQLHeadersCount}`"
>
<GraphqlHeaders v-model="request" />
<GraphqlHeaders
v-model="request"
:inherited-properties="inheritedProperties"
/>
</HoppSmartTab>
<HoppSmartTab :id="'authorization'" :label="`${t('tab.authorization')}`">
<GraphqlAuthorization v-model="request.auth" />
<GraphqlAuthorization
v-model="request.auth"
:inherited-properties="inheritedProperties"
/>
</HoppSmartTab>
</HoppSmartTabs>
<CollectionsSaveRequest
@@ -69,6 +75,7 @@ import { useService } from "dioc/vue"
import { InterceptorService } from "~/services/interceptor.service"
import { editGraphqlRequest } from "~/newstore/collections"
import { GQLTabService } from "~/services/tab/graphql"
import { HoppInheritedProperty } from "~/helpers/types/HoppInheritedProperties"
const VALID_GQL_OPERATIONS = [
"query",
@@ -93,6 +100,7 @@ const props = withDefaults(
response?: GQLResponseEvent[] | null
optionTab?: GQLOptionTabs
tabId: string
inheritedProperties?: HoppInheritedProperty
}>(),
{
response: null,

View File

@@ -5,6 +5,7 @@
v-model="tab.document.request"
v-model:response="tab.document.response"
v-model:option-tab="tab.document.optionTabPreference"
v-model:inherited-properties="tab.document.inheritedProperties"
:tab-id="tab.id"
/>
</template>

View File

@@ -231,7 +231,6 @@ const auth = useVModel(props, "modelValue", emit)
onMounted(() => {
if (props.isRootCollection && auth.value.authType === "inherit") {
console.log("isRootCollection", auth.value.authType)
auth.value = {
authType: "none",
authActive: true,

View File

@@ -6,6 +6,7 @@ import * as E from "fp-ts/Either"
import { getService } from "~/modules/dioc"
import { RESTTabService } from "~/services/tab/rest"
import { HoppInheritedProperty } from "../types/HoppInheritedProperties"
import { GQLTabService } from "~/services/tab/graphql"
/**
* Resolve save context on reorder
@@ -111,9 +112,11 @@ export function updateSaveContextForAffectedRequests(
export function updateInheritedPropertiesForAffectedRequests(
path: string,
inheritedProperties: HoppInheritedProperty
inheritedProperties: HoppInheritedProperty,
type: "rest" | "graphql"
) {
const tabService = getService(RESTTabService)
const tabService =
type === "rest" ? getService(RESTTabService) : getService(GQLTabService)
const tabs = tabService.getTabsRefTo((tab) => {
return (
tab.document.saveContext?.originLocation === "user-collection" &&

View File

@@ -27,7 +27,7 @@ export const getDefaultGQLRequest = (): HoppGQLRequest => ({
}`,
query: DEFAULT_QUERY,
auth: {
authType: "none",
authType: "inherit",
authActive: true,
},
})

View File

@@ -1,6 +1,7 @@
import { HoppGQLRequest } from "@hoppscotch/data"
import { GQLResponseEvent } from "./connection"
import { GQLOptionTabs } from "~/components/graphql/RequestOptions.vue"
import { HoppInheritedProperty } from "../types/HoppInheritedProperties"
export type HoppGQLSaveContext =
| {
@@ -73,4 +74,10 @@ export type HoppGQLDocument = {
* Options tab preference for the current tab's document
*/
optionTabPreference?: GQLOptionTabs
/**
* The inherited properties from the parent collection
* (if any)
*/
inheritedProperties?: HoppInheritedProperty
}

View File

@@ -64,8 +64,12 @@ export function navigateToFolderWithIndexPath(
}
export function cascaseParentCollectionForHeaderAuth(
folderPath: string | undefined
folderPath: string | undefined,
type: "rest" | "graphql"
) {
const collectionStore =
type === "rest" ? restCollectionStore : graphqlCollectionStore
let auth: HoppInheritedProperty["auth"] = {
parentID: folderPath ?? "",
parentName: "",
@@ -87,7 +91,7 @@ export function cascaseParentCollectionForHeaderAuth(
// Loop through the path and get the last parent folder with authType other than 'inherit'
for (let i = 0; i < path.length; i++) {
const parentFolder = navigateToFolderWithIndexPath(
restCollectionStore.value.state,
collectionStore.value.state,
[...path.slice(0, i + 1)] // Create a copy of the path array
)