chore: show toast when duplicating note and update last modified date for duplicated note (#2379)

This commit is contained in:
Aman Harwara
2023-08-01 18:23:20 +05:30
committed by GitHub
parent 45265fcbad
commit b58898687e
11 changed files with 67 additions and 4 deletions

View File

@@ -11,7 +11,7 @@ import {
import { ContentType } from '@standardnotes/domain-core' import { ContentType } from '@standardnotes/domain-core'
import { AlertService, InternalEventBusInterface } from '@standardnotes/services' import { AlertService, InternalEventBusInterface } from '@standardnotes/services'
import { MutatorService, PayloadManager, ItemManager } from '../' import { MutatorService, PayloadManager, ItemManager } from '../'
import { UuidGenerator } from '@standardnotes/utils' import { UuidGenerator, sleep } from '@standardnotes/utils'
const setupRandomUuid = () => { const setupRandomUuid = () => {
UuidGenerator.SetGenerator(() => String(Math.random())) UuidGenerator.SetGenerator(() => String(Math.random()))
@@ -65,6 +65,14 @@ describe('mutator service', () => {
expect(note.userModifiedDate).toEqual(pinnedNote?.userModifiedDate) expect(note.userModifiedDate).toEqual(pinnedNote?.userModifiedDate)
}) })
it('should update the modification date of duplicated notes', async () => {
const note = await insertNote('hello')
await sleep(1, false, 'Delaying duplication by 1ms to create unique timestamps')
const duplicatedNote = await mutatorService.duplicateItem(note)
expect(duplicatedNote.userModifiedDate.getTime()).toBeGreaterThan(note.userModifiedDate.getTime())
})
}) })
describe('linking', () => { describe('linking', () => {

View File

@@ -12,6 +12,7 @@ import { PayloadManager } from '../Payloads/PayloadManager'
import { TagsToFoldersMigrationApplicator } from '@Lib/Migrations/Applicators/TagsToFolders' import { TagsToFoldersMigrationApplicator } from '@Lib/Migrations/Applicators/TagsToFolders'
import { import {
ActionsExtensionMutator, ActionsExtensionMutator,
AppDataField,
ComponentInterface, ComponentInterface,
ComponentMutator, ComponentMutator,
CreateDecryptedMutatorForItem, CreateDecryptedMutatorForItem,
@@ -19,6 +20,7 @@ import {
DecryptedItemMutator, DecryptedItemMutator,
DecryptedPayload, DecryptedPayload,
DecryptedPayloadInterface, DecryptedPayloadInterface,
DefaultAppDomain,
DeleteItemMutator, DeleteItemMutator,
EncryptedItemInterface, EncryptedItemInterface,
FeatureRepoMutator, FeatureRepoMutator,
@@ -319,7 +321,14 @@ export class MutatorService extends AbstractService implements MutatorClientInte
payload, payload,
baseCollection: this.payloadManager.getMasterCollection(), baseCollection: this.payloadManager.getMasterCollection(),
isConflict, isConflict,
additionalContent, additionalContent: {
appData: {
[DefaultAppDomain]: {
[AppDataField.UserModifiedDate]: new Date(),
},
},
...additionalContent,
},
}) })
await this.payloadManager.emitPayloads(resultingPayloads, PayloadEmitSource.LocalChanged) await this.payloadManager.emitPayloads(resultingPayloads, PayloadEmitSource.LocalChanged)

View File

@@ -261,6 +261,7 @@ const ApplicationView: FunctionComponent<Props> = ({ application, mainApplicatio
notesController={viewControllerManager.notesController} notesController={viewControllerManager.notesController}
linkingController={viewControllerManager.linkingController} linkingController={viewControllerManager.linkingController}
historyModalController={viewControllerManager.historyModalController} historyModalController={viewControllerManager.historyModalController}
selectionController={viewControllerManager.selectionController}
/> />
<TagContextMenuWrapper <TagContextMenuWrapper
navigationController={viewControllerManager.navigationController} navigationController={viewControllerManager.navigationController}

View File

@@ -381,6 +381,7 @@ const ContentListView = forwardRef<HTMLDivElement, Props>(
notesController={notesController} notesController={notesController}
historyModalController={historyModalController} historyModalController={historyModalController}
itemListController={itemListController} itemListController={itemListController}
selectionController={selectionController}
/> />
) : ( ) : (
<ContentList <ContentList

View File

@@ -41,6 +41,7 @@ import { useItemLinks } from '@/Hooks/useItemLinks'
import { ItemLink } from '@/Utils/Items/Search/ItemLink' import { ItemLink } from '@/Utils/Items/Search/ItemLink'
import { ItemListController } from '@/Controllers/ItemList/ItemListController' import { ItemListController } from '@/Controllers/ItemList/ItemListController'
import ListItemVaultInfo from '../ContentListView/ListItemVaultInfo' import ListItemVaultInfo from '../ContentListView/ListItemVaultInfo'
import { SelectedItemsController } from '@/Controllers/SelectedItemsController'
const ContextMenuCell = ({ const ContextMenuCell = ({
items, items,
@@ -49,6 +50,7 @@ const ContextMenuCell = ({
linkingController, linkingController,
notesController, notesController,
historyModalController, historyModalController,
selectionController,
}: { }: {
items: DecryptedItemInterface[] items: DecryptedItemInterface[]
filesController: FilesController filesController: FilesController
@@ -56,6 +58,7 @@ const ContextMenuCell = ({
linkingController: LinkingController linkingController: LinkingController
notesController: NotesController notesController: NotesController
historyModalController: HistoryModalController historyModalController: HistoryModalController
selectionController: SelectedItemsController
}) => { }) => {
const [contextMenuVisible, setContextMenuVisible] = useState(false) const [contextMenuVisible, setContextMenuVisible] = useState(false)
const anchorElementRef = useRef<HTMLButtonElement>(null) const anchorElementRef = useRef<HTMLButtonElement>(null)
@@ -117,6 +120,7 @@ const ContextMenuCell = ({
notesController={notesController} notesController={notesController}
linkingController={linkingController} linkingController={linkingController}
historyModalController={historyModalController} historyModalController={historyModalController}
selectionController={selectionController}
closeMenu={() => { closeMenu={() => {
setContextMenuVisible(false) setContextMenuVisible(false)
}} }}
@@ -266,6 +270,7 @@ type Props = {
notesController: NotesController notesController: NotesController
historyModalController: HistoryModalController historyModalController: HistoryModalController
itemListController: ItemListController itemListController: ItemListController
selectionController: SelectedItemsController
} }
const ContentTableView = ({ const ContentTableView = ({
@@ -278,6 +283,7 @@ const ContentTableView = ({
notesController, notesController,
historyModalController, historyModalController,
itemListController, itemListController,
selectionController,
}: Props) => { }: Props) => {
const listHasFiles = items.some((item) => item instanceof FileItem) const listHasFiles = items.some((item) => item instanceof FileItem)
@@ -406,6 +412,7 @@ const ContentTableView = ({
navigationController={navigationController} navigationController={navigationController}
notesController={notesController} notesController={notesController}
historyModalController={historyModalController} historyModalController={historyModalController}
selectionController={selectionController}
/> />
</div> </div>
) )
@@ -418,6 +425,7 @@ const ContentTableView = ({
navigationController={navigationController} navigationController={navigationController}
notesController={notesController} notesController={notesController}
historyModalController={historyModalController} historyModalController={historyModalController}
selectionController={selectionController}
/> />
), ),
showSelectionActions: true, showSelectionActions: true,
@@ -465,6 +473,7 @@ const ContentTableView = ({
notesController={notesController} notesController={notesController}
linkingController={linkingController} linkingController={linkingController}
historyModalController={historyModalController} historyModalController={historyModalController}
selectionController={selectionController}
closeMenu={closeContextMenu} closeMenu={closeContextMenu}
/> />
</Menu> </Menu>

View File

@@ -51,6 +51,7 @@ const MultipleSelectedNotes = ({
notesController={notesController} notesController={notesController}
linkingController={linkingController} linkingController={linkingController}
historyModalController={historyModalController} historyModalController={historyModalController}
selectionController={selectionController}
/> />
</div> </div>
</div> </div>

View File

@@ -932,6 +932,7 @@ class NoteView extends AbstractComponent<NoteViewProps, State> {
notesController={this.viewControllerManager.notesController} notesController={this.viewControllerManager.notesController}
linkingController={this.viewControllerManager.linkingController} linkingController={this.viewControllerManager.linkingController}
historyModalController={this.viewControllerManager.historyModalController} historyModalController={this.viewControllerManager.historyModalController}
selectionController={this.viewControllerManager.selectionController}
onClickPreprocessing={this.ensureNoteIsInsertedBeforeUIAction} onClickPreprocessing={this.ensureNoteIsInsertedBeforeUIAction}
/> />
</div> </div>

View File

@@ -7,12 +7,14 @@ import { HistoryModalController } from '@/Controllers/NoteHistory/HistoryModalCo
import Popover from '../Popover/Popover' import Popover from '../Popover/Popover'
import { LinkingController } from '@/Controllers/LinkingController' import { LinkingController } from '@/Controllers/LinkingController'
import Menu from '../Menu/Menu' import Menu from '../Menu/Menu'
import { SelectedItemsController } from '@/Controllers/SelectedItemsController'
type Props = { type Props = {
navigationController: NavigationController navigationController: NavigationController
notesController: NotesController notesController: NotesController
linkingController: LinkingController linkingController: LinkingController
historyModalController: HistoryModalController historyModalController: HistoryModalController
selectionController: SelectedItemsController
} }
const NotesContextMenu = ({ const NotesContextMenu = ({
@@ -20,6 +22,7 @@ const NotesContextMenu = ({
notesController, notesController,
linkingController, linkingController,
historyModalController, historyModalController,
selectionController,
}: Props) => { }: Props) => {
const { contextMenuOpen, contextMenuClickLocation, setContextMenuOpen } = notesController const { contextMenuOpen, contextMenuClickLocation, setContextMenuOpen } = notesController
@@ -50,6 +53,7 @@ const NotesContextMenu = ({
notesController={notesController} notesController={notesController}
linkingController={linkingController} linkingController={linkingController}
historyModalController={historyModalController} historyModalController={historyModalController}
selectionController={selectionController}
requestDisableClickOutside={handleDisableClickOutsideRequest} requestDisableClickOutside={handleDisableClickOutsideRequest}
closeMenu={closeMenu} closeMenu={closeMenu}
/> />

View File

@@ -55,6 +55,7 @@ const NotesOptions = ({
navigationController, navigationController,
notesController, notesController,
linkingController, linkingController,
selectionController,
historyModalController, historyModalController,
closeMenu, closeMenu,
}: NotesOptionsProps) => { }: NotesOptionsProps) => {
@@ -150,10 +151,32 @@ const NotesOptions = ({
}, [closeMenu, toggleAppPane]) }, [closeMenu, toggleAppPane])
const duplicateSelectedItems = useCallback(async () => { const duplicateSelectedItems = useCallback(async () => {
await Promise.all(notes.map((note) => application.mutator.duplicateItem(note).catch(console.error))) await Promise.all(
notes.map((note) =>
application.mutator
.duplicateItem(note)
.then((duplicated) =>
addToast({
type: ToastType.Regular,
message: `Duplicated note "${duplicated.title}"`,
actions: [
{
label: 'Open',
handler: (toastId) => {
selectionController.selectItem(duplicated.uuid, true).catch(console.error)
dismissToast(toastId)
},
},
],
autoClose: true,
}),
)
.catch(console.error),
),
)
void application.sync.sync() void application.sync.sync()
closeMenuAndToggleNotesList() closeMenuAndToggleNotesList()
}, [application.mutator, application.sync, closeMenuAndToggleNotesList, notes]) }, [application.mutator, application.sync, closeMenuAndToggleNotesList, notes, selectionController])
const openRevisionHistoryModal = useCallback(() => { const openRevisionHistoryModal = useCallback(() => {
historyModalController.openModal(notesController.firstSelectedNote) historyModalController.openModal(notesController.firstSelectedNote)

View File

@@ -8,12 +8,14 @@ import Popover from '../Popover/Popover'
import { LinkingController } from '@/Controllers/LinkingController' import { LinkingController } from '@/Controllers/LinkingController'
import RoundIconButton from '../Button/RoundIconButton' import RoundIconButton from '../Button/RoundIconButton'
import Menu from '../Menu/Menu' import Menu from '../Menu/Menu'
import { SelectedItemsController } from '@/Controllers/SelectedItemsController'
type Props = { type Props = {
navigationController: NavigationController navigationController: NavigationController
notesController: NotesController notesController: NotesController
linkingController: LinkingController linkingController: LinkingController
historyModalController: HistoryModalController historyModalController: HistoryModalController
selectionController: SelectedItemsController
onClickPreprocessing?: () => Promise<void> onClickPreprocessing?: () => Promise<void>
} }
@@ -22,6 +24,7 @@ const NotesOptionsPanel = ({
notesController, notesController,
linkingController, linkingController,
historyModalController, historyModalController,
selectionController,
onClickPreprocessing, onClickPreprocessing,
}: Props) => { }: Props) => {
const [isOpen, setIsOpen] = useState(false) const [isOpen, setIsOpen] = useState(false)
@@ -58,6 +61,7 @@ const NotesOptionsPanel = ({
notesController={notesController} notesController={notesController}
linkingController={linkingController} linkingController={linkingController}
historyModalController={historyModalController} historyModalController={historyModalController}
selectionController={selectionController}
requestDisableClickOutside={handleDisableClickOutsideRequest} requestDisableClickOutside={handleDisableClickOutsideRequest}
closeMenu={toggleMenu} closeMenu={toggleMenu}
/> />

View File

@@ -3,6 +3,7 @@ import { NavigationController } from '@/Controllers/Navigation/NavigationControl
import { NotesController } from '@/Controllers/NotesController/NotesController' import { NotesController } from '@/Controllers/NotesController/NotesController'
import { LinkingController } from '@/Controllers/LinkingController' import { LinkingController } from '@/Controllers/LinkingController'
import { SNNote } from '@standardnotes/snjs' import { SNNote } from '@standardnotes/snjs'
import { SelectedItemsController } from '@/Controllers/SelectedItemsController'
export type NotesOptionsProps = { export type NotesOptionsProps = {
notes: SNNote[] notes: SNNote[]
@@ -10,6 +11,7 @@ export type NotesOptionsProps = {
notesController: NotesController notesController: NotesController
linkingController: LinkingController linkingController: LinkingController
historyModalController: HistoryModalController historyModalController: HistoryModalController
selectionController: SelectedItemsController
requestDisableClickOutside?: (disabled: boolean) => void requestDisableClickOutside?: (disabled: boolean) => void
closeMenu: () => void closeMenu: () => void
} }