From 10ffb1f7f19cba377ab91f7c3417375096b7e49c Mon Sep 17 00:00:00 2001 From: MaxOvs19 Date: Tue, 9 Apr 2024 21:09:06 +0300 Subject: [PATCH] Create new component TrackerTagList --- .../trackerSelectExecutor.scss | 129 +++++++++ .../TrackerTagList/TrackerTagList.jsx | 273 ++++++++++++++++++ .../TrackerTagList/trackerTagList.scss | 0 src/pages/ProjectTracker/ProjectTracker.jsx | 249 +--------------- src/pages/Tracker/tracker.scss | 151 +--------- 5 files changed, 419 insertions(+), 383 deletions(-) create mode 100644 src/components/TrackerTagList/TrackerTagList.jsx create mode 100644 src/components/TrackerTagList/trackerTagList.scss diff --git a/src/components/TrackerSelectExecutor/trackerSelectExecutor.scss b/src/components/TrackerSelectExecutor/trackerSelectExecutor.scss index e69de29b..e7cce324 100644 --- a/src/components/TrackerSelectExecutor/trackerSelectExecutor.scss +++ b/src/components/TrackerSelectExecutor/trackerSelectExecutor.scss @@ -0,0 +1,129 @@ +.tasks { + &__head { + &__executor { + display: flex; + align-items: center; + justify-content: space-between; + cursor: pointer; + margin-right: 10px; + border-radius: 8px; + border: 1px solid #e3e2e2; + padding: 2px 6px; + position: relative; + max-width: 190px; + width: 100%; + + @media (max-width: 915px) { + margin-right: 0; + width: 100%; + max-width: none; + } + + @media (max-width: 650px) { + border-color: gray; + } + + &-selected { + display: flex; + align-items: center; + border-radius: 8px; + max-width: 220px; + width: 100%; + margin-right: 10px; + justify-content: center; + + p { + color: #252c32; + font-weight: 400; + font-size: 14px; + line-height: 24px; + max-width: 155px; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + } + + .avatar { + margin: 0 5px; + } + + .delete { + cursor: pointer; + } + + img { + display: flex; + width: 20px; + height: 20px; + } + + @media (max-width: 915px) { + width: 100%; + max-width: none; + justify-content: start; + + p { + font-size: 16px; + max-width: none; + } + } + } + p { + color: #252c32; + font-weight: 400; + font-size: 14px; + line-height: 24px; + } + + img { + transition: all 0.15s ease; + margin-left: 5px; + } + + .open { + transform: rotate(180deg); + } + + &-dropdown { + position: absolute; + top: 33px; + left: 0; + background: white; + border-radius: 8px; + z-index: 5; + padding: 10px 10px; + display: flex; + flex-direction: column; + row-gap: 7px; + width: 100%; + + .executor-dropdown__person { + display: flex; + justify-content: space-between; + align-items: center; + p { + max-width: 155px; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + + @media (max-width: 915px) { + max-width: none; + } + } + + img { + width: 20px; + height: 20px; + } + + &:hover { + p { + font-weight: 600; + } + } + } + } + } + } +} diff --git a/src/components/TrackerTagList/TrackerTagList.jsx b/src/components/TrackerTagList/TrackerTagList.jsx new file mode 100644 index 00000000..0ac5b972 --- /dev/null +++ b/src/components/TrackerTagList/TrackerTagList.jsx @@ -0,0 +1,273 @@ +import React, { useEffect, useState } from "react"; +import { HexColorPicker } from "react-colorful"; +import { useDispatch } from "react-redux"; +import { useParams } from "react-router-dom"; + +import { + addNewTagToProject, + deleteTagProject, + setProjectBoardFetch +} from "@redux/projectsTrackerSlice"; + +import { apiRequest } from "@api/request"; + +import { useNotification } from "@hooks/useNotification"; + +import arrowDown from "assets/icons/arrows/selectArrow.png"; +import close from "assets/icons/close.png"; +import edit from "assets/icons/edit.svg"; + +const TrackerTagList = ({ projectBoard }) => { + const dispatch = useDispatch(); + const projectId = useParams(); + + const { showNotification } = useNotification(); + const [tagInfo, setTagInfo] = useState({ description: "", name: "" }); + const [color, setColor] = useState("#aabbcc"); + const [tags, setTags] = useState({ + open: false, + add: false, + 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)); + showNotification({ + show: true, + text: "Тег удален", + type: "success" + }); + }); + } + + function addNewTag() { + apiRequest("/mark/create", { + method: "POST", + data: { + title: tagInfo.description, + slug: tagInfo.name, + color: color, + status: 1 + } + }).then((data) => { + apiRequest("/mark/attach", { + method: "POST", + data: { + mark_id: data.id, + entity_type: 1, + entity_id: projectId.id + } + }).then((data) => { + dispatch(addNewTagToProject(data.mark)); + setTags((prevState) => ({ + ...prevState, + add: false + })); + showNotification({ + show: true, + text: "Тег успешно создан", + type: "success" + }); + }); + }); + } + + 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 + })); + setTagInfo({ description: "", name: "" }); + setColor("#aabbcc"); + showNotification({ + show: true, + text: "Тег успешно изменён", + type: "success" + }); + }); + } + + const initListeners = () => { + document.addEventListener("click", closeByClickingOut); + }; + + const closeByClickingOut = (event) => { + const path = event.path || (event.composedPath && event.composedPath()); + if ( + event && + !path.find( + (div) => + div.classList && + (div.classList.contains("tasks__head__tags") || + div.classList.contains("tags__list")) + ) + ) { + setTags({ open: false, add: false, edit: false }); + setTagInfo({ description: "", name: "" }); + setColor("#aabbcc"); + } + }; + + useEffect(() => { + initListeners(); + }, []); + + return ( +
+
{ + setTags((prevState) => ({ + ...prevState, + open: !tags.open + })); + }} + > +

Список тегов

+ arrow +
+ {tags.open && ( +
+ {!tags.add && !tags.edit && ( +
+ setTags((prevState) => ({ + ...prevState, + add: true + })) + } + > +

Добавить новый тег

+ + +
+ )} + {!tags.add && !tags.edit && ( +
+ {projectBoard.mark.map((tag) => { + return ( +
+
+ +
+ {tag.slug} +

{tag.title}

+
+
+
+ edit { + setTags((prevState) => ({ + ...prevState, + edit: true + })); + setTagInfo({ + description: tag.title, + name: tag.slug, + editMarkId: tag.id + }); + setColor(tag.color); + }} + /> + deleteTag(tag.id)} + className="delete" + src={close} + alt="delete" + /> +
+
+ ); + })} +
+ )} + {(tags.add || tags.edit) && ( +
+ + setTagInfo((prevState) => ({ + ...prevState, + description: e.target.value + })) + } + /> + + setTagInfo((prevState) => ({ + ...prevState, + name: e.target.value + })) + } + /> + + + {(tags.add || tags.edit) && ( + + )} +
+ )} +
+ )} +
+ ); +}; + +export default TrackerTagList; diff --git a/src/components/TrackerTagList/trackerTagList.scss b/src/components/TrackerTagList/trackerTagList.scss new file mode 100644 index 00000000..e69de29b diff --git a/src/pages/ProjectTracker/ProjectTracker.jsx b/src/pages/ProjectTracker/ProjectTracker.jsx index 07cee39b..6d8afc87 100644 --- a/src/pages/ProjectTracker/ProjectTracker.jsx +++ b/src/pages/ProjectTracker/ProjectTracker.jsx @@ -1,15 +1,11 @@ import moment from "moment"; import React, { useEffect, useRef, useState } from "react"; -import { HexColorPicker } from "react-colorful"; import { useDispatch, useSelector } from "react-redux"; import { Link, useParams } from "react-router-dom"; import { activeLoader, - addNewTagToProject, - deleteTagProject, filterCreatedByMe, - filteredExecutorTasks, filteredParticipateTasks, getBoarderLoader, getProjectBoard, @@ -41,11 +37,10 @@ import { ProfileBreadcrumbs } from "@components/ProfileBreadcrumbs/ProfileBreadc import { ProfileHeader } from "@components/ProfileHeader/ProfileHeader"; import TrackerSelectColumn from "@components/TrackerSelectColumn/TrackerSelectColumn"; import TrackerSelectExecutor from "@components/TrackerSelectExecutor/TrackerSelectExecutor"; +import TrackerTagList from "@components/TrackerTagList/TrackerTagList"; import arrow from "assets/icons/arrows/arrowRight.png"; -import arrowDown from "assets/icons/arrows/selectArrow.png"; import category from "assets/icons/category.svg"; -import close from "assets/icons/close.png"; import commentsBoard from "assets/icons/commentsBoard.svg"; import del from "assets/icons/delete.svg"; import edit from "assets/icons/edit.svg"; @@ -71,15 +66,8 @@ export const ProjectTracker = () => { const [modalActiveTicket, setModalActiveTicket] = useState(false); const [selectedTicket, setSelectedTicket] = useState({}); const [personListOpen, setPersonListOpen] = useState(false); - const [tags, setTags] = useState({ - open: false, - add: false, - edit: false - }); const [acceptModalOpen, setAcceptModalOpen] = useState(false); const [currentColumnDelete, setCurrentColumnDelete] = useState(null); - const [color, setColor] = useState("#aabbcc"); - const [tagInfo, setTagInfo] = useState({ description: "", name: "" }); const [checkBoxParticipateTasks, setCheckBoxParticipateTasks] = useState(false); const [filteredNoTasks, setFilteredNoTasks] = useState(false); @@ -294,81 +282,6 @@ export const ProjectTracker = () => { dispatch(setProjectBoardFetch(projectId.id)); } - function addNewTag() { - apiRequest("/mark/create", { - method: "POST", - data: { - title: tagInfo.description, - slug: tagInfo.name, - color: color, - status: 1 - } - }).then((data) => { - apiRequest("/mark/attach", { - method: "POST", - data: { - mark_id: data.id, - entity_type: 1, - entity_id: projectId.id - } - }).then((data) => { - dispatch(addNewTagToProject(data.mark)); - setTags((prevState) => ({ - ...prevState, - add: false - })); - showNotification({ - show: true, - text: "Тег успешно создан", - type: "success" - }); - }); - }); - } - - 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 - })); - setTagInfo({ description: "", name: "" }); - setColor("#aabbcc"); - showNotification({ - show: true, - text: "Тег успешно изменён", - type: "success" - }); - }); - } - - function deleteTag(tagId) { - apiRequest("/mark/detach", { - method: "DELETE", - data: { - mark_id: tagId, - entity_type: 1, - entity_id: projectId.id - } - }).then(() => { - dispatch(deleteTagProject(tagId)); - showNotification({ - show: true, - text: "Тег удален", - type: "success" - }); - }); - } - const initListeners = () => { document.addEventListener("click", closeByClickingOut); }; @@ -388,20 +301,6 @@ export const ProjectTracker = () => { setPersonListOpen(false); } - if ( - event && - !path.find( - (div) => - div.classList && - (div.classList.contains("tasks__head__tags") || - div.classList.contains("tags__list")) - ) - ) { - setTags({ open: false, add: false, edit: false }); - setTagInfo({ description: "", name: "" }); - setColor("#aabbcc"); - } - if ( event && !path.find( @@ -567,150 +466,8 @@ export const ProjectTracker = () => { setSelectedExecutor={setSelectedExecutor} /> -
-
{ - setTags((prevState) => ({ - ...prevState, - open: !tags.open - })); - }} - > -

