const { componentOwnerId, createTaskButton, addCreateTaskStatus, cleanCreateTaskStatus, handleColumns, projectId, contract, columnTitle } = props; const PopupContainer = styled.div` position: relative; background-color: #1d1d21; padding: 1rem; width: 489px; height: fit-content; `; const Text = styled.div` display: flex; column-gap: 0.5rem; align-items: center; color: #fff; font-family: Helvetica Neue; font-size: 24px; font-style: normal; font-weight: 500; line-height: 120% margin-bottom: 1rem; `; const DescriptionInput = styled.textarea` color: #fff; font-family: Helvetica Neue; font-size: 16px; font-weight: 400; line-height: 24px; letter-spacing: 0em; text-align: left; height: 40px; margin-top: 1rem; padding-top: 0.5rem; margin-bottom: 1rem; border-radius: 4px; background-color: transparent; :focus { outline-width: 0px; } ::placeholder { color: #D0FC42; } border: none; display: block; flex: 1; `; const TitleInput = styled.input` color: #fff; font-family: Helvetica Neue; font-size: 20px; font-style: normal; font-weight: 500; line-height: 120%; letter-spacing: 0em; text-align: left; flex: 1; height: 40px; margin-top: 1rem; margin-bottom: 1rem; border-radius: 4px; background-color: transparent; :focus { outline-width: 0px; } ::placeholder { color: #FFFFFF7F; } 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: 30%; height: 40px; margin-top: 1rem; margin-bottom: 1rem; border-radius: 4px; background-color: transparent; :focus { outline-width: 0px; } z-index: 10; border: none; display: flex; align-items: center; `; const CloseButton = styled.div` color: #fff; :hover { color: #D0FC42; } cursor: pointer; `; const Header = styled.div` display: flex; flex-direction: row; justify-content: space-between; align-items: center; `; const InputContainer = styled.div` display: flex; flex-direction: row; align-items: center; `; const DescriptionContainer = styled.div` display: flex; flex-direction: row; align-items: flex-start; width: 100%; `; const Divider = styled.div` width: 100%; height: 1px; background-color: #282933; margin-top: 16px; margin-bottom: 16; `; const FieldContainer = styled.div` width: 100%; `; const MissingTitle = styled.div` position: absolute; right: 15.5rem; top: 7rem; font-family: Helvetica Neue; font-size: 16px; font-weight: 400; line-height: 24px; letter-spacing: 0em; color: red; `; const FunctionButton = styled.button` background-color: #D0FC42; :hover { opacity: 0.8; } color: #0E0E10; border-radius: 4px; margin-top: 1rem; padding-top: 0.5rem; padding-bottom: 0.5rem; border: none; width: 100%; `; const Overlay = styled.div` background-color: var(--blackA9); position: fixed; z-index: 1000; inset: 0; display: flex; justify-content: center; align-items: center; animation: overlayShow 150ms cubic-bezier(0.16, 1, 0.3, 1); `; const ModalContent = styled.div` position: absolute; width: 500px; padding: 30px; border-radius: 20px; color: white; `; const DialogTitle = styled.div` color: #777583; font-family: Helvetica Neue; font-size: 15px; font-style: normal; font-weight: 700; line-height: 100%; `; const placeholder = "Assign a person"; const [taskTitle, setTaskTitle] = useState(""); const [taskDescription, setTaskDescription] = useState(""); const [addTaskTitleMissing, setAddTaskTitleMissing] = useState(false); const [isCreateTaskVisible, setIsCreateTaskVisible] = useState(false); const [members, setMembers] = useState(false); const [assignee, setAssignee] = useState(placeholder); const getMembers = useCallback(async (projectId) => { try { Near.asyncCalimeroView(contract, "get_members", { project_id: projectId, }).then((members) => { setMembers(members.map((member) => ({ id: member }))); }); } catch (e) { console.log("getMembers", e); } }, []); useEffect(() => { if (projectId) { getMembers(projectId); } }, [projectId]); const onChangeTaskTitle = ({ target }) => { setAddTaskTitleMissing(false); setTaskTitle(target.value); }; const onChangeTaskDescription = ({ target }) => { setTaskDescription(target.value); }; const handleOnClose = useCallback(() => { setIsCreateTaskVisible(false); setAddTaskTitleMissing(false); setAssignee(placeholder); setTaskTitle(""); setTaskDescription(""); }, []); const handleCreateTask = useCallback(() => { if (!taskTitle || taskTitle.trim() === "") { setAddTaskTitleMissing(true); return; } const newStatus = { title: taskTitle, status: "Saving..." }; try { addCreateTaskStatus(newStatus); const newTask = { project_id: projectId, title: taskTitle, description: taskDescription, status: columnTitle, assignee: assignee === placeholder ? null : assignee, reporter: context.accountId, }; let newColumnsArray = []; const storageColumns = Storage.privateGet( "tempColumns" + contract + projectId ); if (storageColumns && JSON.parse(storageColumns).length > 0) { newColumnsArray = JSON.parse(storageColumns); newColumnsArray.push(newTask); } else { newColumnsArray.push(newTask); } const jsonStringArray = JSON.stringify(newColumnsArray); Storage.privateSet("tempColumns" + contract + projectId, jsonStringArray); handleColumns(projectId); Near.fakCalimeroCall(contract, "create_task", { project_id: projectId, title: taskTitle, description: taskDescription, labels: [], assignee: assignee === placeholder ? null : assignee, }).then(() => { newStatus.status = "Saved"; addCreateTaskStatus(newStatus); setTimeout(() => cleanCreateTaskStatus(taskTitle), 3000); }); } catch (e) { newStatus.status = "Error saving"; addCreateTaskStatus(newStatus); Storage.privateSet("tempColumns" + contract + projectId, ""); setTimeout(() => cleanCreateTaskStatus(taskTitle), 3000); } setIsCreateTaskVisible(false); setTaskTitle(""); setTaskDescription(""); setAssignee(placeholder); }, [taskTitle, taskDescription, setIsCreateTaskVisible, setTaskTitle, setTaskDescription, assignee, placeholder]); const content = <Overlay> <ModalContent> <PopupContainer> <Header> <DialogTitle> Create new Task </DialogTitle> <CloseButton onClick={handleOnClose}> <i className="bi bi-x-circle"></i> </CloseButton> </Header> <Divider /> <FieldContainer> <InputContainer> <Label>Title</Label> <TitleInput onChange={onChangeTaskTitle} value={taskTitle} placeholder="Set a Task Title"/> </InputContainer> {addTaskTitleMissing && <MissingTitle> Missing title </MissingTitle> } </FieldContainer> <FieldContainer> <InputContainer> <Label>Assignee</Label> <Widget src={`${componentOwnerId}/widget/Calimero.TaskChain.BoardContainer.Task.AssigneeDropdown`} props={{ componentOwnerId, members, assignee, setAssignee, placeholder }} /> </InputContainer> </FieldContainer> <FieldContainer> <DescriptionContainer> <Label>Description</Label> <DescriptionInput onChange={onChangeTaskDescription} value={taskDescription} placeholder="Add Description"/> </DescriptionContainer> </FieldContainer> <FunctionButton onClick={() => handleCreateTask( taskTitle, taskDescription, setIsCreateTaskVisible, setAddTaskTitleMissing, setTaskTitle, setTaskDescription )} > Create </FunctionButton> </PopupContainer> </ModalContent> </Overlay> return ( <Widget src={`${componentOwnerId}/widget/Calimero.TaskChain.Popups.BaseModal`} props={{ toggle: createTaskButton, content, open: isCreateTaskVisible, onOpenChange: (open) => setIsCreateTaskVisible(open), }} /> );