feature: add team creation & project deletion

This commit is contained in:
Jordan Knott
2020-06-20 17:49:11 -05:00
parent 5c3afaba7c
commit fd7c006b73
27 changed files with 1590 additions and 98 deletions

View File

@ -11,7 +11,7 @@ const InputWrapper = styled.div<{ width: string }>`
justify-content: center;
margin-bottom: 2.2rem;
margin-top: 17px;
margin-top: 24px;
`;
const InputLabel = styled.span<{ width: string }>`

View File

@ -1,4 +1,5 @@
import styled from 'styled-components';
import Button from 'shared/components/Button';
export const Wrapper = styled.div`
background: #eff2f7;
@ -70,21 +71,7 @@ export const FormError = styled.span`
color: rgb(234, 84, 85);
`;
export const LoginButton = styled.input`
padding: 0.75rem 2rem;
font-size: 1rem;
border-radius: 6px;
background: var(--color-button-background);
outline: none;
border: none;
cursor: pointer;
color: var(--color-button-text-hover);
&:disabled {
opacity: 0.5;
cursor: default;
pointer-events: none;
}
`;
export const LoginButton = styled(Button)``;
export const ActionButtons = styled.div`
margin-top: 17.5px;
@ -92,15 +79,7 @@ export const ActionButtons = styled.div`
justify-content: space-between;
`;
export const RegisterButton = styled.button`
padding: 0.679rem 2rem;
border-radius: 6px;
border: 1px solid rgb(115, 103, 240);
background: transparent;
font-size: 1rem;
color: var(--color-primary);
cursor: pointer;
`;
export const RegisterButton = styled(Button)``;
export const LogoTitle = styled.div`
font-size: 24px;

View File

