Skip to content

Commit

Permalink
Merge pull request #102 from intive/P2022-1394_API-integration-delete…
Browse files Browse the repository at this point in the history
…-issue-from-column

[P2022-1394] api integration delete issue from column
  • Loading branch information
jprymak authored Mar 28, 2022
2 parents 2b7f4f5 + cc9822a commit fe7ccae
Show file tree
Hide file tree
Showing 8 changed files with 139 additions and 63 deletions.
5 changes: 5 additions & 0 deletions src/api/boardStatus/mockBoardStatusApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@ const MockBoardStatusAPI = {
console.log("Fetching issues... response.status:", 200);
return [...mockIssues];
},
deleteIssue: async function (id: number) {
await sleep();
console.log(`Deleting issue with an id of ${id} response.status:`, 200);
return { data: mockIssues, status: 200 };
},
};

export default MockBoardStatusAPI;
12 changes: 8 additions & 4 deletions src/api/requestsApi.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import makeRequest from "./makeFetchRequest";
import { API_GET_BOARD_STATUS, API_GET_STATUS } from "./contsans";
import { API_GET_BOARD_STATUS, API_GET_STATUS, API_ISSUE } from "./contsans";

interface DataObject {
[key: string]: any;
Expand All @@ -16,6 +16,10 @@ const FetchDataAPI = {
const addedData = await response.json();
return addedData;
},
deleteData: async function (url: string, additionalData?: any) {
const response = await makeRequest(url, "DELETE", additionalData);
return response;
},
getBoardStatusById: async function (id: number) {
const boardStatus = await FetchDataAPI.getData(API_GET_BOARD_STATUS);
const status = await FetchDataAPI.getData(API_GET_STATUS);
Expand Down Expand Up @@ -62,9 +66,9 @@ const FetchDataAPI = {
);
return data.data.items;
},
deleteData: async function (url: string, additionalData?: any) {
const response = await makeRequest(url, "DELETE", additionalData);
return response;
deleteIssue: async function (id: string) {
const data = await FetchDataAPI.deleteData(`${API_ISSUE}${id}`);
return data;
},
};

Expand Down
38 changes: 38 additions & 0 deletions src/hooks/useAlerts.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { useState, useEffect } from "react";

export const useAlerts = () => {
const [isSuccessAlertActive, setIsSuccessAlertActive] =
useState<boolean>(false);
const [isErrorAlertActive, setIsErrorAlertActive] = useState<boolean>(false);
const [message, setMessage] = useState<string>("");

useEffect(() => {
if (isSuccessAlertActive === true) {
setTimeout(() => {
setIsSuccessAlertActive(false);
}, 3000);
}
}, [isSuccessAlertActive]);

const openAlert = (alertType: "success" | "error", msg: string) => {
setMessage(msg);
if (alertType === "success") {
setIsSuccessAlertActive(true);
}
if (alertType === "error") {
setIsErrorAlertActive(true);
}
};

const closeErrorAlert = () => {
setIsErrorAlertActive(false);
};

return {
isSuccessAlertActive,
isErrorAlertActive,
message,
openAlert,
closeErrorAlert,
};
};
14 changes: 13 additions & 1 deletion src/modules/TasksCard/TasksCard.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,44 +16,56 @@ export const WithThreeTickets = Template.bind({});
export const WithEightTickets = Template.bind({});

const TicketList = [
<Ticket issueId='999' title={"Unassigned task"} key={"task1"} />,
<Ticket
issueId='999'
title={"Unassigned task"}
key={"task1"}
handleDeleteTicket={() => console.log("deleted")}
/>,
<Ticket
handleDeleteTicket={() => console.log("deleted")}
issueId='999'
title={"Example task"}
assignedTo={"John Doe"}
key={"task2"}
/>,
<Ticket
handleDeleteTicket={() => console.log("deleted")}
issueId='999'
title={"Very long title Very long title Very long title Very long title"}
assignedTo={"Very long name Very long name Very long name Very long name"}
key={"task3"}
/>,
<Ticket
handleDeleteTicket={() => console.log("deleted")}
issueId='999'
title={"Task 4"}
assignedTo={"John Doe"}
key={"task4"}
/>,
<Ticket
handleDeleteTicket={() => console.log("deleted")}
issueId='999'
title={"Task 5"}
assignedTo={"John Doe"}
key={"task4"}
/>,
<Ticket
handleDeleteTicket={() => console.log("deleted")}
issueId='999'
title={"Task 6"}
assignedTo={"John Doe"}
key={"task4"}
/>,
<Ticket
handleDeleteTicket={() => console.log("deleted")}
issueId='999'
title={"Task 7"}
assignedTo={"John Doe"}
key={"task4"}
/>,
<Ticket
handleDeleteTicket={() => console.log("deleted")}
issueId='999'
title={"Task 8"}
assignedTo={"John Doe"}
Expand Down
18 changes: 14 additions & 4 deletions src/modules/Ticket/Ticket.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,23 @@ import {
CardContentNoPadding,
} from "./Ticket.style";
import ThreeDotsMenu from "@components/ThreeDotsMenu/ThreeDotsMenu";
import { mockMenuItems } from "../../mockData/menuItems";
import { useTranslation } from "react-i18next";

import DeleteOutlineIcon from "@mui/icons-material/DeleteOutline";
interface TicketProps {
title: string;
assignedTo?: string;
issueId: string;
handleDeleteTicket: (issueId: string) => void;
}

const Ticket = (props: TicketProps) => {
const { t, i18n } = useTranslation();
const navigate = useNavigate();
const { pathname } = useLocation();
const [isAssigned, setIsAssigned] = React.useState(
props.assignedTo ? true : false
);
const { t, i18n } = useTranslation();

const defaultProps = {
assignedTo: t("unassigned"),
};
Expand All @@ -36,6 +37,15 @@ const Ticket = (props: TicketProps) => {
navigate(`${pathname}/${props.title}&${props.issueId}`);
};

const ticketMenu = [
{
id: 0,
icon: <DeleteOutlineIcon />,
label: `${t("deleteIssue")}`,
onClick: () => props.handleDeleteTicket(props.issueId),
},
];

return (
<StyledTicket onClick={handleClickTicket}>
<CardContentNoPadding>
Expand All @@ -47,7 +57,7 @@ const Ticket = (props: TicketProps) => {
{isAssigned && <AssignedTo>{t("assignedTo")}&nbsp;</AssignedTo>}
<Assignee>{props.assignedTo}</Assignee>
</StyledTicketContentText>
<ThreeDotsMenu menuItems={mockMenuItems} />
<ThreeDotsMenu menuItems={ticketMenu} />
</StyledTicketContent>
</CardContentNoPadding>
</StyledTicket>
Expand Down
5 changes: 4 additions & 1 deletion src/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,5 +59,8 @@
"LoginError": "Fields cannot be empty!",
"NewBoardAddedWithSuccess": "A new board has been successfully added!",
"NewBoardAddedWithError": "An error occurred while creating the new board",
"taskManagementTool": "Task management tool"
"taskManagementTool": "Task management tool",
"deleteIssue": "Delete Issue",
"IssueDeletedSuccess": "Issue has been successfully deleted",
"IssueDeletedError": "A error occured while deleting issue"
}
5 changes: 4 additions & 1 deletion src/translations/pl.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,5 +59,8 @@
"LoginError": "Pola nie mogą być puste!",
"NewBoardAddedWithSuccess": "Dodano nową tablicę!",
"NewBoardAddedWithError": "Wystąpił błąd podczas tworzenia nowej tablicy",
"taskManagementTool": "System zarządzania zadaniami"
"taskManagementTool": "System zarządzania zadaniami",
"deleteIssue": "Usuń Zadanie",
"IssueDeletedSuccess": "Zadanie zostało pomyślnie usunięte",
"IssueDeletedError": "Wystąpił błąd podczas usuwania zadania"
}
105 changes: 53 additions & 52 deletions src/views/Board/Board.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { useState, useEffect } from "react";
import { useState, useEffect, useCallback } from "react";
import { useParams } from "react-router-dom";
import { useTranslation } from "react-i18next";
import { API_ADD_NEW_STATUS, API_GET_BOARD_STATUS } from "../../api/contsans";
import { cleainingSuccessAlerts } from "../../scripts/cleaningSuccessAlerts";
import { useAlerts } from "../../hooks/useAlerts";

import DeleteOutlineIcon from "@mui/icons-material/DeleteOutline";
import ViewWeekOutlinedIcon from "@mui/icons-material/ViewWeekOutlined";
Expand Down Expand Up @@ -38,14 +38,20 @@ interface Statuses {

export const Board = () => {
const { t } = useTranslation();
const {
isSuccessAlertActive,
isErrorAlertActive,
message,
openAlert,
closeErrorAlert,
} = useAlerts();

const [columns, setColumns] = useState<Array<object>>([]);
const [statuses, setStatuses] = useState<Statuses[]>([]);
const [filteredIssues, setFilteredIssues] = useState<any>({});
const [isDialogOpen, setIsDialogOpen] = useState(false);
const [isSuccess, setIsSuccess] = useState(false);
const [boardNumberAlert, setBoardNumberAlert] = useState(false);
const [boardNameAlert, setBoardNameAlert] = useState(false);

const { boardId, projectName, projectId, board } = useParams();
const [state, setState] = useState({});

Expand All @@ -57,39 +63,31 @@ export const Board = () => {
setStatuses(boardStatus[1]);
}
fetchStatus();
cleainingSuccessAlerts(setisAlertStatusSuccessOpen);
fetchIssues();
return () => {
setState({});
};
}, [isSuccess]);

const [isAlertStatusSuccessOpen, setisAlertStatusSuccessOpen] =
useState(false);
const [isAlertStatusErrorOpen, setisAlertStatusErrorOpen] = useState(false);
const fetchIssues = useCallback(async () => {
await importApiModule();
const issues = await FetchDataAPI.getIssuesByBoardStatusId(boardId);

useEffect(() => {
async function fetchIssues() {
await importApiModule();
const issues = await FetchDataAPI.getIssuesByBoardStatusId(boardId);

const filterIssuesByStatusId = () => {
const issuesFilteredByStatusId: any = {};

issues.reduce((_: any, issue: any) => {
if (!issuesFilteredByStatusId[issue.statusId]) {
issuesFilteredByStatusId[issue.statusId] = [];
issuesFilteredByStatusId[issue.statusId].push(issue);
} else {
issuesFilteredByStatusId[issue.statusId].push(issue);
}
}, issuesFilteredByStatusId);
const filterIssuesByStatusId = () => {
const issuesFilteredByStatusId: any = {};

return issuesFilteredByStatusId;
};
issues.reduce((_: any, issue: any) => {
if (!issuesFilteredByStatusId[issue.statusId]) {
issuesFilteredByStatusId[issue.statusId] = [];
issuesFilteredByStatusId[issue.statusId].push(issue);
} else {
issuesFilteredByStatusId[issue.statusId].push(issue);
}
}, issuesFilteredByStatusId);

setFilteredIssues(filterIssuesByStatusId());
}
fetchIssues();
return () => {
setState({});
return issuesFilteredByStatusId;
};
setFilteredIssues(filterIssuesByStatusId());
}, []);

const handleAddNewColumn = (inputValue: string) => {
Expand All @@ -105,10 +103,10 @@ export const Board = () => {
statusId: res.data,
}).then((res: any) => {
if (res.responseCode) {
setisAlertStatusSuccessOpen(true);
openAlert("success", t("NewBoardAddedWithSuccess"));
setIsSuccess(!isSuccess);
} else {
setisAlertStatusErrorOpen(true);
openAlert("error", t("NewBoardAddedWithError"));
}
});
}
Expand All @@ -119,15 +117,29 @@ export const Board = () => {
statusId: index.id,
}).then((res: any) => {
if (res.responseCode) {
setisAlertStatusSuccessOpen(true);
openAlert("success", t("NewBoardAddedWithSuccess"));
setIsSuccess(!isSuccess);
} else {
setisAlertStatusErrorOpen(true);
openAlert("error", t("NewBoardAddedWithError"));
}
});
}
};

const handleDeleteTicket = (issueId: string) => {
async function deleteIssue() {
const response = await FetchDataAPI.deleteIssue(issueId);
if (response.status === 200) {
openAlert("success", t("IssueDeletedSuccess"));
setIsSuccess(!isSuccess);
} else {
openAlert("error", t("IssueDeletedError"));
}
}
deleteIssue();
fetchIssues();
};

const menuOptions = [
{
id: 0,
Expand All @@ -137,7 +149,7 @@ export const Board = () => {
if (columns?.length < 5 || columns == undefined) {
setIsDialogOpen(!isDialogOpen);
} else {
setBoardNumberAlert(true);
openAlert("error", t("columnAlertNumber"));
}
},
},
Expand Down Expand Up @@ -179,29 +191,18 @@ export const Board = () => {
key={ticket.id}
assignedTo={ticket.assignUserId}
issueId={ticket.id}
handleDeleteTicket={handleDeleteTicket}
/>
);
})}
</TasksCard>
))}
</TaskWrapper>
<AlertSuccess
isOpen={isAlertStatusSuccessOpen}
alertMsg={t("NewBoardAddedWithSuccess")}
/>
<AlertError
isOpen={isAlertStatusErrorOpen}
alertMsg={t("NewBoardAddedWithError")}
handleClose={() => {
setisAlertStatusErrorOpen(false);
}}
/>
<AlertSuccess isOpen={isSuccessAlertActive} alertMsg={message} />
<AlertError
isOpen={boardNumberAlert}
alertMsg={t("columnAlertNumber")}
handleClose={() => {
setBoardNumberAlert(false);
}}
isOpen={isErrorAlertActive}
alertMsg={message}
handleClose={() => closeErrorAlert()}
/>
</StyledPageWrapper>
);
Expand Down

0 comments on commit fe7ccae

Please sign in to comment.