Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: minor
Type: changed

Forms: move view actions to modal header on mobile
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
/**
* External dependencies
*/
import { Button } from '@wordpress/components';
import { useRegistry } from '@wordpress/data';
import { useCallback, useState } from '@wordpress/element';
/**
* Internal dependencies
*/
import {
markAsSpamAction,
markAsNotSpamAction,
moveToTrashAction,
restoreAction,
deleteAction,
markAsReadAction,
markAsUnreadAction,
} from '../../inbox/dataviews/actions';
/**
* Types
*/
import type { FormResponse } from '../../../types';

type ResponseNavigationProps = {
onActionComplete?: ( FormResponse ) => void;
response: FormResponse;
};

const ResponseActions = ( {
onActionComplete,
response,
}: ResponseNavigationProps ): JSX.Element => {
const [ isMarkingAsSpam, setIsMarkingAsSpam ] = useState( false );
const [ isMarkingAsNotSpam, setIsMarkingAsNotSpam ] = useState( false );
const [ isMovingToTrash, setIsMovingToTrash ] = useState( false );
const [ isRestoring, setIsRestoring ] = useState( false );
const [ isDeleting, setIsDeleting ] = useState( false );
const [ isTogglingReadStatus, setIsTogglingReadStatus ] = useState( false );

const registry = useRegistry();

const handleMarkAsSpam = useCallback( async () => {
onActionComplete?.( response );
setIsMarkingAsSpam( true );
await markAsSpamAction.callback( [ response ], { registry } );
setIsMarkingAsSpam( false );
}, [ response, registry, onActionComplete ] );

const handleMarkAsNotSpam = useCallback( async () => {
onActionComplete?.( response );
setIsMarkingAsNotSpam( true );
await markAsNotSpamAction.callback( [ response ], { registry } );
setIsMarkingAsNotSpam( false );
}, [ response, registry, onActionComplete ] );

const handleMoveToTrash = useCallback( async () => {
onActionComplete?.( response );
setIsMovingToTrash( true );
await moveToTrashAction.callback( [ response ], { registry } );
setIsMovingToTrash( false );
}, [ response, registry, onActionComplete ] );

const handleRestore = useCallback( async () => {
onActionComplete?.( response );
setIsRestoring( true );
await restoreAction.callback( [ response ], { registry } );
setIsRestoring( false );
}, [ response, registry, onActionComplete ] );

const handleDelete = useCallback( async () => {
onActionComplete?.( response );
setIsDeleting( true );
await deleteAction.callback( [ response ], { registry } );
setIsDeleting( false );
}, [ response, registry, onActionComplete ] );

const handleMarkAsRead = useCallback( async () => {
setIsTogglingReadStatus( true );
await markAsReadAction.callback( [ response ], { registry } );
setIsTogglingReadStatus( false );
onActionComplete?.( { ...response, is_unread: false } );
}, [ response, registry, onActionComplete ] );

const handleMarkAsUnread = useCallback( async () => {
setIsTogglingReadStatus( true );
await markAsUnreadAction.callback( [ response ], { registry } );
setIsTogglingReadStatus( false );
onActionComplete?.( { ...response, is_unread: true } );
}, [ response, registry, onActionComplete ] );

const readUnreadButtons = (
<>
{ response.is_unread && (
<Button
variant="tertiary"
onClick={ handleMarkAsRead }
isBusy={ isTogglingReadStatus }
showTooltip={ true }
label={ markAsReadAction.label }
iconSize={ 24 }
icon={ markAsReadAction.icon }
size="compact"
></Button>
) }
{ ! response.is_unread && (
<Button
variant="tertiary"
onClick={ handleMarkAsUnread }
isBusy={ isTogglingReadStatus }
showTooltip={ true }
label={ markAsUnreadAction.label }
iconSize={ 24 }
icon={ markAsUnreadAction.icon }
size="compact"
></Button>
) }
</>
);

switch ( response.status ) {
case 'spam':
return (
<div>
{ readUnreadButtons }
<Button
variant="tertiary"
onClick={ handleMarkAsNotSpam }
isBusy={ isMarkingAsNotSpam }
showTooltip={ true }
label={ markAsNotSpamAction.label }
iconSize={ 24 }
icon={ markAsNotSpamAction.icon }
size="compact"
></Button>
<Button
variant="tertiary"
onClick={ handleMoveToTrash }
isBusy={ isMovingToTrash }
showTooltip={ true }
label={ moveToTrashAction.label }
iconSize={ 24 }
icon={ moveToTrashAction.icon }
size="compact"
></Button>
</div>
);

case 'trash':
return (
<div>
{ readUnreadButtons }
<Button
variant="tertiary"
onClick={ handleRestore }
isBusy={ isRestoring }
showTooltip={ true }
label={ restoreAction.label }
iconSize={ 24 }
icon={ restoreAction.icon }
size="compact"
></Button>
<Button
variant="tertiary"
onClick={ handleDelete }
showTooltip={ true }
isBusy={ isDeleting }
label={ deleteAction.label }
iconSize={ 24 }
icon={ deleteAction.icon }
size="compact"
></Button>
</div>
);

default: // 'publish' (inbox) or any other status
return (
<div>
{ readUnreadButtons }
<Button
variant="tertiary"
onClick={ handleMarkAsSpam }
isBusy={ isMarkingAsSpam }
showTooltip={ true }
label={ markAsSpamAction.label }
iconSize={ 24 }
icon={ markAsSpamAction.icon }
size="compact"
></Button>
<Button
variant="tertiary"
onClick={ handleMoveToTrash }
isBusy={ isMovingToTrash }
showTooltip={ true }
label={ moveToTrashAction.label }
iconSize={ 24 }
icon={ moveToTrashAction.icon }
size="compact"
></Button>
</div>
);
}
};

