diff --git a/packages/hoppscotch-common/src/components/http/Request.vue b/packages/hoppscotch-common/src/components/http/Request.vue index ef4dfa1c5..cc2019e1d 100644 --- a/packages/hoppscotch-common/src/components/http/Request.vue +++ b/packages/hoppscotch-common/src/components/http/Request.vue @@ -534,6 +534,7 @@ const saveRequest = async () => { if (E.isLeft(requestHandleResult)) { // INVALID_COLLECTION_HANDLE | INVALID_REQUEST_ID | REQUEST_NOT_FOUND + showSaveRequestModal.value = true return } diff --git a/packages/hoppscotch-common/src/components/new-collections/rest/Collection.vue b/packages/hoppscotch-common/src/components/new-collections/rest/Collection.vue index f28567745..34e13cf10 100644 --- a/packages/hoppscotch-common/src/components/new-collections/rest/Collection.vue +++ b/packages/hoppscotch-common/src/components/new-collections/rest/Collection.vue @@ -22,8 +22,8 @@ >
() const emit = defineEmits<{ @@ -349,8 +349,10 @@ const editCollection = () => { const dragStart = ({ dataTransfer }: DragEvent) => { if (dataTransfer) { emit("drag-event", dataTransfer) + dropItemID.value = dataTransfer.getData("collectionIndex") dragging.value = !dragging.value + changeCurrentReorderStatus({ type: "collection", id: props.collectionView.collectionID, @@ -376,7 +378,7 @@ const handleDragOver = (e: DragEvent) => { notSameDestination.value && !isRequestDragging.value && isSameParent.value && - props.isLastItem + props.collectionView.isLastItem ) { orderingLastItem.value = true dragging.value = false diff --git a/packages/hoppscotch-common/src/components/new-collections/rest/Request.vue b/packages/hoppscotch-common/src/components/new-collections/rest/Request.vue index 53a9f5c99..50b26075f 100644 --- a/packages/hoppscotch-common/src/components/new-collections/rest/Request.vue +++ b/packages/hoppscotch-common/src/components/new-collections/rest/Request.vue @@ -1,8 +1,27 @@ @@ -142,8 +176,13 @@ import { useI18n } from "@composables/i18n" import { HoppRESTRequest } from "@hoppscotch/data" import { computed, ref } from "vue" import { TippyComponent } from "vue-tippy" +import { useReadonlyStream } from "~/composables/stream" import { getMethodLabelColorClassOf } from "~/helpers/rest/labelColoring" +import { + currentReorderingStatus$, + changeCurrentReorderStatus, +} from "~/newstore/reordering" import { RESTCollectionViewRequest } from "~/services/new-workspace/view" import IconCheckCircle from "~icons/lucide/check-circle" @@ -156,6 +195,12 @@ import IconTrash2 from "~icons/lucide/trash-2" const t = useI18n() +const currentReorderingStatus = useReadonlyStream(currentReorderingStatus$, { + type: "collection", + id: "", + parentID: "", +}) + const props = defineProps<{ isActive: boolean requestView: RESTCollectionViewRequest @@ -174,6 +219,9 @@ const emit = defineEmits<{ (event: "remove-request", requestIndexPath: string): void (event: "select-request", requestIndexPath: string): void (event: "share-request", request: HoppRESTRequest): void + (event: "drag-request", payload: DataTransfer): void + (event: "update-request-order", payload: DataTransfer): void + (event: "update-last-request-order", payload: DataTransfer): void }>() const tippyActions = ref(null) @@ -183,9 +231,105 @@ const options = ref(null) const duplicate = ref(null) const shareAction = ref(null) +const dragging = ref(false) +const ordering = ref(false) +const orderingLastItem = ref(false) + +const isCollectionDragging = computed(() => { + return currentReorderingStatus.value.type === "collection" +}) + +const isLastItemReorderable = computed(() => { + return ( + orderingLastItem.value && isSameParent.value && !isCollectionDragging.value + ) +}) + +const isReorderable = computed(() => { + return ( + ordering.value && + !isCollectionDragging.value && + isSameParent.value && + !isSameRequest.value + ) +}) + +const isSameParent = computed(() => { + return ( + currentReorderingStatus.value.parentID === + props.requestView.parentCollectionID + ) +}) + +const isSameRequest = computed(() => { + return currentReorderingStatus.value.id === props.requestView.requestID +}) + const requestLabelColor = computed(() => getMethodLabelColorClassOf(props.requestView.request) ) +const dragStart = ({ dataTransfer }: DragEvent) => { + if (dataTransfer) { + emit("drag-request", dataTransfer) + dragging.value = !dragging.value + + changeCurrentReorderStatus({ + type: "request", + id: props.requestView.requestID, + parentID: props.requestView.parentCollectionID, + }) + } +} + +const handleDrop = (e: DragEvent) => { + if (ordering.value) { + updateRequestOrder(e) + } else if (orderingLastItem.value) { + updateLastItemOrder(e) + } else { + updateRequestOrder(e) + } +} + +// Trigger the re-ordering event when a request is dragged over another request's top section +const handleDragOver = (e: DragEvent) => { + dragging.value = true + if (e.offsetY < 10) { + ordering.value = true + dragging.value = false + orderingLastItem.value = false + } else if (e.offsetY > 18) { + orderingLastItem.value = true + dragging.value = false + ordering.value = false + } else { + ordering.value = false + orderingLastItem.value = false + } +} + +const resetDragState = () => { + dragging.value = false + ordering.value = false + orderingLastItem.value = false +} + const selectRequest = () => emit("select-request", props.requestView.requestID) + +const updateRequestOrder = (e: DragEvent) => { + if (e.dataTransfer) { + e.stopPropagation() + resetDragState() + emit("update-request-order", e.dataTransfer) + } +} + +const updateLastItemOrder = (e: DragEvent) => { + if (e.dataTransfer) { + e.stopPropagation() + resetDragState() + emit("update-last-request-order", e.dataTransfer) + } +} diff --git a/packages/hoppscotch-common/src/components/new-collections/rest/index.vue b/packages/hoppscotch-common/src/components/new-collections/rest/index.vue index 4b147e18b..1c28e8485 100644 --- a/packages/hoppscotch-common/src/components/new-collections/rest/index.vue +++ b/packages/hoppscotch-common/src/components/new-collections/rest/index.vue @@ -12,9 +12,10 @@ >
+
- + () const workspaceService = useService(NewWorkspaceService) @@ -1301,7 +1271,7 @@ const dragRequest = ( dataTransfer.setData("requestIndex", requestIndex) } -const dropEvent = ( +const dropEvent = async ( dataTransfer: DataTransfer, destinationCollectionIndex: string ) => { @@ -1309,22 +1279,17 @@ const dropEvent = ( "parentCollectionIndexPath" ) const requestIndex = dataTransfer.getData("requestIndex") - const collectionIndexDragged = dataTransfer.getData("collectionIndex") + const draggedCollectionIndex = dataTransfer.getData("collectionIndex") if (parentCollectionIndexPath && requestIndex) { - // emit("drop-request", { - // parentCollectionIndexPath, - // requestIndex, - // destinationCollectionIndex, - // }) - dropRequest({ + await dropRequest({ parentCollectionIndexPath, requestIndex, destinationCollectionIndex, }) } else { - dropCollection({ - collectionIndexDragged, + await dropCollection({ + draggedCollectionIndex, destinationCollectionIndex, }) } @@ -1335,23 +1300,115 @@ const dropEvent = ( * to the root * @param payload - object containing the collection index dragged */ -const dropToRoot = ({ dataTransfer }: DragEvent) => { - if (dataTransfer) { - const collectionIndexDragged = dataTransfer.getData("collectionIndex") - if (!collectionIndexDragged) return - // check if the collection is already in the root - if (isAlreadyInRoot(collectionIndexDragged)) { - toast.error(`${t("collection.invalid_root_move")}`) - } else { - moveRESTFolder(collectionIndexDragged, null) - toast.success(`${t("collection.moved")}`) - } - - draggingToRoot.value = false +const dropToRoot = async ({ dataTransfer }: DragEvent) => { + if (!dataTransfer) { + return } + + const draggedCollectionIndex = dataTransfer.getData("collectionIndex") + if (!draggedCollectionIndex) { + return + } + + // check if the collection is already in the root + if (isAlreadyInRoot(draggedCollectionIndex)) { + toast.error(`${t("collection.invalid_root_move")}`) + draggingToRoot.value = false + return + } + + const draggedCollectionHandleResult = + await workspaceService.getCollectionHandle( + props.workspaceHandle, + draggedCollectionIndex + ) + + if (E.isLeft(draggedCollectionHandleResult)) { + // INVALID_WORKSPACE_HANDLE | INVALID_COLLECTION_ID | INVALID_PATH + return + } + + const draggedCollectionHandle = draggedCollectionHandleResult.right + + if (draggedCollectionHandle.value.type === "invalid") { + // WORKSPACE_INVALIDATED + return + } + + const result = await workspaceService.moveRESTCollection( + draggedCollectionHandle, + null + ) + + if (E.isLeft(result)) { + // INVALID_COLLECTION_HANDLE + return + } + + const destinationRootCollectionIndex = ( + restCollectionState.value.length - 1 + ).toString() + + updateSaveContextForAffectedRequests( + draggedCollectionIndex, + destinationRootCollectionIndex + ) + + const destinationRootCollectionHandleResult = + await workspaceService.getCollectionHandle( + props.workspaceHandle, + destinationRootCollectionIndex + ) + + if (E.isLeft(destinationRootCollectionHandleResult)) { + // INVALID_WORKSPACE_HANDLE | INVALID_COLLECTION_ID | INVALID_PATH + return + } + + const destinationRootCollectionHandle = + destinationRootCollectionHandleResult.right + + if (destinationRootCollectionHandle.value.type === "invalid") { + // WORKSPACE_INVALIDATED + return + } + + const cascadingAuthHeadersHandleResult = + await workspaceService.getRESTCollectionLevelAuthHeadersView( + destinationRootCollectionHandle + ) + + if (E.isLeft(cascadingAuthHeadersHandleResult)) { + // INVALID_COLLECTION_HANDLE + return + } + + const cascadingAuthHeadersHandle = cascadingAuthHeadersHandleResult.right + + if (cascadingAuthHeadersHandle.value.type === "invalid") { + // COLLECTION_INVALIDATED + return + } + + const { auth, headers } = cascadingAuthHeadersHandle.value.data + + const inheritedProperty = { + auth, + headers, + } + + updateInheritedPropertiesForAffectedRequests( + destinationRootCollectionIndex, + inheritedProperty, + "rest" + ) + + toast.success(`${t("collection.moved")}`) + + draggingToRoot.value = false } -const dropRequest = (payload: { +const dropRequest = async (payload: { parentCollectionIndexPath?: string | undefined requestIndex: string destinationCollectionIndex: string @@ -1366,65 +1423,137 @@ const dropRequest = (payload: { !requestIndex || !destinationCollectionIndex || !parentCollectionIndexPath - ) + ) { return + } - // const { auth, headers } = cascadeParentCollectionForHeaderAuth( - // destinationCollectionIndex, - // "rest" - // ) + const requestHandleResult = await workspaceService.getRequestHandle( + props.workspaceHandle, + requestIndex + ) - // const possibleTab = tabs.getTabRefWithSaveContext({ - // originLocation: "user-collection", - // folderPath, - // requestIndex: pathToLastIndex(requestIndex), - // }) + if (E.isLeft(requestHandleResult)) { + // INVALID_COLLECTION_HANDLE | INVALID_REQUEST_ID | REQUEST_NOT_FOUND + return + } - // If there is a tab attached to this request, change save its save context - // if (possibleTab) { - // possibleTab.value.document.saveContext = { - // originLocation: "user-collection", - // folderPath: destinationCollectionIndex, - // requestIndex: getRequestsByPath( - // restCollectionState.value, - // destinationCollectionIndex - // ).length, - // } + const requestHandle = requestHandleResult.right - // possibleTab.value.document.inheritedProperties = { - // auth, - // headers, - // } - // } + if (requestHandle.value.type === "invalid") { + // COLLECTION_INVALIDATED + return + } - // When it's drop it's basically getting deleted from last folder. reordering last folder accordingly - // resolveSaveContextOnRequestReorder({ - // lastIndex: pathToLastIndex(requestIndex), - // newIndex: -1, // being deleted from last folder - // folderPath, - // length: getRequestsByPath(myCollections.value, folderPath).length, - // }) - moveRESTRequest( - parentCollectionIndexPath, - pathToLastIndex(requestIndex), + const result = await workspaceService.moveRESTRequest( + requestHandle, destinationCollectionIndex ) + if (E.isLeft(result)) { + // INVALID_REQUEST_HANDLE + return + } + + const collectionHandleResult = await workspaceService.getCollectionHandle( + props.workspaceHandle, + destinationCollectionIndex + ) + + if (E.isLeft(collectionHandleResult)) { + // INVALID_WORKSPACE_HANDLE | INVALID_COLLECTION_ID | INVALID_PATH + return + } + + const collectionHandle = collectionHandleResult.right + + if (collectionHandle.value.type === "invalid") { + // WORKSPACE_INVALIDATED + return + } + + const cascadingAuthHeadersHandleResult = + await workspaceService.getRESTCollectionLevelAuthHeadersView( + collectionHandle + ) + + if (E.isLeft(cascadingAuthHeadersHandleResult)) { + // INVALID_COLLECTION_HANDLE + return + } + + const cascadingAuthHeadersHandle = cascadingAuthHeadersHandleResult.right + + if (cascadingAuthHeadersHandle.value.type === "invalid") { + // COLLECTION_INVALIDATED + return + } + + const { auth, headers } = cascadingAuthHeadersHandle.value.data + + const { collectionID, providerID, requestID, workspaceID } = + requestHandle.value.data + + const possibleTab = tabs.getTabRefWithSaveContext({ + originLocation: "workspace-user-collection", + workspaceID, + providerID, + collectionID, + requestID, + }) + + // If there is a tab attached to this request, update its save context + if (possibleTab) { + const newCollectionID = destinationCollectionIndex + const newRequestID = `${destinationCollectionIndex}/${( + getRequestsByPath(restCollectionState.value, destinationCollectionIndex) + .length - 1 + ).toString()}` + + possibleTab.value.document.saveContext = { + originLocation: "workspace-user-collection", + workspaceID, + providerID, + collectionID: newCollectionID, + requestID: newRequestID, + } + + possibleTab.value.document.inheritedProperties = { + auth, + headers, + } + } + + // When it's drop it's basically getting deleted from last folder. reordering last folder accordingly + resolveSaveContextOnRequestReorder({ + lastIndex: pathToLastIndex(requestIndex), + newIndex: -1, // being deleted from last folder + folderPath: parentCollectionIndexPath, + length: + getRequestsByPath(restCollectionState.value, parentCollectionIndexPath) + .length - 1, + }) + toast.success(`${t("request.moved")}`) - // draggingToRoot.value = false + draggingToRoot.value = false } -const dropCollection = (payload: { - collectionIndexDragged: string +const dropCollection = async (payload: { + draggedCollectionIndex: string destinationCollectionIndex: string }) => { - const { collectionIndexDragged, destinationCollectionIndex } = payload - if (!collectionIndexDragged || !destinationCollectionIndex) return - if (collectionIndexDragged === destinationCollectionIndex) return + const { draggedCollectionIndex, destinationCollectionIndex } = payload + + if ( + !draggedCollectionIndex || + !destinationCollectionIndex || + draggedCollectionIndex === destinationCollectionIndex + ) { + return + } if ( checkIfCollectionIsAParentOfTheChildren( - collectionIndexDragged, + draggedCollectionIndex, destinationCollectionIndex ) ) { @@ -1434,38 +1563,96 @@ const dropCollection = (payload: { //check if the collection is being moved to its own parent if ( - isMoveToSameLocation(collectionIndexDragged, destinationCollectionIndex) + isMoveToSameLocation(draggedCollectionIndex, destinationCollectionIndex) ) { return } - const parentFolder = collectionIndexDragged.split("/").slice(0, -1).join("/") // remove last folder to get parent folder + const parentFolder = draggedCollectionIndex.split("/").slice(0, -1).join("/") // remove last folder to get parent folder const totalFoldersOfDestinationCollection = getFoldersByPath(restCollectionState.value, destinationCollectionIndex) .length - (parentFolder === destinationCollectionIndex ? 1 : 0) - moveRESTFolder(collectionIndexDragged, destinationCollectionIndex) + const draggedCollectionHandleResult = + await workspaceService.getCollectionHandle( + props.workspaceHandle, + draggedCollectionIndex + ) - // resolveSaveContextOnCollectionReorder( - // { - // lastIndex: pathToLastIndex(collectionIndexDragged), - // newIndex: -1, - // folderPath: parentFolder, - // length: getFoldersByPath(restCollectionState.value, parentFolder).length, - // }, - // "drop" - // ) + if (E.isLeft(draggedCollectionHandleResult)) { + // INVALID_WORKSPACE_HANDLE | INVALID_COLLECTION_ID | INVALID_PATH + return + } - // updateSaveContextForAffectedRequests( - // collectionIndexDragged, - // `${destinationCollectionIndex}/${totalFoldersOfDestinationCollection}` - // ) + const draggedCollectionHandle = draggedCollectionHandleResult.right - const { auth, headers } = cascadeParentCollectionForHeaderAuth( - `${destinationCollectionIndex}/${totalFoldersOfDestinationCollection}`, - "rest" + if (draggedCollectionHandle.value.type === "invalid") { + // WORKSPACE_INVALIDATED + return + } + + const result = await workspaceService.moveRESTCollection( + draggedCollectionHandle, + destinationCollectionIndex ) + if (E.isLeft(result)) { + // INVALID_COLLECTION_HANDLE + return + } + + resolveSaveContextOnCollectionReorder( + { + lastIndex: pathToLastIndex(draggedCollectionIndex), + newIndex: -1, + folderPath: parentFolder, + length: getFoldersByPath(restCollectionState.value, parentFolder).length, + }, + "drop" + ) + + updateSaveContextForAffectedRequests( + draggedCollectionIndex, + `${destinationCollectionIndex}/${totalFoldersOfDestinationCollection}` + ) + + const destinationCollectionHandleResult = + await workspaceService.getCollectionHandle( + props.workspaceHandle, + destinationCollectionIndex + ) + + if (E.isLeft(destinationCollectionHandleResult)) { + // INVALID_WORKSPACE_HANDLE | INVALID_COLLECTION_ID | INVALID_PATH + return + } + + const destinationCollectionHandle = destinationCollectionHandleResult.right + + if (destinationCollectionHandle.value.type === "invalid") { + // WORKSPACE_INVALIDATED + return + } + + const cascadingAuthHeadersHandleResult = + await workspaceService.getRESTCollectionLevelAuthHeadersView( + destinationCollectionHandle + ) + + if (E.isLeft(cascadingAuthHeadersHandleResult)) { + // INVALID_COLLECTION_HANDLE + return + } + + const cascadingAuthHeadersHandle = cascadingAuthHeadersHandleResult.right + + if (cascadingAuthHeadersHandle.value.type === "invalid") { + // COLLECTION_INVALIDATED + return + } + + const { auth, headers } = cascadingAuthHeadersHandle.value.data + const inheritedProperty = { auth, headers, @@ -1477,50 +1664,75 @@ const dropCollection = (payload: { "rest" ) - // draggingToRoot.value = false + draggingToRoot.value = false toast.success(`${t("collection.moved")}`) } -const updateRequestOrder = ( +const updateRequestOrder = async ( dataTransfer: DataTransfer, { parentCollectionIndexPath, requestIndex, }: { parentCollectionIndexPath: string | null; requestIndex: string | null } ) => { - if (!parentCollectionIndexPath) return - const dragedRequestIndex = dataTransfer.getData("requestIndex") + if (!parentCollectionIndexPath) { + return + } + + const draggedRequestIndex = dataTransfer.getData("requestIndex") const destinationRequestIndex = requestIndex const destinationCollectionIndex = parentCollectionIndexPath if ( - !dragedRequestIndex || + !draggedRequestIndex || !destinationCollectionIndex || - dragedRequestIndex === destinationRequestIndex + draggedRequestIndex === destinationRequestIndex ) { return } if ( !isSameSameParent( - dragedRequestIndex, + draggedRequestIndex, destinationRequestIndex, destinationCollectionIndex ) ) { - toast.error(`${t("collection.different_parent")}`) - } else { - updateRESTRequestOrder( - pathToLastIndex(dragedRequestIndex), - destinationRequestIndex ? pathToLastIndex(destinationRequestIndex) : null, - destinationCollectionIndex - ) - - toast.success(`${t("request.order_changed")}`) + return toast.error(`${t("collection.different_parent")}`) } + + const requestHandleResult = await workspaceService.getRequestHandle( + props.workspaceHandle, + draggedRequestIndex + ) + + if (E.isLeft(requestHandleResult)) { + // INVALID_COLLECTION_HANDLE | INVALID_REQUEST_ID | REQUEST_NOT_FOUND + return + } + + const requestHandle = requestHandleResult.right + + if (requestHandle.value.type === "invalid") { + // COLLECTION_INVALIDATED + return + } + + const result = await workspaceService.reorderRESTRequest( + requestHandle, + destinationCollectionIndex, + destinationRequestIndex + ) + + if (E.isLeft(result)) { + // INVALID_REQUEST_HANDLE + return + } + + toast.success(`${t("request.order_changed")}`) } -const updateCollectionOrder = ( +const updateCollectionOrder = async ( dataTransfer: DataTransfer, destinationCollection: { destinationCollectionIndex: string | null @@ -1546,21 +1758,43 @@ const updateCollectionOrder = ( destinationCollectionParentIndex ) ) { - toast.error(`${t("collection.different_parent")}`) - } else { - updateRESTCollectionOrder( - draggedCollectionIndex, - destinationCollectionIndex - ) - // resolveSaveContextOnCollectionReorder({ - // lastIndex: pathToLastIndex(draggedCollectionIndex), - // newIndex: pathToLastIndex( - // destinationCollectionIndex ? destinationCollectionIndex : "" - // ), - // folderPath: draggedCollectionIndex.split("/").slice(0, -1).join("/"), - // }) - toast.success(`${t("collection.order_changed")}`) + return toast.error(`${t("collection.different_parent")}`) } + + const collectionHandleResult = await workspaceService.getCollectionHandle( + props.workspaceHandle, + draggedCollectionIndex + ) + + if (E.isLeft(collectionHandleResult)) { + // INVALID_WORKSPACE_HANDLE | INVALID_COLLECTION_ID | INVALID_PATH + return + } + + const collectionHandle = collectionHandleResult.right + + if (collectionHandle.value.type === "invalid") { + // WORKSPACE_INVALIDATED + return + } + + const result = await workspaceService.reorderRESTCollection( + collectionHandle, + destinationCollectionIndex + ) + + if (E.isLeft(result)) { + // INVALID_COLLECTION_HANDLE + return + } + + resolveSaveContextOnCollectionReorder({ + lastIndex: pathToLastIndex(draggedCollectionIndex), + newIndex: pathToLastIndex(destinationCollectionIndex ?? ""), + folderPath: draggedCollectionIndex.split("/").slice(0, -1).join("/"), + }) + + toast.success(`${t("collection.order_changed")}`) } const shareRequest = (request: HoppRESTRequest) => { @@ -1579,15 +1813,15 @@ const shareRequest = (request: HoppRESTRequest) => { /** * Used to check if the collection exist as the parent of the childrens - * @param collectionIndexDragged The index of the collection dragged + * @param draggedCollectionIndex The index of the collection dragged * @param destinationCollectionIndex The index of the destination collection * @returns True if the collection exist as the parent of the childrens */ const checkIfCollectionIsAParentOfTheChildren = ( - collectionIndexDragged: string, + draggedCollectionIndex: string, destinationCollectionIndex: string ) => { - const collectionDraggedPath = pathToIndex(collectionIndexDragged) + const collectionDraggedPath = pathToIndex(draggedCollectionIndex) const destinationCollectionPath = pathToIndex(destinationCollectionIndex) if (collectionDraggedPath.length < destinationCollectionPath.length) { @@ -1701,9 +1935,9 @@ const isSameSameParent = ( draggedItemIndex.length !== 1 && destinationCollectionIndex !== null ) { - const dragedItemParent = draggedItemIndex.slice(0, -1) + const draggedItemParent = draggedItemIndex.slice(0, -1) - return dragedItemParent.join("/") === destinationCollectionIndex + return draggedItemParent.join("/") === destinationCollectionIndex } if (destinationItemPath === null) return false const destinationItemIndex = pathToIndex(destinationItemPath) @@ -1712,9 +1946,9 @@ const isSameSameParent = ( if (draggedItemIndex.length === 1 && destinationItemIndex.length === 1) { return true } else if (draggedItemIndex.length === destinationItemIndex.length) { - const dragedItemParent = draggedItemIndex.slice(0, -1) + const draggedItemParent = draggedItemIndex.slice(0, -1) const destinationItemParent = destinationItemIndex.slice(0, -1) - if (isEqual(dragedItemParent, destinationItemParent)) { + if (isEqual(draggedItemParent, destinationItemParent)) { return true } return false diff --git a/packages/hoppscotch-common/src/helpers/collection/collection.ts b/packages/hoppscotch-common/src/helpers/collection/collection.ts index 59f25cb62..814c3ec32 100644 --- a/packages/hoppscotch-common/src/helpers/collection/collection.ts +++ b/packages/hoppscotch-common/src/helpers/collection/collection.ts @@ -87,10 +87,15 @@ export function resolveSaveContextOnCollectionReorder( tab.value.document.saveContext?.originLocation === "workspace-user-collection" ) { - const newPath = affectedPaths.get( + const newCollectionID = affectedPaths.get( tab.value.document.saveContext?.collectionID )! - tab.value.document.saveContext.collectionID = newPath + const newRequestID = `${newCollectionID}/${ + tab.value.document.saveContext.requestID.split("/").slice(-1)[0] + }` + + tab.value.document.saveContext.collectionID = newCollectionID + tab.value.document.saveContext.requestID = newRequestID } } } @@ -134,12 +139,19 @@ export function updateSaveContextForAffectedRequests( tab.value.document.saveContext?.originLocation === "workspace-user-collection" ) { - tab.value.document.saveContext = { - ...tab.value.document.saveContext, - collectionID: tab.value.document.saveContext.collectionID.replace( + const newCollectionID = + tab.value.document.saveContext.collectionID.replace( oldFolderPath, newFolderPath - ), + ) + const newRequestID = `${newCollectionID}/${ + tab.value.document.saveContext.requestID.split("/").slice(-1)[0] + }` + + tab.value.document.saveContext = { + ...tab.value.document.saveContext, + collectionID: newCollectionID, + requestID: newRequestID, } } } diff --git a/packages/hoppscotch-common/src/helpers/collection/request.ts b/packages/hoppscotch-common/src/helpers/collection/request.ts index 300c5963c..642c37bb0 100644 --- a/packages/hoppscotch-common/src/helpers/collection/request.ts +++ b/packages/hoppscotch-common/src/helpers/collection/request.ts @@ -63,6 +63,19 @@ export function resolveSaveContextOnRequestReorder(payload: { )! tab.value.document.saveContext.requestIndex = newIndex } + + if ( + tab.value.document.saveContext?.originLocation === + "workspace-user-collection" + ) { + const requestID = tab.value.document.saveContext.requestID + const requestIDArray = requestID.split("/") + const requestIndex = affectedIndexes.get( + parseInt(requestIDArray[requestIDArray.length - 1]) + )! + requestIDArray[requestIDArray.length - 1] = requestIndex.toString() + tab.value.document.saveContext.requestID = requestIDArray.join("/") + } } } diff --git a/packages/hoppscotch-common/src/services/new-workspace/index.ts b/packages/hoppscotch-common/src/services/new-workspace/index.ts index 9413207e1..448b640c3 100644 --- a/packages/hoppscotch-common/src/services/new-workspace/index.ts +++ b/packages/hoppscotch-common/src/services/new-workspace/index.ts @@ -478,7 +478,7 @@ export class NewWorkspaceService extends Service { public async reorderRESTCollection( collectionHandle: HandleRef, - destinationCollectionIndex: string + destinationCollectionIndex: string | null ): Promise< E.Either, void> > { @@ -508,7 +508,7 @@ export class NewWorkspaceService extends Service { public async moveRESTCollection( collectionHandle: HandleRef, - destinationCollectionIndex: string + destinationCollectionIndex: string | null ): Promise< E.Either, void> > { @@ -538,8 +538,8 @@ export class NewWorkspaceService extends Service { public async reorderRESTRequest( requestHandle: HandleRef, - destinationRequestIndex: string, - destinationCollectionIndex: string + destinationCollectionIndex: string, + destinationRequestIndex: string | null ): Promise< E.Either, void> > { @@ -557,8 +557,8 @@ export class NewWorkspaceService extends Service { const result = await provider.reorderRESTRequest( requestHandle, - destinationRequestIndex, - destinationCollectionIndex + destinationCollectionIndex, + destinationRequestIndex ) if (E.isLeft(result)) { diff --git a/packages/hoppscotch-common/src/services/new-workspace/provider.ts b/packages/hoppscotch-common/src/services/new-workspace/provider.ts index 99a5a43a2..34de31035 100644 --- a/packages/hoppscotch-common/src/services/new-workspace/provider.ts +++ b/packages/hoppscotch-common/src/services/new-workspace/provider.ts @@ -83,7 +83,7 @@ export interface WorkspaceProvider { reorderRESTCollection( collectionHandle: HandleRef, - destinationCollectionIndex: string + destinationCollectionIndex: string | null ): Promise> moveRESTCollection( collectionHandle: HandleRef, @@ -91,8 +91,8 @@ export interface WorkspaceProvider { ): Promise> reorderRESTRequest( requestHandle: HandleRef, - destinationRequestIndex: string, - destinationCollectionIndex: string + destinationCollectionIndex: string, + destinationRequestIndex: string | null ): Promise> moveRESTRequest( requestHandle: HandleRef, diff --git a/packages/hoppscotch-common/src/services/new-workspace/providers/personal.workspace.ts b/packages/hoppscotch-common/src/services/new-workspace/providers/personal.workspace.ts index afdec1ee4..53545b314 100644 --- a/packages/hoppscotch-common/src/services/new-workspace/providers/personal.workspace.ts +++ b/packages/hoppscotch-common/src/services/new-workspace/providers/personal.workspace.ts @@ -16,7 +16,6 @@ import { addRESTCollection, addRESTFolder, appendRESTCollections, - cascadeParentCollectionForHeaderAuth, editRESTCollection, editRESTFolder, editRESTRequest, @@ -52,20 +51,10 @@ import { HoppRESTRequest } from "@hoppscotch/data" import { merge } from "lodash-es" import path from "path" import { HoppGQLHeader } from "~/helpers/graphql" +import { initializeDownloadFile } from "~/helpers/import-export/export" import { HoppInheritedProperty } from "~/helpers/types/HoppInheritedProperties" import IconUser from "~icons/lucide/user" import { NewWorkspaceService } from ".." -import { initializeDownloadFile } from "~/helpers/import-export/export" -import { - getFoldersByPath, - resolveSaveContextOnCollectionReorder, - updateInheritedPropertiesForAffectedRequests, - updateSaveContextForAffectedRequests, -} from "~/helpers/collection/collection" -import { - getRequestsByPath, - resolveSaveContextOnRequestReorder, -} from "~/helpers/collection/request" export class PersonalWorkspaceProviderService extends Service @@ -492,7 +481,7 @@ export class PersonalWorkspaceProviderService public reorderRESTCollection( collectionHandle: HandleRef, - destinationCollectionIndex: string + destinationCollectionIndex: string | null ): Promise> { if ( collectionHandle.value.type !== "ok" || @@ -508,11 +497,6 @@ export class PersonalWorkspaceProviderService draggedCollectionIndex, destinationCollectionIndex ) - resolveSaveContextOnCollectionReorder({ - lastIndex: this.pathToLastIndex(draggedCollectionIndex), - newIndex: this.pathToLastIndex(destinationCollectionIndex ?? ""), - folderPath: draggedCollectionIndex.split("/").slice(0, -1).join("/"), - }) return Promise.resolve(E.right(undefined)) } @@ -529,64 +513,18 @@ export class PersonalWorkspaceProviderService return Promise.resolve(E.left("INVALID_COLLECTION_HANDLE" as const)) } - const draggedCollectionIndex = collectionHandle.value.data.collectionID - - moveRESTFolder(draggedCollectionIndex, destinationCollectionIndex) - - if (destinationCollectionIndex === null) { - return Promise.resolve(E.right(undefined)) - } - - const parentFolder = draggedCollectionIndex - .split("/") - .slice(0, -1) - .join("/") // remove last folder to get parent folder - - const totalFoldersOfDestinationCollection = - getFoldersByPath( - restCollectionStore.value.state, - destinationCollectionIndex - ).length - (parentFolder === destinationCollectionIndex ? 1 : 0) - - resolveSaveContextOnCollectionReorder( - { - lastIndex: this.pathToLastIndex(draggedCollectionIndex), - newIndex: -1, - folderPath: parentFolder, - length: getFoldersByPath(restCollectionStore.value.state, parentFolder) - .length, - }, - "drop" + moveRESTFolder( + collectionHandle.value.data.collectionID, + destinationCollectionIndex ) - updateSaveContextForAffectedRequests( - draggedCollectionIndex, - `${destinationCollectionIndex}/${totalFoldersOfDestinationCollection}` - ) - - // const { auth, headers } = cascadeParentCollectionForHeaderAuth( - // `${destinationCollectionIndex}/${totalFoldersOfDestinationCollection}`, - // "rest" - // ) - - // const inheritedProperty = { - // auth, - // headers, - // } - - // updateInheritedPropertiesForAffectedRequests( - // `${destinationCollectionIndex}/${totalFoldersOfDestinationCollection}`, - // inheritedProperty, - // "rest" - // ) - return Promise.resolve(E.right(undefined)) } public reorderRESTRequest( requestHandle: HandleRef, destinationCollectionIndex: string, - destinationRequestIndex: string + destinationRequestIndex: string | null ): Promise> { if ( requestHandle.value.type !== "ok" || @@ -627,45 +565,6 @@ export class PersonalWorkspaceProviderService .slice(0, -1) .join("/") - // const { auth, headers } = cascadeParentCollectionForHeaderAuth( - // destinationCollectionIndex, - // "rest" - // ) - - // const possibleTab = tabs.getTabRefWithSaveContext({ - // originLocation: "user-collection", - // folderPath: parentCollectionIndexPath, - // requestIndex: this.pathToLastIndex(requestIndex), - // }) - - // // If there is a tab attached to this request, change save its save context - // if (possibleTab) { - // possibleTab.value.document.saveContext = { - // originLocation: "user-collection", - // folderPath: destinationCollectionIndex, - // requestIndex: getRequestsByPath( - // restCollectionStore.value.state, - // destinationCollectionIndex - // ).length, - // } - - // possibleTab.value.document.inheritedProperties = { - // auth, - // headers, - // } - // } - - // // When it's drop it's basically getting deleted from last folder. reordering last folder accordingly - // resolveSaveContextOnRequestReorder({ - // lastIndex: this.pathToLastIndex(requestIndex), - // newIndex: -1, // being deleted from last folder - // folderPath: parentCollectionIndexPath, - // length: getRequestsByPath( - // restCollectionStore.value.state, - // parentCollectionIndexPath - // ).length, - // }) - moveRESTRequest( parentCollectionIndexPath, this.pathToLastIndex(requestIndex), @@ -924,7 +823,7 @@ export class PersonalWorkspaceProviderService isLastItem: id === this.restCollectionState.value.state.length - 1, name: coll.name, - parentIndex: null, + parentCollectionID: null, } }) }),