marks
This commit is contained in:
		| @@ -39,6 +39,7 @@ import file from "assets/icons/fileModal.svg"; | ||||
| import link from "assets/icons/link.svg"; | ||||
| import send from "assets/icons/send.svg"; | ||||
| import watch from "assets/icons/watch.svg"; | ||||
| import arrowDown from "assets/icons/arrows/selectArrow.png"; | ||||
| import avatarMok from "assets/images/avatarMok.png"; | ||||
|  | ||||
| import { getCorrectDate } from "../../../Calendar/calendarHelper"; | ||||
| @@ -54,6 +55,7 @@ export const ModalTiсket = ({ | ||||
|   projectName, | ||||
|   projectUsers, | ||||
|   projectOwnerId, | ||||
|   projectMarks | ||||
| }) => { | ||||
|   const dispatch = useDispatch(); | ||||
|   const [addSubtask, setAddSubtask] = useState(false); | ||||
| @@ -73,6 +75,7 @@ export const ModalTiсket = ({ | ||||
|   const [dropListMembersOpen, setDropListMembersOpen] = useState(false); | ||||
|   const [executor, setExecutor] = useState(task.executor); | ||||
|   const [members, setMembers] = useState(task.taskUsers); | ||||
|   const [taskTags, setTaskTags] = useState(task.mark) | ||||
|   const [users, setUsers] = useState([]); | ||||
|   const [timerStart, setTimerStart] = useState(false); | ||||
|   const [timerInfo, setTimerInfo] = useState({}); | ||||
| @@ -85,9 +88,11 @@ export const ModalTiсket = ({ | ||||
|   const [timerId, setTimerId] = useState(null); | ||||
|   const [taskFiles, setTaskFiles] = useState([]); | ||||
|   const [correctProjectUsers, setCorrectProjectUsers] = useState(projectUsers); | ||||
|   const [correctProjectTags, setCorrectProjectTags] = useState([]) | ||||
|   const [executorId, setExecutorId] = useState(task.executor_id); | ||||
|   const profileInfo = useSelector(getProfileInfo); | ||||
|   const [acceptModalOpen, setAcceptModalOpen] = useState(false); | ||||
|   const [selectTagsOpen, setSelectTagsOpen] = useState(false) | ||||
|   const { showNotification } = useNotification(); | ||||
|  | ||||
|   function deleteTask() { | ||||
| @@ -347,6 +352,14 @@ export const ModalTiсket = ({ | ||||
|     } | ||||
|   }, []); | ||||
|  | ||||
|   useEffect(() => { | ||||
|     let tagIds = taskTags.map((tag) => tag.id) | ||||
|     setCorrectProjectTags(projectMarks.reduce((acc, cur) => { | ||||
|       if (!tagIds.includes(cur.id)) acc.push(cur) | ||||
|       return acc | ||||
|     }, [])) | ||||
|     }, [taskTags]) | ||||
|  | ||||
|   async function handleUpload(event) { | ||||
|     const formData = new FormData(); | ||||
|     formData.append("uploadFile", event.target.files[0]); | ||||
| @@ -454,6 +467,35 @@ export const ModalTiсket = ({ | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   function addTagToTask(tagId) { | ||||
|     apiRequest("/mark/attach", { | ||||
|       method: "POST", | ||||
|       data: { | ||||
|         mark_id: tagId, | ||||
|         entity_type: 2, | ||||
|         entity_id: task.id | ||||
|       } | ||||
|     }).then((data) => { | ||||
|       setSelectTagsOpen(false) | ||||
|       setTaskTags((prevValue) => [...prevValue, data.mark]) | ||||
|       dispatch(setProjectBoardFetch(projectId)); | ||||
|     }) | ||||
|   } | ||||
|  | ||||
|   function deleteTagFromTask(tagId) { | ||||
|     apiRequest("/mark/detach", { | ||||
|       method: "DELETE", | ||||
|       data: { | ||||
|         mark_id: tagId, | ||||
|         entity_type: 2, | ||||
|         entity_id: task.id | ||||
|       } | ||||
|     }).then(() => { | ||||
|       setTaskTags((prevValue) => prevValue.filter((tag) => tag.id !== tagId)) | ||||
|       dispatch(setProjectBoardFetch(projectId)); | ||||
|     }) | ||||
|   } | ||||
|  | ||||
|   function closeAcceptModal() { | ||||
|     setAcceptModalOpen(false); | ||||
|   } | ||||
| @@ -478,7 +520,6 @@ export const ModalTiсket = ({ | ||||
|               <img src={fullScreen}></img> | ||||
|             </Link> | ||||
|           </h3> | ||||
|  | ||||
|           <div className="content__task"> | ||||
|             {editOpen ? ( | ||||
|               <input | ||||
| @@ -813,6 +854,42 @@ export const ModalTiсket = ({ | ||||
|           </div> | ||||
|  | ||||
|           <div className="workers_box-bottom"> | ||||
|             <div className='tags'> | ||||
|               <div className='tags__selected'> | ||||
|                 {taskTags.map((tag) => { | ||||
|                   return <div className='tags__selected__item' key={tag.id} style={{background: tag.color}}> | ||||
|                     <p> | ||||
|                       {tag.slug} | ||||
|                     </p> | ||||
|                     <img src={close} className='delete' alt='delete' onClick={() => deleteTagFromTask(tag.id)} /> | ||||
|                   </div> | ||||
|                 }) | ||||
|                 } | ||||
|               </div> | ||||
|               <div className='tags__select' onClick={() => setSelectTagsOpen(!selectTagsOpen)}> | ||||
|                 <span>Выберите тег</span> | ||||
|                 <img | ||||
|                     className={selectTagsOpen ? "open" : ""} | ||||
|                     src={arrowDown} | ||||
|                     alt="arrow" | ||||
|                 /> | ||||
|               </div> | ||||
|               {selectTagsOpen && | ||||
|                   <div className='tags__dropDown'> | ||||
|                     <img onClick={() => setSelectTagsOpen(false)} className='tags__dropDown__close' src={close} alt="close" /> | ||||
|                     {correctProjectTags.map((tag) => { | ||||
|                       return <div className='tagItem' key={tag.id} onClick={() => addTagToTask(tag.id)}> | ||||
|                         <p>{tag.slug}</p> | ||||
|                         <span style={{background: tag.color}} /> | ||||
|                       </div> | ||||
|                     }) | ||||
|                     } | ||||
|                     {!Boolean(correctProjectTags.length) && | ||||
|                       <p className='tags__dropDown__noItem'>Нет тегов</p> | ||||
|                     } | ||||
|                   </div> | ||||
|               } | ||||
|             </div> | ||||
|             <div | ||||
|               className={editOpen ? "edit" : ""} | ||||
|               onClick={() => { | ||||
|   | ||||
| @@ -971,7 +971,7 @@ | ||||
|       } | ||||
|  | ||||
|       &-bottom { | ||||
|         padding: 20px 110px 35px 56px; | ||||
|         padding: 10px 110px 15px 56px; | ||||
|         font-weight: 400; | ||||
|         font-size: 14px; | ||||
|         line-height: 38px; | ||||
| @@ -991,6 +991,129 @@ | ||||
|           } | ||||
|         } | ||||
|  | ||||
|         .tags { | ||||
|           display: flex; | ||||
|           flex-direction: column; | ||||
|           position: relative; | ||||
|           row-gap: 5px; | ||||
|           padding: 5px; | ||||
|           border-radius: 10px; | ||||
|           border: 1px solid #e0e0e0; | ||||
|           margin-bottom: 10px; | ||||
|  | ||||
|           &__selected { | ||||
|             display: flex; | ||||
|             flex-wrap: wrap; | ||||
|             padding: 0; | ||||
|             width: 100%; | ||||
|             gap: 8px; | ||||
|             max-width: 200px; | ||||
|  | ||||
|             &__item { | ||||
|               display: flex; | ||||
|               padding: 3px 5px 3px 8px; | ||||
|               border-radius: 8px; | ||||
|               align-items: center; | ||||
|               column-gap: 8px; | ||||
|               cursor: default; | ||||
|  | ||||
|               p { | ||||
|                 font-weight: 600; | ||||
|                 text-decoration: none !important; | ||||
|                 font-size: 15px; | ||||
|                 margin: 0; | ||||
|                 line-height: 15px; | ||||
|                 color: white; | ||||
|               } | ||||
|  | ||||
|               .delete { | ||||
|                 cursor: pointer; | ||||
|                 width: 12px; | ||||
|                 height: 12px; | ||||
|               } | ||||
|             } | ||||
|           } | ||||
|  | ||||
|           &__select { | ||||
|             width: 100%; | ||||
|             height: 25px; | ||||
|             border-radius: 8px; | ||||
|             border: 1px solid gray; | ||||
|             padding: 5px 8px; | ||||
|             display: flex; | ||||
|             justify-content: space-between; | ||||
|  | ||||
|             span { | ||||
|               font-size: 14px; | ||||
|               color: black; | ||||
|             } | ||||
|  | ||||
|             img { | ||||
|               transition: all 0.3s ease; | ||||
|             } | ||||
|  | ||||
|             .open { | ||||
|               transform: rotate(180deg); | ||||
|             } | ||||
|           } | ||||
|  | ||||
|           &__dropDown { | ||||
|             position: absolute; | ||||
|             padding: 15px 10px 10px; | ||||
|             background: white; | ||||
|             width: 100%; | ||||
|             border-radius: 8px; | ||||
|             border: 1px solid #e4e4e4; | ||||
|             top: 110%; | ||||
|             display: flex; | ||||
|             flex-direction: column; | ||||
|             row-gap: 4px; | ||||
|             z-index: 10; | ||||
|  | ||||
|             &__close { | ||||
|               width: 8px; | ||||
|               height: 8px; | ||||
|               position: absolute; | ||||
|               right: 8px; | ||||
|               top: 5px; | ||||
|             } | ||||
|  | ||||
|             .tagItem { | ||||
|               display: flex; | ||||
|               width: 100%; | ||||
|               cursor: pointer; | ||||
|               column-gap: 8px; | ||||
|               padding: 5px; | ||||
|               border: 1px solid #ececec; | ||||
|               border-radius: 8px; | ||||
|               justify-content: space-between; | ||||
|  | ||||
|               p { | ||||
|                 font-size: 18px; | ||||
|                 font-weight: 500; | ||||
|                 margin: 0; | ||||
|                 line-height: 20px; | ||||
|                 text-decoration: none; | ||||
|               } | ||||
|  | ||||
|               span { | ||||
|                 width: 18px; | ||||
|                 height: 18px; | ||||
|                 border-radius: 50px; | ||||
|               } | ||||
|             } | ||||
|  | ||||
|             &__noItem { | ||||
|               line-height: 20px; | ||||
|               font-size: 15px; | ||||
|               margin: 0; | ||||
|               font-weight: 500; | ||||
|               text-decoration: none !important; | ||||
|               cursor: default; | ||||
|             } | ||||
|           } | ||||
|         } | ||||
|  | ||||
|         .edit { | ||||
|           background: #52b709; | ||||
|           border-radius: 50px; | ||||
|   | ||||
| @@ -12,6 +12,7 @@ import { | ||||
|   filteredParticipateTasks, | ||||
|   getBoarderLoader, | ||||
|   getProjectBoard, | ||||
|   deleteTagProject, | ||||
|   modalToggle, | ||||
|   movePositionProjectTask, | ||||
|   moveProjectTask, | ||||
| @@ -71,6 +72,7 @@ export const ProjectTracker = () => { | ||||
|   const [tags, setTags] = useState({ | ||||
|     open: false, | ||||
|     add: false, | ||||
|     edit: false | ||||
|   }); | ||||
|   const [color, setColor] = useState("#aabbcc"); | ||||
|   const [tagInfo, setTagInfo] = useState({ description: "", name: "" }); | ||||
| @@ -318,6 +320,37 @@ export const ProjectTracker = () => { | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   function editTag() { | ||||
|     apiRequest("/mark/update", { | ||||
|       method: "PUT", | ||||
|       data: { | ||||
|         mark_id: tagInfo.editMarkId, | ||||
|         title: tagInfo.description, | ||||
|         slug: tagInfo.name, | ||||
|         color: color | ||||
|       } | ||||
|     }).then(() => { | ||||
|       dispatch(setProjectBoardFetch(projectId.id)) | ||||
|       setTags((prevState) => ({ | ||||
|         ...prevState, | ||||
|         edit: false, | ||||
|       })); | ||||
|     }) | ||||
|   } | ||||
|  | ||||
|   function deleteTag(tagId) { | ||||
|     apiRequest("/mark/detach", { | ||||
|       method: "DELETE", | ||||
|       data: { | ||||
|         mark_id: tagId, | ||||
|         entity_type: 1, | ||||
|         entity_id: projectId.id, | ||||
|       } | ||||
|     }).then(() => { | ||||
|       dispatch(deleteTagProject(tagId)) | ||||
|     }) | ||||
|   } | ||||
|  | ||||
|   return ( | ||||
|     <div className="tracker"> | ||||
|       <ProfileHeader /> | ||||
| @@ -586,13 +619,19 @@ export const ProjectTracker = () => { | ||||
|                           className="close" | ||||
|                           alt="close" | ||||
|                           onClick={() => { | ||||
|                             setTags((prevState) => ({ | ||||
|                               ...prevState, | ||||
|                             setTags({ | ||||
|                               open: false, | ||||
|                             })); | ||||
|                               add: false, | ||||
|                               edit: false | ||||
|                             }); | ||||
|                             setTagInfo({ | ||||
|                               description: '', | ||||
|                               name: '' | ||||
|                             }) | ||||
|                             setColor("#aabbcc") | ||||
|                           }} | ||||
|                         /> | ||||
|                         {!tags.add && ( | ||||
|                         {!tags.add && !tags.edit && ( | ||||
|                           <div className="tags__list__created"> | ||||
|                             {projectBoard.mark.map((tag) => { | ||||
|                               return ( | ||||
| @@ -609,6 +648,21 @@ export const ProjectTracker = () => { | ||||
|                                       style={{ background: tag.color }} | ||||
|                                     /> | ||||
|                                   </div> | ||||
|                                   <div className='tagItem__images'> | ||||
|                                     <img src={edit} alt='edit' onClick={() => { | ||||
|                                       setTags((prevState) => ({ | ||||
|                                         ...prevState, | ||||
|                                         edit: true, | ||||
|                                       })) | ||||
|                                       setTagInfo({ | ||||
|                                         description: tag.title, | ||||
|                                         name: tag.slug, | ||||
|                                         editMarkId: tag.id | ||||
|                                       }) | ||||
|                                       setColor(tag.color) | ||||
|                                     }} /> | ||||
|                                     <img onClick={() => deleteTag(tag.id)} className='delete' src={close} alt='delete' /> | ||||
|                                   </div> | ||||
|                                 </div> | ||||
|                               ); | ||||
|                             })} | ||||
| @@ -626,7 +680,7 @@ export const ProjectTracker = () => { | ||||
|                             </div> | ||||
|                           </div> | ||||
|                         )} | ||||
|                         {tags.add && ( | ||||
|                         {(tags.add || tags.edit) && ( | ||||
|                           <div className="formTag"> | ||||
|                             <img | ||||
|                               src={arrow} | ||||
| @@ -636,7 +690,13 @@ export const ProjectTracker = () => { | ||||
|                                 setTags((prevState) => ({ | ||||
|                                   ...prevState, | ||||
|                                   add: false, | ||||
|                                   edit: false | ||||
|                                 })); | ||||
|                                 setTagInfo({ | ||||
|                                   description: '', | ||||
|                                   name: '' | ||||
|                                 }) | ||||
|                                 setColor("#aabbcc") | ||||
|                               }} | ||||
|                             /> | ||||
|                             <input | ||||
| @@ -665,14 +725,17 @@ export const ProjectTracker = () => { | ||||
|                             /> | ||||
|                             <HexColorPicker color={color} onChange={setColor} /> | ||||
|                             <button | ||||
|                               onClick={addNewTag} | ||||
|                               onClick={() => { | ||||
|                                 tags.add ? addNewTag() : editTag() | ||||
|                               } | ||||
|                             } | ||||
|                               className={ | ||||
|                                 tagInfo.name && tagInfo.description | ||||
|                                   ? "formTag__btn" | ||||
|                                   : "formTag__btn disable" | ||||
|                               } | ||||
|                             > | ||||
|                               Добавить | ||||
|                               {tags.add ? 'Добавить' : 'Изменить'} | ||||
|                             </button> | ||||
|                           </div> | ||||
|                         )} | ||||
| @@ -695,6 +758,7 @@ export const ProjectTracker = () => { | ||||
|                   projectName={projectBoard.name} | ||||
|                   projectUsers={projectBoard.projectUsers} | ||||
|                   projectOwnerId={projectBoard.owner_id} | ||||
|                   projectMarks={projectBoard.mark} | ||||
|                 /> | ||||
|               )} | ||||
|  | ||||
| @@ -827,6 +891,14 @@ export const ProjectTracker = () => { | ||||
|                                     /> | ||||
|                                   )} | ||||
|                                 </div> | ||||
|                                 {Boolean(task.mark.length) && | ||||
|                                   <div className='tasks__board__item__tags'> | ||||
|                                     {task.mark.map((tag) => { | ||||
|                                       return <div className='tagItem' key={tag.id} style={{background: tag.color}}><p>{tag.slug}</p></div> | ||||
|                                     }) | ||||
|                                     } | ||||
|                                   </div> | ||||
|                                 } | ||||
|                                 {task.dead_line && ( | ||||
|                                   <div className="tasks__board__item__deadLine"> | ||||
|                                     <p>Срок исполнения:</p> | ||||
|   | ||||
| @@ -386,7 +386,7 @@ | ||||
|  | ||||
|             .persons__list { | ||||
|               position: absolute; | ||||
|               z-index: 20; | ||||
|               z-index: 8; | ||||
|               display: flex; | ||||
|               flex-direction: column; | ||||
|               background: linear-gradient(180deg, #ffffff 0%, #ebebeb 100%); | ||||
| @@ -784,7 +784,7 @@ | ||||
|               &__list { | ||||
|                 position: absolute; | ||||
|                 background: #f8f9fa; | ||||
|                 z-index: 20; | ||||
|                 z-index: 8; | ||||
|                 border-radius: 8px; | ||||
|                 padding: 20px 10px 10px; | ||||
|                 top: 30px; | ||||
| @@ -808,6 +808,7 @@ | ||||
|                   margin-top: 8px; | ||||
|  | ||||
|                   .tagItem { | ||||
|                     position: relative; | ||||
|                     display: flex; | ||||
|                     flex-direction: column; | ||||
|                     padding: 5px; | ||||
| @@ -835,6 +836,23 @@ | ||||
|                         border-radius: 50px; | ||||
|                       } | ||||
|                     } | ||||
|  | ||||
|                     &__images { | ||||
|                       position: absolute; | ||||
|                       right: 5px; | ||||
|                       top: 3px; | ||||
|                       display: flex; | ||||
|                       column-gap: 3px; | ||||
|  | ||||
|                       img { | ||||
|                         cursor: pointer; | ||||
|                       } | ||||
|  | ||||
|                       .delete { | ||||
|                         width: 14px; | ||||
|                         height: 14px; | ||||
|                       } | ||||
|                     } | ||||
|                   } | ||||
|                 } | ||||
|  | ||||
| @@ -999,7 +1017,6 @@ | ||||
|  | ||||
|           &__item { | ||||
|             width: 328px; | ||||
|             max-height: 250px; | ||||
|             padding: 16px; | ||||
|             position: relative; | ||||
|             box-shadow: 0px 3px 2px -2px rgba(0, 0, 0, 0.06), | ||||
| @@ -1147,6 +1164,21 @@ | ||||
|                 height: 25px; | ||||
|               } | ||||
|             } | ||||
|  | ||||
|             &__tags { | ||||
|               display: flex; | ||||
|               flex-wrap: wrap; | ||||
|               column-gap: 6px; | ||||
|               row-gap: 3px; | ||||
|               margin: 5px 0 10px; | ||||
|  | ||||
|               .tagItem { | ||||
|                 padding: 3px 10px; | ||||
|                 border-radius: 10px; | ||||
|                 color: white; | ||||
|                 font-size: 12px; | ||||
|               } | ||||
|             } | ||||
|           } | ||||
|  | ||||
|           .openItems { | ||||
|   | ||||
| @@ -42,6 +42,9 @@ export const projectsTrackerSlice = createSlice({ | ||||
|         (person) => person.user_id !== action.payload | ||||
|       ); | ||||
|     }, | ||||
|     deleteTagProject: (state, action) => { | ||||
|       state.projectBoard.mark = state.projectBoard.mark.filter((tag) => tag.id !== action.payload) | ||||
|     }, | ||||
|     addPersonToProject: (state, action) => { | ||||
|       state.projectBoard.projectUsers.push(action.payload); | ||||
|     }, | ||||
| @@ -181,6 +184,7 @@ export const { | ||||
|   setColumnId, | ||||
|   setColumnPriority, | ||||
|   deletePersonOnProject, | ||||
|   deleteTagProject, | ||||
|   addPersonToProject, | ||||
|   addNewTagToProject, | ||||
|   filterCreatedByMe, | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Mikola
					Mikola