diff --git a/packages/hoppscotch-common/src/components/collections/AddRequest.vue b/packages/hoppscotch-common/src/components/collections/AddRequest.vue index 3d60e17af..02870f2ef 100644 --- a/packages/hoppscotch-common/src/components/collections/AddRequest.vue +++ b/packages/hoppscotch-common/src/components/collections/AddRequest.vue @@ -37,7 +37,8 @@ import { ref, watch } from "vue" import { useI18n } from "@composables/i18n" import { useToast } from "@composables/toast" -import { currentActiveTab } from "~/helpers/rest/tab" +import { useService } from "dioc/vue" +import { RESTTabService } from "~/services/tab/rest" const toast = useToast() const t = useI18n() @@ -60,11 +61,12 @@ const emit = defineEmits<{ const editingName = ref("") +const tabs = useService(RESTTabService) watch( () => props.show, (show) => { if (show) { - editingName.value = currentActiveTab.value.document.request.name + editingName.value = tabs.currentActiveTab.value.document.request.name } } ) diff --git a/packages/hoppscotch-common/src/components/collections/MyCollections.vue b/packages/hoppscotch-common/src/components/collections/MyCollections.vue index d1e59ca54..559173d3d 100644 --- a/packages/hoppscotch-common/src/components/collections/MyCollections.vue +++ b/packages/hoppscotch-common/src/components/collections/MyCollections.vue @@ -327,7 +327,8 @@ import { useColorMode } from "@composables/theming" import { pipe } from "fp-ts/function" import * as O from "fp-ts/Option" import { Picked } from "~/helpers/types/HoppPicked.js" -import { currentActiveTab } from "~/helpers/rest/tab" +import { useService } from "dioc/vue" +import { RESTTabService } from "~/services/tab/rest" export type Collection = { type: "collections" @@ -535,7 +536,8 @@ const isSelected = ({ } } -const active = computed(() => currentActiveTab.value.document.saveContext) +const tabs = useService(RESTTabService) +const active = computed(() => tabs.currentActiveTab.value.document.saveContext) const isActiveRequest = (folderPath: string, requestIndex: number) => { return pipe( diff --git a/packages/hoppscotch-common/src/components/collections/SaveRequest.vue b/packages/hoppscotch-common/src/components/collections/SaveRequest.vue index e591534ab..8a08609ea 100644 --- a/packages/hoppscotch-common/src/components/collections/SaveRequest.vue +++ b/packages/hoppscotch-common/src/components/collections/SaveRequest.vue @@ -82,12 +82,16 @@ import { import { GQLError } from "~/helpers/backend/GQLClient" import { computedWithControl } from "@vueuse/core" import { platform } from "~/platform" -import { currentActiveTab as activeRESTTab } from "~/helpers/rest/tab" -import { currentActiveTab as activeGQLTab } from "~/helpers/graphql/tab" +import { useService } from "dioc/vue" +import { RESTTabService } from "~/services/tab/rest" +import { GQLTabService } from "~/services/tab/graphql" const t = useI18n() const toast = useToast() +const RESTTabs = useService(RESTTabService) +const GQLTabs = useService(GQLTabService) + type SelectedTeam = GetMyTeamsQuery["myTeams"][number] | undefined type CollectionType = @@ -123,13 +127,13 @@ const emit = defineEmits<{ }>() const gqlRequestName = computedWithControl( - () => activeGQLTab.value, - () => activeGQLTab.value.document.request.name + () => GQLTabs.currentActiveTab.value, + () => GQLTabs.currentActiveTab.value.document.request.name ) const restRequestName = computedWithControl( - () => activeRESTTab.value, - () => activeRESTTab.value.document.request.name + () => RESTTabs.currentActiveTab.value, + () => RESTTabs.currentActiveTab.value.document.request.name ) const reqName = computed(() => { @@ -145,12 +149,14 @@ const reqName = computed(() => { const requestName = ref(reqName.value) watch( - () => [activeRESTTab.value, activeGQLTab.value], + () => [RESTTabs.currentActiveTab.value, GQLTabs.currentActiveTab.value], () => { if (props.mode === "rest") { - requestName.value = activeRESTTab.value?.document.request.name ?? "" + requestName.value = + RESTTabs.currentActiveTab.value?.document.request.name ?? "" } else { - requestName.value = activeGQLTab.value?.document.request.name ?? "" + requestName.value = + GQLTabs.currentActiveTab.value?.document.request.name ?? "" } } ) @@ -210,8 +216,8 @@ const saveRequestAs = async () => { const requestUpdated = props.mode === "rest" - ? cloneDeep(activeRESTTab.value.document.request) - : cloneDeep(activeGQLTab.value.document.request) + ? cloneDeep(RESTTabs.currentActiveTab.value.document.request) + : cloneDeep(GQLTabs.currentActiveTab.value.document.request) requestUpdated.name = requestName.value @@ -224,7 +230,7 @@ const saveRequestAs = async () => { requestUpdated ) - activeRESTTab.value.document = { + RESTTabs.currentActiveTab.value.document = { request: requestUpdated, isDirty: false, saveContext: { @@ -251,7 +257,7 @@ const saveRequestAs = async () => { requestUpdated ) - activeRESTTab.value.document = { + RESTTabs.currentActiveTab.value.document = { request: requestUpdated, isDirty: false, saveContext: { @@ -279,7 +285,7 @@ const saveRequestAs = async () => { requestUpdated ) - activeRESTTab.value.document = { + RESTTabs.currentActiveTab.value.document = { request: requestUpdated, isDirty: false, saveContext: { @@ -439,7 +445,7 @@ const updateTeamCollectionOrFolder = ( (result) => { const { createRequestInCollection } = result - activeRESTTab.value.document = { + RESTTabs.currentActiveTab.value.document = { request: requestUpdated, isDirty: false, saveContext: { @@ -460,7 +466,7 @@ const updateTeamCollectionOrFolder = ( const requestSaved = () => { toast.success(`${t("request.added")}`) nextTick(() => { - activeRESTTab.value.document.isDirty = false + RESTTabs.currentActiveTab.value.document.isDirty = false }) hideModal() } diff --git a/packages/hoppscotch-common/src/components/collections/TeamCollections.vue b/packages/hoppscotch-common/src/components/collections/TeamCollections.vue index d51c0bcb3..45cc864ef 100644 --- a/packages/hoppscotch-common/src/components/collections/TeamCollections.vue +++ b/packages/hoppscotch-common/src/components/collections/TeamCollections.vue @@ -357,10 +357,12 @@ import { HoppRESTRequest } from "@hoppscotch/data" import { pipe } from "fp-ts/function" import * as O from "fp-ts/Option" import { Picked } from "~/helpers/types/HoppPicked.js" -import { currentActiveTab } from "~/helpers/rest/tab" +import { RESTTabService } from "~/services/tab/rest" +import { useService } from "dioc/vue" const t = useI18n() const colorMode = useColorMode() +const tabs = useService(RESTTabService) type SelectedTeam = GetMyTeamsQuery["myTeams"][number] | undefined @@ -558,7 +560,7 @@ const isSelected = ({ } } -const active = computed(() => currentActiveTab.value.document.saveContext) +const active = computed(() => tabs.currentActiveTab.value.document.saveContext) const isActiveRequest = (requestID: string) => { return pipe( diff --git a/packages/hoppscotch-common/src/components/collections/graphql/AddRequest.vue b/packages/hoppscotch-common/src/components/collections/graphql/AddRequest.vue index a956abd2e..7b2ea9243 100644 --- a/packages/hoppscotch-common/src/components/collections/graphql/AddRequest.vue +++ b/packages/hoppscotch-common/src/components/collections/graphql/AddRequest.vue @@ -36,11 +36,14 @@ import { ref, watch } from "vue" import { useI18n } from "@composables/i18n" import { useToast } from "@composables/toast" -import { currentActiveTab } from "~/helpers/graphql/tab" +import { useService } from "dioc/vue" +import { GQLTabService } from "~/services/tab/graphql" const toast = useToast() const t = useI18n() +const tabs = useService(GQLTabService) + const props = defineProps<{ show: boolean folderPath?: string @@ -63,7 +66,7 @@ watch( () => props.show, (show) => { if (show) { - editingName.value = currentActiveTab.value?.document.request.name + editingName.value = tabs.currentActiveTab.value?.document.request.name } } ) diff --git a/packages/hoppscotch-common/src/components/collections/graphql/Collection.vue b/packages/hoppscotch-common/src/components/collections/graphql/Collection.vue index a103d9bc5..df8d4e786 100644 --- a/packages/hoppscotch-common/src/components/collections/graphql/Collection.vue +++ b/packages/hoppscotch-common/src/components/collections/graphql/Collection.vue @@ -220,7 +220,8 @@ import { moveGraphqlRequest, } from "~/newstore/collections" import { Picked } from "~/helpers/types/HoppPicked" -import { getTabsRefTo } from "~/helpers/graphql/tab" +import { useService } from "dioc/vue" +import { GQLTabService } from "~/services/tab/graphql" const props = defineProps({ picked: { type: Object, default: null }, @@ -235,6 +236,8 @@ const colorMode = useColorMode() const toast = useToast() const t = useI18n() +const tabs = useService(GQLTabService) + // TODO: improve types plz const emit = defineEmits<{ (e: "select", i: Picked | null): void @@ -295,7 +298,7 @@ const removeCollection = () => { emit("select", null) } - const possibleTabs = getTabsRefTo((tab) => { + const possibleTabs = tabs.getTabsRefTo((tab) => { const ctx = tab.document.saveContext if (!ctx) return false diff --git a/packages/hoppscotch-common/src/components/collections/graphql/Folder.vue b/packages/hoppscotch-common/src/components/collections/graphql/Folder.vue index e3901063a..1ba88464e 100644 --- a/packages/hoppscotch-common/src/components/collections/graphql/Folder.vue +++ b/packages/hoppscotch-common/src/components/collections/graphql/Folder.vue @@ -203,12 +203,15 @@ import { useI18n } from "@composables/i18n" import { useColorMode } from "@composables/theming" import { removeGraphqlFolder, moveGraphqlRequest } from "~/newstore/collections" import { computed, ref } from "vue" -import { getTabsRefTo } from "~/helpers/graphql/tab" +import { useService } from "dioc/vue" +import { GQLTabService } from "~/services/tab/graphql" const toast = useToast() const t = useI18n() const colorMode = useColorMode() +const tabs = useService(GQLTabService) + const props = defineProps({ picked: { type: Object, default: null }, // Whether the request is in a selectable mode (activates 'select' event) @@ -277,7 +280,7 @@ const removeFolder = () => { emit("select", { picked: null }) } - const possibleTabs = getTabsRefTo((tab) => { + const possibleTabs = tabs.getTabsRefTo((tab) => { const ctx = tab.document.saveContext if (!ctx) return false diff --git a/packages/hoppscotch-common/src/components/collections/graphql/Request.vue b/packages/hoppscotch-common/src/components/collections/graphql/Request.vue index 9d8dacbb6..6bf70d872 100644 --- a/packages/hoppscotch-common/src/components/collections/graphql/Request.vue +++ b/packages/hoppscotch-common/src/components/collections/graphql/Request.vue @@ -137,12 +137,8 @@ import { useToast } from "@composables/toast" import { HoppGQLRequest, makeGQLRequest } from "@hoppscotch/data" import { cloneDeep } from "lodash-es" import { removeGraphqlRequest } from "~/newstore/collections" -import { - createNewTab, - getTabRefWithSaveContext, - currentTabID, - currentActiveTab, -} from "~/helpers/graphql/tab" +import { useService } from "dioc/vue" +import { GQLTabService } from "~/services/tab/graphql" // Template refs const tippyActions = ref(null) @@ -154,6 +150,8 @@ const deleteAction = ref(null) const t = useI18n() const toast = useToast() +const tabs = useService(GQLTabService) + const props = defineProps({ // Whether the object is selected (show the tick mark) picked: { type: Object, default: null }, @@ -165,7 +163,7 @@ const props = defineProps({ }) const isActive = computed(() => { - const saveCtx = currentActiveTab.value?.document.saveContext + const saveCtx = tabs.currentActiveTab.value?.document.saveContext if (!saveCtx) return false @@ -201,7 +199,7 @@ const selectRequest = () => { if (props.saveRequest) { pick() } else { - const possibleTab = getTabRefWithSaveContext({ + const possibleTab = tabs.getTabRefWithSaveContext({ originLocation: "user-collection", folderPath: props.folderPath, requestIndex: props.requestIndex, @@ -209,11 +207,11 @@ const selectRequest = () => { // Switch to that request if that request is open if (possibleTab) { - currentTabID.value = possibleTab.value.id + tabs.setActiveTab(possibleTab.value.id) return } - createNewTab({ + tabs.createNewTab({ saveContext: { originLocation: "user-collection", folderPath: props.folderPath, @@ -253,7 +251,7 @@ const removeRequest = () => { } // Detach the request from any of the tabs - const possibleTab = getTabRefWithSaveContext({ + const possibleTab = tabs.getTabRefWithSaveContext({ originLocation: "user-collection", folderPath: props.folderPath, requestIndex: props.requestIndex, diff --git a/packages/hoppscotch-common/src/components/collections/graphql/index.vue b/packages/hoppscotch-common/src/components/collections/graphql/index.vue index 906c439f2..64d134018 100644 --- a/packages/hoppscotch-common/src/components/collections/graphql/index.vue +++ b/packages/hoppscotch-common/src/components/collections/graphql/index.vue @@ -145,7 +145,8 @@ import { useI18n } from "@composables/i18n" import { useReadonlyStream } from "@composables/stream" import { useColorMode } from "@composables/theming" import { platform } from "~/platform" -import { createNewTab, currentActiveTab } from "~/helpers/graphql/tab" +import { useService } from "dioc/vue" +import { GQLTabService } from "~/services/tab/graphql" export default defineComponent({ props: { @@ -158,11 +159,13 @@ export default defineComponent({ const collections = useReadonlyStream(graphqlCollections$, [], "deep") const colorMode = useColorMode() const t = useI18n() + const tabs = useService(GQLTabService) return { collections, colorMode, t, + tabs, IconPlus, IconHelpCircle, IconArchive, @@ -267,13 +270,13 @@ export default defineComponent({ }, onAddRequest({ name, path, index }) { const newRequest = { - ...currentActiveTab.value.document.request, + ...this.tabs.currentActiveTab.value.document.request, name, } saveGraphqlRequestAs(path, newRequest) - createNewTab({ + this.tabs.createNewTab({ saveContext: { originLocation: "user-collection", folderPath: path, diff --git a/packages/hoppscotch-common/src/components/collections/index.vue b/packages/hoppscotch-common/src/components/collections/index.vue index 1d015572e..c19e6dbfe 100644 --- a/packages/hoppscotch-common/src/components/collections/index.vue +++ b/packages/hoppscotch-common/src/components/collections/index.vue @@ -219,12 +219,6 @@ import { import * as E from "fp-ts/Either" import { platform } from "~/platform" import { createCollectionGists } from "~/helpers/gist" -import { - createNewTab, - currentActiveTab, - currentTabID, - getTabRefWithSaveContext, -} from "~/helpers/rest/tab" import { getRequestsByPath, resolveSaveContextOnRequestReorder, @@ -239,9 +233,11 @@ import { currentReorderingStatus$ } from "~/newstore/reordering" import { defineActionHandler } from "~/helpers/actions" import { WorkspaceService } from "~/services/workspace.service" import { useService } from "dioc/vue" +import { RESTTabService } from "~/services/tab/rest" const t = useI18n() const toast = useToast() +const tabs = useService(RESTTabService) const props = defineProps({ saveRequest: { @@ -654,7 +650,7 @@ const addRequest = (payload: { const onAddRequest = (requestName: string) => { const newRequest = { - ...cloneDeep(currentActiveTab.value.document.request), + ...cloneDeep(tabs.currentActiveTab.value.document.request), name: requestName, } @@ -663,7 +659,7 @@ const onAddRequest = (requestName: string) => { if (!path) return const insertionIndex = saveRESTRequestAs(path, newRequest) - createNewTab({ + tabs.createNewTab({ request: newRequest, isDirty: false, saveContext: { @@ -712,7 +708,7 @@ const onAddRequest = (requestName: string) => { (result) => { const { createRequestInCollection } = result - createNewTab({ + tabs.createNewTab({ request: newRequest, isDirty: false, saveContext: { @@ -935,7 +931,7 @@ const updateEditingRequest = (newName: string) => { if (folderPath === null || requestIndex === null) return - const possibleActiveTab = getTabRefWithSaveContext({ + const possibleActiveTab = tabs.getTabRefWithSaveContext({ originLocation: "user-collection", requestIndex, folderPath, @@ -979,7 +975,7 @@ const updateEditingRequest = (newName: string) => { ) )() - const possibleTab = getTabRefWithSaveContext({ + const possibleTab = tabs.getTabRefWithSaveContext({ originLocation: "team-collection", requestID, }) @@ -1215,7 +1211,7 @@ const onRemoveRequest = () => { emit("select", null) } - const possibleTab = getTabRefWithSaveContext({ + const possibleTab = tabs.getTabRefWithSaveContext({ originLocation: "user-collection", folderPath, requestIndex, @@ -1275,7 +1271,7 @@ const onRemoveRequest = () => { )() // If there is a tab attached to this request, dissociate its state and mark it dirty - const possibleTab = getTabRefWithSaveContext({ + const possibleTab = tabs.getTabRefWithSaveContext({ originLocation: "team-collection", requestID, }) @@ -1308,14 +1304,14 @@ const selectRequest = (selectedRequest: { let possibleTab = null if (collectionsType.value.type === "team-collections") { - possibleTab = getTabRefWithSaveContext({ + possibleTab = tabs.getTabRefWithSaveContext({ originLocation: "team-collection", requestID: requestIndex, }) if (possibleTab) { - currentTabID.value = possibleTab.value.id + tabs.setActiveTab(possibleTab.value.id) } else { - createNewTab({ + tabs.createNewTab({ request: cloneDeep(request), isDirty: false, saveContext: { @@ -1325,16 +1321,16 @@ const selectRequest = (selectedRequest: { }) } } else { - possibleTab = getTabRefWithSaveContext({ + possibleTab = tabs.getTabRefWithSaveContext({ originLocation: "user-collection", requestIndex: parseInt(requestIndex), folderPath: folderPath!, }) if (possibleTab) { - currentTabID.value = possibleTab.value.id + tabs.setActiveTab(possibleTab.value.id) } else { // If not, open the request in a new tab - createNewTab({ + tabs.createNewTab({ request: cloneDeep(request), isDirty: false, saveContext: { @@ -1377,7 +1373,7 @@ const dropRequest = (payload: { destinationCollectionIndex ) - const possibleTab = getTabRefWithSaveContext({ + const possibleTab = tabs.getTabRefWithSaveContext({ originLocation: "user-collection", folderPath, requestIndex: pathToLastIndex(requestIndex), @@ -1426,7 +1422,7 @@ const dropRequest = (payload: { 1 ) - const possibleTab = getTabRefWithSaveContext({ + const possibleTab = tabs.getTabRefWithSaveContext({ originLocation: "team-collection", requestID: requestIndex, }) diff --git a/packages/hoppscotch-common/src/components/environments/Add.vue b/packages/hoppscotch-common/src/components/environments/Add.vue index be4af410b..93e6414ca 100644 --- a/packages/hoppscotch-common/src/components/environments/Add.vue +++ b/packages/hoppscotch-common/src/components/environments/Add.vue @@ -83,11 +83,14 @@ import { import * as TE from "fp-ts/TaskEither" import { pipe } from "fp-ts/function" import { updateTeamEnvironment } from "~/helpers/backend/mutations/TeamEnvironment" -import { currentActiveTab } from "~/helpers/rest/tab" +import { RESTTabService } from "~/services/tab/rest" +import { useService } from "dioc/vue" const t = useI18n() const toast = useToast() +const tabs = useService(RESTTabService) + const props = defineProps<{ show: boolean position: { top: number; left: number } @@ -189,8 +192,8 @@ const addEnvironment = async () => { //replace the current tab endpoint with the variable name with << and >> const variableName = `<<${editingName.value}>>` //replace the currenttab endpoint containing the value in the text with variablename - currentActiveTab.value.document.request.endpoint = - currentActiveTab.value.document.request.endpoint.replace( + tabs.currentActiveTab.value.document.request.endpoint = + tabs.currentActiveTab.value.document.request.endpoint.replace( editingValue.value, variableName ) diff --git a/packages/hoppscotch-common/src/components/graphql/Request.vue b/packages/hoppscotch-common/src/components/graphql/Request.vue index 894ef6238..671cc6f1c 100644 --- a/packages/hoppscotch-common/src/components/graphql/Request.vue +++ b/packages/hoppscotch-common/src/components/graphql/Request.vue @@ -64,7 +64,6 @@ diff --git a/packages/hoppscotch-common/src/components/http/RequestOptions.vue b/packages/hoppscotch-common/src/components/http/RequestOptions.vue index 9f9625909..1ceda984a 100644 --- a/packages/hoppscotch-common/src/components/http/RequestOptions.vue +++ b/packages/hoppscotch-common/src/components/http/RequestOptions.vue @@ -1,6 +1,6 @@ @@ -13,16 +16,17 @@ diff --git a/packages/hoppscotch-common/src/components/http/ResponseMeta.vue b/packages/hoppscotch-common/src/components/http/ResponseMeta.vue index a3e9f069d..2d31fffeb 100644 --- a/packages/hoppscotch-common/src/components/http/ResponseMeta.vue +++ b/packages/hoppscotch-common/src/components/http/ResponseMeta.vue @@ -93,10 +93,11 @@ import { useColorMode } from "@composables/theming" import { getStatusCodeReasonPhrase } from "~/helpers/utils/statusCodes" import { useService } from "dioc/vue" import { InspectionService } from "~/services/inspection" -import { currentTabID } from "~/helpers/rest/tab" +import { RESTTabService } from "~/services/tab/rest" const t = useI18n() const colorMode = useColorMode() +const tabs = useService(RESTTabService) const props = defineProps<{ response: HoppRESTResponse | null | undefined @@ -146,7 +147,7 @@ const statusCategory = computed(() => { const inspectionService = useService(InspectionService) const tabResults = inspectionService.getResultViewFor( - currentTabID.value, + tabs.currentTabID.value, (result) => result.locations.type === "response" ) diff --git a/packages/hoppscotch-common/src/components/http/TabHead.vue b/packages/hoppscotch-common/src/components/http/TabHead.vue index 3b2ed1bd4..f3e870e34 100644 --- a/packages/hoppscotch-common/src/components/http/TabHead.vue +++ b/packages/hoppscotch-common/src/components/http/TabHead.vue @@ -96,16 +96,17 @@ import { ref } from "vue" import { TippyComponent } from "vue-tippy" import { getMethodLabelColorClassOf } from "~/helpers/rest/labelColoring" import { useI18n } from "~/composables/i18n" -import { HoppRESTTab } from "~/helpers/rest/tab" import IconXCircle from "~icons/lucide/x-circle" import IconXSquare from "~icons/lucide/x-square" import IconFileEdit from "~icons/lucide/file-edit" import IconCopy from "~icons/lucide/copy" +import { HoppTab } from "~/services/tab" +import { HoppRESTDocument } from "~/helpers/rest/document" const t = useI18n() defineProps<{ - tab: HoppRESTTab + tab: HoppTab isRemovable: boolean }>() diff --git a/packages/hoppscotch-common/src/components/lenses/ResponseBodyRenderer.vue b/packages/hoppscotch-common/src/components/lenses/ResponseBodyRenderer.vue index 6ad7ef987..a012ebab9 100644 --- a/packages/hoppscotch-common/src/components/lenses/ResponseBodyRenderer.vue +++ b/packages/hoppscotch-common/src/components/lenses/ResponseBodyRenderer.vue @@ -1,6 +1,6 @@ @@ -54,20 +45,30 @@ import { } from "~/helpers/lenses/lenses" import { useI18n } from "@composables/i18n" import { useVModel } from "@vueuse/core" -import { HoppRESTTab } from "~/helpers/rest/tab" +import { HoppRESTDocument } from "~/helpers/rest/document" const props = defineProps<{ - tab: HoppRESTTab - selectedTabPreference: string | null + document: HoppRESTDocument }>() const emit = defineEmits<{ - (e: "update:tab", val: HoppRESTTab): void - (e: "update:selectedTabPreference", newTab: string): void + (e: "update:document", document: HoppRESTDocument): void }>() -const tab = useVModel(props, "tab", emit) -const selectedTabPreference = useVModel(props, "selectedTabPreference", emit) +const doc = useVModel(props, "document", emit) + +const showIndicator = computed(() => { + if (!doc.value.testResults) return false + + const { expectResults, tests, envDiff } = doc.value.testResults + return Boolean( + expectResults.length || + tests.length || + envDiff.selected.additions.length || + envDiff.selected.updations.length || + envDiff.global.updations.length + ) +}) const allLensRenderers = getLensRenderers() @@ -81,19 +82,19 @@ const selectedLensTab = ref("") const maybeHeaders = computed(() => { if ( - !tab.value.response || + !doc.value.response || !( - tab.value.response.type === "success" || - tab.value.response.type === "fail" + doc.value.response.type === "success" || + doc.value.response.type === "fail" ) ) return null - return tab.value.response.headers + return doc.value.response.headers }) const validLenses = computed(() => { - if (!tab.value.response) return [] - return getSuitableLenses(tab.value.response) + if (!doc.value.response) return [] + return getSuitableLenses(doc.value.response) }) watch( @@ -107,11 +108,13 @@ watch( "results", ] + const { responseTabPreference } = doc.value + if ( - selectedTabPreference.value && - validRenderers.includes(selectedTabPreference.value) + responseTabPreference && + validRenderers.includes(responseTabPreference) ) { - selectedLensTab.value = selectedTabPreference.value + selectedLensTab.value = responseTabPreference } else { selectedLensTab.value = newLenses[0].renderer } @@ -120,6 +123,6 @@ watch( ) watch(selectedLensTab, (newLensID) => { - selectedTabPreference.value = newLensID + doc.value.responseTabPreference = newLensID }) diff --git a/packages/hoppscotch-common/src/helpers/RequestRunner.ts b/packages/hoppscotch-common/src/helpers/RequestRunner.ts index 6bf9c2fe0..7d1f3a9b3 100644 --- a/packages/hoppscotch-common/src/helpers/RequestRunner.ts +++ b/packages/hoppscotch-common/src/helpers/RequestRunner.ts @@ -29,8 +29,9 @@ import { setGlobalEnvVariables, updateEnvironment, } from "~/newstore/environments" -import { HoppRESTTab } from "./rest/tab" import { Ref } from "vue" +import { HoppTab } from "~/services/tab" +import { HoppRESTDocument } from "./rest/document" const getTestableBody = ( res: HoppRESTResponse & { type: "success" | "fail" } @@ -69,7 +70,7 @@ export const executedResponses$ = new Subject< >() export function runRESTRequest$( - tab: Ref + tab: Ref> ): [ () => void, Promise< @@ -127,7 +128,7 @@ export function runRESTRequest$( )() if (E.isRight(runResult)) { - tab.value.testResults = translateToSandboxTestResults( + tab.value.document.testResults = translateToSandboxTestResults( runResult.right ) @@ -163,7 +164,7 @@ export function runRESTRequest$( )() } } else { - tab.value.testResults = { + tab.value.document.testResults = { description: "", expectResults: [], tests: [], diff --git a/packages/hoppscotch-common/src/helpers/collection/collection.ts b/packages/hoppscotch-common/src/helpers/collection/collection.ts index ddbe5afc3..8e55c3e5d 100644 --- a/packages/hoppscotch-common/src/helpers/collection/collection.ts +++ b/packages/hoppscotch-common/src/helpers/collection/collection.ts @@ -1,9 +1,10 @@ import { HoppCollection, HoppRESTRequest } from "@hoppscotch/data" -import { getTabsRefTo } from "../rest/tab" import { getAffectedIndexes } from "./affectedIndex" import { GetSingleRequestDocument } from "../backend/graphql" import { runGQLQuery } from "../backend/GQLClient" import * as E from "fp-ts/Either" +import { getService } from "~/modules/dioc" +import { RESTTabService } from "~/services/tab/rest" /** * Resolve save context on reorder @@ -56,7 +57,9 @@ export function resolveSaveContextOnCollectionReorder( } } - const tabs = getTabsRefTo((tab) => { + const tabService = getService(RESTTabService) + + const tabs = tabService.getTabsRefTo((tab) => { return ( tab.document.saveContext?.originLocation === "user-collection" && affectedPaths.has(tab.document.saveContext.folderPath) @@ -84,7 +87,8 @@ export function updateSaveContextForAffectedRequests( oldFolderPath: string, newFolderPath: string ) { - const tabs = getTabsRefTo((tab) => { + const tabService = getService(RESTTabService) + const tabs = tabService.getTabsRefTo((tab) => { return ( tab.document.saveContext?.originLocation === "user-collection" && tab.document.saveContext.folderPath.startsWith(oldFolderPath) @@ -105,7 +109,8 @@ export function updateSaveContextForAffectedRequests( } function resetSaveContextForAffectedRequests(folderPath: string) { - const tabs = getTabsRefTo((tab) => { + const tabService = getService(RESTTabService) + const tabs = tabService.getTabsRefTo((tab) => { return ( tab.document.saveContext?.originLocation === "user-collection" && tab.document.saveContext.folderPath.startsWith(folderPath) @@ -124,7 +129,8 @@ function resetSaveContextForAffectedRequests(folderPath: string) { */ export async function resetTeamRequestsContext() { - const tabs = getTabsRefTo((tab) => { + const tabService = getService(RESTTabService) + const tabs = tabService.getTabsRefTo((tab) => { return tab.document.saveContext?.originLocation === "team-collection" }) diff --git a/packages/hoppscotch-common/src/helpers/collection/request.ts b/packages/hoppscotch-common/src/helpers/collection/request.ts index a4889c9b4..ec7b819f4 100644 --- a/packages/hoppscotch-common/src/helpers/collection/request.ts +++ b/packages/hoppscotch-common/src/helpers/collection/request.ts @@ -1,6 +1,7 @@ import { HoppCollection, HoppRESTRequest } from "@hoppscotch/data" -import { getTabsRefTo } from "../rest/tab" import { getAffectedIndexes } from "./affectedIndex" +import { RESTTabService } from "~/services/tab/rest" +import { getService } from "~/modules/dioc" /** * Resolve save context on reorder @@ -32,7 +33,8 @@ export function resolveSaveContextOnRequestReorder(payload: { // if (newIndex === -1) remove it from the map because it will be deleted if (newIndex === -1) affectedIndexes.delete(lastIndex) - const tabs = getTabsRefTo((tab) => { + const tabService = getService(RESTTabService) + const tabs = tabService.getTabsRefTo((tab) => { return ( tab.document.saveContext?.originLocation === "user-collection" && tab.document.saveContext.folderPath === folderPath && diff --git a/packages/hoppscotch-common/src/helpers/graphql/document.ts b/packages/hoppscotch-common/src/helpers/graphql/document.ts index 947e1a132..eecfd787c 100644 --- a/packages/hoppscotch-common/src/helpers/graphql/document.ts +++ b/packages/hoppscotch-common/src/helpers/graphql/document.ts @@ -1,4 +1,6 @@ import { HoppGQLRequest } from "@hoppscotch/data" +import { GQLResponseEvent } from "./connection" +import { GQLOptionTabs } from "~/components/graphql/RequestOptions.vue" export type HoppGQLSaveContext = | { @@ -55,4 +57,20 @@ export type HoppGQLDocument = { * This contains where the request is originated from basically. */ saveContext?: HoppGQLSaveContext + + /** + * The response as it is in the document + * (if any) + */ + response?: GQLResponseEvent[] | null + + /** + * Response tab preference for the current tab's document + */ + responseTabPreference?: string + + /** + * Options tab preference for the current tab's document + */ + optionTabPreference?: GQLOptionTabs } diff --git a/packages/hoppscotch-common/src/helpers/graphql/tab.ts b/packages/hoppscotch-common/src/helpers/graphql/tab.ts deleted file mode 100644 index 55097270a..000000000 --- a/packages/hoppscotch-common/src/helpers/graphql/tab.ts +++ /dev/null @@ -1,226 +0,0 @@ -import { refWithControl } from "@vueuse/core" -import { isEqual } from "lodash-es" -import { v4 as uuidV4 } from "uuid" -import { computed, reactive, ref, shallowReadonly, watch } from "vue" -import { HoppTestResult } from "../types/HoppTestResult" -import { GQLResponseEvent } from "./connection" -import { getDefaultGQLRequest } from "./default" -import { HoppGQLDocument, HoppGQLSaveContext } from "./document" - -export type HoppGQLTab = { - id: string - document: HoppGQLDocument - response?: GQLResponseEvent[] | null - testResults?: HoppTestResult | null -} - -export type PersistableGQLTabState = { - lastActiveTabID: string - orderedDocs: Array<{ - tabID: string - doc: HoppGQLDocument - }> -} - -export const currentTabID = refWithControl("test", { - onBeforeChange(newTabID) { - if (!newTabID || !tabMap.has(newTabID)) { - console.warn( - `Tried to set current tab id to an invalid value. (value: ${newTabID})` - ) - - // Don't allow change - return false - } - }, -}) - -const tabMap = reactive( - new Map([ - [ - "test", - { - id: "test", - document: { - request: getDefaultGQLRequest(), - isDirty: false, - }, - }, - ], - ]) -) -const tabOrdering = ref(["test"]) - -watch( - tabOrdering, - (newOrdering) => { - if (!currentTabID.value || !newOrdering.includes(currentTabID.value)) { - currentTabID.value = newOrdering[newOrdering.length - 1] // newOrdering should always be non-empty - } - }, - { deep: true } -) - -export const persistableTabState = computed(() => ({ - lastActiveTabID: currentTabID.value, - orderedDocs: tabOrdering.value.map((tabID) => { - const tab = tabMap.get(tabID)! // tab ordering is guaranteed to have value for this key - return { - tabID: tab.id, - doc: tab.document, - } - }), -})) - -export const currentActiveTab = computed(() => tabMap.get(currentTabID.value)!) // Guaranteed to not be undefined - -// TODO: Mark this unknown and do validations -export function loadTabsFromPersistedState(data: PersistableGQLTabState) { - if (data) { - tabMap.clear() - tabOrdering.value = [] - - for (const doc of data.orderedDocs) { - tabMap.set(doc.tabID, { - id: doc.tabID, - document: doc.doc, - }) - - tabOrdering.value.push(doc.tabID) - } - - currentTabID.value = data.lastActiveTabID - } -} - -/** - * Returns all the active Tab IDs in order - */ -export function getActiveTabs() { - return shallowReadonly( - computed(() => tabOrdering.value.map((x) => tabMap.get(x)!)) - ) -} - -export function getTabRef(tabID: string) { - return computed({ - get() { - const result = tabMap.get(tabID) - - if (result === undefined) throw new Error(`Invalid tab id: ${tabID}`) - - return result - }, - set(value) { - return tabMap.set(tabID, value) - }, - }) -} - -function generateNewTabID() { - while (true) { - const id = uuidV4() - - if (!tabMap.has(id)) return id - } -} - -export function updateTab(tabUpdate: HoppGQLTab) { - if (!tabMap.has(tabUpdate.id)) { - console.warn( - `Cannot update tab as tab with that tab id does not exist (id: ${tabUpdate.id})` - ) - } - - tabMap.set(tabUpdate.id, tabUpdate) -} - -export function createNewTab(document: HoppGQLDocument, switchToIt = true) { - const id = generateNewTabID() - - const tab: HoppGQLTab = { id, document } - - tabMap.set(id, tab) - tabOrdering.value.push(id) - - if (switchToIt) { - currentTabID.value = id - } - - return tab -} - -export function updateTabOrdering(fromIndex: number, toIndex: number) { - tabOrdering.value.splice( - toIndex, - 0, - tabOrdering.value.splice(fromIndex, 1)[0] - ) -} - -export function closeTab(tabID: string) { - if (!tabMap.has(tabID)) { - console.warn(`Tried to close a tab which does not exist (tab id: ${tabID})`) - return - } - - if (tabOrdering.value.length === 1) { - console.warn( - `Tried to close the only tab open, which is not allowed. (tab id: ${tabID})` - ) - return - } - - tabOrdering.value.splice(tabOrdering.value.indexOf(tabID), 1) - - tabMap.delete(tabID) -} - -export function getTabRefWithSaveContext(ctx: HoppGQLSaveContext) { - for (const tab of tabMap.values()) { - // For `team-collection` request id can be considered unique - if (ctx && ctx.originLocation === "team-collection") { - if ( - tab.document.saveContext?.originLocation === "team-collection" && - tab.document.saveContext.requestID === ctx.requestID - ) { - return getTabRef(tab.id) - } - } else if (isEqual(ctx, tab.document.saveContext)) return getTabRef(tab.id) - } - - return null -} - -export function getTabsRefTo(func: (tab: HoppGQLTab) => boolean) { - return Array.from(tabMap.values()) - .filter(func) - .map((tab) => getTabRef(tab.id)) -} - -export function closeOtherTabs(tabID: string) { - if (!tabMap.has(tabID)) { - console.warn( - `The tab to close other tabs does not exist (tab id: ${tabID})` - ) - return - } - - tabOrdering.value = [tabID] - - tabMap.forEach((_, id) => { - if (id !== tabID) tabMap.delete(id) - }) - - currentTabID.value = tabID -} - -export function getDirtyTabsCount() { - let count = 0 - - for (const tab of tabMap.values()) { - if (tab.document.isDirty) count++ - } - - return count -} diff --git a/packages/hoppscotch-common/src/helpers/rest/document.ts b/packages/hoppscotch-common/src/helpers/rest/document.ts index e80ef8e88..93272dbc3 100644 --- a/packages/hoppscotch-common/src/helpers/rest/document.ts +++ b/packages/hoppscotch-common/src/helpers/rest/document.ts @@ -1,4 +1,7 @@ import { HoppRESTRequest } from "@hoppscotch/data" +import { HoppRESTResponse } from "../types/HoppRESTResponse" +import { HoppTestResult } from "../types/HoppTestResult" +import { RESTOptionTabs } from "~/components/http/RequestOptions.vue" export type HoppRESTSaveContext = | { @@ -55,4 +58,26 @@ export type HoppRESTDocument = { * This contains where the request is originated from basically. */ saveContext?: HoppRESTSaveContext + + /** + * The response as it is in the document + * (if any) + */ + response?: HoppRESTResponse | null + + /** + * The test results as it is in the document + * (if any) + */ + testResults?: HoppTestResult | null + + /** + * Response tab preference for the current tab's document + */ + responseTabPreference?: string + + /** + * Options tab preference for the current tab's document + */ + optionTabPreference?: RESTOptionTabs } diff --git a/packages/hoppscotch-common/src/helpers/rest/tab.ts b/packages/hoppscotch-common/src/helpers/rest/tab.ts deleted file mode 100644 index 963e1237d..000000000 --- a/packages/hoppscotch-common/src/helpers/rest/tab.ts +++ /dev/null @@ -1,234 +0,0 @@ -import { v4 as uuidV4 } from "uuid" -import { isEqual } from "lodash-es" -import { reactive, watch, computed, ref, shallowReadonly } from "vue" -import { HoppRESTDocument, HoppRESTSaveContext } from "./document" -import { refWithControl } from "@vueuse/core" -import { HoppRESTResponse } from "../types/HoppRESTResponse" -import { getDefaultRESTRequest } from "./default" -import { HoppTestResult } from "../types/HoppTestResult" -import { platform } from "~/platform" -import { nextTick } from "vue" - -export type HoppRESTTab = { - id: string - document: HoppRESTDocument - response?: HoppRESTResponse | null - testResults?: HoppTestResult | null -} - -export type PersistableRESTTabState = { - lastActiveTabID: string - orderedDocs: Array<{ - tabID: string - doc: HoppRESTDocument - }> -} - -export const currentTabID = refWithControl("test", { - onBeforeChange(newTabID) { - if (!newTabID || !tabMap.has(newTabID)) { - console.warn( - `Tried to set current tab id to an invalid value. (value: ${newTabID})` - ) - - // Don't allow change - return false - } - }, -}) - -const tabMap = reactive( - new Map([ - [ - "test", - { - id: "test", - document: { - request: getDefaultRESTRequest(), - isDirty: false, - }, - }, - ], - ]) -) -const tabOrdering = ref(["test"]) - -watch( - tabOrdering, - (newOrdering) => { - if (!currentTabID.value || !newOrdering.includes(currentTabID.value)) { - currentTabID.value = newOrdering[newOrdering.length - 1] // newOrdering should always be non-empty - } - }, - { deep: true } -) - -export const persistableTabState = computed(() => ({ - lastActiveTabID: currentTabID.value, - orderedDocs: tabOrdering.value.map((tabID) => { - const tab = tabMap.get(tabID)! // tab ordering is guaranteed to have value for this key - return { - tabID: tab.id, - doc: tab.document, - } - }), -})) - -export const currentActiveTab = computed(() => tabMap.get(currentTabID.value)!) // Guaranteed to not be undefined - -// TODO: Mark this unknown and do validations -export function loadTabsFromPersistedState(data: PersistableRESTTabState) { - if (data) { - tabMap.clear() - tabOrdering.value = [] - - for (const doc of data.orderedDocs) { - tabMap.set(doc.tabID, { - id: doc.tabID, - document: doc.doc, - }) - - tabOrdering.value.push(doc.tabID) - } - - currentTabID.value = data.lastActiveTabID - } -} - -/** - * Returns all the active Tab IDs in order - */ -export function getActiveTabs() { - return shallowReadonly( - computed(() => tabOrdering.value.map((x) => tabMap.get(x)!)) - ) -} - -export function getTabRef(tabID: string) { - return computed({ - get() { - const result = tabMap.get(tabID) - - if (result === undefined) throw new Error(`Invalid tab id: ${tabID}`) - - return result - }, - set(value) { - return tabMap.set(tabID, value) - }, - }) -} - -function generateNewTabID() { - while (true) { - const id = uuidV4() - - if (!tabMap.has(id)) return id - } -} - -export function updateTab(tabUpdate: HoppRESTTab) { - if (!tabMap.has(tabUpdate.id)) { - console.warn( - `Cannot update tab as tab with that tab id does not exist (id: ${tabUpdate.id})` - ) - } - - tabMap.set(tabUpdate.id, tabUpdate) -} - -export function createNewTab(document: HoppRESTDocument, switchToIt = true) { - const id = generateNewTabID() - - const tab: HoppRESTTab = { id, document } - - tabMap.set(id, tab) - tabOrdering.value.push(id) - - if (switchToIt) { - currentTabID.value = id - } - - platform.analytics?.logEvent({ - type: "HOPP_REST_NEW_TAB_OPENED", - }) - - return tab -} - -export function updateTabOrdering(fromIndex: number, toIndex: number) { - tabOrdering.value.splice( - toIndex, - 0, - tabOrdering.value.splice(fromIndex, 1)[0] - ) -} - -export function closeTab(tabID: string) { - if (!tabMap.has(tabID)) { - console.warn(`Tried to close a tab which does not exist (tab id: ${tabID})`) - return - } - - if (tabOrdering.value.length === 1) { - console.warn( - `Tried to close the only tab open, which is not allowed. (tab id: ${tabID})` - ) - return - } - - tabOrdering.value.splice(tabOrdering.value.indexOf(tabID), 1) - - nextTick(() => { - tabMap.delete(tabID) - }) -} - -export function closeOtherTabs(tabID: string) { - if (!tabMap.has(tabID)) { - console.warn( - `The tab to close other tabs does not exist (tab id: ${tabID})` - ) - return - } - - tabOrdering.value = [tabID] - - tabMap.forEach((_, id) => { - if (id !== tabID) tabMap.delete(id) - }) - - currentTabID.value = tabID -} - -export function getDirtyTabsCount() { - let count = 0 - - for (const tab of tabMap.values()) { - if (tab.document.isDirty) count++ - } - - return count -} - -export function getTabRefWithSaveContext(ctx: HoppRESTSaveContext) { - for (const tab of tabMap.values()) { - // For `team-collection` request id can be considered unique - if (ctx && ctx.originLocation === "team-collection") { - if ( - tab.document.saveContext?.originLocation === "team-collection" && - tab.document.saveContext.requestID === ctx.requestID - ) { - return getTabRef(tab.id) - } - } else if (isEqual(ctx, tab.document.saveContext)) return getTabRef(tab.id) - } - - return null -} - -export function getTabsRefTo(func: (tab: HoppRESTTab) => boolean) { - return Array.from(tabMap.values()) - .filter(func) - .map((tab) => getTabRef(tab.id)) -} diff --git a/packages/hoppscotch-common/src/helpers/utils/EffectiveURL.ts b/packages/hoppscotch-common/src/helpers/utils/EffectiveURL.ts index 73966016f..047d6684c 100644 --- a/packages/hoppscotch-common/src/helpers/utils/EffectiveURL.ts +++ b/packages/hoppscotch-common/src/helpers/utils/EffectiveURL.ts @@ -198,11 +198,11 @@ export const resolvesEnvsInBody = ( } ), } - } else { - return { - contentType: body.contentType, - body: parseTemplateString(body.body, env.variables), - } + } + + return { + contentType: body.contentType, + body: parseTemplateString(body.body ?? "", env.variables), } } @@ -210,9 +210,7 @@ function getFinalBodyFromRequest( request: HoppRESTRequest, envVariables: Environment["variables"] ): FormData | string | null { - if (request.body.contentType === null) { - return null - } + if (request.body.contentType === null) return null if (request.body.contentType === "application/x-www-form-urlencoded") { const parsedBodyRecord = pipe( @@ -280,7 +278,10 @@ function getFinalBodyFromRequest( ), toFormData ) - } else return parseBodyEnvVariables(request.body.body, envVariables) + } + + // body can be null if the content-type is not set + return parseBodyEnvVariables(request.body.body ?? "", envVariables) } /** diff --git a/packages/hoppscotch-common/src/newstore/collections.ts b/packages/hoppscotch-common/src/newstore/collections.ts index 5ba18dfee..2f1c5838f 100644 --- a/packages/hoppscotch-common/src/newstore/collections.ts +++ b/packages/hoppscotch-common/src/newstore/collections.ts @@ -7,8 +7,9 @@ import { } from "@hoppscotch/data" import DispatchingStore, { defineDispatchers } from "./DispatchingStore" import { cloneDeep } from "lodash-es" -import { getTabRefWithSaveContext } from "~/helpers/rest/tab" import { resolveSaveContextOnRequestReorder } from "~/helpers/collection/request" +import { getService } from "~/modules/dioc" +import { RESTTabService } from "~/services/tab/rest" const defaultRESTCollectionState = { state: [ @@ -454,7 +455,10 @@ const restCollectionDispatchers = defineDispatchers({ // Deal with situations where a tab with the given thing is deleted // We are just going to dissociate the save context of the tab and mark it dirty - const tab = getTabRefWithSaveContext({ + + const tabService = getService(RESTTabService) + + const tab = tabService.getTabRefWithSaveContext({ originLocation: "user-collection", folderPath: path, requestIndex: requestIndex, @@ -512,7 +516,8 @@ const restCollectionDispatchers = defineDispatchers({ destLocation.requests.push(req) targetLocation.requests.splice(requestIndex, 1) - const possibleTab = getTabRefWithSaveContext({ + const tabService = getService(RESTTabService) + const possibleTab = tabService.getTabRefWithSaveContext({ originLocation: "user-collection", folderPath: path, requestIndex, diff --git a/packages/hoppscotch-common/src/newstore/localpersistence.ts b/packages/hoppscotch-common/src/newstore/localpersistence.ts index 1cfe91783..e3308df8d 100644 --- a/packages/hoppscotch-common/src/newstore/localpersistence.ts +++ b/packages/hoppscotch-common/src/newstore/localpersistence.ts @@ -44,14 +44,9 @@ import { SSERequest$, setSSERequest } from "./SSESession" import { MQTTRequest$, setMQTTRequest } from "./MQTTSession" import { bulkApplyLocalState, localStateStore } from "./localstate" import { StorageLike, watchDebounced } from "@vueuse/core" -import { - loadTabsFromPersistedState, - persistableTabState, -} from "~/helpers/rest/tab" -import { - loadTabsFromPersistedState as loadGQLTabsFromPersistedState, - persistableTabState as persistableGQLTabState, -} from "~/helpers/graphql/tab" +import { getService } from "~/modules/dioc" +import { RESTTabService } from "~/services/tab/rest" +import { GQLTabService } from "~/services/tab/graphql" function checkAndMigrateOldSettings() { if (window.localStorage.getItem("selectedEnvIndex")) { @@ -320,11 +315,13 @@ function setupGlobalEnvsPersistence() { // TODO: Graceful error handling ? export function setupRESTTabsPersistence() { + const tabService = getService(RESTTabService) + try { const state = window.localStorage.getItem("restTabState") if (state) { const data = JSON.parse(state) - loadTabsFromPersistedState(data) + tabService.loadTabsFromPersistedState(data) } } catch (e) { console.error( @@ -334,7 +331,7 @@ export function setupRESTTabsPersistence() { } watchDebounced( - persistableTabState, + tabService.persistableTabState, (state) => { window.localStorage.setItem("restTabState", JSON.stringify(state)) }, @@ -343,11 +340,13 @@ export function setupRESTTabsPersistence() { } function setupGQLTabsPersistence() { + const tabService = getService(GQLTabService) + try { const state = window.localStorage.getItem("gqlTabState") if (state) { const data = JSON.parse(state) - loadGQLTabsFromPersistedState(data) + tabService.loadTabsFromPersistedState(data) } } catch (e) { console.error( @@ -357,7 +356,7 @@ function setupGQLTabsPersistence() { } watchDebounced( - persistableGQLTabState, + tabService.persistableTabState, (state) => { window.localStorage.setItem("gqlTabState", JSON.stringify(state)) }, diff --git a/packages/hoppscotch-common/src/pages/graphql.vue b/packages/hoppscotch-common/src/pages/graphql.vue index cb960411d..65504de91 100644 --- a/packages/hoppscotch-common/src/pages/graphql.vue +++ b/packages/hoppscotch-common/src/pages/graphql.vue @@ -7,23 +7,24 @@