Список тегов

- arrow -
- {tags.open && ( -
- {!tags.add && !tags.edit && ( -
- setTags((prevState) => ({ - ...prevState, - add: true - })) - } - > -

Добавить новый тег

- + -
- )} - {!tags.add && !tags.edit && ( -
- {projectBoard.mark.map((tag) => { - return ( -
-
- -
- - {tag.slug} - -

- {tag.title} -

-
-
-
- edit { - setTags((prevState) => ({ - ...prevState, - edit: true - })); - setTagInfo({ - description: tag.title, - name: tag.slug, - editMarkId: tag.id - }); - setColor(tag.color); - }} - /> - deleteTag(tag.id)} - className="delete" - src={close} - alt="delete" - /> -
-
- ); - })} -
- )} - {(tags.add || tags.edit) && ( -
- - setTagInfo((prevState) => ({ - ...prevState, - description: e.target.value - })) - } - /> - - setTagInfo((prevState) => ({ - ...prevState, - name: e.target.value - })) - } - /> - - - {(tags.add || tags.edit) && ( - - )} -
- )} -
- )} -
+ +

К списку проектов

arrow diff --git a/src/pages/Tracker/tracker.scss b/src/pages/Tracker/tracker.scss index 06bd1c07..45f7f351 100644 --- a/src/pages/Tracker/tracker.scss +++ b/src/pages/Tracker/tracker.scss @@ -361,132 +361,6 @@ } } - &__executor { - display: flex; - align-items: center; - justify-content: space-between; - cursor: pointer; - margin-right: 10px; - border-radius: 8px; - border: 1px solid #e3e2e2; - padding: 2px 6px; - position: relative; - max-width: 190px; - width: 100%; - - @media (max-width: 915px) { - margin-right: 0; - width: 100%; - max-width: none; - } - - @media (max-width: 650px) { - border-color: gray; - } - - &-selected { - display: flex; - align-items: center; - border-radius: 8px; - max-width: 220px; - width: 100%; - margin-right: 10px; - justify-content: center; - - p { - color: #252c32; - font-weight: 400; - font-size: 14px; - line-height: 24px; - max-width: 155px; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - } - - .avatar { - margin: 0 5px; - } - - .delete { - cursor: pointer; - } - - img { - display: flex; - width: 20px; - height: 20px; - } - - @media (max-width: 915px) { - width: 100%; - max-width: none; - justify-content: start; - - p { - font-size: 16px; - max-width: none; - } - } - } - p { - color: #252c32; - font-weight: 400; - font-size: 14px; - line-height: 24px; - } - - img { - transition: all 0.15s ease; - margin-left: 5px; - } - - .open { - transform: rotate(180deg); - } - - &-dropdown { - position: absolute; - top: 33px; - left: 0; - background: white; - border-radius: 8px; - z-index: 5; - padding: 10px 10px; - display: flex; - flex-direction: column; - row-gap: 7px; - width: 100%; - - .executor-dropdown__person { - display: flex; - justify-content: space-between; - align-items: center; - p { - max-width: 155px; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - - @media (max-width: 915px) { - max-width: none; - } - } - - img { - width: 20px; - height: 20px; - } - - &:hover { - p { - font-weight: 600; - } - } - } - } - } - &__back { cursor: pointer; display: flex; @@ -1958,7 +1832,7 @@ .table { &__search { display: flex; - background: #F0F2F5; + background: #f0f2f5; border-radius: 5px; width: 100%; padding: 14px 12px; @@ -1976,11 +1850,11 @@ border: none; outline: none; font-size: 16px; - color: #9BABC5; + color: #9babc5; width: 100%; &::placeholder { - color: #9BABC5; + color: #9babc5; } } } @@ -1995,12 +1869,12 @@ width: 32px; border-radius: 5px; height: 32px; - color: #2E3A59; + color: #2e3a59; } .switch { border: none; - background: #F0F2F5; + background: #f0f2f5; font-weight: 600; } @@ -2016,12 +1890,12 @@ background: white; .page { - border: 1px solid #E8ECF8; + border: 1px solid #e8ecf8; background: none; &--active { border: none; - background: #9DA65D; + background: #9da65d; color: white; } } @@ -2029,17 +1903,20 @@ } table { - grid-template-columns: minmax(0px, 2fr) minmax(0px, 1fr) minmax(0px, 1fr) minmax(0px, 1fr); + grid-template-columns: minmax(0px, 2fr) minmax(0px, 1fr) minmax(0px, 1fr) minmax( + 0px, + 1fr + ); th { border-top: none; - border-bottom: 1px solid #F5F6F8; - color: #2E3A59; + border-bottom: 1px solid #f5f6f8; + color: #2e3a59; padding: 0 7.5px 15px; } td { padding: 22px 7.5px; - color: #2E3A59; + color: #2e3a59; border-top: none; p {