chore: make "move to vault" stricter if item has links (#2501)

This commit is contained in:
Aman Harwara
2023-09-15 15:46:57 +05:30
committed by GitHub
parent a3e1a1f366
commit daab6e12cf
3 changed files with 36 additions and 17 deletions

View File

@@ -87,7 +87,6 @@ export interface ItemManagerInterface extends AbstractService {
removeItemsFromMemory(items: AnyItemInterface[]): void removeItemsFromMemory(items: AnyItemInterface[]): void
getDirtyItems(): (DecryptedItemInterface | DeletedItemInterface)[] getDirtyItems(): (DecryptedItemInterface | DeletedItemInterface)[]
getTagLongTitle(tag: SNTag): string getTagLongTitle(tag: SNTag): string
getSortedTagsForItem(item: DecryptedItemInterface<ItemContent>): SNTag[]
itemsReferencingItem<I extends DecryptedItemInterface = DecryptedItemInterface>( itemsReferencingItem<I extends DecryptedItemInterface = DecryptedItemInterface>(
itemToLookupUuidFor: { uuid: string }, itemToLookupUuidFor: { uuid: string },
contentType?: string, contentType?: string,
@@ -130,6 +129,9 @@ export interface ItemManagerInterface extends AbstractService {
getDisplayableNotesAndFiles(): (SNNote | FileItem)[] getDisplayableNotesAndFiles(): (SNNote | FileItem)[]
setPrimaryItemDisplayOptions(options: NotesAndFilesDisplayControllerOptions): void setPrimaryItemDisplayOptions(options: NotesAndFilesDisplayControllerOptions): void
getTagPrefixTitle(tag: SNTag): string | undefined getTagPrefixTitle(tag: SNTag): string | undefined
getNoteLinkedFiles(note: SNNote): FileItem[] getItemLinkedFiles(item: DecryptedItemInterface): FileItem[]
getItemLinkedNotes(item: DecryptedItemInterface): SNNote[]
getSortedTagsForItem(item: DecryptedItemInterface<ItemContent>): SNTag[]
getUnsortedTagsForItem(item: DecryptedItemInterface<ItemContent>): SNTag[]
conflictsOf(uuid: string): AnyItemInterface[] conflictsOf(uuid: string): AnyItemInterface[]
} }

View File

@@ -5,13 +5,13 @@ import { isClientDisplayableError } from '@standardnotes/responses'
import { import {
DecryptedItemInterface, DecryptedItemInterface,
EmojiString, EmojiString,
FileItem,
IconType, IconType,
KeySystemIdentifier, KeySystemIdentifier,
KeySystemRootKeyStorageMode, KeySystemRootKeyStorageMode,
SharedVaultListingInterface, SharedVaultListingInterface,
VaultListingInterface, VaultListingInterface,
VaultListingMutator, VaultListingMutator,
isFile,
isNote, isNote,
} from '@standardnotes/models' } from '@standardnotes/models'
import { VaultServiceInterface } from './VaultServiceInterface' import { VaultServiceInterface } from './VaultServiceInterface'
@@ -151,22 +151,27 @@ export class VaultService
throw new Error('Attempting to add item to locked vault') throw new Error('Attempting to add item to locked vault')
} }
let linkedFiles: FileItem[] = [] if (isNote(item) || isFile(item)) {
if (isNote(item)) { const linkedFiles = this.items.getItemLinkedFiles(item)
linkedFiles = this.items.getNoteLinkedFiles(item) const linkedNotes = this.items.getItemLinkedNotes(item)
const linkedTags = this.items.getUnsortedTagsForItem(item)
if (linkedFiles.length > 0) { const areAnyLinkedItemsInOtherVaults = [...linkedFiles, ...linkedNotes, ...linkedTags].some((linkedItem) => {
const confirmed = await this.alerts.confirmV2({ return linkedItem.key_system_identifier !== vault.systemIdentifier
title: 'Linked files will be moved to vault', })
text: `This note has ${linkedFiles.length} linked files. They will also be moved to the vault. Do you want to continue?`,
}) if (areAnyLinkedItemsInOtherVaults) {
if (!confirmed) { this.alerts
return undefined .alertV2({
} 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.',
})
.catch(console.error)
return undefined
} }
} }
await this._moveItemsToVault.execute({ vault, items: [item, ...linkedFiles] }) await this._moveItemsToVault.execute({ vault, items: [item] })
return this.items.findSureItem(item.uuid) return this.items.findSureItem(item.uuid)
} }

View File

@@ -740,6 +740,12 @@ export class ItemManager extends Services.AbstractService implements Services.It
) )
} }
public getUnsortedTagsForItem(item: Models.DecryptedItemInterface<Models.ItemContent>): Models.SNTag[] {
return this.itemsReferencingItem(item).filter((ref) => {
return ref?.content_type === ContentType.TYPES.Tag
}) as Models.SNTag[]
}
public isSmartViewTitle(title: string): boolean { public isSmartViewTitle(title: string): boolean {
return title.startsWith(Models.SMART_TAG_DSL_PREFIX) return title.startsWith(Models.SMART_TAG_DSL_PREFIX)
} }
@@ -860,8 +866,14 @@ export class ItemManager extends Services.AbstractService implements Services.It
return this.findItems(this.collection.uuidsOfItemsWithConflicts()).filter(Models.isNote).length return this.findItems(this.collection.uuidsOfItemsWithConflicts()).filter(Models.isNote).length
} }
getNoteLinkedFiles(note: Models.SNNote): Models.FileItem[] { getItemLinkedFiles(item: Models.DecryptedItemInterface): Models.FileItem[] {
return this.itemsReferencingItem(note).filter(Models.isFile) return item.content_type === ContentType.TYPES.File
? this.referencesForItem(item).filter(Models.isFile)
: this.itemsReferencingItem(item).filter(Models.isFile)
}
getItemLinkedNotes(item: Models.DecryptedItemInterface<Models.ItemContent>): Models.SNNote[] {
return this.referencesForItem(item).filter(Models.isNote)
} }
/** /**