// LOC830 import React, { useState, useRef, useEffect, useContext } from 'react'; 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 { useParams, Route, useRouteMatch, useHistory, RouteComponentProps, useLocation, Redirect, } from 'react-router-dom'; import { useUpdateProjectMemberRoleMutation, useCreateProjectMemberMutation, useDeleteProjectMemberMutation, useToggleTaskLabelMutation, useUpdateProjectNameMutation, useFindProjectQuery, useUpdateTaskNameMutation, useCreateTaskMutation, useDeleteTaskMutation, useUpdateTaskLocationMutation, useUpdateTaskGroupLocationMutation, useCreateTaskGroupMutation, useUpdateTaskDescriptionMutation, FindProjectDocument, FindProjectQuery, } from 'shared/generated/graphql'; 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 LabelManagerEditor from './LabelManagerEditor'; const CARD_LABEL_VARIANT_STORAGE_KEY = 'card_label_variant'; const useStateWithLocalStorage = (localStorageKey: string): [string, React.Dispatch>] => { const [value, setValue] = React.useState(localStorage.getItem(localStorageKey) || ''); React.useEffect(() => { localStorage.setItem(localStorageKey, value); }, [value]); return [value, setValue]; }; const SearchInput = styled(Input)` margin: 0; `; const UserMember = styled(Member)` padding: 4px 0; cursor: pointer; &:hover { background: rgba(${props => props.theme.colors.bg.primary}, 0.4); } border-radius: 6px; `; const MemberList = styled.div` margin: 8px 0; `; type UserManagementPopupProps = { users: Array; projectMembers: Array; onAddProjectMember: (userID: string) => void; }; const UserManagementPopup: React.FC = ({ users, projectMembers, onAddProjectMember }) => { return ( {users .filter(u => u.id !== projectMembers.find(p => p.id === u.id)?.id) .map(user => ( onAddProjectMember(user.id)} showName member={user} taskID="" /> ))} ); }; type TaskRouteProps = { taskID: string; }; interface QuickCardEditorState { isOpen: boolean; target: React.RefObject | null; taskID: string | null; taskGroupID: string | null; } interface ProjectParams { projectID: string; } const initialQuickCardEditorState: QuickCardEditorState = { taskID: null, taskGroupID: null, isOpen: false, target: null, }; const Project = () => { const { projectID } = useParams(); const history = useHistory(); const match = useRouteMatch(); const [updateTaskDescription] = useUpdateTaskDescriptionMutation(); const taskLabelsRef = useRef>([]); const [toggleTaskLabel] = useToggleTaskLabelMutation({ onCompleted: newTaskLabel => { taskLabelsRef.current = newTaskLabel.toggleTaskLabel.task.labels; }, }); const [value, setValue] = useStateWithLocalStorage(CARD_LABEL_VARIANT_STORAGE_KEY); const [updateProjectMemberRole] = useUpdateProjectMemberRoleMutation(); const [deleteTask] = useDeleteTaskMutation(); const [updateTaskName] = useUpdateTaskNameMutation(); const { loading, data } = useFindProjectQuery({ variables: { projectID }, }); const [updateProjectName] = useUpdateProjectNameMutation({ update: (client, newName) => { updateApolloCache( client, FindProjectDocument, cache => produce(cache, draftCache => { draftCache.findProject.name = newName.data.updateProjectName.name; }), { projectID }, ); }, }); const [createProjectMember] = useCreateProjectMemberMutation({ update: (client, response) => { updateApolloCache( client, FindProjectDocument, cache => produce(cache, draftCache => { draftCache.findProject.members.push({ ...response.data.createProjectMember.member }); }), { projectID }, ); }, }); const [deleteProjectMember] = useDeleteProjectMemberMutation({ update: (client, response) => { updateApolloCache( client, FindProjectDocument, cache => produce(cache, draftCache => { draftCache.findProject.members = cache.findProject.members.filter( m => m.id !== response.data.deleteProjectMember.member.id, ); }), { projectID }, ); }, }); const { user } = useCurrentUser(); const location = useLocation(); const { showPopup, hidePopup } = usePopup(); const $labelsRef = useRef(null); const labelsRef = useRef>([]); useEffect(() => { if (data) { document.title = `${data.findProject.name} | Taskcafé`; } }, [data]); if (loading) { return ( <> ); } if (data) { labelsRef.current = data.findProject.labels; return ( <> { updateProjectMemberRole({ variables: { userID, roleCode, projectID } }); }} onChangeProjectOwner={uid => { hidePopup(); }} onRemoveFromBoard={userID => { deleteProjectMember({ variables: { userID, projectID } }); hidePopup(); }} onSaveProjectName={projectName => { updateProjectName({ variables: { projectID, name: projectName } }); }} onInviteUser={$target => { showPopup( $target, { createProjectMember({ variables: { userID, projectID } }); }} users={data.users} projectMembers={data.findProject.members} />, ); }} popupContent={} menuType={[{ name: 'Board', link: location.pathname }]} currentTab={0} projectMembers={data.findProject.members} projectID={projectID} teamID={data.findProject.team.id} name={data.findProject.name} /> } /> ( { const variant = value === 'small' ? 'large' : 'small'; setValue(() => variant); }} projectID={projectID} /> )} /> ) => (
{ updateTaskName({ variables: { taskID: updatedTask.id, name: newName } }); }} onTaskDescriptionChange={(updatedTask, newDescription) => { updateTaskDescription({ variables: { taskID: updatedTask.id, description: newDescription }, optimisticResponse: { __typename: 'Mutation', updateTaskDescription: { __typename: 'Task', id: updatedTask.id, description: newDescription, }, }, }); }} onDeleteTask={deletedTask => { deleteTask({ variables: { taskID: deletedTask.id } }); }} onOpenAddLabelPopup={(task, $targetRef) => { taskLabelsRef.current = task.labels; showPopup( $targetRef, { toggleTaskLabel({ variables: { taskID: task.id, projectLabelID: labelID } }); }} labelColors={data.labelColors} labels={labelsRef} taskLabels={taskLabelsRef} projectID={projectID} />, ); }} /> )} /> ); } return
Error
; }; export default Project;