diff --git a/src/components/ObsEdit/Header.js b/src/components/ObsEdit/Header.js index 1d99cd0ef..f3a4d5c03 100644 --- a/src/components/ObsEdit/Header.js +++ b/src/components/ObsEdit/Header.js @@ -154,14 +154,25 @@ const Header = ( { setDeleteSheetVisible( true ); setKebabMenuVisible( false ); }} - title={ - observations.length > 1 - ? t( "Delete-observations" ) - : t( "Delete-observation" ) - } + title={t( "Delete-observation" )} /> + { observations.length > 1 && ( + { + setDiscardObservationSheetVisible( true ); + setKebabMenuVisible( false ); + }} + title={t( "Delete-all-observations" )} + /> + ) } - ), [kebabMenuVisible, observations, t, setDeleteSheetVisible] ); + ), [ + kebabMenuVisible, + observations, + setDeleteSheetVisible, + t + ] ); return ( @@ -176,6 +187,7 @@ const Header = ( { navToObsList={navToObsList} observations={observations} currentObservation={currentObservation} + updateObservations={updateObservations} /> )} {discardObservationSheetVisible && ( diff --git a/src/components/ObsEdit/Sheets/DeleteObservationSheet.js b/src/components/ObsEdit/Sheets/DeleteObservationSheet.js index 99d33f7ce..78b58a800 100644 --- a/src/components/ObsEdit/Sheets/DeleteObservationSheet.js +++ b/src/components/ObsEdit/Sheets/DeleteObservationSheet.js @@ -6,26 +6,25 @@ import { import { RealmContext } from "providers/contexts"; import type { Node } from "react"; import React, { useCallback } from "react"; -import { log } from "sharedHelpers/logger"; import safeRealmWrite from "sharedHelpers/safeRealmWrite"; import { useTranslation } from "sharedHooks"; const { useRealm } = RealmContext; -const logger = log.extend( "DeleteObservationSheet" ); - type Props = { + currentObservation: Object, handleClose: Function, navToObsList: Function, - currentObservation: Object, - observations: Array + observations: Array, + updateObservations: Function } const DeleteObservationSheet = ( { + currentObservation, handleClose, navToObsList, - currentObservation, - observations + observations, + updateObservations }: Props ): Node => { const { t } = useTranslation( ); const realm = useRealm( ); @@ -35,35 +34,35 @@ const DeleteObservationSheet = ( { const addObservationToDeletionQueue = useCallback( ( ) => { const localObsToDelete = realm.objectForPrimaryKey( "Observation", uuid ); - if ( !localObsToDelete ) { - logger.info( - "Observation to delete is not saved in realm; returning to MyObservations" - ); - navToObsList( ); - } else { - logger.info( "Observation to add to deletion queue: ", localObsToDelete.uuid ); + if ( localObsToDelete ) { safeRealmWrite( realm, ( ) => { localObsToDelete._deleted_at = new Date( ); }, "adding _deleted_at date in DeleteObservationSheet" ); - logger.info( - "Observation added to deletion queue; returning to MyObservations" - ); - navToObsList( ); } - }, [uuid, realm, navToObsList] ); + if ( multipleObservations ) { + updateObservations( observations.filter( o => o.uuid !== uuid ) ); + handleClose( ); + return; + } + navToObsList( ); + }, [ + handleClose, + multipleObservations, + navToObsList, + observations, + realm, + updateObservations, + uuid + ] ); return ( ); }; diff --git a/src/i18n/l10n/en.ftl b/src/i18n/l10n/en.ftl index d7e07b9fe..aca9029bd 100644 --- a/src/i18n/l10n/en.ftl +++ b/src/i18n/l10n/en.ftl @@ -304,6 +304,8 @@ Delete-comment = Delete comment DELETE-OBSERVATION = DELETE OBSERVATION? +Delete-all-observations = Delete all observations + Delete-observation = Delete observation Delete-observations = Delete observations diff --git a/src/i18n/l10n/en.ftl.json b/src/i18n/l10n/en.ftl.json index 5c8243204..69c52db91 100644 --- a/src/i18n/l10n/en.ftl.json +++ b/src/i18n/l10n/en.ftl.json @@ -176,6 +176,7 @@ "DELETE-COMMENT-QUESTION": "DELETE COMMENT?", "Delete-comment": "Delete comment", "DELETE-OBSERVATION": "DELETE OBSERVATION?", + "Delete-all-observations": "Delete all observations", "Delete-observation": "Delete observation", "Delete-observations": "Delete observations", "DELETE-X-OBSERVATIONS": "DELETE { $count ->\n [one] 1 OBSERVATION?\n *[other] { $count } OBSERVATIONS?\n}", diff --git a/src/i18n/strings.ftl b/src/i18n/strings.ftl index d7e07b9fe..aca9029bd 100644 --- a/src/i18n/strings.ftl +++ b/src/i18n/strings.ftl @@ -304,6 +304,8 @@ Delete-comment = Delete comment DELETE-OBSERVATION = DELETE OBSERVATION? +Delete-all-observations = Delete all observations + Delete-observation = Delete observation Delete-observations = Delete observations diff --git a/tests/unit/components/ObsEdit/DeleteObservationSheet.test.js b/tests/unit/components/ObsEdit/DeleteObservationSheet.test.js index 25d7db45a..700660608 100644 --- a/tests/unit/components/ObsEdit/DeleteObservationSheet.test.js +++ b/tests/unit/components/ObsEdit/DeleteObservationSheet.test.js @@ -5,7 +5,6 @@ import inatjs from "inaturalistjs"; import React from "react"; import safeRealmWrite from "sharedHelpers/safeRealmWrite"; import factory from "tests/factory"; -import faker from "tests/helpers/faker"; import { renderComponent } from "tests/helpers/render"; const observations = [factory( "LocalObservation", { @@ -14,6 +13,8 @@ const observations = [factory( "LocalObservation", { const currentObservation = observations[0]; +const mockUpdateObservations = jest.fn( ); + afterEach( ( ) => { jest.clearAllMocks( ); } ); @@ -22,9 +23,11 @@ const mockNavigate = jest.fn( ); const renderDeleteSheet = ( ) => renderComponent( ); @@ -67,23 +70,44 @@ describe( "delete observation", ( ) => { } ); } ); - describe( "handles multiple observation deletion", ( ) => { - it( "navigates back to MyObservations when observations are not in realm", ( ) => { - const unsavedObservations = [{ - uuid: faker.string.uuid( ) - }, { - uuid: faker.string.uuid( ) - }]; + it( "navigates back when there's only one observation", ( ) => { + expect( observations.length ).toEqual( 1 ); + renderDeleteSheet( ); + const deleteButton = screen.queryByText( "DELETE" ); + fireEvent.press( deleteButton ); + expect( mockNavigate ).toBeCalled( ); + } ); + + describe( "with multiple observations", ( ) => { + const unsavedObservations = [ + factory( "LocalObservation" ), + factory( "LocalObservation" ) + ]; + + function renderDeleteSheetWithMultiple( ) { renderComponent( ); - const deleteButton = screen.queryByText( /DELETE ALL/ ); + } + + it( "does not navigate back when there's more than one observation", ( ) => { + renderDeleteSheetWithMultiple( ); + const deleteButton = screen.queryByText( "DELETE" ); + fireEvent.press( deleteButton ); + expect( mockNavigate ).not.toBeCalled( ); + } ); + + it( "removes observation from state when there's more than one observation", ( ) => { + renderDeleteSheetWithMultiple( ); + const deleteButton = screen.queryByText( "DELETE" ); fireEvent.press( deleteButton ); - expect( mockNavigate ).toBeCalled( ); + expect( mockUpdateObservations ).toBeCalledWith( [unsavedObservations[1]] ); } ); } ); } );