const { task, componentOwnerId, onCloseTaskDetails, removeTaskFromColumn, projectId, contract, addActionStatus, taskColumn, columnIndex, updateTaskInColumn, } = props; const OverlayContainer = styled.div` left: 12px; right: 12px; bottom: 0px; top: 40px; position: absolute; z-index: 20; display: flex; background-color: rgba(0, 0, 0, 0.5); justify-content: center; padding-top: 100px; `; const PopupContainer = styled.div` position: relative; background-color: #1d1d21; padding: 1rem; width: 734px; height: fit-content; `; const Header = styled.div` display: flex; flex-direction: row; justify-content: space-between; align-items: center; `; const Title = styled.input` color: #fff; font-family: Helvetica Neue; font-size: 20px; font-weight: 500; line-height: 24px; letter-spacing: 0em; text-align: left; width: 100%; height: 40px; padding: 8px 60px 8px 16px; margin-top: 1rem; margin-bottom: 1rem; border-radius: 4px; background-color: transparent; :focus { outline-color: transparent; outline-style: solid; outline-width: 1px; } ::placeholder { color: #d0fc42; } border: none; `; const Input = styled.input` color: #fff; font-family: Helvetica Neue; font-size: 16px; font-weight: 400; line-height: 24px; letter-spacing: 0em; text-align: left; flex: 1; height: 40px; padding: 8px 60px 8px 16px; margin-top: 1rem; margin-bottom: 1rem; border-radius: 4px; background-color: transparent; :focus { outline-color: transparent; outline-style: solid; outline-width: 1px; } ::placeholder { color: #d0fc42; } border: none; `; const Label = styled.label` color: #777583; font-family: Helvetica Neue; font-size: 16px; font-weight: 400; line-height: 24px; letter-spacing: 0em; text-align: left; width: 104px; height: 40px; padding: 8px 60px 8px 16px; margin-top: 1rem; margin-bottom: 1rem; border-radius: 4px; background-color: transparent; :focus { outline-color: #d0fc42; outline-style: solid; outline-width: 1px; } border: none; white-space: nowrap; `; const CloseButton = styled.div` color: #fff; :hover { color: #d0fc42; } cursor: pointer; `; const InputContainer = styled.div` display: flex; flex-direction: row; align-items: center; gap: 68px; `; const Divider = styled.div` width: 100%; height: 1px; background-color: #282933; margin-top: 16px; margin-bottom: 16; `; const FieldContainer = styled.div` position: relative; width: 100%; `; const MissingTitle = styled.div` position: absolute; left: 185px; top: 75%; font-family: Helvetica Neue; font-size: 16px; font-weight: 400; line-height: 24px; letter-spacing: 0em; color: red; `; const LabelContainer = styled.div` width: 100%; `; const ReporterInfo = styled.div` display: flex; column-gap: 0.5rem; padding: 1rem; `; const ReporterId = styled.div` display: flex; justify-content: start; align-items: center; width: 100%; color: #fff; `; const AssigneeContainer = styled.div` margin-left: 16px; `; const FunctionButton = styled.button` ${({ backgroundColor }) => backgroundColor && `background-color: ${backgroundColor};`} ${({ color }) => (color ? `color: ${color};` : 'color: #fff;')} ${({ disabled }) => disabled ? 'cursor: not-allowed; opacity: 0.5;' : 'cursor: pointer;'} :hover { ${({ hoverColor, disabled }) => hoverColor && !disabled && `background-color: ${hoverColor};`} } border-radius: 4px; padding-top: 0.5rem; padding-bottom: 0.5rem; border: none; width: 100%; `; const DialogTitle = styled.p` color: #777583; font-family: Helvetica Neue; font-size: 15px; font-style: normal; font-weight: 700; line-height: 100%; padding: 0; margin: 0; `; const ButtonsContainer = styled.div` display: flex; flex-direction: column; gap: 8px; margin-top: 24px; `; const [editTaskTitle, setEditTaskTitle] = useState(task.title); const [editTaskDescription, setEditTaskDescription] = useState( task.description, ); const [assignee, setAssignee] = useState(task.assignee); const [editTaskTitleMissing, setEditTaskTitleMissing] = useState(false); const [isDeleteTaskVisible, setIsDeleteTaskVisible] = useState(false); const onEditTaskTitle = (e) => { setEditTaskTitleMissing(false); setEditTaskTitle(e.target.value); }; const onEditTaskDescription = (e) => { setEditTaskDescription(e.target.value); }; const updateTask = useCallback(() => { try { const editedTask = { ...task, title: editTaskTitle, description: editTaskDescription, assignee: assignee === 'no_assignee' ? null : assignee, }; let promises = []; if (task.title !== editTaskTitle) { promises.push( Near.fakCalimeroCall(contract, 'change_task_name', { project_id: projectId, task_id: task.id, new_title: editTaskTitle, }), ); } if (task.description !== editTaskDescription) { promises.push( Near.fakCalimeroCall(contract, 'edit_task_description', { project_id: projectId, task_id: task.id, new_description: editTaskDescription, }), ); } if (task.assignee !== assignee) { promises.push( Near.fakCalimeroCall( contract, assignee === 'no_assignee' ? 'remove_assignee' : 'assign_task', { project_id: projectId, task_id: task.id, ...(assignee !== 'no_assignee' && { assignee: assignee }), }, ), ); } if (promises.length > 0) { updateTaskInColumn(columnIndex, editedTask); Promise.all(promises); } } catch (e) { console.log('updateTask', e); } onCloseTaskDetails(); }, [ task, editTaskTitle, editTaskDescription, projectId, contract, taskColumn, assignee, columnIndex, ]); let deleteTask = useCallback( (task) => { const actionStatusPrefix = 'Delete task'; let newActionStatus = { id: actionStatusPrefix + task.id, status: `Deleting task: ${task.id}`, }; try { addActionStatus(newActionStatus); removeTaskFromColumn(task.id, columnIndex); Near.fakCalimeroCall(contract, 'delete_task_by_id', { project_id: projectId, task_id: task.id, }).then(() => { newActionStatus.status = `Deleted task: ${task.id}`; addActionStatus(newActionStatus); }); } catch (e) { newActionStatus.status = `Error deleting task: ${task.id}`; addActionStatus(newActionStatus); } setIsDeleteTaskVisible(false); onCloseTaskDetails(); }, [projectId, contract, addActionStatus, columnIndex], ); const handleUpdateTask = useCallback(() => { if (!editTaskTitle || editTaskTitle.trim() === '') { setEditTaskTitleMissing(true); setTimeout(() => { setEditTaskTitleMissing(false); setEditTaskTitle(task.title); }, 3000); return; } else if ( editTaskTitle !== task.title || editTaskDescription !== task.description || assignee !== task.assignee ) { updateTask(); } }, [ task, editTaskTitle, editTaskDescription, setEditTaskTitleMissing, setEditTaskTitle, updateTask, assignee, ]); return ( <> {isDeleteTaskVisible && ( <Widget src={`${componentOwnerId}/widget/Calimero.TaskChain.ConfirmationPopup`} props={{ onClick: () => deleteTask(task), onClose: () => setIsDeleteTaskVisible(false), title: 'Are you sure you want to delete the task?', }} /> )} <OverlayContainer> <PopupContainer> <Header> <DialogTitle>Edit task</DialogTitle> <CloseButton onClick={onCloseTaskDetails}> <i className="bi bi-x-circle"></i> </CloseButton> </Header> <Divider /> <FieldContainer> <InputContainer> <Label>Title</Label> <Title onChange={onEditTaskTitle} value={editTaskTitle} placeholder="Add Title" /> {editTaskTitleMissing && <MissingTitle>Missing title</MissingTitle>} </InputContainer> </FieldContainer> <FieldContainer> <InputContainer> <Label>Assignee</Label> <AssigneeContainer> <Widget src={`${componentOwnerId}/widget/Calimero.TaskChain.BoardContainer.Task.AssigneeDropdown`} props={{ componentOwnerId, assignee, setAssignee, contract, projectId, }} /> </AssigneeContainer> </InputContainer> </FieldContainer> <LabelContainer> <InputContainer> <Label>Created by</Label> <ReporterInfo> <Widget src={`${componentOwnerId}/widget/Calimero.TaskChain.ProfileIcon.UserProfileIcon`} props={{ accountId: task.reporter, componentOwnerId, }} /> <ReporterId>{task.reporter}</ReporterId> </ReporterInfo> </InputContainer> </LabelContainer> <FieldContainer> <InputContainer> <Label>Description</Label> <Input onChange={onEditTaskDescription} value={editTaskDescription} placeholder="Add Description" /> </InputContainer> </FieldContainer> <Widget src={`${componentOwnerId}/widget/Calimero.TaskChain.BoardContainer.Task.Comments`} props={{ componentOwnerId, comments: task.comments, contract, projectId, taskId: task.id, }} /> <ButtonsContainer> <FunctionButton backgroundColor="#D0FC42" color="black" hoverColor="#BBE33B" disabled={ editTaskTitle === task.title && editTaskDescription === task.description && assignee === task.assignee } onClick={handleUpdateTask} > Save </FunctionButton> <FunctionButton backgroundColor="transparent" hoverColor="#F25757" onClick={() => setIsDeleteTaskVisible(true)} > Delete </FunctionButton> </ButtonsContainer> </PopupContainer> </OverlayContainer> </> );