/** * 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 ); };