feat: add pre commit hook to lint frontend & fix warnings

This commit is contained in:
Jordan Knott
2020-08-23 12:27:56 -05:00
committed by Jordan Knott
parent 8ce19a1ceb
commit 46e724e731
46 changed files with 256 additions and 730 deletions

View File

@ -1,39 +1,26 @@
import React, { useState, useRef, useContext, useEffect } from 'react';
import { MENU_TYPES } from 'shared/components/TopNavbar';
import React, { useState, useRef } from 'react';
import updateApolloCache from 'shared/utils/cache';
import GlobalTopNavbar, { ProjectPopup } from 'App/TopNavbar';
import LabelManagerEditor from '../LabelManagerEditor';
import styled, { css } from 'styled-components/macro';
import { Bolt, ToggleOn, Tags, CheckCircle, Sort, Filter } from 'shared/icons';
import { usePopup, Popup } from 'shared/components/PopupMenu';
import { useParams, Route, useRouteMatch, useHistory, RouteComponentProps, useLocation } from 'react-router-dom';
import { useRouteMatch, useHistory } from 'react-router-dom';
import {
useUpdateProjectMemberRoleMutation,
useCreateProjectMemberMutation,
useDeleteProjectMemberMutation,
useSetTaskCompleteMutation,
useToggleTaskLabelMutation,
useUpdateProjectNameMutation,
useFindProjectQuery,
useUpdateTaskGroupNameMutation,
useUpdateTaskNameMutation,
useUpdateProjectLabelMutation,
useCreateTaskMutation,
useDeleteProjectLabelMutation,
useDeleteTaskMutation,
useUpdateTaskLocationMutation,
useUpdateTaskGroupLocationMutation,
useCreateTaskGroupMutation,
useDeleteTaskGroupMutation,
useUpdateTaskDescriptionMutation,
useAssignTaskMutation,
DeleteTaskDocument,
FindProjectDocument,
useCreateProjectLabelMutation,
useUnassignTaskMutation,
useUpdateTaskDueDateMutation,
FindProjectQuery,
useUsersQuery,
} from 'shared/generated/graphql';
import QuickCardEditor from 'shared/components/QuickCardEditor';
@ -43,10 +30,9 @@ import SimpleLists from 'shared/components/Lists';
import produce from 'immer';
import MiniProfile from 'shared/components/MiniProfile';
import DueDateManager from 'shared/components/DueDateManager';
import UserContext, { useCurrentUser } from 'App/context';
import LabelManager from 'shared/components/PopupMenu/LabelManager';
import LabelEditor from 'shared/components/PopupMenu/LabelEditor';
import EmptyBoard from 'shared/components/EmptyBoard';
import NOOP from 'shared/utils/noop';
import LabelManagerEditor from 'Projects/Project/LabelManagerEditor';
const ProjectBar = styled.div`
display: flex;
@ -155,7 +141,6 @@ const ProjectBoard: React.FC<ProjectBoardProps> = ({ projectID, onCardLabelClick
const { showPopup, hidePopup } = usePopup();
const taskLabelsRef = useRef<Array<TaskLabel>>([]);
const [quickCardEditor, setQuickCardEditor] = useState(initialQuickCardEditorState);
const { user } = useCurrentUser();
const [updateTaskGroupLocation] = useUpdateTaskGroupLocationMutation({});
const history = useHistory();
const [deleteTaskGroup] = useDeleteTaskGroupMutation({
@ -308,12 +293,6 @@ const ProjectBoard: React.FC<ProjectBoardProps> = ({ projectID, onCardLabelClick
if (data) {
labelsRef.current = data.findProject.labels;
const onQuickEditorOpen = ($target: React.RefObject<HTMLElement>, taskID: string, taskGroupID: string) => {
if ($target && $target.current) {
const pos = $target.current.getBoundingClientRect();
const height = 120;
if (window.innerHeight - pos.bottom < height) {
}
}
const taskGroup = data.findProject.taskGroups.find(t => t.id === taskGroupID);
const currentTask = taskGroup ? taskGroup.tasks.find(t => t.id === taskID) : null;
if (currentTask) {
@ -381,7 +360,7 @@ const ProjectBoard: React.FC<ProjectBoardProps> = ({ projectID, onCardLabelClick
onTaskClick={task => {
history.push(`${match.url}/c/${task.id}`);
}}
onCardLabelClick={onCardLabelClick ?? (() => {})}
onCardLabelClick={onCardLabelClick ?? NOOP}
cardLabelVariant={cardLabelVariant ?? 'large'}
onTaskDrop={(droppedTask, previousTaskGroupID) => {
updateTaskLocation({
@ -427,7 +406,7 @@ const ProjectBoard: React.FC<ProjectBoardProps> = ({ projectID, onCardLabelClick
taskGroups={data.findProject.taskGroups}
onCreateTask={onCreateTask}
onCreateTaskGroup={onCreateList}
onCardMemberClick={($targetRef, taskID, memberID) => {
onCardMemberClick={($targetRef, _taskID, memberID) => {
const member = data.findProject.members.find(m => m.id === memberID);
if (member) {
showPopup(
@ -486,7 +465,7 @@ const ProjectBoard: React.FC<ProjectBoardProps> = ({ projectID, onCardLabelClick
</Popup>,
);
}}
onCardMemberClick={($targetRef, taskID, memberID) => {
onCardMemberClick={($targetRef, _taskID, memberID) => {
const member = data.findProject.members.find(m => m.id === memberID);
if (member) {
showPopup(
@ -516,8 +495,8 @@ const ProjectBoard: React.FC<ProjectBoardProps> = ({ projectID, onCardLabelClick
/>,
);
}}
onArchiveCard={(_listId: string, cardId: string) =>
deleteTask({
onArchiveCard={(_listId: string, cardId: string) => {
return deleteTask({
variables: { taskID: cardId },
update: client => {
updateApolloCache<FindProjectQuery>(
@ -533,8 +512,8 @@ const ProjectBoard: React.FC<ProjectBoardProps> = ({ projectID, onCardLabelClick
{ projectID },
);
},
})
}
});
}}
onOpenDueDatePopup={($targetRef, task) => {
showPopup(
$targetRef,
@ -549,7 +528,7 @@ const ProjectBoard: React.FC<ProjectBoardProps> = ({ projectID, onCardLabelClick
updateTaskDueDate({ variables: { taskID: t.id, dueDate: newDueDate } });
hidePopup();
}}
onCancel={() => {}}
onCancel={NOOP}
/>
</Popup>,
);

View File

@ -1,7 +1,7 @@
import React, { useState, useContext, useEffect } from 'react';
import React, { useState } from 'react';
import Modal from 'shared/components/Modal';
import TaskDetails from 'shared/components/TaskDetails';
import PopupMenu, { Popup, usePopup } from 'shared/components/PopupMenu';
import { Popup, usePopup } from 'shared/components/PopupMenu';
import MemberManager from 'shared/components/MemberManager';
import { useRouteMatch, useHistory } from 'react-router';
import {
@ -22,7 +22,7 @@ import {
FindTaskDocument,
FindTaskQuery,
} from 'shared/generated/graphql';
import UserContext, { useCurrentUser } from 'App/context';
import { useCurrentUser } from 'App/context';
import MiniProfile from 'shared/components/MiniProfile';
import DueDateManager from 'shared/components/DueDateManager';
import produce from 'immer';
@ -31,6 +31,7 @@ import Button from 'shared/components/Button';
import Input from 'shared/components/Input';
import { useForm } from 'react-hook-form';
import updateApolloCache from 'shared/utils/cache';
import NOOP from 'shared/utils/noop';
const calculateChecklistBadge = (checklists: Array<TaskChecklist>) => {
const total = checklists.reduce((prev: any, next: any) => {
@ -75,15 +76,12 @@ const CreateChecklistInput = styled(Input)`
margin-bottom: 8px;
`;
const InputError = styled.span`
color: rgba(${props => props.theme.colors.danger});
font-size: 12px;
`;
type CreateChecklistPopupProps = {
onCreateChecklist: (data: CreateChecklistData) => void;
};
const CreateChecklistPopup: React.FC<CreateChecklistPopupProps> = ({ onCreateChecklist }) => {
const { register, handleSubmit, errors } = useForm<CreateChecklistData>();
const { register, handleSubmit } = useForm<CreateChecklistData>();
const createUser = (data: CreateChecklistData) => {
onCreateChecklist(data);
};
@ -132,9 +130,6 @@ const Details: React.FC<DetailsProps> = ({
const { user } = useCurrentUser();
const { showPopup, hidePopup } = usePopup();
const history = useHistory();
const match = useRouteMatch();
const [currentMemberTask, setCurrentMemberTask] = useState('');
const [memberPopupData, setMemberPopupData] = useState(initialMemberPopupState);
const [updateTaskChecklistLocation] = useUpdateTaskChecklistLocationMutation();
const [updateTaskChecklistItemLocation] = useUpdateTaskChecklistItemLocationMutation({
update: (client, response) => {
@ -148,7 +143,7 @@ const Details: React.FC<DetailsProps> = ({
const oldIdx = cache.findTask.checklists.findIndex(c => c.id === prevChecklistID);
const newIdx = cache.findTask.checklists.findIndex(c => c.id === checklistID);
if (oldIdx > -1 && newIdx > -1) {
const item = cache.findTask.checklists[oldIdx].items.find(item => item.id === checklistItem.id);
const item = cache.findTask.checklists[oldIdx].items.find(i => i.id === checklistItem.id);
if (item) {
draftCache.findTask.checklists[oldIdx].items = cache.findTask.checklists[oldIdx].items.filter(
i => i.id !== checklistItem.id,
@ -398,7 +393,7 @@ const Details: React.FC<DetailsProps> = ({
if (member) {
showPopup(
$targetRef,
<Popup title={null} onClose={() => {}} tab={0}>
<Popup title={null} onClose={NOOP} tab={0}>
<MiniProfile
user={member}
bio="None"
@ -412,19 +407,19 @@ const Details: React.FC<DetailsProps> = ({
);
}
}}
onOpenAddMemberPopup={(task, $targetRef) => {
onOpenAddMemberPopup={(_task, $targetRef) => {
showPopup(
$targetRef,
<Popup title="Members" tab={0} onClose={() => {}}>
<Popup title="Members" tab={0} onClose={NOOP}>
<MemberManager
availableMembers={availableMembers}
activeMembers={data.findTask.assigned}
onMemberChange={(member, isActive) => {
if (user) {
if (isActive) {
assignTask({ variables: { taskID: data.findTask.id, userID: user.id } });
assignTask({ variables: { taskID: data.findTask.id, userID: member.id } });
} else {
unassignTask({ variables: { taskID: data.findTask.id, userID: user.id } });
unassignTask({ variables: { taskID: data.findTask.id, userID: member.id } });
}
}
}}
@ -486,7 +481,7 @@ const Details: React.FC<DetailsProps> = ({
showPopup(
$targetRef,
<Popup
title={'Change Due Date'}
title="Change Due Date"
tab={0}
onClose={() => {
hidePopup();
@ -502,7 +497,7 @@ const Details: React.FC<DetailsProps> = ({
updateTaskDueDate({ variables: { taskID: t.id, dueDate: newDueDate } });
hidePopup();
}}
onCancel={() => {}}
onCancel={NOOP}
/>
</Popup>,
);

View File

@ -4,7 +4,6 @@ import updateApolloCache from 'shared/utils/cache';
import GlobalTopNavbar, { ProjectPopup } from 'App/TopNavbar';
import styled from 'styled-components/macro';
import { usePopup, Popup } from 'shared/components/PopupMenu';
import LabelManagerEditor from './LabelManagerEditor';
import {
useParams,
Route,
@ -36,9 +35,11 @@ import produce from 'immer';
import UserContext, { useCurrentUser } from 'App/context';
import Input from 'shared/components/Input';
import Member from 'shared/components/Member';
import EmptyBoard from 'shared/components/EmptyBoard';
import NOOP from 'shared/utils/noop';
import Board, { BoardLoading } from './Board';
import Details from './Details';
import EmptyBoard from 'shared/components/EmptyBoard';
import LabelManagerEditor from './LabelManagerEditor';
const CARD_LABEL_VARIANT_STORAGE_KEY = 'card_label_variant';
@ -124,6 +125,7 @@ const Project = () => {
const match = useRouteMatch();
const [updateTaskDescription] = useUpdateTaskDescriptionMutation();
const taskLabelsRef = useRef<Array<TaskLabel>>([]);
const [toggleTaskLabel] = useToggleTaskLabelMutation({
onCompleted: newTaskLabel => {
taskLabelsRef.current = newTaskLabel.toggleTaskLabel.task.labels;
@ -190,7 +192,6 @@ const Project = () => {
const { showPopup, hidePopup } = usePopup();
const $labelsRef = useRef<HTMLDivElement>(null);
const labelsRef = useRef<Array<ProjectLabel>>([]);
const taskLabelsRef = useRef<Array<TaskLabel>>([]);
useEffect(() => {
if (data) {
document.title = `${data.findProject.name} | Taskcafé`;
@ -199,7 +200,7 @@ const Project = () => {
if (loading) {
return (
<>
<GlobalTopNavbar onSaveProjectName={projectName => {}} name="" projectID={null} />
<GlobalTopNavbar onSaveProjectName={NOOP} name="" projectID={null} />
<BoardLoading />
</>
);
@ -261,7 +262,7 @@ const Project = () => {
path={`${match.path}/board/c/:taskID`}
render={(routeProps: RouteComponentProps<TaskRouteProps>) => (
<Details
refreshCache={() => {}}
refreshCache={NOOP}
availableMembers={data.findProject.members}
projectURL={`${match.url}/board`}
taskID={routeProps.match.params.taskID}

View File

@ -1,4 +1,4 @@
import React, { useState, useContext, useEffect } from 'react';
import React, { useState, useEffect } from 'react';
import styled from 'styled-components/macro';
import GlobalTopNavbar from 'App/TopNavbar';
import Empty from 'shared/undraw/Empty';
@ -10,16 +10,17 @@ import {
GetProjectsQuery,
} from 'shared/generated/graphql';
import ProjectGridItem, { AddProjectItem } from 'shared/components/ProjectGridItem';
import { Link } from 'react-router-dom';
import NewProject from 'shared/components/NewProject';
import UserContext, { PermissionLevel, PermissionObjectType, useCurrentUser } from 'App/context';
import { PermissionLevel, PermissionObjectType, useCurrentUser } from 'App/context';
import Button from 'shared/components/Button';
import { usePopup, Popup } from 'shared/components/PopupMenu';
import { useForm } from 'react-hook-form';
import Input from 'shared/components/Input';
import updateApolloCache from 'shared/utils/cache';
import produce from 'immer';
import NOOP from 'shared/utils/noop';
const EmptyStateContent = styled.div`
display: flex;
justy-content: center;
@ -37,21 +38,26 @@ const EmptyStatePrompt = styled.span`
font-size: 16px;
margin-top: 8px;
`;
const EmptyState = styled(Empty)`
display: block;
margin: 0 auto;
`;
const CreateTeamButton = styled(Button)`
width: 100%;
`;
type CreateTeamData = { teamName: string };
type CreateTeamFormProps = {
onCreateTeam: (teamName: string) => void;
};
const CreateTeamFormContainer = styled.form``;
const CreateTeamForm: React.FC<CreateTeamFormProps> = ({ onCreateTeam }) => {
const { register, handleSubmit, errors } = useForm<CreateTeamData>();
const { register, handleSubmit } = useForm<CreateTeamData>();
const createTeam = (data: CreateTeamData) => {
onCreateTeam(data.teamName);
};
@ -186,6 +192,7 @@ const SectionActions = styled.div`
const SectionAction = styled(Button)`
padding: 6px 12px;
`;
const SectionActionLink = styled(Link)`
margin-right: 8px;
`;
@ -201,12 +208,14 @@ const ProjectsContainer = styled.div`
max-width: 825px;
min-width: 288px;
`;
const ProjectGrid = styled.div`
max-width: 780px;
display: grid;
grid-template-columns: 240px 240px 240px;
gap: 20px 10px;
`;
const AddTeamButton = styled(Button)`
padding: 6px 12px;
position: absolute;
@ -217,13 +226,12 @@ const AddTeamButton = styled(Button)`
const CreateFirstTeam = styled(Button)`
margin-top: 8px;
`;
type ShowNewProject = {
open: boolean;
initialTeamID: null | string;
};
const ProjectLink = styled(Link)``;
const Projects = () => {
const { showPopup, hidePopup } = usePopup();
const { loading, data } = useGetProjectsQuery({ fetchPolicy: 'network-only' });
@ -241,7 +249,7 @@ const Projects = () => {
});
const [showNewProject, setShowNewProject] = useState<ShowNewProject>({ open: false, initialTeamID: null });
const { user, setUser } = useCurrentUser();
const { user } = useCurrentUser();
const [createTeam] = useCreateTeamMutation({
update: (client, createData) => {
updateApolloCache<GetProjectsQuery>(client, GetProjectsDocument, cache =>
@ -267,7 +275,7 @@ const Projects = () => {
.sort((a, b) => {
const textA = a.name.toUpperCase();
const textB = b.name.toUpperCase();
return textA < textB ? -1 : textA > textB ? 1 : 0;
return textA < textB ? -1 : textA > textB ? 1 : 0; // eslint-disable-line no-nested-ternary
})
.map(team => {
return {
@ -278,13 +286,13 @@ const Projects = () => {
.sort((a, b) => {
const textA = a.name.toUpperCase();
const textB = b.name.toUpperCase();
return textA < textB ? -1 : textA > textB ? 1 : 0;
return textA < textB ? -1 : textA > textB ? 1 : 0; // eslint-disable-line no-nested-ternary
}),
};
});
return (
<>
<GlobalTopNavbar onSaveProjectName={() => {}} projectID={null} name={null} />
<GlobalTopNavbar onSaveProjectName={NOOP} projectID={null} name={null} />
<Wrapper>
<ProjectsContainer>
{user.roles.org === 'admin' && (