export default ResponseActions;
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/**
* External dependencies
*/
import { Button } from '@wordpress/components';
import { __ } from '@wordpress/i18n';
import { close, chevronLeft, chevronRight } from '@wordpress/icons';

type ResponseNavigationProps = {
hasNext: boolean;
hasPrevious: boolean;
onClose: ( () => void ) | null;
onNext: () => void;
onPrevious: () => void;
};

const ResponseNavigation = ( {
hasNext,
hasPrevious,
onClose,
onNext,
onPrevious,
}: ResponseNavigationProps ): JSX.Element => {
return (
<div>
{ onPrevious && (
<Button
accessibleWhenDisabled={ true }
disabled={ ! hasPrevious }
icon={ chevronLeft }
label={ __( 'Previous', 'jetpack-forms' ) }
onClick={ onPrevious }
showTooltip={ true }
size="compact"
variant="tertiary"
></Button>
) }
{ onNext && (
<Button
accessibleWhenDisabled={ true }
disabled={ ! hasNext }
icon={ chevronRight }
label={ __( 'Next', 'jetpack-forms' ) }
onClick={ onNext }
showTooltip={ true }
size="compact"
variant="tertiary"
></Button>
) }
{ onClose && (
<Button
icon={ close }
label={ __( 'Close', 'jetpack-forms' ) }
onClick={ onClose }
showTooltip={ true }
size="compact"
variant="tertiary"
></Button>
) }
</div>
);
};

export default ResponseNavigation;
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import { seen, unseen, trash, backup, commentContent } from '@wordpress/icons';
import { store as noticesStore } from '@wordpress/notices';
import { notSpam, spam } from '../../icons';
import { store as dashboardStore } from '../../store';
import InboxResponse from '../response';
import { updateMenuCounter, updateMenuCounterOptimistically } from '../utils';

export const BULK_ACTIONS = {
Expand All @@ -20,10 +19,6 @@ export const viewAction = {
isPrimary: true,
label: __( 'View response', 'jetpack-forms' ),
modalHeader: __( 'Response', 'jetpack-forms' ),
RenderModal: ( { items } ) => {
const [ item ] = items;
return <InboxResponse isLoading={ false } response={ item } />;
},
};

// TODO: We should probably have better error messages in case of failure.
Expand Down
Loading
Loading