chore: handle moving & removing tags with subtags into/out of vaults (#2528)
This commit is contained in:
@@ -116,6 +116,7 @@ export interface ItemManagerInterface extends AbstractService {
|
|||||||
getNoteCount(): number
|
getNoteCount(): number
|
||||||
getDisplayableTags(): SNTag[]
|
getDisplayableTags(): SNTag[]
|
||||||
getTagChildren(itemToLookupUuidFor: SNTag): SNTag[]
|
getTagChildren(itemToLookupUuidFor: SNTag): SNTag[]
|
||||||
|
getDeepTagChildren(itemToLookupUuidFor: SNTag): SNTag[]
|
||||||
getTagParent(itemToLookupUuidFor: SNTag): SNTag | undefined
|
getTagParent(itemToLookupUuidFor: SNTag): SNTag | undefined
|
||||||
getDisplayableTagParent(itemToLookupUuidFor: SNTag): SNTag | undefined
|
getDisplayableTagParent(itemToLookupUuidFor: SNTag): SNTag | undefined
|
||||||
isValidTagParent(parentTagToLookUpUuidFor: SNTag, childToLookUpUuidFor: SNTag): boolean
|
isValidTagParent(parentTagToLookUpUuidFor: SNTag, childToLookUpUuidFor: SNTag): boolean
|
||||||
|
|||||||
@@ -8,11 +8,13 @@ import {
|
|||||||
IconType,
|
IconType,
|
||||||
KeySystemIdentifier,
|
KeySystemIdentifier,
|
||||||
KeySystemRootKeyStorageMode,
|
KeySystemRootKeyStorageMode,
|
||||||
|
SNTag,
|
||||||
SharedVaultListingInterface,
|
SharedVaultListingInterface,
|
||||||
VaultListingInterface,
|
VaultListingInterface,
|
||||||
VaultListingMutator,
|
VaultListingMutator,
|
||||||
isFile,
|
isFile,
|
||||||
isNote,
|
isNote,
|
||||||
|
isTag,
|
||||||
} from '@standardnotes/models'
|
} from '@standardnotes/models'
|
||||||
import { VaultServiceInterface } from './VaultServiceInterface'
|
import { VaultServiceInterface } from './VaultServiceInterface'
|
||||||
import { ChangeVaultKeyOptionsDTO } from './UseCase/ChangeVaultKeyOptionsDTO'
|
import { ChangeVaultKeyOptionsDTO } from './UseCase/ChangeVaultKeyOptionsDTO'
|
||||||
@@ -161,20 +163,39 @@ export class VaultService
|
|||||||
})
|
})
|
||||||
|
|
||||||
if (areAnyLinkedItemsInOtherVaults) {
|
if (areAnyLinkedItemsInOtherVaults) {
|
||||||
|
const reason =
|
||||||
|
'This item is linked to other items that are not in the same vault. Please move those items to this vault first.'
|
||||||
this.alerts
|
this.alerts
|
||||||
.alertV2({
|
.alertV2({
|
||||||
title: 'Cannot move item to vault',
|
title: 'Cannot move item to vault',
|
||||||
text: 'This item is linked to other items that are not in the same vault. Please move those items to this vault first.',
|
text: reason,
|
||||||
})
|
})
|
||||||
.catch(console.error)
|
.catch(console.error)
|
||||||
|
return Result.fail(reason)
|
||||||
return Result.fail(
|
|
||||||
'This item is linked to other items that are not in the same vault. Please move those items to this vault first.',
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await this._moveItemsToVault.execute({ vault, items: [item] })
|
let moveableSubtags: SNTag[] = []
|
||||||
|
if (isTag(item)) {
|
||||||
|
const deepSubtags = this.items.getDeepTagChildren(item)
|
||||||
|
const anySubtagIsInOtherVault = deepSubtags.some((subtag) => {
|
||||||
|
return subtag.key_system_identifier && subtag.key_system_identifier !== vault.systemIdentifier
|
||||||
|
})
|
||||||
|
if (anySubtagIsInOtherVault) {
|
||||||
|
const reason =
|
||||||
|
'One or more subtags are in other vaults. Please remove those subtags from the vaults or move them to this vault first.'
|
||||||
|
this.alerts
|
||||||
|
.alertV2({
|
||||||
|
title: 'Cannot move item to vault',
|
||||||
|
text: reason,
|
||||||
|
})
|
||||||
|
.catch(console.error)
|
||||||
|
return Result.fail(reason)
|
||||||
|
}
|
||||||
|
moveableSubtags = deepSubtags
|
||||||
|
}
|
||||||
|
|
||||||
|
await this._moveItemsToVault.execute({ vault, items: [item, ...moveableSubtags] })
|
||||||
|
|
||||||
return Result.ok(this.items.findSureItem(item.uuid))
|
return Result.ok(this.items.findSureItem(item.uuid))
|
||||||
}
|
}
|
||||||
@@ -189,6 +210,13 @@ export class VaultService
|
|||||||
throw new Error('Attempting to remove item from locked vault')
|
throw new Error('Attempting to remove item from locked vault')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isTag(item)) {
|
||||||
|
const deepSubtags = this.items.getDeepTagChildren(item)
|
||||||
|
for (const subtag of deepSubtags) {
|
||||||
|
await this._removeItemFromVault.execute({ item: subtag })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
await this._removeItemFromVault.execute({ item })
|
await this._removeItemFromVault.execute({ item })
|
||||||
return this.items.findSureItem(item.uuid)
|
return this.items.findSureItem(item.uuid)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -702,6 +702,18 @@ export class ItemManager extends Services.AbstractService implements Services.It
|
|||||||
return tags.filter((tag) => tag.parentId === itemToLookupUuidFor.uuid)
|
return tags.filter((tag) => tag.parentId === itemToLookupUuidFor.uuid)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getDeepTagChildren(itemToLookupUuidFor: Models.SNTag): Models.SNTag[] {
|
||||||
|
const allChildren: Models.SNTag[] = []
|
||||||
|
|
||||||
|
const children = this.getTagChildren(itemToLookupUuidFor)
|
||||||
|
for (const child of children) {
|
||||||
|
allChildren.push(child)
|
||||||
|
allChildren.push(...this.getDeepTagChildren(child))
|
||||||
|
}
|
||||||
|
|
||||||
|
return allChildren
|
||||||
|
}
|
||||||
|
|
||||||
public isTagAncestor(tagToLookUpUuidFor: Models.SNTag, childToLookUpUuidFor: Models.SNTag): boolean {
|
public isTagAncestor(tagToLookUpUuidFor: Models.SNTag, childToLookUpUuidFor: Models.SNTag): boolean {
|
||||||
const tag = this.findItem<Models.SNTag>(childToLookUpUuidFor.uuid)
|
const tag = this.findItem<Models.SNTag>(childToLookUpUuidFor.uuid)
|
||||||
if (!tag) {
|
if (!tag) {
|
||||||
|
|||||||
Reference in New Issue
Block a user