@ -72,8 +72,10 @@ const Login = ({ onSubmit }: LoginProps) => {
{errors.password && <FormError>{errors.password.message}</FormError>}
<ActionButtons>
<RegisterButton>Register</RegisterButton>
<LoginButton type="submit" value="Login" disabled={!isComplete} />
<RegisterButton variant="outline">Register</RegisterButton>
<LoginButton type="submit" disabled={!isComplete}>
Login
</LoginButton>
</ActionButtons>
</Form>
</LoginFormContainer>

View File

@ -16,7 +16,7 @@ import {
type PopupContextState = {
show: (target: RefObject<HTMLElement>, content: JSX.Element, width?: string | number) => void;
setTab: (newTab: number) => void;
setTab: (newTab: number, width?: number | string) => void;
getCurrentTab: () => number;
hide: () => void;
};
@ -139,12 +139,14 @@ export const PopupProvider: React.FC = ({ children }) => {
};
const portalTarget = canUseDOM ? document.body : null; // appease flow
const setTab = (newTab: number) => {
const setTab = (newTab: number, width?: number | string) => {
let newWidth = width ?? currentState.width;
setState((prevState: PopupState) => {
return {
...prevState,
previousTab: currentState.currentTab,
currentTab: newTab,
width: newWidth,
};
});
};

View File

@ -1,6 +1,7 @@
import React from 'react';
import styled from 'styled-components';
import Button from 'shared/components/Button';
export const ListActionsWrapper = styled.ul`
list-style-type: none;
@ -36,16 +37,64 @@ export const ListSeparator = styled.hr`
width: 100%;
`;
type Props = {};
const ProjectSettings: React.FC<Props> = () => {
type Props = {
onDeleteProject: () => void;
};
const ProjectSettings: React.FC<Props> = ({ onDeleteProject }) => {
return (
<>
<ListActionsWrapper>
<ListActionItemWrapper onClick={() => {}}>
<ListActionItemWrapper onClick={() => onDeleteProject()}>
<ListActionItem>Delete Project</ListActionItem>
</ListActionItemWrapper>
</ListActionsWrapper>
</>
);
};
const ConfirmWrapper = styled.div``;
const ConfirmSubTitle = styled.h3`
font-size: 14px;
`;
const ConfirmDescription = styled.div`
font-size: 14px;
`;
const DeleteList = styled.ul`
margin-bottom: 12px;
`;
const DeleteListItem = styled.li`
padding: 6px 0;
list-style: disc;
margin-left: 12px;
`;
const ConfirmDeleteButton = styled(Button)`
width: 100%;
padding: 6px 12px;
`;
type DeleteProjectProps = {
name: string;
onDeleteProject: () => void;
};
const DeleteProject: React.FC<DeleteProjectProps> = ({ name, onDeleteProject }) => {
return (
<ConfirmWrapper>
<ConfirmDescription>
Deleting the project will also delete the following:
<DeleteList>
<DeleteListItem>Task groups and tasks</DeleteListItem>
</DeleteList>
</ConfirmDescription>
<ConfirmDeleteButton onClick={() => onDeleteProject()} color="danger">
Delete
</ConfirmDeleteButton>
</ConfirmWrapper>
);
};
export { DeleteProject };
export default ProjectSettings;

View File

@ -78,6 +78,7 @@ export type Team = {
id: Scalars['ID'];
createdAt: Scalars['Time'];
name: Scalars['String'];
members: Array<ProjectMember>;
};
export type Project = {
@ -145,8 +146,15 @@ export type FindTask = {
taskID: Scalars['UUID'];
};
export type Organization = {
__typename?: 'Organization';
id: Scalars['ID'];
name: Scalars['String'];
};
export type Query = {
__typename?: 'Query';
organizations: Array<Organization>;
users: Array<UserAccount>;
findUser: UserAccount;
findProject: Project;
@ -192,7 +200,7 @@ export type NewUserAccount = {
export type NewTeam = {
name: Scalars['String'];
organizationID: Scalars['String'];
organizationID: Scalars['UUID'];
};
export type NewProject = {
@ -390,13 +398,36 @@ export type UpdateTaskChecklistItemName = {
name: Scalars['String'];
};
export type CreateTeamMember = {
userID: Scalars['UUID'];
teamID: Scalars['UUID'];
};
export type CreateTeamMemberPayload = {
__typename?: 'CreateTeamMemberPayload';
team: Team;
teamMember: ProjectMember;
};
export type DeleteProject = {
projectID: Scalars['UUID'];
};
export type DeleteProjectPayload = {
__typename?: 'DeleteProjectPayload';
ok: Scalars['Boolean'];
project: Project;
};
export type Mutation = {
__typename?: 'Mutation';
createRefreshToken: RefreshToken;
createUserAccount: UserAccount;
createTeam: Team;
clearProfileAvatar: UserAccount;
createTeamMember: CreateTeamMemberPayload;
createProject: Project;
deleteProject: DeleteProjectPayload;
updateProjectName: Project;
createProjectLabel: ProjectLabel;
deleteProjectLabel: ProjectLabel;
@ -443,11 +474,21 @@ export type MutationCreateTeamArgs = {
};
export type MutationCreateTeamMemberArgs = {
input: CreateTeamMember;
};
export type MutationCreateProjectArgs = {
input: NewProject;
};
export type MutationDeleteProjectArgs = {
input: DeleteProject;
};
export type MutationUpdateProjectNameArgs = {
input?: Maybe<UpdateProjectName>;
};
@ -869,7 +910,10 @@ export type GetProjectsQueryVariables = {};
export type GetProjectsQuery = (
{ __typename?: 'Query' }
& { teams: Array<(
& { organizations: Array<(
{ __typename?: 'Organization' }
& Pick<Organization, 'id' | 'name'>
)>, teams: Array<(
{ __typename?: 'Team' }
& Pick<Team, 'id' | 'name' | 'createdAt'>
)>, projects: Array<(
@ -897,6 +941,23 @@ export type MeQuery = (
) }
);
export type DeleteProjectMutationVariables = {
projectID: Scalars['UUID'];
};
export type DeleteProjectMutation = (
{ __typename?: 'Mutation' }
& { deleteProject: (
{ __typename?: 'DeleteProjectPayload' }
& Pick<DeleteProjectPayload, 'ok'>
& { project: (
{ __typename?: 'Project' }
& Pick<Project, 'id'>
) }
) }
);
export type CreateTaskChecklistItemMutationVariables = {
taskChecklistID: Scalars['UUID'];
name: Scalars['String'];
@ -985,6 +1046,20 @@ export type UpdateTaskGroupNameMutation = (
) }
);
export type CreateTeamMutationVariables = {
name: Scalars['String'];
organizationID: Scalars['UUID'];
};
export type CreateTeamMutation = (
{ __typename?: 'Mutation' }
& { createTeam: (
{ __typename?: 'Team' }
& Pick<Team, 'id' | 'createdAt' | 'name'>
) }
);
export type ToggleTaskLabelMutationVariables = {
taskID: Scalars['UUID'];
projectLabelID: Scalars['UUID'];
@ -1690,6 +1765,10 @@ export type FindTaskLazyQueryHookResult = ReturnType<typeof useFindTaskLazyQuery
export type FindTaskQueryResult = ApolloReactCommon.QueryResult<FindTaskQuery, FindTaskQueryVariables>;
export const GetProjectsDocument = gql`
query getProjects {
organizations {
id
name
}
teams {
id
name
@ -1768,6 +1847,41 @@ export function useMeLazyQuery(baseOptions?: ApolloReactHooks.LazyQueryHookOptio
export type MeQueryHookResult = ReturnType<typeof useMeQuery>;
export type MeLazyQueryHookResult = ReturnType<typeof useMeLazyQuery>;
export type MeQueryResult = ApolloReactCommon.QueryResult<MeQuery, MeQueryVariables>;
export const DeleteProjectDocument = gql`
mutation deleteProject($projectID: UUID!) {
deleteProject(input: {projectID: $projectID}) {
ok
project {
id
}
}
}
`;
export type DeleteProjectMutationFn = ApolloReactCommon.MutationFunction<DeleteProjectMutation, DeleteProjectMutationVariables>;
/**
* __useDeleteProjectMutation__
*
* To run a mutation, you first call `useDeleteProjectMutation` within a React component and pass it any options that fit your needs.
* When your component renders, `useDeleteProjectMutation` returns a tuple that includes:
* - A mutate function that you can call at any time to execute the mutation
* - An object with fields that represent the current status of the mutation's execution
*
* @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2;
*
* @example
* const [deleteProjectMutation, { data, loading, error }] = useDeleteProjectMutation({
* variables: {
* projectID: // value for 'projectID'
* },
* });
*/
export function useDeleteProjectMutation(baseOptions?: ApolloReactHooks.MutationHookOptions<DeleteProjectMutation, DeleteProjectMutationVariables>) {
return ApolloReactHooks.useMutation<DeleteProjectMutation, DeleteProjectMutationVariables>(DeleteProjectDocument, baseOptions);
}
export type DeleteProjectMutationHookResult = ReturnType<typeof useDeleteProjectMutation>;
export type DeleteProjectMutationResult = ApolloReactCommon.MutationResult<DeleteProjectMutation>;
export type DeleteProjectMutationOptions = ApolloReactCommon.BaseMutationOptions<DeleteProjectMutation, DeleteProjectMutationVariables>;
export const CreateTaskChecklistItemDocument = gql`
mutation createTaskChecklistItem($taskChecklistID: UUID!, $name: String!, $position: Float!) {
createTaskChecklistItem(input: {taskChecklistID: $taskChecklistID, name: $name, position: $position}) {
@ -1980,6 +2094,41 @@ export function useUpdateTaskGroupNameMutation(baseOptions?: ApolloReactHooks.Mu
export type UpdateTaskGroupNameMutationHookResult = ReturnType<typeof useUpdateTaskGroupNameMutation>;
export type UpdateTaskGroupNameMutationResult = ApolloReactCommon.MutationResult<UpdateTaskGroupNameMutation>;
export type UpdateTaskGroupNameMutationOptions = ApolloReactCommon.BaseMutationOptions<UpdateTaskGroupNameMutation, UpdateTaskGroupNameMutationVariables>;
export const CreateTeamDocument = gql`
mutation createTeam($name: String!, $organizationID: UUID!) {
createTeam(input: {name: $name, organizationID: $organizationID}) {
id
createdAt
name
}
}
`;
export type CreateTeamMutationFn = ApolloReactCommon.MutationFunction<CreateTeamMutation, CreateTeamMutationVariables>;
/**
* __useCreateTeamMutation__
*
* To run a mutation, you first call `useCreateTeamMutation` within a React component and pass it any options that fit your needs.
* When your component renders, `useCreateTeamMutation` returns a tuple that includes:
* - A mutate function that you can call at any time to execute the mutation
* - An object with fields that represent the current status of the mutation's execution
*
* @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2;
*
* @example
* const [createTeamMutation, { data, loading, error }] = useCreateTeamMutation({
* variables: {
* name: // value for 'name'
* organizationID: // value for 'organizationID'
* },
* });
*/
export function useCreateTeamMutation(baseOptions?: ApolloReactHooks.MutationHookOptions<CreateTeamMutation, CreateTeamMutationVariables>) {
return ApolloReactHooks.useMutation<CreateTeamMutation, CreateTeamMutationVariables>(CreateTeamDocument, baseOptions);
}
export type CreateTeamMutationHookResult = ReturnType<typeof useCreateTeamMutation>;
export type CreateTeamMutationResult = ApolloReactCommon.MutationResult<CreateTeamMutation>;
export type CreateTeamMutationOptions = ApolloReactCommon.BaseMutationOptions<CreateTeamMutation, CreateTeamMutationVariables>;
export const ToggleTaskLabelDocument = gql`
mutation toggleTaskLabel($taskID: UUID!, $projectLabelID: UUID!) {
toggleTaskLabel(input: {taskID: $taskID, projectLabelID: $projectLabelID}) {

View File

@ -1,4 +1,8 @@
query getProjects {
organizations {
id
name
}
teams {
id
name

View File

@ -0,0 +1,14 @@
import gql from 'graphql-tag';
export const DELETE_PROJECT_MUTATION = gql`
mutation deleteProject($projectID: UUID!) {
deleteProject(input: { projectID: $projectID }) {
ok
project {
id
}
}
}
`;
export default DELETE_PROJECT_MUTATION;

View File

@ -0,0 +1,13 @@
import gql from 'graphql-tag';
export const CREATE_TEAM_MUTATION = gql`
mutation createTeam($name: String!, $organizationID: UUID!) {
createTeam(input: { name: $name, organizationID: $organizationID }) {
id
createdAt
name
}
}
`;
export default CREATE_TEAM_MUTATION;