refactor: persist IDs under tab save context

This commit is contained in:
jamesgeorge007
2024-02-16 19:09:06 +05:30
parent 89f7c2ce5e
commit 316dc8f759
9 changed files with 110 additions and 182 deletions

View File

@@ -228,30 +228,30 @@ const saveRequestAs = async () => {
if (!isHoppRESTRequest(updatedRequest))
throw new Error("requestUpdated is not a REST Request")
const collPathIndex =
const collectionPathIndex =
picked.value.pickedType === "my-collection"
? picked.value.collectionIndex.toString()
: picked.value.folderPath
const collHandleResult = await workspaceService.getCollectionHandle(
const collectionHandleResult = await workspaceService.getCollectionHandle(
workspaceService.activeWorkspaceHandle.value,
collPathIndex
collectionPathIndex
)
if (E.isLeft(collHandleResult)) {
if (E.isLeft(collectionHandleResult)) {
// INVALID_WORKSPACE_HANDLE | INVALID_COLLECTION_ID | INVALID_PATH
return
}
const collHandle = collHandleResult.right
const collectionHandle = collectionHandleResult.right
if (collHandle.value.type === "invalid") {
if (collectionHandle.value.type === "invalid") {
// WORKSPACE_INVALIDATED
return
}
const requestHandleResult = await workspaceService.createRESTRequest(
collHandle,
collectionHandle,
updatedRequest
)
@@ -299,13 +299,18 @@ const saveRequestAs = async () => {
return
}
// These remain here in the component
const { collectionID, providerID, requestID, workspaceID } =
requestHandle.value.data
RESTTabs.currentActiveTab.value.document = {
request: updatedRequest,
isDirty: false,
saveContext: {
originLocation: "workspace-user-collection",
requestHandle,
workspaceID,
providerID,
collectionID,
requestID,
},
}

View File

@@ -525,7 +525,19 @@ const saveRequest = async () => {
return
}
const { requestHandle } = saveContext
const { requestID } = saveContext
const requestHandleResult = await newWorkspaceService.getRequestHandle(
newWorkspaceService.activeWorkspaceHandle.value,
requestID
)
if (E.isLeft(requestHandleResult)) {
// INVALID_COLLECTION_HANDLE | INVALID_REQUEST_ID | REQUEST_NOT_FOUND
return
}
const requestHandle = requestHandleResult.right
if (!requestHandle.value) {
return

View File

@@ -1,7 +1,7 @@
<template>
<div
v-tippy="{ theme: 'tooltip', delay: [500, 20] }"
:title="tabDocument.request.name"
:title="tab.document.request.name"
class="flex items-center truncate px-2"
@dblclick="emit('open-rename-modal')"
@contextmenu.prevent="options?.tippy?.show()"
@@ -9,9 +9,9 @@
>
<span
class="text-tiny font-semibold mr-2"
:style="{ color: getMethodLabelColorClassOf(tabDocument.request) }"
:style="{ color: getMethodLabelColorClassOf(tab.document.request) }"
>
{{ tabDocument.request.method }}
{{ tab.document.request.method }}
</span>
<tippy
ref="options"
@@ -21,7 +21,7 @@
:on-shown="() => tippyActions!.focus()"
>
<span class="truncate">
{{ tabDocument.request.name }}
{{ tab.document.request.name }}
</span>
<template #content="{ hide }">
<div
@@ -104,24 +104,21 @@
</template>
<script setup lang="ts">
import { ComputedRef, ref, watch } from "vue"
import { ref } from "vue"
import { TippyComponent } from "vue-tippy"
import { getMethodLabelColorClassOf } from "~/helpers/rest/labelColoring"
import { useI18n } from "~/composables/i18n"
import { HoppRESTDocument } from "~/helpers/rest/document"
import { getMethodLabelColorClassOf } from "~/helpers/rest/labelColoring"
import { HoppTab } from "~/services/tab"
import IconCopy from "~icons/lucide/copy"
import IconFileEdit from "~icons/lucide/file-edit"
import IconShare2 from "~icons/lucide/share-2"
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 IconShare2 from "~icons/lucide/share-2"
import { HoppTab } from "~/services/tab"
import { HoppRESTDocument } from "~/helpers/rest/document"
import { computed } from "vue"
import { HandleRef } from "~/services/new-workspace/handle"
import { WorkspaceRequest } from "~/services/new-workspace/workspace"
const t = useI18n()
const props = defineProps<{
defineProps<{
tab: HoppTab<HoppRESTDocument>
isRemovable: boolean
}>()
@@ -142,40 +139,4 @@ const closeAction = ref<HTMLButtonElement | null>(null)
const closeOthersAction = ref<HTMLButtonElement | null>(null)
const duplicateAction = ref<HTMLButtonElement | null>(null)
const shareRequestAction = ref<HTMLButtonElement | null>(null)
const tabDocument = ref<HoppRESTDocument>(props.tab.document)
const requestHandleForCurrentTab = computed(() => {
return props.tab.document.saveContext?.originLocation ===
"workspace-user-collection"
? props.tab.document.saveContext.requestHandle
: undefined
}) as ComputedRef<HandleRef<WorkspaceRequest>["value"] | undefined>
watch(
requestHandleForCurrentTab,
(newRequestHandleState) => {
if (!newRequestHandleState) {
return
}
if (newRequestHandleState.type !== "ok") {
return
}
if (
tabDocument.value.request.name !== newRequestHandleState.data.request.name
) {
tabDocument.value.request.name = newRequestHandleState.data.request.name
}
},
{ deep: true }
)
watch(
props.tab.document,
(newTabDocument) => {
;(tabDocument.value as HoppRESTDocument) = newTabDocument
},
{ deep: true }
)
</script>

View File

@@ -389,34 +389,9 @@ const onRemoveRootCollection = async () => {
if (
tab.document.saveContext?.originLocation === "workspace-user-collection"
) {
const requestHandle = ref(tab.document.saveContext.requestHandle)
const { requestID } = tab.document.saveContext
if (requestHandle.value.type === "invalid") {
tab.document.saveContext = null
tab.document.isDirty = true
continue
}
const requestID = requestHandle.value.data.requestID
const parentCollectionIndexPath = requestID
.split("/")
.slice(0, -1)
.join("/")
const requestIndex = parseInt(requestID.split("/").slice(-1)[0])
const parentCollection = navigateToFolderWithIndexPath(
restCollectionState.value,
parentCollectionIndexPath.split("/").map((id) => parseInt(id))
)
if (!parentCollection) {
tab.document.saveContext = null
tab.document.isDirty = true
continue
}
if (!parentCollection.requests[requestIndex]) {
if (requestID.startsWith(collectionIndexPath)) {
tab.document.saveContext = null
tab.document.isDirty = true
}
@@ -493,12 +468,18 @@ const onAddRequest = async (requestName: string) => {
const { auth, headers } = cascadingAuthHeadersHandle.value.data
const { collectionID, providerID, requestID, workspaceID } =
requestHandle.value.data
tabs.createNewTab({
request: newRequest,
isDirty: false,
saveContext: {
originLocation: "workspace-user-collection",
requestHandle,
workspaceID,
providerID,
collectionID,
requestID,
},
inheritedProperties: {
auth,
@@ -693,34 +674,9 @@ const onRemoveChildCollection = async () => {
if (
tab.document.saveContext?.originLocation === "workspace-user-collection"
) {
const requestHandle = ref(tab.document.saveContext.requestHandle)
const { requestID } = tab.document.saveContext
if (requestHandle.value.type === "invalid") {
tab.document.saveContext = null
tab.document.isDirty = true
continue
}
const requestID = requestHandle.value.data.requestID
const parentCollectionIndexPath = requestID
.split("/")
.slice(0, -1)
.join("/")
const requestIndex = parseInt(requestID.split("/").slice(-1)[0])
const parentCollection = navigateToFolderWithIndexPath(
restCollectionState.value,
parentCollectionIndexPath.split("/").map((id) => parseInt(id))
)
if (!parentCollection) {
tab.document.saveContext = null
tab.document.isDirty = true
continue
}
if (!parentCollection.requests[requestIndex]) {
if (requestID.startsWith(parentCollectionIndexPath)) {
tab.document.saveContext = null
tab.document.isDirty = true
}
@@ -761,9 +717,15 @@ const onRemoveRequest = async () => {
return
}
const { collectionID, providerID, requestID, workspaceID } =
requestHandle.value.data
const possibleTab = tabs.getTabRefWithSaveContext({
originLocation: "workspace-user-collection",
requestHandle,
workspaceID,
providerID,
requestID,
collectionID,
})
if (
@@ -857,10 +819,16 @@ const selectRequest = async (requestIndexPath: string) => {
const { auth, headers } = cascadingAuthHeadersHandle.value.data
const { collectionID, providerID, requestID, workspaceID } =
requestHandle.value.data
// If there is a request with this save context, switch into it
const possibleTab = tabs.getTabRefWithSaveContext({
originLocation: "workspace-user-collection",
requestHandle,
workspaceID,
providerID,
collectionID,
requestID,
})
if (possibleTab) {
@@ -872,7 +840,10 @@ const selectRequest = async (requestIndexPath: string) => {
isDirty: false,
saveContext: {
originLocation: "workspace-user-collection",
requestHandle,
workspaceID,
providerID,
collectionID,
requestID,
},
inheritedProperties: {
auth,
@@ -959,13 +930,21 @@ const onEditRequest = async (newRequestName: string) => {
return
}
const { collectionID, providerID, workspaceID } = requestHandle.value.data
const possibleActiveTab = tabs.getTabRefWithSaveContext({
originLocation: "workspace-user-collection",
requestHandle,
workspaceID,
providerID,
collectionID,
requestID,
})
if (possibleActiveTab) {
possibleActiveTab.value.document.request.name = newRequestName
possibleActiveTab.value.document.request = {
...possibleActiveTab.value.document.request,
name: newRequestName,
}
nextTick(() => {
possibleActiveTab.value.document.isDirty = false
})
@@ -1181,17 +1160,9 @@ const isActiveRequest = (requestView: RESTCollectionViewRequest) => {
return false
}
const requestHandle = ref(
tabs.currentActiveTab.value.document.saveContext?.requestHandle
)
const { requestID } = tabs.currentActiveTab.value.document.saveContext
if (requestHandle.value.type === "invalid") {
return false
}
return (
requestHandle.value.data.requestID === requestView.requestID &&
requestHandle.value.data.request.id === requestView.request.id
)
return requestID === requestView.requestID
}
const onSelectPick = (payload: Picked | null) => {

View File

@@ -1,5 +1,7 @@
import { HoppCollection } from "@hoppscotch/data"
import * as E from "fp-ts/Either"
import { ref } from "vue"
import { getService } from "~/modules/dioc"
import { GQLTabService } from "~/services/tab/graphql"
import { RESTTabService } from "~/services/tab/rest"
@@ -183,19 +185,10 @@ export function updateInheritedPropertiesForAffectedRequests(
return Boolean(tab.document.saveContext.collectionID?.startsWith(path))
}
if (
tab.document.saveContext?.originLocation !== "workspace-user-collection"
) {
return false
}
const requestHandle = ref(tab.document.saveContext.requestHandle)
return (
tab.document.saveContext?.originLocation ===
"workspace-user-collection" &&
requestHandle.value.type === "ok" &&
requestHandle.value.data.collectionID.startsWith(path)
tab.document.saveContext.collectionID?.startsWith(path)
)
})
@@ -212,18 +205,6 @@ export function updateInheritedPropertiesForAffectedRequests(
)
}
if (tab.value.document.saveContext?.originLocation === "team-collection") {
return (
tab.value.document.saveContext.collectionID?.startsWith(path) &&
path ===
folderPathCloseToSaveContext(
tab.value.document.inheritedProperties?.auth.parentID,
path,
tab.value.document.saveContext.collectionID
)
)
}
if (
tab.value.document.saveContext?.originLocation !==
"workspace-user-collection"
@@ -231,16 +212,15 @@ export function updateInheritedPropertiesForAffectedRequests(
return false
}
const requestHandle = ref(tab.value.document.saveContext.requestHandle)
const { collectionID } = tab.value.document.saveContext
return (
requestHandle.value.type === "ok" &&
requestHandle.value.data.collectionID.startsWith(path) &&
collectionID.startsWith(path) &&
path ===
folderPathCloseToSaveContext(
tab.value.document.inheritedProperties?.auth.parentID,
path,
requestHandle.value.data.collectionID
collectionID
)
)
})

View File

@@ -3,8 +3,6 @@ import { HoppRESTResponse } from "../types/HoppRESTResponse"
import { HoppTestResult } from "../types/HoppTestResult"
import { RESTOptionTabs } from "~/components/http/RequestOptions.vue"
import { HoppInheritedProperty } from "../types/HoppInheritedProperties"
import { HandleRef } from "~/services/new-workspace/handle"
import { WorkspaceRequest } from "~/services/new-workspace/workspace"
export type HoppRESTSaveContext =
| {
@@ -14,9 +12,24 @@ export type HoppRESTSaveContext =
// TODO: Make this `user-collection` after porting all usages
originLocation: "workspace-user-collection"
/**
* Handle to a request in the workspace
* ID of the workspace
*/
requestHandle: HandleRef<WorkspaceRequest>
workspaceID: string
/**
* ID of the provider
*/
providerID: string
/**
* ID of the collection
*/
collectionID: string
/**
* Path to the request in the collection tree
*/
requestID: string
}
| {
/**

View File

@@ -1183,7 +1183,6 @@ export function editRESTRequest(
requestIndex: number,
requestNew: HoppRESTRequest
) {
debugger
const indexPaths = path.split("/").map((x) => parseInt(x))
if (
!navigateToFolderWithIndexPath(restCollectionStore.value.state, indexPaths)

View File

@@ -495,8 +495,10 @@ const HoppRESTSaveContextSchema = z.nullable(
z
.object({
originLocation: z.literal("workspace-user-collection"),
// TODO: Specify the correct shape
requestHandle: z.any(),
workspaceID: z.string(),
providerID: z.string(),
collectionID: z.string(),
requestID: z.string(),
})
.strict(),
z

View File

@@ -1,5 +1,5 @@
import { isEqual } from "lodash-es"
import { computed, ref } from "vue"
import { computed } from "vue"
import { getDefaultRESTRequest } from "~/helpers/rest/default"
import { HoppRESTDocument, HoppRESTSaveContext } from "~/helpers/rest/document"
import { TabService } from "./tab"
@@ -58,24 +58,9 @@ export class RESTTabService extends TabService<HoppRESTDocument> {
ctx?.originLocation === "workspace-user-collection" &&
tab.document.saveContext?.originLocation === "workspace-user-collection"
) {
const tabDocumentRequestHandle = ref(
tab.document.saveContext?.requestHandle
)
if (
ctx?.requestHandle.value?.type === "invalid" ||
tabDocumentRequestHandle?.value.type === "invalid"
) {
return
}
if (
isEqual(
ctx?.requestHandle.value.data.request.id,
tabDocumentRequestHandle.value.data.request.id
)
)
if (isEqual(ctx, tab.document.saveContext)) {
return this.getTabRef(tab.id)
}
}
}