refactor: handle based updates post collection move
This commit is contained in:
@@ -1569,10 +1569,10 @@ const dropToRoot = async ({ dataTransfer }: DragEvent) => {
|
||||
restCollectionState.value.length - 1
|
||||
).toString()
|
||||
|
||||
updateSaveContextForAffectedRequests(
|
||||
draggedCollectionIndex,
|
||||
destinationRootCollectionIndex
|
||||
)
|
||||
// updateSaveContextForAffectedRequests(
|
||||
// draggedCollectionIndex,
|
||||
// destinationRootCollectionIndex
|
||||
// )
|
||||
|
||||
const destinationRootCollectionHandleResult =
|
||||
await workspaceService.getCollectionHandle(
|
||||
@@ -1808,43 +1808,43 @@ const dropCollection = async (payload: {
|
||||
// Hence, we need to reduce the destination root collection index by 1
|
||||
// This only applies to the case when the destination collection lies below the dragged collection
|
||||
|
||||
let resolvedDestinationCollectionIndex = destinationCollectionIndex
|
||||
// let resolvedDestinationCollectionIndex = destinationCollectionIndex
|
||||
|
||||
const draggedRootCollectionIndex = parseInt(
|
||||
pathToIndex(draggedCollectionIndex)[0]
|
||||
)
|
||||
const destinationRootCollectionIndex = parseInt(
|
||||
pathToIndex(destinationCollectionIndex)[0]
|
||||
)
|
||||
// const draggedRootCollectionIndex = parseInt(
|
||||
// pathToIndex(draggedCollectionIndex)[0]
|
||||
// )
|
||||
// const destinationRootCollectionIndex = parseInt(
|
||||
// pathToIndex(destinationCollectionIndex)[0]
|
||||
// )
|
||||
|
||||
if (
|
||||
isAlreadyInRoot(draggedCollectionIndex) &&
|
||||
destinationRootCollectionIndex > draggedRootCollectionIndex
|
||||
) {
|
||||
resolvedDestinationCollectionIndex = `${
|
||||
destinationRootCollectionIndex - 1
|
||||
}/${pathToIndex(destinationCollectionIndex).slice(1).join("/")}`
|
||||
// if (
|
||||
// isAlreadyInRoot(draggedCollectionIndex) &&
|
||||
// destinationRootCollectionIndex > draggedRootCollectionIndex
|
||||
// ) {
|
||||
// resolvedDestinationCollectionIndex = `${
|
||||
// destinationRootCollectionIndex - 1
|
||||
// }/${pathToIndex(destinationCollectionIndex).slice(1).join("/")}`
|
||||
|
||||
resolvedDestinationCollectionIndex =
|
||||
resolvedDestinationCollectionIndex.endsWith("/")
|
||||
? resolvedDestinationCollectionIndex.slice(0, -1)
|
||||
: resolvedDestinationCollectionIndex
|
||||
}
|
||||
// resolvedDestinationCollectionIndex =
|
||||
// resolvedDestinationCollectionIndex.endsWith("/")
|
||||
// ? resolvedDestinationCollectionIndex.slice(0, -1)
|
||||
// : resolvedDestinationCollectionIndex
|
||||
// }
|
||||
|
||||
resolveSaveContextOnCollectionReorder({
|
||||
lastIndex: pathToLastIndex(draggedCollectionIndex),
|
||||
newIndex: -1,
|
||||
folderPath: draggedParentCollectionIndex,
|
||||
length: getFoldersByPath(
|
||||
restCollectionState.value,
|
||||
draggedParentCollectionIndex
|
||||
).length,
|
||||
})
|
||||
// resolveSaveContextOnCollectionReorder({
|
||||
// lastIndex: pathToLastIndex(draggedCollectionIndex),
|
||||
// newIndex: -1,
|
||||
// folderPath: draggedParentCollectionIndex,
|
||||
// length: getFoldersByPath(
|
||||
// restCollectionState.value,
|
||||
// draggedParentCollectionIndex
|
||||
// ).length,
|
||||
// })
|
||||
|
||||
updateSaveContextForAffectedRequests(
|
||||
draggedCollectionIndex,
|
||||
`${resolvedDestinationCollectionIndex}/${totalChildCollectionsInDestinationCollection}`
|
||||
)
|
||||
// updateSaveContextForAffectedRequests(
|
||||
// draggedCollectionIndex,
|
||||
// `${resolvedDestinationCollectionIndex}/${totalChildCollectionsInDestinationCollection}`
|
||||
// )
|
||||
|
||||
const destinationCollectionHandleResult =
|
||||
await workspaceService.getCollectionHandle(
|
||||
|
||||
@@ -12,6 +12,7 @@ export type HoppRESTSaveContext =
|
||||
* The origin source of the request
|
||||
*/
|
||||
// TODO: Make this `user-collection` after porting all usages
|
||||
// Future TODO: Keep separate types for the IDs (specific to persistence) & `requestHandle` (only existing at runtime)
|
||||
originLocation: "workspace-user-collection"
|
||||
/**
|
||||
* ID of the workspace
|
||||
|
||||
@@ -295,7 +295,7 @@ const onResolveConfirmSaveTab = () => {
|
||||
if (
|
||||
!saveContext ||
|
||||
(saveContext.originLocation === "workspace-user-collection" &&
|
||||
saveContext.requestHandle?.value.type === "invalid")
|
||||
saveContext.requestHandle?.get().value.type === "invalid")
|
||||
) {
|
||||
return (savingRequest.value = true)
|
||||
}
|
||||
@@ -331,7 +331,7 @@ const getTabDirtyStatus = (tab: HoppTab<HoppRESTDocument>) => {
|
||||
|
||||
return (
|
||||
tab.document.saveContext?.originLocation === "workspace-user-collection" &&
|
||||
tab.document.saveContext.requestHandle?.value.type === "invalid"
|
||||
tab.document.saveContext.requestHandle?.get().value.type === "invalid"
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -120,6 +120,8 @@ export class PersonalWorkspaceProviderService
|
||||
this.workspaceService.registerWorkspaceProvider(this)
|
||||
}
|
||||
|
||||
// TODO: Move the below out of provider definitions as generic helper functions
|
||||
|
||||
/**
|
||||
* Used to get the index of the request from the path
|
||||
* @param path The path of the request
|
||||
@@ -130,6 +132,25 @@ export class PersonalWorkspaceProviderService
|
||||
return parseInt(pathArr[pathArr.length - 1])
|
||||
}
|
||||
|
||||
/**
|
||||
* @param path The path of the collection or request
|
||||
* @returns The index of the collection or request
|
||||
*/
|
||||
private pathToIndex(path: string) {
|
||||
const pathArr = path.split("/")
|
||||
return pathArr
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the collection is already in the root
|
||||
* @param id - path of the collection
|
||||
* @returns boolean - true if the collection is already in the root
|
||||
*/
|
||||
private isAlreadyInRoot(id: string) {
|
||||
const indexPath = this.pathToIndex(id)
|
||||
return indexPath.length === 1
|
||||
}
|
||||
|
||||
public createRESTRootCollection(
|
||||
workspaceHandle: Handle<Workspace>,
|
||||
newCollection: Partial<Exclude<HoppCollection, "id">> & { name: string }
|
||||
@@ -665,12 +686,165 @@ export class PersonalWorkspaceProviderService
|
||||
) {
|
||||
return Promise.resolve(E.left("INVALID_COLLECTION_HANDLE" as const))
|
||||
}
|
||||
const { collectionID: draggedCollectionID } = collectionHandleRef.value.data
|
||||
|
||||
const draggedParentCollectionID = this.isAlreadyInRoot(draggedCollectionID)
|
||||
? draggedCollectionID
|
||||
: draggedCollectionID.split("/").slice(0, -1).join("/")
|
||||
|
||||
const isMoveToSiblingCollection = this.isAlreadyInRoot(draggedCollectionID)
|
||||
? this.isAlreadyInRoot(
|
||||
destinationCollectionID === null
|
||||
? // Move to root
|
||||
this.restCollectionState.value.state.length.toString()
|
||||
: destinationCollectionID
|
||||
)
|
||||
: !!destinationCollectionID?.startsWith(draggedParentCollectionID)
|
||||
|
||||
const draggedCollectionIndexPos = this.pathToLastIndex(draggedCollectionID)
|
||||
|
||||
let resolvedDestinationCollectionID = ""
|
||||
|
||||
if (destinationCollectionID === null) {
|
||||
// destinationCollectionID` being `null` indicates moving to root
|
||||
// New ID will be the length of the root nodes at this point (before the store update)
|
||||
resolvedDestinationCollectionID =
|
||||
this.restCollectionState.value.state.length.toString()
|
||||
} else {
|
||||
// Move to an inner-level collection
|
||||
const destinationCollectionIndexPos = this.pathToLastIndex(
|
||||
destinationCollectionID
|
||||
)
|
||||
|
||||
// The count of child collections within the destination collection will be the new index position
|
||||
// Appended to the `resolvedDestinationCollectionID`
|
||||
const resolvedDestinationCollectionIndexPos = getFoldersByPath(
|
||||
this.restCollectionState.value.state,
|
||||
destinationCollectionID
|
||||
).length
|
||||
|
||||
// Indicates a move from a collection at the top to a sibling collection below it
|
||||
if (
|
||||
isMoveToSiblingCollection &&
|
||||
destinationCollectionIndexPos > draggedCollectionIndexPos
|
||||
) {
|
||||
const draggedCollectionIDStrLength =
|
||||
draggedCollectionID.split("/").length
|
||||
|
||||
// Obtain a subset of the destination collection ID till the dragged collection ID string length
|
||||
// Only update the index position at the level of the dragged collection
|
||||
// This ensures moves to deeply any nested collections are accounted
|
||||
const destinationCollectionIDSubset = destinationCollectionID
|
||||
.split("/")
|
||||
.slice(0, draggedCollectionIDStrLength)
|
||||
.join("/")
|
||||
|
||||
// Reduce `1` from the index position to account for the dragged collection
|
||||
// Dragged collection doesn't exist anymore at the previous level
|
||||
const collectionIDSubsetIndexPos = Number(
|
||||
this.pathToLastIndex(destinationCollectionIDSubset) - 1
|
||||
)
|
||||
|
||||
// Replace the destination collection ID with `1` reduced from the index position
|
||||
const replacedDestinationCollectionID = destinationCollectionID.replace(
|
||||
destinationCollectionIDSubset,
|
||||
`${destinationCollectionIDSubset
|
||||
.split("/")
|
||||
.slice(0, -1)
|
||||
.join("/")}/${collectionIDSubsetIndexPos}`
|
||||
)
|
||||
|
||||
const resolvedDestinationCollectionIDPrefix = this.isAlreadyInRoot(
|
||||
draggedCollectionID
|
||||
)
|
||||
? collectionIDSubsetIndexPos
|
||||
: replacedDestinationCollectionID
|
||||
|
||||
resolvedDestinationCollectionID = `${resolvedDestinationCollectionIDPrefix}/${resolvedDestinationCollectionIndexPos}`
|
||||
} else {
|
||||
resolvedDestinationCollectionID = `${destinationCollectionID}/${resolvedDestinationCollectionIndexPos}`
|
||||
}
|
||||
}
|
||||
|
||||
const draggedParentCollectionSize = this.isAlreadyInRoot(
|
||||
draggedCollectionID
|
||||
)
|
||||
? this.restCollectionState.value.state.length
|
||||
: getFoldersByPath(
|
||||
this.restCollectionState.value.state,
|
||||
draggedParentCollectionID
|
||||
).length
|
||||
|
||||
const affectedParentCollectionIDRange =
|
||||
draggedParentCollectionSize - 1 - draggedCollectionIndexPos
|
||||
|
||||
moveRESTFolder(
|
||||
collectionHandleRef.value.data.collectionID,
|
||||
destinationCollectionID
|
||||
)
|
||||
|
||||
this.issuedHandles.forEach((handle) => {
|
||||
if (handle.value.type === "invalid") {
|
||||
return
|
||||
}
|
||||
|
||||
if (!("requestID" in handle.value.data)) {
|
||||
return
|
||||
}
|
||||
|
||||
const { collectionID, requestID } = handle.value.data
|
||||
|
||||
const reqIndexPos = requestID.slice(-1)[0]
|
||||
|
||||
if (requestID.startsWith(draggedCollectionID)) {
|
||||
const newCollectionID = collectionID.replace(
|
||||
draggedCollectionID,
|
||||
resolvedDestinationCollectionID
|
||||
)
|
||||
|
||||
handle.value.data.collectionID = newCollectionID
|
||||
handle.value.data.requestID = `${newCollectionID}/${reqIndexPos}`
|
||||
}
|
||||
})
|
||||
|
||||
Array.from({ length: affectedParentCollectionIDRange }).forEach(
|
||||
(_, idx) => {
|
||||
// Adding `1` to dragged collection index position to get the affected collection index position
|
||||
const affectedCollectionIndexPos = draggedCollectionIndexPos + idx + 1
|
||||
|
||||
const affectedCollectionID = `${draggedParentCollectionID}/${affectedCollectionIndexPos}`
|
||||
|
||||
// The index position will be reduced by `1` for the affected collections
|
||||
const newAffectedCollectionID = `${draggedParentCollectionID}/${
|
||||
affectedCollectionIndexPos - 1
|
||||
}`
|
||||
|
||||
// For each affected collection, we'll have to iterate over the `issuedHandles` to account for nested collections
|
||||
this.issuedHandles.forEach((handle) => {
|
||||
if (
|
||||
handle.value.type === "invalid" ||
|
||||
!("requestID" in handle.value.data)
|
||||
) {
|
||||
return
|
||||
}
|
||||
|
||||
if (handle.value.data.requestID.startsWith(affectedCollectionID)) {
|
||||
const { collectionID, requestID } = handle.value.data
|
||||
|
||||
handle.value.data.collectionID = collectionID.replace(
|
||||
affectedCollectionID,
|
||||
newAffectedCollectionID
|
||||
)
|
||||
|
||||
handle.value.data.requestID = requestID.replace(
|
||||
affectedCollectionID,
|
||||
newAffectedCollectionID
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
)
|
||||
|
||||
return Promise.resolve(E.right(undefined))
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user