Compare commits
	
		
			1 Commits
		
	
	
		
			refactor/c
			...
			feat/updat
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					4a8d4a6ec3 | 
@@ -323,6 +323,7 @@ const ProjectBoard: React.FC<ProjectBoardProps> = ({ projectID, onCardLabelClick
 | 
				
			|||||||
  const [updateTaskGroupName] = useUpdateTaskGroupNameMutation({});
 | 
					  const [updateTaskGroupName] = useUpdateTaskGroupNameMutation({});
 | 
				
			||||||
  const { loading, data } = useFindProjectQuery({
 | 
					  const { loading, data } = useFindProjectQuery({
 | 
				
			||||||
    variables: { projectID },
 | 
					    variables: { projectID },
 | 
				
			||||||
 | 
					    pollInterval: 5000,
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
  const [deleteTaskGroupTasks] = useDeleteTaskGroupTasksMutation({
 | 
					  const [deleteTaskGroupTasks] = useDeleteTaskGroupTasksMutation({
 | 
				
			||||||
    update: (client, resp) =>
 | 
					    update: (client, resp) =>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@ import Modal from 'shared/components/Modal';
 | 
				
			|||||||
import TaskDetails from 'shared/components/TaskDetails';
 | 
					import TaskDetails from 'shared/components/TaskDetails';
 | 
				
			||||||
import { Popup, usePopup } from 'shared/components/PopupMenu';
 | 
					import { Popup, usePopup } from 'shared/components/PopupMenu';
 | 
				
			||||||
import MemberManager from 'shared/components/MemberManager';
 | 
					import MemberManager from 'shared/components/MemberManager';
 | 
				
			||||||
import { useRouteMatch, useHistory } from 'react-router';
 | 
					import { useRouteMatch, useHistory, Redirect } from 'react-router';
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
  useDeleteTaskChecklistMutation,
 | 
					  useDeleteTaskChecklistMutation,
 | 
				
			||||||
  useUpdateTaskChecklistNameMutation,
 | 
					  useUpdateTaskChecklistNameMutation,
 | 
				
			||||||
@@ -32,6 +32,7 @@ import Input from 'shared/components/Input';
 | 
				
			|||||||
import { useForm } from 'react-hook-form';
 | 
					import { useForm } from 'react-hook-form';
 | 
				
			||||||
import updateApolloCache from 'shared/utils/cache';
 | 
					import updateApolloCache from 'shared/utils/cache';
 | 
				
			||||||
import NOOP from 'shared/utils/noop';
 | 
					import NOOP from 'shared/utils/noop';
 | 
				
			||||||
 | 
					import hasNotFoundError from 'shared/utils/error';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const calculateChecklistBadge = (checklists: Array<TaskChecklist>) => {
 | 
					const calculateChecklistBadge = (checklists: Array<TaskChecklist>) => {
 | 
				
			||||||
  const total = checklists.reduce((prev: any, next: any) => {
 | 
					  const total = checklists.reduce((prev: any, next: any) => {
 | 
				
			||||||
@@ -269,8 +270,8 @@ const Details: React.FC<DetailsProps> = ({
 | 
				
			|||||||
      );
 | 
					      );
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
  const { loading, data, refetch } = useFindTaskQuery({ variables: { taskID } });
 | 
					  const { loading, data, refetch, error } = useFindTaskQuery({ variables: { taskID }, pollInterval: 5000 });
 | 
				
			||||||
  const [setTaskComplete] = useSetTaskCompleteMutation();
 | 
					  const [setTaskComplete, { error: setTaskCompleteError }] = useSetTaskCompleteMutation();
 | 
				
			||||||
  const [updateTaskDueDate] = useUpdateTaskDueDateMutation({
 | 
					  const [updateTaskDueDate] = useUpdateTaskDueDateMutation({
 | 
				
			||||||
    onCompleted: () => {
 | 
					    onCompleted: () => {
 | 
				
			||||||
      refetch();
 | 
					      refetch();
 | 
				
			||||||
@@ -289,9 +290,13 @@ const Details: React.FC<DetailsProps> = ({
 | 
				
			|||||||
      refreshCache();
 | 
					      refreshCache();
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
  if (loading) {
 | 
					  if (hasNotFoundError(error, setTaskCompleteError)) {
 | 
				
			||||||
    return null;
 | 
					    return <Redirect to={projectURL} />;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					  if (setTaskCompleteError && setTaskCompleteError)
 | 
				
			||||||
 | 
					    if (loading) {
 | 
				
			||||||
 | 
					      return null;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
  if (!data) {
 | 
					  if (!data) {
 | 
				
			||||||
    return null;
 | 
					    return null;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@@ -346,7 +351,11 @@ const Details: React.FC<DetailsProps> = ({
 | 
				
			|||||||
              onTaskNameChange={onTaskNameChange}
 | 
					              onTaskNameChange={onTaskNameChange}
 | 
				
			||||||
              onTaskDescriptionChange={onTaskDescriptionChange}
 | 
					              onTaskDescriptionChange={onTaskDescriptionChange}
 | 
				
			||||||
              onToggleTaskComplete={task => {
 | 
					              onToggleTaskComplete={task => {
 | 
				
			||||||
                setTaskComplete({ variables: { taskID: task.id, complete: !task.complete } });
 | 
					                setTaskComplete({ variables: { taskID: task.id, complete: !task.complete } }).catch(r => {
 | 
				
			||||||
 | 
					                  if (hasNotFoundError(r)) {
 | 
				
			||||||
 | 
					                    history.push(projectURL);
 | 
				
			||||||
 | 
					                  }
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
              }}
 | 
					              }}
 | 
				
			||||||
              onDeleteTask={onDeleteTask}
 | 
					              onDeleteTask={onDeleteTask}
 | 
				
			||||||
              onChangeItemName={(itemID, itemName) => {
 | 
					              onChangeItemName={(itemID, itemName) => {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -234,7 +234,7 @@ type ShowNewProject = {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
const Projects = () => {
 | 
					const Projects = () => {
 | 
				
			||||||
  const { showPopup, hidePopup } = usePopup();
 | 
					  const { showPopup, hidePopup } = usePopup();
 | 
				
			||||||
  const { loading, data } = useGetProjectsQuery({ fetchPolicy: 'network-only' });
 | 
					  const { loading, data } = useGetProjectsQuery({ fetchPolicy: 'network-only', pollInterval: 5000 });
 | 
				
			||||||
  useEffect(() => {
 | 
					  useEffect(() => {
 | 
				
			||||||
    document.title = 'Taskcafé';
 | 
					    document.title = 'Taskcafé';
 | 
				
			||||||
  }, []);
 | 
					  }, []);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -154,7 +154,7 @@ type TeamProjectsProps = {
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const TeamProjects: React.FC<TeamProjectsProps> = ({ teamID }) => {
 | 
					const TeamProjects: React.FC<TeamProjectsProps> = ({ teamID }) => {
 | 
				
			||||||
  const { loading, data } = useGetTeamQuery({ variables: { teamID } });
 | 
					  const { loading, data } = useGetTeamQuery({ variables: { teamID }, pollInterval: 5000 });
 | 
				
			||||||
  if (loading) {
 | 
					  if (loading) {
 | 
				
			||||||
    return <span>loading</span>;
 | 
					    return <span>loading</span>;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -209,7 +209,8 @@ export enum ObjectType {
 | 
				
			|||||||
  Org = 'ORG',
 | 
					  Org = 'ORG',
 | 
				
			||||||
  Team = 'TEAM',
 | 
					  Team = 'TEAM',
 | 
				
			||||||
  Project = 'PROJECT',
 | 
					  Project = 'PROJECT',
 | 
				
			||||||
  Task = 'TASK'
 | 
					  Task = 'TASK',
 | 
				
			||||||
 | 
					  TaskGroup = 'TASK_GROUP'
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export type Query = {
 | 
					export type Query = {
 | 
				
			||||||
@@ -722,7 +723,7 @@ export type UpdateProjectMemberRolePayload = {
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export type NewTask = {
 | 
					export type NewTask = {
 | 
				
			||||||
  taskGroupID: Scalars['String'];
 | 
					  taskGroupID: Scalars['UUID'];
 | 
				
			||||||
  name: Scalars['String'];
 | 
					  name: Scalars['String'];
 | 
				
			||||||
  position: Scalars['Float'];
 | 
					  position: Scalars['Float'];
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
@@ -1472,7 +1473,7 @@ export type UpdateProjectMemberRoleMutation = (
 | 
				
			|||||||
);
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export type CreateTaskMutationVariables = {
 | 
					export type CreateTaskMutationVariables = {
 | 
				
			||||||
  taskGroupID: Scalars['String'];
 | 
					  taskGroupID: Scalars['UUID'];
 | 
				
			||||||
  name: Scalars['String'];
 | 
					  name: Scalars['String'];
 | 
				
			||||||
  position: Scalars['Float'];
 | 
					  position: Scalars['Float'];
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
@@ -3044,7 +3045,7 @@ export type UpdateProjectMemberRoleMutationHookResult = ReturnType<typeof useUpd
 | 
				
			|||||||
export type UpdateProjectMemberRoleMutationResult = ApolloReactCommon.MutationResult<UpdateProjectMemberRoleMutation>;
 | 
					export type UpdateProjectMemberRoleMutationResult = ApolloReactCommon.MutationResult<UpdateProjectMemberRoleMutation>;
 | 
				
			||||||
export type UpdateProjectMemberRoleMutationOptions = ApolloReactCommon.BaseMutationOptions<UpdateProjectMemberRoleMutation, UpdateProjectMemberRoleMutationVariables>;
 | 
					export type UpdateProjectMemberRoleMutationOptions = ApolloReactCommon.BaseMutationOptions<UpdateProjectMemberRoleMutation, UpdateProjectMemberRoleMutationVariables>;
 | 
				
			||||||
export const CreateTaskDocument = gql`
 | 
					export const CreateTaskDocument = gql`
 | 
				
			||||||
    mutation createTask($taskGroupID: String!, $name: String!, $position: Float!) {
 | 
					    mutation createTask($taskGroupID: UUID!, $name: String!, $position: Float!) {
 | 
				
			||||||
  createTask(input: {taskGroupID: $taskGroupID, name: $name, position: $position}) {
 | 
					  createTask(input: {taskGroupID: $taskGroupID, name: $name, position: $position}) {
 | 
				
			||||||
    ...TaskFields
 | 
					    ...TaskFields
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,7 +2,7 @@ import gql from 'graphql-tag';
 | 
				
			|||||||
import TASK_FRAGMENT from '../fragments/task';
 | 
					import TASK_FRAGMENT from '../fragments/task';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const CREATE_TASK_MUTATION = gql`
 | 
					const CREATE_TASK_MUTATION = gql`
 | 
				
			||||||
  mutation createTask($taskGroupID: String!, $name: String!, $position: Float!) {
 | 
					  mutation createTask($taskGroupID: UUID!, $name: String!, $position: Float!) {
 | 
				
			||||||
    createTask(input: { taskGroupID: $taskGroupID, name: $name, position: $position }) {
 | 
					    createTask(input: { taskGroupID: $taskGroupID, name: $name, position: $position }) {
 | 
				
			||||||
      ...TaskFields
 | 
					      ...TaskFields
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										13
									
								
								frontend/src/shared/utils/error.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								frontend/src/shared/utils/error.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
				
			|||||||
 | 
					import { ApolloError } from '@apollo/client';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default function hasNotFoundError(...errors: Array<ApolloError | undefined>) {
 | 
				
			||||||
 | 
					  for (const error of errors) {
 | 
				
			||||||
 | 
					    if (error && error.graphQLErrors.length !== 0) {
 | 
				
			||||||
 | 
					      const notFound = error.graphQLErrors.find(e => e.extensions && e.extensions.code === '404');
 | 
				
			||||||
 | 
					      if (notFound) {
 | 
				
			||||||
 | 
					        return true;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -2648,6 +2648,7 @@ enum ObjectType {
 | 
				
			|||||||
  TEAM
 | 
					  TEAM
 | 
				
			||||||
  PROJECT
 | 
					  PROJECT
 | 
				
			||||||
  TASK
 | 
					  TASK
 | 
				
			||||||
 | 
					  TASK_GROUP
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
directive @hasRole(roles: [RoleLevel!]!, level: ActionLevel!, type: ObjectType!) on FIELD_DEFINITION
 | 
					directive @hasRole(roles: [RoleLevel!]!, level: ActionLevel!, type: ObjectType!) on FIELD_DEFINITION
 | 
				
			||||||
@@ -2851,20 +2852,20 @@ type UpdateProjectMemberRolePayload {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
extend type Mutation {
 | 
					extend type Mutation {
 | 
				
			||||||
  createTask(input: NewTask!):
 | 
					  createTask(input: NewTask!):
 | 
				
			||||||
    Task! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
 | 
					    Task! @hasRole(roles: [ADMIN], level: PROJECT, type: TASK_GROUP)
 | 
				
			||||||
  deleteTask(input: DeleteTaskInput!):
 | 
					  deleteTask(input: DeleteTaskInput!):
 | 
				
			||||||
    DeleteTaskPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
 | 
					    DeleteTaskPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: TASK)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  updateTaskDescription(input: UpdateTaskDescriptionInput!):
 | 
					  updateTaskDescription(input: UpdateTaskDescriptionInput!):
 | 
				
			||||||
    Task! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
 | 
					    Task! @hasRole(roles: [ADMIN], level: PROJECT, type: TASK)
 | 
				
			||||||
  updateTaskLocation(input: NewTaskLocation!):
 | 
					  updateTaskLocation(input: NewTaskLocation!):
 | 
				
			||||||
    UpdateTaskLocationPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
 | 
					    UpdateTaskLocationPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: TASK)
 | 
				
			||||||
  updateTaskName(input: UpdateTaskName!):
 | 
					  updateTaskName(input: UpdateTaskName!):
 | 
				
			||||||
    Task! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
 | 
					    Task! @hasRole(roles: [ADMIN], level: PROJECT, type: TASK)
 | 
				
			||||||
  setTaskComplete(input: SetTaskComplete!):
 | 
					  setTaskComplete(input: SetTaskComplete!):
 | 
				
			||||||
    Task! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
 | 
					    Task! @hasRole(roles: [ADMIN], level: PROJECT, type: TASK)
 | 
				
			||||||
  updateTaskDueDate(input: UpdateTaskDueDate!):
 | 
					  updateTaskDueDate(input: UpdateTaskDueDate!):
 | 
				
			||||||
    Task! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
 | 
					    Task! @hasRole(roles: [ADMIN], level: PROJECT, type: TASK)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  assignTask(input: AssignTaskInput):
 | 
					  assignTask(input: AssignTaskInput):
 | 
				
			||||||
    Task! @hasRole(roles: [ADMIN], level: PROJECT, type: TASK)
 | 
					    Task! @hasRole(roles: [ADMIN], level: PROJECT, type: TASK)
 | 
				
			||||||
@@ -2873,7 +2874,7 @@ extend type Mutation {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
input NewTask {
 | 
					input NewTask {
 | 
				
			||||||
  taskGroupID: String!
 | 
					  taskGroupID: UUID!
 | 
				
			||||||
  name: String!
 | 
					  name: String!
 | 
				
			||||||
  position: Float!
 | 
					  position: Float!
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -6533,7 +6534,7 @@ func (ec *executionContext) _Mutation_createTask(ctx context.Context, field grap
 | 
				
			|||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				return nil, err
 | 
									return nil, err
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			typeArg, err := ec.unmarshalNObjectType2githubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋgraphᚐObjectType(ctx, "PROJECT")
 | 
								typeArg, err := ec.unmarshalNObjectType2githubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋgraphᚐObjectType(ctx, "TASK_GROUP")
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				return nil, err
 | 
									return nil, err
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
@@ -6606,7 +6607,7 @@ func (ec *executionContext) _Mutation_deleteTask(ctx context.Context, field grap
 | 
				
			|||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				return nil, err
 | 
									return nil, err
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			typeArg, err := ec.unmarshalNObjectType2githubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋgraphᚐObjectType(ctx, "PROJECT")
 | 
								typeArg, err := ec.unmarshalNObjectType2githubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋgraphᚐObjectType(ctx, "TASK")
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				return nil, err
 | 
									return nil, err
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
@@ -6679,7 +6680,7 @@ func (ec *executionContext) _Mutation_updateTaskDescription(ctx context.Context,
 | 
				
			|||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				return nil, err
 | 
									return nil, err
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			typeArg, err := ec.unmarshalNObjectType2githubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋgraphᚐObjectType(ctx, "PROJECT")
 | 
								typeArg, err := ec.unmarshalNObjectType2githubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋgraphᚐObjectType(ctx, "TASK")
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				return nil, err
 | 
									return nil, err
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
@@ -6752,7 +6753,7 @@ func (ec *executionContext) _Mutation_updateTaskLocation(ctx context.Context, fi
 | 
				
			|||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				return nil, err
 | 
									return nil, err
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			typeArg, err := ec.unmarshalNObjectType2githubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋgraphᚐObjectType(ctx, "PROJECT")
 | 
								typeArg, err := ec.unmarshalNObjectType2githubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋgraphᚐObjectType(ctx, "TASK")
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				return nil, err
 | 
									return nil, err
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
@@ -6825,7 +6826,7 @@ func (ec *executionContext) _Mutation_updateTaskName(ctx context.Context, field
 | 
				
			|||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				return nil, err
 | 
									return nil, err
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			typeArg, err := ec.unmarshalNObjectType2githubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋgraphᚐObjectType(ctx, "PROJECT")
 | 
								typeArg, err := ec.unmarshalNObjectType2githubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋgraphᚐObjectType(ctx, "TASK")
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				return nil, err
 | 
									return nil, err
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
@@ -6898,7 +6899,7 @@ func (ec *executionContext) _Mutation_setTaskComplete(ctx context.Context, field
 | 
				
			|||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				return nil, err
 | 
									return nil, err
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			typeArg, err := ec.unmarshalNObjectType2githubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋgraphᚐObjectType(ctx, "PROJECT")
 | 
								typeArg, err := ec.unmarshalNObjectType2githubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋgraphᚐObjectType(ctx, "TASK")
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				return nil, err
 | 
									return nil, err
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
@@ -6971,7 +6972,7 @@ func (ec *executionContext) _Mutation_updateTaskDueDate(ctx context.Context, fie
 | 
				
			|||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				return nil, err
 | 
									return nil, err
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			typeArg, err := ec.unmarshalNObjectType2githubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋgraphᚐObjectType(ctx, "PROJECT")
 | 
								typeArg, err := ec.unmarshalNObjectType2githubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋgraphᚐObjectType(ctx, "TASK")
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				return nil, err
 | 
									return nil, err
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
@@ -15194,7 +15195,7 @@ func (ec *executionContext) unmarshalInputNewTask(ctx context.Context, obj inter
 | 
				
			|||||||
		switch k {
 | 
							switch k {
 | 
				
			||||||
		case "taskGroupID":
 | 
							case "taskGroupID":
 | 
				
			||||||
			var err error
 | 
								var err error
 | 
				
			||||||
			it.TaskGroupID, err = ec.unmarshalNString2string(ctx, v)
 | 
								it.TaskGroupID, err = ec.unmarshalNUUID2githubᚗcomᚋgoogleᚋuuidᚐUUID(ctx, v)
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				return it, err
 | 
									return it, err
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -19,6 +19,7 @@ import (
 | 
				
			|||||||
	"github.com/jordanknott/taskcafe/internal/db"
 | 
						"github.com/jordanknott/taskcafe/internal/db"
 | 
				
			||||||
	"github.com/jordanknott/taskcafe/internal/utils"
 | 
						"github.com/jordanknott/taskcafe/internal/utils"
 | 
				
			||||||
	log "github.com/sirupsen/logrus"
 | 
						log "github.com/sirupsen/logrus"
 | 
				
			||||||
 | 
						"github.com/vektah/gqlparser/v2/gqlerror"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// NewHandler returns a new graphql endpoint handler.
 | 
					// NewHandler returns a new graphql endpoint handler.
 | 
				
			||||||
@@ -51,6 +52,8 @@ func NewHandler(repo db.Repository) http.Handler {
 | 
				
			|||||||
			fieldName = "TeamID"
 | 
								fieldName = "TeamID"
 | 
				
			||||||
		case ObjectTypeTask:
 | 
							case ObjectTypeTask:
 | 
				
			||||||
			fieldName = "TaskID"
 | 
								fieldName = "TaskID"
 | 
				
			||||||
 | 
							case ObjectTypeTaskGroup:
 | 
				
			||||||
 | 
								fieldName = "TaskGroupID"
 | 
				
			||||||
		default:
 | 
							default:
 | 
				
			||||||
			fieldName = "ProjectID"
 | 
								fieldName = "ProjectID"
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -68,6 +71,13 @@ func NewHandler(repo db.Repository) http.Handler {
 | 
				
			|||||||
				if err != nil {
 | 
									if err != nil {
 | 
				
			||||||
					return nil, err
 | 
										return nil, err
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
								} else if typeArg == ObjectTypeTaskGroup {
 | 
				
			||||||
 | 
									log.WithFields(log.Fields{"subjectID": subjectID}).Info("fetching project ID using task group ID")
 | 
				
			||||||
 | 
									taskGroup, err := repo.GetTaskGroupByID(ctx, subjectID)
 | 
				
			||||||
 | 
									if err != nil {
 | 
				
			||||||
 | 
										return nil, err
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									subjectID = taskGroup.ProjectID
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			roles, err := GetProjectRoles(ctx, repo, subjectID)
 | 
								roles, err := GetProjectRoles(ctx, repo, subjectID)
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
@@ -186,3 +196,13 @@ func GetActionType(actionType int32) ActionType {
 | 
				
			|||||||
		panic("Not a valid entity type!")
 | 
							panic("Not a valid entity type!")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// NotFoundError creates a 404 gqlerror
 | 
				
			||||||
 | 
					func NotFoundError(message string) error {
 | 
				
			||||||
 | 
						return &gqlerror.Error{
 | 
				
			||||||
 | 
							Message: message,
 | 
				
			||||||
 | 
							Extensions: map[string]interface{}{
 | 
				
			||||||
 | 
								"code": "404",
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -229,9 +229,9 @@ type NewRefreshToken struct {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type NewTask struct {
 | 
					type NewTask struct {
 | 
				
			||||||
	TaskGroupID string  `json:"taskGroupID"`
 | 
						TaskGroupID uuid.UUID `json:"taskGroupID"`
 | 
				
			||||||
	Name        string  `json:"name"`
 | 
						Name        string    `json:"name"`
 | 
				
			||||||
	Position    float64 `json:"position"`
 | 
						Position    float64   `json:"position"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type NewTaskGroup struct {
 | 
					type NewTaskGroup struct {
 | 
				
			||||||
@@ -648,10 +648,11 @@ func (e EntityType) MarshalGQL(w io.Writer) {
 | 
				
			|||||||
type ObjectType string
 | 
					type ObjectType string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
	ObjectTypeOrg     ObjectType = "ORG"
 | 
						ObjectTypeOrg       ObjectType = "ORG"
 | 
				
			||||||
	ObjectTypeTeam    ObjectType = "TEAM"
 | 
						ObjectTypeTeam      ObjectType = "TEAM"
 | 
				
			||||||
	ObjectTypeProject ObjectType = "PROJECT"
 | 
						ObjectTypeProject   ObjectType = "PROJECT"
 | 
				
			||||||
	ObjectTypeTask    ObjectType = "TASK"
 | 
						ObjectTypeTask      ObjectType = "TASK"
 | 
				
			||||||
 | 
						ObjectTypeTaskGroup ObjectType = "TASK_GROUP"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var AllObjectType = []ObjectType{
 | 
					var AllObjectType = []ObjectType{
 | 
				
			||||||
@@ -659,11 +660,12 @@ var AllObjectType = []ObjectType{
 | 
				
			|||||||
	ObjectTypeTeam,
 | 
						ObjectTypeTeam,
 | 
				
			||||||
	ObjectTypeProject,
 | 
						ObjectTypeProject,
 | 
				
			||||||
	ObjectTypeTask,
 | 
						ObjectTypeTask,
 | 
				
			||||||
 | 
						ObjectTypeTaskGroup,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (e ObjectType) IsValid() bool {
 | 
					func (e ObjectType) IsValid() bool {
 | 
				
			||||||
	switch e {
 | 
						switch e {
 | 
				
			||||||
	case ObjectTypeOrg, ObjectTypeTeam, ObjectTypeProject, ObjectTypeTask:
 | 
						case ObjectTypeOrg, ObjectTypeTeam, ObjectTypeProject, ObjectTypeTask, ObjectTypeTaskGroup:
 | 
				
			||||||
		return true
 | 
							return true
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return false
 | 
						return false
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -174,6 +174,7 @@ enum ObjectType {
 | 
				
			|||||||
  TEAM
 | 
					  TEAM
 | 
				
			||||||
  PROJECT
 | 
					  PROJECT
 | 
				
			||||||
  TASK
 | 
					  TASK
 | 
				
			||||||
 | 
					  TASK_GROUP
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
directive @hasRole(roles: [RoleLevel!]!, level: ActionLevel!, type: ObjectType!) on FIELD_DEFINITION
 | 
					directive @hasRole(roles: [RoleLevel!]!, level: ActionLevel!, type: ObjectType!) on FIELD_DEFINITION
 | 
				
			||||||
@@ -377,20 +378,20 @@ type UpdateProjectMemberRolePayload {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
extend type Mutation {
 | 
					extend type Mutation {
 | 
				
			||||||
  createTask(input: NewTask!):
 | 
					  createTask(input: NewTask!):
 | 
				
			||||||
    Task! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
 | 
					    Task! @hasRole(roles: [ADMIN], level: PROJECT, type: TASK_GROUP)
 | 
				
			||||||
  deleteTask(input: DeleteTaskInput!):
 | 
					  deleteTask(input: DeleteTaskInput!):
 | 
				
			||||||
    DeleteTaskPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
 | 
					    DeleteTaskPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: TASK)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  updateTaskDescription(input: UpdateTaskDescriptionInput!):
 | 
					  updateTaskDescription(input: UpdateTaskDescriptionInput!):
 | 
				
			||||||
    Task! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
 | 
					    Task! @hasRole(roles: [ADMIN], level: PROJECT, type: TASK)
 | 
				
			||||||
  updateTaskLocation(input: NewTaskLocation!):
 | 
					  updateTaskLocation(input: NewTaskLocation!):
 | 
				
			||||||
    UpdateTaskLocationPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
 | 
					    UpdateTaskLocationPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: TASK)
 | 
				
			||||||
  updateTaskName(input: UpdateTaskName!):
 | 
					  updateTaskName(input: UpdateTaskName!):
 | 
				
			||||||
    Task! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
 | 
					    Task! @hasRole(roles: [ADMIN], level: PROJECT, type: TASK)
 | 
				
			||||||
  setTaskComplete(input: SetTaskComplete!):
 | 
					  setTaskComplete(input: SetTaskComplete!):
 | 
				
			||||||
    Task! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
 | 
					    Task! @hasRole(roles: [ADMIN], level: PROJECT, type: TASK)
 | 
				
			||||||
  updateTaskDueDate(input: UpdateTaskDueDate!):
 | 
					  updateTaskDueDate(input: UpdateTaskDueDate!):
 | 
				
			||||||
    Task! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
 | 
					    Task! @hasRole(roles: [ADMIN], level: PROJECT, type: TASK)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  assignTask(input: AssignTaskInput):
 | 
					  assignTask(input: AssignTaskInput):
 | 
				
			||||||
    Task! @hasRole(roles: [ADMIN], level: PROJECT, type: TASK)
 | 
					    Task! @hasRole(roles: [ADMIN], level: PROJECT, type: TASK)
 | 
				
			||||||
@@ -399,7 +400,7 @@ extend type Mutation {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
input NewTask {
 | 
					input NewTask {
 | 
				
			||||||
  taskGroupID: String!
 | 
					  taskGroupID: UUID!
 | 
				
			||||||
  name: String!
 | 
					  name: String!
 | 
				
			||||||
  position: Float!
 | 
					  position: Float!
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -179,14 +179,9 @@ func (r *mutationResolver) UpdateProjectMemberRole(ctx context.Context, input Up
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (r *mutationResolver) CreateTask(ctx context.Context, input NewTask) (*db.Task, error) {
 | 
					func (r *mutationResolver) CreateTask(ctx context.Context, input NewTask) (*db.Task, error) {
 | 
				
			||||||
	taskGroupID, err := uuid.Parse(input.TaskGroupID)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		log.WithError(err).Error("issue while parsing task group ID")
 | 
					 | 
				
			||||||
		return &db.Task{}, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	createdAt := time.Now().UTC()
 | 
						createdAt := time.Now().UTC()
 | 
				
			||||||
	log.WithFields(log.Fields{"positon": input.Position, "taskGroupID": taskGroupID}).Info("creating task")
 | 
						log.WithFields(log.Fields{"positon": input.Position, "taskGroupID": input.TaskGroupID}).Info("creating task")
 | 
				
			||||||
	task, err := r.Repository.CreateTask(ctx, db.CreateTaskParams{taskGroupID, createdAt, input.Name, input.Position})
 | 
						task, err := r.Repository.CreateTask(ctx, db.CreateTaskParams{input.TaskGroupID, createdAt, input.Name, input.Position})
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		log.WithError(err).Error("issue while creating task")
 | 
							log.WithError(err).Error("issue while creating task")
 | 
				
			||||||
		return &db.Task{}, err
 | 
							return &db.Task{}, err
 | 
				
			||||||
@@ -238,6 +233,9 @@ func (r *mutationResolver) SetTaskComplete(ctx context.Context, input SetTaskCom
 | 
				
			|||||||
	completedAt := time.Now().UTC()
 | 
						completedAt := time.Now().UTC()
 | 
				
			||||||
	task, err := r.Repository.SetTaskComplete(ctx, db.SetTaskCompleteParams{TaskID: input.TaskID, Complete: input.Complete, CompletedAt: sql.NullTime{Time: completedAt, Valid: true}})
 | 
						task, err := r.Repository.SetTaskComplete(ctx, db.SetTaskCompleteParams{TaskID: input.TaskID, Complete: input.Complete, CompletedAt: sql.NullTime{Time: completedAt, Valid: true}})
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
 | 
							if err == sql.ErrNoRows {
 | 
				
			||||||
 | 
								return &db.Task{}, NotFoundError("task does not exist")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		return &db.Task{}, err
 | 
							return &db.Task{}, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return &task, nil
 | 
						return &task, nil
 | 
				
			||||||
@@ -1033,6 +1031,14 @@ func (r *queryResolver) FindProject(ctx context.Context, input FindProject) (*db
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func (r *queryResolver) FindTask(ctx context.Context, input FindTask) (*db.Task, error) {
 | 
					func (r *queryResolver) FindTask(ctx context.Context, input FindTask) (*db.Task, error) {
 | 
				
			||||||
	task, err := r.Repository.GetTaskByID(ctx, input.TaskID)
 | 
						task, err := r.Repository.GetTaskByID(ctx, input.TaskID)
 | 
				
			||||||
 | 
						if err == sql.ErrNoRows {
 | 
				
			||||||
 | 
							return &db.Task{}, &gqlerror.Error{
 | 
				
			||||||
 | 
								Message: "Task does not exist",
 | 
				
			||||||
 | 
								Extensions: map[string]interface{}{
 | 
				
			||||||
 | 
									"code": "404",
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	return &task, err
 | 
						return &task, err
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1240,6 +1246,9 @@ func (r *taskResolver) Assigned(ctx context.Context, obj *db.Task) ([]Member, er
 | 
				
			|||||||
	taskMemberLinks, err := r.Repository.GetAssignedMembersForTask(ctx, obj.TaskID)
 | 
						taskMemberLinks, err := r.Repository.GetAssignedMembersForTask(ctx, obj.TaskID)
 | 
				
			||||||
	taskMembers := []Member{}
 | 
						taskMembers := []Member{}
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
 | 
							if err == sql.ErrNoRows {
 | 
				
			||||||
 | 
								return taskMembers, nil
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		return taskMembers, err
 | 
							return taskMembers, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	for _, taskMemberLink := range taskMemberLinks {
 | 
						for _, taskMemberLink := range taskMemberLinks {
 | 
				
			||||||
@@ -1274,11 +1283,19 @@ func (r *taskResolver) Assigned(ctx context.Context, obj *db.Task) ([]Member, er
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (r *taskResolver) Labels(ctx context.Context, obj *db.Task) ([]db.TaskLabel, error) {
 | 
					func (r *taskResolver) Labels(ctx context.Context, obj *db.Task) ([]db.TaskLabel, error) {
 | 
				
			||||||
	return r.Repository.GetTaskLabelsForTaskID(ctx, obj.TaskID)
 | 
						labels, err := r.Repository.GetTaskLabelsForTaskID(ctx, obj.TaskID)
 | 
				
			||||||
 | 
						if err != nil && err != sql.ErrNoRows {
 | 
				
			||||||
 | 
							return []db.TaskLabel{}, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return labels, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (r *taskResolver) Checklists(ctx context.Context, obj *db.Task) ([]db.TaskChecklist, error) {
 | 
					func (r *taskResolver) Checklists(ctx context.Context, obj *db.Task) ([]db.TaskChecklist, error) {
 | 
				
			||||||
	return r.Repository.GetTaskChecklistsForTask(ctx, obj.TaskID)
 | 
						checklists, err := r.Repository.GetTaskChecklistsForTask(ctx, obj.TaskID)
 | 
				
			||||||
 | 
						if err != nil && err != sql.ErrNoRows {
 | 
				
			||||||
 | 
							return []db.TaskChecklist{}, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return checklists, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (r *taskResolver) Badges(ctx context.Context, obj *db.Task) (*TaskBadges, error) {
 | 
					func (r *taskResolver) Badges(ctx context.Context, obj *db.Task) (*TaskBadges, error) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,6 +14,7 @@ enum ObjectType {
 | 
				
			|||||||
  TEAM
 | 
					  TEAM
 | 
				
			||||||
  PROJECT
 | 
					  PROJECT
 | 
				
			||||||
  TASK
 | 
					  TASK
 | 
				
			||||||
 | 
					  TASK_GROUP
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
directive @hasRole(roles: [RoleLevel!]!, level: ActionLevel!, type: ObjectType!) on FIELD_DEFINITION
 | 
					directive @hasRole(roles: [RoleLevel!]!, level: ActionLevel!, type: ObjectType!) on FIELD_DEFINITION
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,19 +1,19 @@
 | 
				
			|||||||
extend type Mutation {
 | 
					extend type Mutation {
 | 
				
			||||||
  createTask(input: NewTask!):
 | 
					  createTask(input: NewTask!):
 | 
				
			||||||
    Task! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
 | 
					    Task! @hasRole(roles: [ADMIN], level: PROJECT, type: TASK_GROUP)
 | 
				
			||||||
  deleteTask(input: DeleteTaskInput!):
 | 
					  deleteTask(input: DeleteTaskInput!):
 | 
				
			||||||
    DeleteTaskPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
 | 
					    DeleteTaskPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: TASK)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  updateTaskDescription(input: UpdateTaskDescriptionInput!):
 | 
					  updateTaskDescription(input: UpdateTaskDescriptionInput!):
 | 
				
			||||||
    Task! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
 | 
					    Task! @hasRole(roles: [ADMIN], level: PROJECT, type: TASK)
 | 
				
			||||||
  updateTaskLocation(input: NewTaskLocation!):
 | 
					  updateTaskLocation(input: NewTaskLocation!):
 | 
				
			||||||
    UpdateTaskLocationPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
 | 
					    UpdateTaskLocationPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: TASK)
 | 
				
			||||||
  updateTaskName(input: UpdateTaskName!):
 | 
					  updateTaskName(input: UpdateTaskName!):
 | 
				
			||||||
    Task! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
 | 
					    Task! @hasRole(roles: [ADMIN], level: PROJECT, type: TASK)
 | 
				
			||||||
  setTaskComplete(input: SetTaskComplete!):
 | 
					  setTaskComplete(input: SetTaskComplete!):
 | 
				
			||||||
    Task! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
 | 
					    Task! @hasRole(roles: [ADMIN], level: PROJECT, type: TASK)
 | 
				
			||||||
  updateTaskDueDate(input: UpdateTaskDueDate!):
 | 
					  updateTaskDueDate(input: UpdateTaskDueDate!):
 | 
				
			||||||
    Task! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
 | 
					    Task! @hasRole(roles: [ADMIN], level: PROJECT, type: TASK)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  assignTask(input: AssignTaskInput):
 | 
					  assignTask(input: AssignTaskInput):
 | 
				
			||||||
    Task! @hasRole(roles: [ADMIN], level: PROJECT, type: TASK)
 | 
					    Task! @hasRole(roles: [ADMIN], level: PROJECT, type: TASK)
 | 
				
			||||||
@@ -22,7 +22,7 @@ extend type Mutation {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
input NewTask {
 | 
					input NewTask {
 | 
				
			||||||
  taskGroupID: String!
 | 
					  taskGroupID: UUID!
 | 
				
			||||||
  name: String!
 | 
					  name: String!
 | 
				
			||||||
  position: Float!
 | 
					  position: Float!
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user