/**
* WordPress dependencies
*/
import { Button, CheckboxControl, Dashicon } from '@safe-wordpress/components';
import { useSelect, useDispatch } from '@safe-wordpress/data';
import { _x } from '@safe-wordpress/i18n';
/**
* External dependencies
*/
import clsx from 'clsx';
import { DeleteButton } from '@nelio-content/components';
import { useAuthorName, store as NC_DATA } from '@nelio-content/data';
import { store as NC_TASK_EDITOR } from '@nelio-content/task-editor';
import { getTaskDateDue, getHumanDateDue } from '@nelio-content/utils';
import type { EditorialTask, Maybe, Uuid } from '@nelio-content/types';
/**
* Internal dependencies
*/
import './style.scss';
import { store as NC_EDIT_POST } from '../../../store';
import { useMemo } from '@safe-wordpress/element';
export type TaskProps = {
readonly taskId: Uuid;
};
export const Task = ( { taskId }: TaskProps ): JSX.Element => {
const task = useTask( taskId );
const { canCompleteTask, canDeleteTask, canEditTask } =
usePermissions( taskId );
const { isDeleting, isSynching, isPastDateDue } = useStatus( taskId );
const { completed, color = '', task: description } = task || {};
const editTask = useTaskEditor( task );
const deleteTask = useTaskDeleter( taskId );
const toggleTaskCompletion = useTaskToggler( taskId );
const assignee = useAuthorName(
task?.assigneeId,
_x( 'Unknown Assignee', 'text', 'nelio-content' )
);
const post = useSelect(
( select ) => select( NC_EDIT_POST ).getPost(),
[]
);
const humanDateDue = task
? getHumanDateDue( post, task.dateType, task.dateValue )
: '';
return (
{ isSynching && _x( 'Saving…', 'text', 'nelio-content' ) }
{ ! isSynching && `${ assignee } • ${ humanDateDue }` }
{ isPastDateDue && }
);
};
// =====
// HOOKS
// =====
const useTask = ( taskId: Uuid ) =>
useSelect( ( select ) => select( NC_DATA ).getTask( taskId ), [ taskId ] );
const usePermissions = ( taskId: Uuid ) => {
const task = useTask( taskId );
return useSelect(
( select ) => {
const canEditTask =
select( NC_DATA ).canCurrentUserEditTask( task );
const canDeleteTask =
select( NC_DATA ).canCurrentUserDeleteTask( task );
return {
canCompleteTask: !! task && canEditTask,
canDeleteTask: !! task && canDeleteTask,
canEditTask: !! task && canEditTask,
};
},
[ task ]
);
};
const EMPTY = {
isDeleting: false,
isSynching: false,
isPastDateDue: false,
} as const;
const useStatus = ( taskId: Uuid ) => {
const task = useTask( taskId );
const sel = useSelect(
( select ) => {
const isDeleting =
select( NC_EDIT_POST ).isEditorialTaskBeingDeleted( taskId );
const isSynching =
select( NC_EDIT_POST ).isEditorialTaskBeingSynched( taskId );
const postDate = select( NC_EDIT_POST ).getPost()?.date;
const today = select( NC_DATA ).getToday();
return { isDeleting, isSynching, postDate, today };
},
[ taskId ]
);
return useMemo( () => {
if ( ! task ) {
return EMPTY;
}
const isPastDateDue =
! task.completed &&
! sel.isSynching &&
getTaskDateDue( {
baseDatetime: sel.postDate || undefined,
dateType: task.dateType,
dateValue: task.dateValue,
} ) < sel.today;
return {
isDeleting: sel.isDeleting,
isSynching: sel.isSynching,
isPastDateDue,
};
}, [ task, sel.isDeleting, sel.isSynching, sel.postDate, sel.today ] );
};
const useTaskEditor = ( task: Maybe< EditorialTask > ) => {
const post = useSelect(
( select ) => select( NC_EDIT_POST ).getPost(),
[]
);
const { openExistingTaskEditor } = useDispatch( NC_TASK_EDITOR );
return () =>
!! post &&
!! task &&
openExistingTaskEditor( task, {
context: 'post',
post,
} );
};
const useTaskDeleter = ( taskId: Uuid ) => {
const { deleteEditorialTask } = useDispatch( NC_EDIT_POST );
return () => deleteEditorialTask( taskId );
};
const useTaskToggler = ( taskId: Uuid ) => {
const task = useTask( taskId );
const { markTaskAsCompleted } = useDispatch( NC_EDIT_POST );
return () => markTaskAsCompleted( taskId, ! task?.completed );
};