fix: member permissions now works correctly

This commit is contained in:
Jordan Knott 2020-09-19 17:26:02 -05:00
parent 0366b4c7f7
commit 0d4fb6a0d0
29 changed files with 604 additions and 462 deletions

View File

@ -309,7 +309,7 @@ const Details: React.FC<DetailsProps> = ({
task={data.findTask} task={data.findTask}
onChecklistDrop={checklist => { onChecklistDrop={checklist => {
updateTaskChecklistLocation({ updateTaskChecklistLocation({
variables: { checklistID: checklist.id, position: checklist.position }, variables: { taskChecklistID: checklist.id, position: checklist.position },
optimisticResponse: { optimisticResponse: {
__typename: 'Mutation', __typename: 'Mutation',
@ -324,20 +324,24 @@ const Details: React.FC<DetailsProps> = ({
}, },
}); });
}} }}
onChecklistItemDrop={(prevChecklistID, checklistID, checklistItem) => { onChecklistItemDrop={(prevChecklistID, taskChecklistID, checklistItem) => {
updateTaskChecklistItemLocation({ updateTaskChecklistItemLocation({
variables: { checklistID, checklistItemID: checklistItem.id, position: checklistItem.position }, variables: {
taskChecklistID,
taskChecklistItemID: checklistItem.id,
position: checklistItem.position,
},
optimisticResponse: { optimisticResponse: {
__typename: 'Mutation', __typename: 'Mutation',
updateTaskChecklistItemLocation: { updateTaskChecklistItemLocation: {
__typename: 'UpdateTaskChecklistItemLocationPayload', __typename: 'UpdateTaskChecklistItemLocationPayload',
prevChecklistID, prevChecklistID,
checklistID, taskChecklistID,
checklistItem: { checklistItem: {
__typename: 'TaskChecklistItem', __typename: 'TaskChecklistItem',
position: checklistItem.position, position: checklistItem.position,
id: checklistItem.id, id: checklistItem.id,
taskChecklistID: checklistID, taskChecklistID,
}, },
}, },
}, },

View File

@ -135,7 +135,26 @@ const Project = () => {
const [value, setValue] = useStateWithLocalStorage(CARD_LABEL_VARIANT_STORAGE_KEY); const [value, setValue] = useStateWithLocalStorage(CARD_LABEL_VARIANT_STORAGE_KEY);
const [updateProjectMemberRole] = useUpdateProjectMemberRoleMutation(); const [updateProjectMemberRole] = useUpdateProjectMemberRoleMutation();
const [deleteTask] = useDeleteTaskMutation(); const [deleteTask] = useDeleteTaskMutation({
update: (client, resp) =>
updateApolloCache<FindProjectQuery>(
client,
FindProjectDocument,
cache =>
produce(cache, draftCache => {
const taskGroupIdx = draftCache.findProject.taskGroups.findIndex(
tg => tg.tasks.findIndex(t => t.id === resp.data.deleteTask.taskID) !== -1,
);
if (taskGroupIdx !== -1) {
draftCache.findProject.taskGroups[taskGroupIdx].tasks = cache.findProject.taskGroups[
taskGroupIdx
].tasks.filter(t => t.id !== resp.data.deleteTask.taskID);
}
}),
{ projectID },
),
});
const [updateTaskName] = useUpdateTaskNameMutation(); const [updateTaskName] = useUpdateTaskNameMutation();
@ -284,6 +303,7 @@ const Project = () => {
}} }}
onDeleteTask={deletedTask => { onDeleteTask={deletedTask => {
deleteTask({ variables: { taskID: deletedTask.id } }); deleteTask({ variables: { taskID: deletedTask.id } });
history.push(`${match.url}/board`);
}} }}
onOpenAddLabelPopup={(task, $targetRef) => { onOpenAddLabelPopup={(task, $targetRef) => {
taskLabelsRef.current = task.labels; taskLabelsRef.current = task.labels;

View File

@ -209,7 +209,10 @@ export enum ObjectType {
Org = 'ORG', Org = 'ORG',
Team = 'TEAM', Team = 'TEAM',
Project = 'PROJECT', Project = 'PROJECT',
Task = 'TASK' Task = 'TASK',
TaskGroup = 'TASK_GROUP',
TaskChecklist = 'TASK_CHECKLIST',
TaskChecklistItem = 'TASK_CHECKLIST_ITEM'
} }
export type Query = { export type Query = {
@ -588,7 +591,7 @@ export type ProjectsFilter = {
}; };
export type FindUser = { export type FindUser = {
userId: Scalars['String']; userID: Scalars['UUID'];
}; };
export type FindProject = { export type FindProject = {
@ -722,7 +725,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'];
}; };
@ -765,34 +768,34 @@ export type NewTaskLocation = {
}; };
export type DeleteTaskInput = { export type DeleteTaskInput = {
taskID: Scalars['String']; taskID: Scalars['UUID'];
}; };
export type DeleteTaskPayload = { export type DeleteTaskPayload = {
__typename?: 'DeleteTaskPayload'; __typename?: 'DeleteTaskPayload';
taskID: Scalars['String']; taskID: Scalars['UUID'];
}; };
export type UpdateTaskName = { export type UpdateTaskName = {
taskID: Scalars['String']; taskID: Scalars['UUID'];
name: Scalars['String']; name: Scalars['String'];
}; };
export type UpdateTaskChecklistItemLocation = { export type UpdateTaskChecklistItemLocation = {
checklistID: Scalars['UUID']; taskChecklistID: Scalars['UUID'];
checklistItemID: Scalars['UUID']; taskChecklistItemID: Scalars['UUID'];
position: Scalars['Float']; position: Scalars['Float'];
}; };
export type UpdateTaskChecklistItemLocationPayload = { export type UpdateTaskChecklistItemLocationPayload = {
__typename?: 'UpdateTaskChecklistItemLocationPayload'; __typename?: 'UpdateTaskChecklistItemLocationPayload';
checklistID: Scalars['UUID']; taskChecklistID: Scalars['UUID'];
prevChecklistID: Scalars['UUID']; prevChecklistID: Scalars['UUID'];
checklistItem: TaskChecklistItem; checklistItem: TaskChecklistItem;
}; };
export type UpdateTaskChecklistLocation = { export type UpdateTaskChecklistLocation = {
checklistID: Scalars['UUID']; taskChecklistID: Scalars['UUID'];
position: Scalars['Float']; position: Scalars['Float'];
}; };
@ -908,7 +911,7 @@ export type DeleteTaskGroupPayload = {
}; };
export type NewTaskGroup = { export type NewTaskGroup = {
projectID: Scalars['String']; projectID: Scalars['UUID'];
name: Scalars['String']; name: Scalars['String'];
position: Scalars['Float']; position: Scalars['Float'];
}; };
@ -919,6 +922,7 @@ export type AddTaskLabelInput = {
}; };
export type RemoveTaskLabelInput = { export type RemoveTaskLabelInput = {
taskID: Scalars['UUID'];
taskLabelID: Scalars['UUID']; taskLabelID: Scalars['UUID'];
}; };
@ -1020,7 +1024,7 @@ export type UpdateUserRolePayload = {
}; };
export type NewRefreshToken = { export type NewRefreshToken = {
userId: Scalars['String']; userID: Scalars['UUID'];
}; };
export type NewUserAccount = { export type NewUserAccount = {
@ -1033,7 +1037,7 @@ export type NewUserAccount = {
}; };
export type LogoutUser = { export type LogoutUser = {
userID: Scalars['String']; userID: Scalars['UUID'];
}; };
export type DeleteUserAccount = { export type DeleteUserAccount = {
@ -1119,7 +1123,7 @@ export type CreateProjectLabelMutation = (
); );
export type CreateTaskGroupMutationVariables = { export type CreateTaskGroupMutationVariables = {
projectID: Scalars['String']; projectID: Scalars['UUID'];
name: Scalars['String']; name: Scalars['String'];
position: Scalars['Float']; position: Scalars['Float'];
}; };
@ -1147,7 +1151,7 @@ export type DeleteProjectLabelMutation = (
); );
export type DeleteTaskMutationVariables = { export type DeleteTaskMutationVariables = {
taskID: Scalars['String']; taskID: Scalars['UUID'];
}; };
@ -1472,7 +1476,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'];
}; };
@ -1583,8 +1587,8 @@ export type SetTaskCompleteMutation = (
); );
export type UpdateTaskChecklistItemLocationMutationVariables = { export type UpdateTaskChecklistItemLocationMutationVariables = {
checklistID: Scalars['UUID']; taskChecklistID: Scalars['UUID'];
checklistItemID: Scalars['UUID']; taskChecklistItemID: Scalars['UUID'];
position: Scalars['Float']; position: Scalars['Float'];
}; };
@ -1593,7 +1597,7 @@ export type UpdateTaskChecklistItemLocationMutation = (
{ __typename?: 'Mutation' } { __typename?: 'Mutation' }
& { updateTaskChecklistItemLocation: ( & { updateTaskChecklistItemLocation: (
{ __typename?: 'UpdateTaskChecklistItemLocationPayload' } { __typename?: 'UpdateTaskChecklistItemLocationPayload' }
& Pick<UpdateTaskChecklistItemLocationPayload, 'checklistID' | 'prevChecklistID'> & Pick<UpdateTaskChecklistItemLocationPayload, 'taskChecklistID' | 'prevChecklistID'>
& { checklistItem: ( & { checklistItem: (
{ __typename?: 'TaskChecklistItem' } { __typename?: 'TaskChecklistItem' }
& Pick<TaskChecklistItem, 'id' | 'taskChecklistID' | 'position'> & Pick<TaskChecklistItem, 'id' | 'taskChecklistID' | 'position'>
@ -1616,7 +1620,7 @@ export type UpdateTaskChecklistItemNameMutation = (
); );
export type UpdateTaskChecklistLocationMutationVariables = { export type UpdateTaskChecklistLocationMutationVariables = {
checklistID: Scalars['UUID']; taskChecklistID: Scalars['UUID'];
position: Scalars['Float']; position: Scalars['Float'];
}; };
@ -2072,7 +2076,7 @@ export type UpdateTaskLocationMutation = (
); );
export type UpdateTaskNameMutationVariables = { export type UpdateTaskNameMutationVariables = {
taskID: Scalars['String']; taskID: Scalars['UUID'];
name: Scalars['String']; name: Scalars['String'];
}; };
@ -2442,7 +2446,7 @@ export type CreateProjectLabelMutationHookResult = ReturnType<typeof useCreatePr
export type CreateProjectLabelMutationResult = ApolloReactCommon.MutationResult<CreateProjectLabelMutation>; export type CreateProjectLabelMutationResult = ApolloReactCommon.MutationResult<CreateProjectLabelMutation>;
export type CreateProjectLabelMutationOptions = ApolloReactCommon.BaseMutationOptions<CreateProjectLabelMutation, CreateProjectLabelMutationVariables>; export type CreateProjectLabelMutationOptions = ApolloReactCommon.BaseMutationOptions<CreateProjectLabelMutation, CreateProjectLabelMutationVariables>;
export const CreateTaskGroupDocument = gql` export const CreateTaskGroupDocument = gql`
mutation createTaskGroup($projectID: String!, $name: String!, $position: Float!) { mutation createTaskGroup($projectID: UUID!, $name: String!, $position: Float!) {
createTaskGroup(input: {projectID: $projectID, name: $name, position: $position}) { createTaskGroup(input: {projectID: $projectID, name: $name, position: $position}) {
id id
name name
@ -2510,7 +2514,7 @@ export type DeleteProjectLabelMutationHookResult = ReturnType<typeof useDeletePr
export type DeleteProjectLabelMutationResult = ApolloReactCommon.MutationResult<DeleteProjectLabelMutation>; export type DeleteProjectLabelMutationResult = ApolloReactCommon.MutationResult<DeleteProjectLabelMutation>;
export type DeleteProjectLabelMutationOptions = ApolloReactCommon.BaseMutationOptions<DeleteProjectLabelMutation, DeleteProjectLabelMutationVariables>; export type DeleteProjectLabelMutationOptions = ApolloReactCommon.BaseMutationOptions<DeleteProjectLabelMutation, DeleteProjectLabelMutationVariables>;
export const DeleteTaskDocument = gql` export const DeleteTaskDocument = gql`
mutation deleteTask($taskID: String!) { mutation deleteTask($taskID: UUID!) {
deleteTask(input: {taskID: $taskID}) { deleteTask(input: {taskID: $taskID}) {
taskID taskID
} }
@ -3044,7 +3048,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
} }
@ -3297,9 +3301,9 @@ export type SetTaskCompleteMutationHookResult = ReturnType<typeof useSetTaskComp
export type SetTaskCompleteMutationResult = ApolloReactCommon.MutationResult<SetTaskCompleteMutation>; export type SetTaskCompleteMutationResult = ApolloReactCommon.MutationResult<SetTaskCompleteMutation>;
export type SetTaskCompleteMutationOptions = ApolloReactCommon.BaseMutationOptions<SetTaskCompleteMutation, SetTaskCompleteMutationVariables>; export type SetTaskCompleteMutationOptions = ApolloReactCommon.BaseMutationOptions<SetTaskCompleteMutation, SetTaskCompleteMutationVariables>;
export const UpdateTaskChecklistItemLocationDocument = gql` export const UpdateTaskChecklistItemLocationDocument = gql`
mutation updateTaskChecklistItemLocation($checklistID: UUID!, $checklistItemID: UUID!, $position: Float!) { mutation updateTaskChecklistItemLocation($taskChecklistID: UUID!, $taskChecklistItemID: UUID!, $position: Float!) {
updateTaskChecklistItemLocation(input: {checklistID: $checklistID, checklistItemID: $checklistItemID, position: $position}) { updateTaskChecklistItemLocation(input: {taskChecklistID: $taskChecklistID, taskChecklistItemID: $taskChecklistItemID, position: $position}) {
checklistID taskChecklistID
prevChecklistID prevChecklistID
checklistItem { checklistItem {
id id
@ -3324,8 +3328,8 @@ export type UpdateTaskChecklistItemLocationMutationFn = ApolloReactCommon.Mutati
* @example * @example
* const [updateTaskChecklistItemLocationMutation, { data, loading, error }] = useUpdateTaskChecklistItemLocationMutation({ * const [updateTaskChecklistItemLocationMutation, { data, loading, error }] = useUpdateTaskChecklistItemLocationMutation({
* variables: { * variables: {
* checklistID: // value for 'checklistID' * taskChecklistID: // value for 'taskChecklistID'
* checklistItemID: // value for 'checklistItemID' * taskChecklistItemID: // value for 'taskChecklistItemID'
* position: // value for 'position' * position: // value for 'position'
* }, * },
* }); * });
@ -3371,8 +3375,8 @@ export type UpdateTaskChecklistItemNameMutationHookResult = ReturnType<typeof us
export type UpdateTaskChecklistItemNameMutationResult = ApolloReactCommon.MutationResult<UpdateTaskChecklistItemNameMutation>; export type UpdateTaskChecklistItemNameMutationResult = ApolloReactCommon.MutationResult<UpdateTaskChecklistItemNameMutation>;
export type UpdateTaskChecklistItemNameMutationOptions = ApolloReactCommon.BaseMutationOptions<UpdateTaskChecklistItemNameMutation, UpdateTaskChecklistItemNameMutationVariables>; export type UpdateTaskChecklistItemNameMutationOptions = ApolloReactCommon.BaseMutationOptions<UpdateTaskChecklistItemNameMutation, UpdateTaskChecklistItemNameMutationVariables>;
export const UpdateTaskChecklistLocationDocument = gql` export const UpdateTaskChecklistLocationDocument = gql`
mutation updateTaskChecklistLocation($checklistID: UUID!, $position: Float!) { mutation updateTaskChecklistLocation($taskChecklistID: UUID!, $position: Float!) {
updateTaskChecklistLocation(input: {checklistID: $checklistID, position: $position}) { updateTaskChecklistLocation(input: {taskChecklistID: $taskChecklistID, position: $position}) {
checklist { checklist {
id id
position position
@ -3395,7 +3399,7 @@ export type UpdateTaskChecklistLocationMutationFn = ApolloReactCommon.MutationFu
* @example * @example
* const [updateTaskChecklistLocationMutation, { data, loading, error }] = useUpdateTaskChecklistLocationMutation({ * const [updateTaskChecklistLocationMutation, { data, loading, error }] = useUpdateTaskChecklistLocationMutation({
* variables: { * variables: {
* checklistID: // value for 'checklistID' * taskChecklistID: // value for 'taskChecklistID'
* position: // value for 'position' * position: // value for 'position'
* }, * },
* }); * });
@ -4275,7 +4279,7 @@ export type UpdateTaskLocationMutationHookResult = ReturnType<typeof useUpdateTa
export type UpdateTaskLocationMutationResult = ApolloReactCommon.MutationResult<UpdateTaskLocationMutation>; export type UpdateTaskLocationMutationResult = ApolloReactCommon.MutationResult<UpdateTaskLocationMutation>;
export type UpdateTaskLocationMutationOptions = ApolloReactCommon.BaseMutationOptions<UpdateTaskLocationMutation, UpdateTaskLocationMutationVariables>; export type UpdateTaskLocationMutationOptions = ApolloReactCommon.BaseMutationOptions<UpdateTaskLocationMutation, UpdateTaskLocationMutationVariables>;
export const UpdateTaskNameDocument = gql` export const UpdateTaskNameDocument = gql`
mutation updateTaskName($taskID: String!, $name: String!) { mutation updateTaskName($taskID: UUID!, $name: String!) {
updateTaskName(input: {taskID: $taskID, name: $name}) { updateTaskName(input: {taskID: $taskID, name: $name}) {
id id
name name

View File

@ -1,4 +1,4 @@
mutation createTaskGroup( $projectID: String!, $name: String!, $position: Float! ) { mutation createTaskGroup( $projectID: UUID!, $name: String!, $position: Float! ) {
createTaskGroup( createTaskGroup(
input: { projectID: $projectID, name: $name, position: $position } input: { projectID: $projectID, name: $name, position: $position }
) { ) {

View File

@ -1,4 +1,4 @@
mutation deleteTask($taskID: String!) { mutation deleteTask($taskID: UUID!) {
deleteTask(input: { taskID: $taskID }) { deleteTask(input: { taskID: $taskID }) {
taskID taskID
} }

View File

@ -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
} }

View File

@ -1,11 +1,11 @@
import gql from 'graphql-tag'; import gql from 'graphql-tag';
const UPDATE_TASK_CHECKLIST_ITEM_LOCATION_MUTATION = gql` const UPDATE_TASK_CHECKLIST_ITEM_LOCATION_MUTATION = gql`
mutation updateTaskChecklistItemLocation($checklistID: UUID!, $checklistItemID: UUID!, $position: Float!) { mutation updateTaskChecklistItemLocation($taskChecklistID: UUID!, $taskChecklistItemID: UUID!, $position: Float!) {
updateTaskChecklistItemLocation( updateTaskChecklistItemLocation(
input: { checklistID: $checklistID, checklistItemID: $checklistItemID, position: $position } input: { taskChecklistID: $taskChecklistID, taskChecklistItemID: $taskChecklistItemID, position: $position }
) { ) {
checklistID taskChecklistID
prevChecklistID prevChecklistID
checklistItem { checklistItem {
id id

View File

@ -1,8 +1,8 @@
import gql from 'graphql-tag'; import gql from 'graphql-tag';
const UPDATE_TASK_CHECKLIST_LOCATION_MUTATION = gql` const UPDATE_TASK_CHECKLIST_LOCATION_MUTATION = gql`
mutation updateTaskChecklistLocation($checklistID: UUID!, $position: Float!) { mutation updateTaskChecklistLocation($taskChecklistID: UUID!, $position: Float!) {
updateTaskChecklistLocation(input: { checklistID: $checklistID, position: $position }) { updateTaskChecklistLocation(input: { taskChecklistID: $taskChecklistID, position: $position }) {
checklist { checklist {
id id
position position

View File

@ -1,4 +1,4 @@
mutation updateTaskName($taskID: String!, $name: String!) { mutation updateTaskName($taskID: UUID!, $name: String!) {
updateTaskName(input: { taskID: $taskID, name: $name }) { updateTaskName(input: { taskID: $taskID, name: $name }) {
id id
name name

View File

@ -2,9 +2,10 @@ package commands
import ( import (
"fmt" "fmt"
"time"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/viper" "github.com/spf13/viper"
"time"
"github.com/RichardKnop/machinery/v1" "github.com/RichardKnop/machinery/v1"
"github.com/RichardKnop/machinery/v1/config" "github.com/RichardKnop/machinery/v1/config"

View File

@ -64,6 +64,9 @@ type Querier interface {
GetNotificationForNotificationID(ctx context.Context, notificationID uuid.UUID) (GetNotificationForNotificationIDRow, error) GetNotificationForNotificationID(ctx context.Context, notificationID uuid.UUID) (GetNotificationForNotificationIDRow, error)
GetProjectByID(ctx context.Context, projectID uuid.UUID) (Project, error) GetProjectByID(ctx context.Context, projectID uuid.UUID) (Project, error)
GetProjectIDForTask(ctx context.Context, taskID uuid.UUID) (uuid.UUID, error) GetProjectIDForTask(ctx context.Context, taskID uuid.UUID) (uuid.UUID, error)
GetProjectIDForTaskChecklist(ctx context.Context, taskChecklistID uuid.UUID) (uuid.UUID, error)
GetProjectIDForTaskChecklistItem(ctx context.Context, taskChecklistItemID uuid.UUID) (uuid.UUID, error)
GetProjectIDForTaskGroup(ctx context.Context, taskGroupID uuid.UUID) (uuid.UUID, error)
GetProjectLabelByID(ctx context.Context, projectLabelID uuid.UUID) (ProjectLabel, error) GetProjectLabelByID(ctx context.Context, projectLabelID uuid.UUID) (ProjectLabel, error)
GetProjectLabelsForProject(ctx context.Context, projectID uuid.UUID) ([]ProjectLabel, error) GetProjectLabelsForProject(ctx context.Context, projectID uuid.UUID) ([]ProjectLabel, error)
GetProjectMembersForProjectID(ctx context.Context, projectID uuid.UUID) ([]ProjectMember, error) GetProjectMembersForProjectID(ctx context.Context, projectID uuid.UUID) ([]ProjectMember, error)

View File

@ -25,4 +25,3 @@ WHERE n.notification_id = $1;
-- name: CreateNotification :one -- name: CreateNotification :one
INSERT INTO notification(notification_object_id, notifier_id) INSERT INTO notification(notification_object_id, notifier_id)
VALUES ($1, $2) RETURNING *; VALUES ($1, $2) RETURNING *;

View File

@ -41,3 +41,16 @@ UPDATE task_checklist SET position = $2 WHERE task_checklist_id = $1 RETURNING *
-- name: UpdateTaskChecklistItemLocation :one -- name: UpdateTaskChecklistItemLocation :one
UPDATE task_checklist_item SET position = $2, task_checklist_id = $3 WHERE task_checklist_item_id = $1 RETURNING *; UPDATE task_checklist_item SET position = $2, task_checklist_id = $3 WHERE task_checklist_item_id = $1 RETURNING *;
-- name: GetProjectIDForTaskChecklist :one
SELECT project_id FROM task_checklist
INNER JOIN task ON task.task_id = task_checklist.task_id
INNER JOIN task_group ON task_group.task_group_id = task.task_group_id
WHERE task_checklist.task_checklist_id = $1;
-- name: GetProjectIDForTaskChecklistItem :one
SELECT project_id FROM task_checklist_item AS tci
INNER JOIN task_checklist ON task_checklist.task_checklist_id = tci.task_checklist_id
INNER JOIN task ON task.task_id = task_checklist.task_id
INNER JOIN task_group ON task_group.task_group_id = task.task_group_id
WHERE tci.task_checklist_item_id = $1;

View File

@ -5,6 +5,9 @@ INSERT INTO task_group (project_id, created_at, name, position)
-- name: GetTaskGroupsForProject :many -- name: GetTaskGroupsForProject :many
SELECT * FROM task_group WHERE project_id = $1; SELECT * FROM task_group WHERE project_id = $1;
-- name: GetProjectIDForTaskGroup :one
SELECT project_id from task_group WHERE task_group_id = $1;
-- name: GetAllTaskGroups :many -- name: GetAllTaskGroups :many
SELECT * FROM task_group; SELECT * FROM task_group;

View File

@ -90,6 +90,35 @@ func (q *Queries) DeleteTaskChecklistItem(ctx context.Context, taskChecklistItem
return err return err
} }
const getProjectIDForTaskChecklist = `-- name: GetProjectIDForTaskChecklist :one
SELECT project_id FROM task_checklist
INNER JOIN task ON task.task_id = task_checklist.task_id
INNER JOIN task_group ON task_group.task_group_id = task.task_group_id
WHERE task_checklist.task_checklist_id = $1
`
func (q *Queries) GetProjectIDForTaskChecklist(ctx context.Context, taskChecklistID uuid.UUID) (uuid.UUID, error) {
row := q.db.QueryRowContext(ctx, getProjectIDForTaskChecklist, taskChecklistID)
var project_id uuid.UUID
err := row.Scan(&project_id)
return project_id, err
}
const getProjectIDForTaskChecklistItem = `-- name: GetProjectIDForTaskChecklistItem :one
SELECT project_id FROM task_checklist_item AS tci
INNER JOIN task_checklist ON task_checklist.task_checklist_id = tci.task_checklist_id
INNER JOIN task ON task.task_id = task_checklist.task_id
INNER JOIN task_group ON task_group.task_group_id = task.task_group_id
WHERE tci.task_checklist_item_id = $1
`
func (q *Queries) GetProjectIDForTaskChecklistItem(ctx context.Context, taskChecklistItemID uuid.UUID) (uuid.UUID, error) {
row := q.db.QueryRowContext(ctx, getProjectIDForTaskChecklistItem, taskChecklistItemID)
var project_id uuid.UUID
err := row.Scan(&project_id)
return project_id, err
}
const getTaskChecklistByID = `-- name: GetTaskChecklistByID :one const getTaskChecklistByID = `-- name: GetTaskChecklistByID :one
SELECT task_checklist_id, task_id, created_at, name, position FROM task_checklist WHERE task_checklist_id = $1 SELECT task_checklist_id, task_id, created_at, name, position FROM task_checklist WHERE task_checklist_id = $1
` `

View File

@ -85,6 +85,17 @@ func (q *Queries) GetAllTaskGroups(ctx context.Context) ([]TaskGroup, error) {
return items, nil return items, nil
} }
const getProjectIDForTaskGroup = `-- name: GetProjectIDForTaskGroup :one
SELECT project_id from task_group WHERE task_group_id = $1
`
func (q *Queries) GetProjectIDForTaskGroup(ctx context.Context, taskGroupID uuid.UUID) (uuid.UUID, error) {
row := q.db.QueryRowContext(ctx, getProjectIDForTaskGroup, taskGroupID)
var project_id uuid.UUID
err := row.Scan(&project_id)
return project_id, err
}
const getTaskGroupByID = `-- name: GetTaskGroupByID :one const getTaskGroupByID = `-- name: GetTaskGroupByID :one
SELECT task_group_id, project_id, created_at, name, position FROM task_group WHERE task_group_id = $1 SELECT task_group_id, project_id, created_at, name, position FROM task_group WHERE task_group_id = $1
` `

File diff suppressed because it is too large Load Diff

View File

@ -51,31 +51,56 @@ func NewHandler(repo db.Repository) http.Handler {
fieldName = "TeamID" fieldName = "TeamID"
case ObjectTypeTask: case ObjectTypeTask:
fieldName = "TaskID" fieldName = "TaskID"
case ObjectTypeTaskGroup:
fieldName = "TaskGroupID"
case ObjectTypeTaskChecklist:
fieldName = "TaskChecklistID"
case ObjectTypeTaskChecklistItem:
fieldName = "TaskChecklistItemID"
default: default:
fieldName = "ProjectID" fieldName = "ProjectID"
} }
log.WithFields(log.Fields{"typeArg": typeArg, "fieldName": fieldName}).Info("getting field by name") log.WithFields(log.Fields{"typeArg": typeArg, "fieldName": fieldName}).Info("getting field by name")
subjectID, ok = val.FieldByName(fieldName).Interface().(uuid.UUID) subjectField := val.FieldByName(fieldName)
if !subjectField.IsValid() {
log.Error("subject field name does not exist on input type")
return nil, errors.New("subject field name does not exist on input type")
}
subjectID, ok = subjectField.Interface().(uuid.UUID)
if !ok { if !ok {
log.Error("error while casting subject UUID")
return nil, errors.New("error while casting subject uuid") return nil, errors.New("error while casting subject uuid")
} }
var err error var err error
if level == ActionLevelProject { if level == ActionLevelProject {
log.WithFields(log.Fields{"subjectID": subjectID}).Info("fetching subject ID by typeArg")
if typeArg == ObjectTypeTask { if typeArg == ObjectTypeTask {
log.WithFields(log.Fields{"subjectID": subjectID}).Info("fetching project ID using task ID")
subjectID, err = repo.GetProjectIDForTask(ctx, subjectID) subjectID, err = repo.GetProjectIDForTask(ctx, subjectID)
if err != nil {
return nil, err
}
} }
roles, err := GetProjectRoles(ctx, repo, subjectID) if typeArg == ObjectTypeTaskGroup {
subjectID, err = repo.GetProjectIDForTaskGroup(ctx, subjectID)
}
if typeArg == ObjectTypeTaskChecklist {
subjectID, err = repo.GetProjectIDForTaskChecklist(ctx, subjectID)
}
if typeArg == ObjectTypeTaskChecklistItem {
subjectID, err = repo.GetProjectIDForTaskChecklistItem(ctx, subjectID)
}
if err != nil { if err != nil {
log.WithError(err).Error("error while getting subject ID")
return nil, err return nil, err
} }
if roles.TeamRole == "admin" || roles.ProjectRole == "admin" { projectRoles, err := GetProjectRoles(ctx, repo, subjectID)
log.WithFields(log.Fields{"teamRole": roles.TeamRole, "projectRole": roles.ProjectRole}).Info("is team or project role") if err != nil {
return next(ctx) log.WithError(err).Error("error while getting project roles")
return nil, err
}
for _, validRole := range roles {
if GetRoleLevel(projectRoles.TeamRole) == validRole || GetRoleLevel(projectRoles.ProjectRole) == validRole {
log.WithFields(log.Fields{"teamRole": projectRoles.TeamRole, "projectRole": projectRoles.ProjectRole}).Info("is team or project role")
return next(ctx)
}
} }
return nil, errors.New("must be a team or project admin") return nil, errors.New("must be a team or project admin")
} else if level == ActionLevelTeam { } else if level == ActionLevelTeam {
@ -85,10 +110,13 @@ func NewHandler(repo db.Repository) http.Handler {
} }
role, err := repo.GetTeamRoleForUserID(ctx, db.GetTeamRoleForUserIDParams{UserID: userID, TeamID: subjectID}) role, err := repo.GetTeamRoleForUserID(ctx, db.GetTeamRoleForUserIDParams{UserID: userID, TeamID: subjectID})
if err != nil { if err != nil {
log.WithError(err).Error("error while getting team roles for user ID")
return nil, err return nil, err
} }
if role.RoleCode == "admin" { for _, validRole := range roles {
return next(ctx) if GetRoleLevel(role.RoleCode) == validRole || GetRoleLevel(role.RoleCode) == validRole {
return next(ctx)
}
} }
return nil, errors.New("must be a team admin") return nil, errors.New("must be a team admin")
@ -156,6 +184,14 @@ func GetProjectRoles(ctx context.Context, r db.Repository, projectID uuid.UUID)
return r.GetUserRolesForProject(ctx, db.GetUserRolesForProjectParams{UserID: userID, ProjectID: projectID}) return r.GetUserRolesForProject(ctx, db.GetUserRolesForProjectParams{UserID: userID, ProjectID: projectID})
} }
// GetRoleLevel converts a role level string to a RoleLevel type
func GetRoleLevel(r string) RoleLevel {
if r == RoleLevelAdmin.String() {
return RoleLevelAdmin
}
return RoleLevelMember
}
// ConvertToRoleCode converts a role code string to a RoleCode type // ConvertToRoleCode converts a role code string to a RoleCode type
func ConvertToRoleCode(r string) RoleCode { func ConvertToRoleCode(r string) RoleCode {
if r == RoleCodeAdmin.String() { if r == RoleCodeAdmin.String() {

View File

@ -121,11 +121,11 @@ type DeleteTaskGroupTasksPayload struct {
} }
type DeleteTaskInput struct { type DeleteTaskInput struct {
TaskID string `json:"taskID"` TaskID uuid.UUID `json:"taskID"`
} }
type DeleteTaskPayload struct { type DeleteTaskPayload struct {
TaskID string `json:"taskID"` TaskID uuid.UUID `json:"taskID"`
} }
type DeleteTeam struct { type DeleteTeam struct {
@ -184,11 +184,11 @@ type FindTeam struct {
} }
type FindUser struct { type FindUser struct {
UserID string `json:"userId"` UserID uuid.UUID `json:"userID"`
} }
type LogoutUser struct { type LogoutUser struct {
UserID string `json:"userID"` UserID uuid.UUID `json:"userID"`
} }
type MePayload struct { type MePayload struct {
@ -225,19 +225,19 @@ type NewProjectLabel struct {
} }
type NewRefreshToken struct { type NewRefreshToken struct {
UserID string `json:"userId"` UserID uuid.UUID `json:"userID"`
} }
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 {
ProjectID string `json:"projectID"` ProjectID uuid.UUID `json:"projectID"`
Name string `json:"name"` Name string `json:"name"`
Position float64 `json:"position"` Position float64 `json:"position"`
} }
type NewTaskGroupLocation struct { type NewTaskGroupLocation struct {
@ -303,6 +303,7 @@ type ProjectsFilter struct {
} }
type RemoveTaskLabelInput struct { type RemoveTaskLabelInput struct {
TaskID uuid.UUID `json:"taskID"`
TaskLabelID uuid.UUID `json:"taskLabelID"` TaskLabelID uuid.UUID `json:"taskLabelID"`
} }
@ -388,13 +389,13 @@ type UpdateProjectName struct {
} }
type UpdateTaskChecklistItemLocation struct { type UpdateTaskChecklistItemLocation struct {
ChecklistID uuid.UUID `json:"checklistID"` TaskChecklistID uuid.UUID `json:"taskChecklistID"`
ChecklistItemID uuid.UUID `json:"checklistItemID"` TaskChecklistItemID uuid.UUID `json:"taskChecklistItemID"`
Position float64 `json:"position"` Position float64 `json:"position"`
} }
type UpdateTaskChecklistItemLocationPayload struct { type UpdateTaskChecklistItemLocationPayload struct {
ChecklistID uuid.UUID `json:"checklistID"` TaskChecklistID uuid.UUID `json:"taskChecklistID"`
PrevChecklistID uuid.UUID `json:"prevChecklistID"` PrevChecklistID uuid.UUID `json:"prevChecklistID"`
ChecklistItem *db.TaskChecklistItem `json:"checklistItem"` ChecklistItem *db.TaskChecklistItem `json:"checklistItem"`
} }
@ -405,8 +406,8 @@ type UpdateTaskChecklistItemName struct {
} }
type UpdateTaskChecklistLocation struct { type UpdateTaskChecklistLocation struct {
ChecklistID uuid.UUID `json:"checklistID"` TaskChecklistID uuid.UUID `json:"taskChecklistID"`
Position float64 `json:"position"` Position float64 `json:"position"`
} }
type UpdateTaskChecklistLocationPayload struct { type UpdateTaskChecklistLocationPayload struct {
@ -439,8 +440,8 @@ type UpdateTaskLocationPayload struct {
} }
type UpdateTaskName struct { type UpdateTaskName struct {
TaskID string `json:"taskID"` TaskID uuid.UUID `json:"taskID"`
Name string `json:"name"` Name string `json:"name"`
} }
type UpdateTeamMemberRole struct { type UpdateTeamMemberRole struct {
@ -648,10 +649,13 @@ 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"
ObjectTypeTaskChecklist ObjectType = "TASK_CHECKLIST"
ObjectTypeTaskChecklistItem ObjectType = "TASK_CHECKLIST_ITEM"
) )
var AllObjectType = []ObjectType{ var AllObjectType = []ObjectType{
@ -659,11 +663,14 @@ var AllObjectType = []ObjectType{
ObjectTypeTeam, ObjectTypeTeam,
ObjectTypeProject, ObjectTypeProject,
ObjectTypeTask, ObjectTypeTask,
ObjectTypeTaskGroup,
ObjectTypeTaskChecklist,
ObjectTypeTaskChecklistItem,
} }
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, ObjectTypeTaskChecklist, ObjectTypeTaskChecklistItem:
return true return true
} }
return false return false

View File

@ -174,6 +174,9 @@ enum ObjectType {
TEAM TEAM
PROJECT PROJECT
TASK TASK
TASK_GROUP
TASK_CHECKLIST
TASK_CHECKLIST_ITEM
} }
directive @hasRole(roles: [RoleLevel!]!, level: ActionLevel!, type: ObjectType!) on FIELD_DEFINITION directive @hasRole(roles: [RoleLevel!]!, level: ActionLevel!, type: ObjectType!) on FIELD_DEFINITION
@ -215,7 +218,7 @@ input ProjectsFilter {
} }
input FindUser { input FindUser {
userId: String! userID: UUID!
} }
input FindProject { input FindProject {
@ -297,15 +300,15 @@ type DeleteProjectPayload {
extend type Mutation { extend type Mutation {
createProjectLabel(input: NewProjectLabel!): createProjectLabel(input: NewProjectLabel!):
ProjectLabel! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT) ProjectLabel! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: PROJECT)
deleteProjectLabel(input: DeleteProjectLabel!): deleteProjectLabel(input: DeleteProjectLabel!):
ProjectLabel! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT) ProjectLabel! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: PROJECT)
updateProjectLabel(input: UpdateProjectLabel!): updateProjectLabel(input: UpdateProjectLabel!):
ProjectLabel! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT) ProjectLabel! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: PROJECT)
updateProjectLabelName(input: UpdateProjectLabelName!): updateProjectLabelName(input: UpdateProjectLabelName!):
ProjectLabel! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT) ProjectLabel! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: PROJECT)
updateProjectLabelColor(input: UpdateProjectLabelColor!): updateProjectLabelColor(input: UpdateProjectLabelColor!):
ProjectLabel! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT) ProjectLabel! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: PROJECT)
} }
input NewProjectLabel { input NewProjectLabel {
@ -377,29 +380,29 @@ 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, MEMBER], level: PROJECT, type: TASK_GROUP)
deleteTask(input: DeleteTaskInput!): deleteTask(input: DeleteTaskInput!):
DeleteTaskPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT) DeleteTaskPayload! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK)
updateTaskDescription(input: UpdateTaskDescriptionInput!): updateTaskDescription(input: UpdateTaskDescriptionInput!):
Task! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT) Task! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK)
updateTaskLocation(input: NewTaskLocation!): updateTaskLocation(input: NewTaskLocation!):
UpdateTaskLocationPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT) UpdateTaskLocationPayload! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK)
updateTaskName(input: UpdateTaskName!): updateTaskName(input: UpdateTaskName!):
Task! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT) Task! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK)
setTaskComplete(input: SetTaskComplete!): setTaskComplete(input: SetTaskComplete!):
Task! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT) Task! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK)
updateTaskDueDate(input: UpdateTaskDueDate!): updateTaskDueDate(input: UpdateTaskDueDate!):
Task! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT) Task! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK)
assignTask(input: AssignTaskInput): assignTask(input: AssignTaskInput):
Task! @hasRole(roles: [ADMIN], level: PROJECT, type: TASK) Task! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK)
unassignTask(input: UnassignTaskInput): unassignTask(input: UnassignTaskInput):
Task! @hasRole(roles: [ADMIN], level: PROJECT, type: TASK) Task! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK)
} }
input NewTask { input NewTask {
taskGroupID: String! taskGroupID: UUID!
name: String! name: String!
position: Float! position: Float!
} }
@ -441,54 +444,55 @@ input NewTaskLocation {
} }
input DeleteTaskInput { input DeleteTaskInput {
taskID: String! taskID: UUID!
} }
type DeleteTaskPayload { type DeleteTaskPayload {
taskID: String! taskID: UUID!
} }
input UpdateTaskName { input UpdateTaskName {
taskID: String! taskID: UUID!
name: String! name: String!
} }
extend type Mutation { extend type Mutation {
createTaskChecklist(input: CreateTaskChecklist!): createTaskChecklist(input: CreateTaskChecklist!):
TaskChecklist! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT) TaskChecklist! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK)
deleteTaskChecklist(input: DeleteTaskChecklist!): deleteTaskChecklist(input: DeleteTaskChecklist!):
DeleteTaskChecklistPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT) DeleteTaskChecklistPayload! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_CHECKLIST)
updateTaskChecklistName(input: UpdateTaskChecklistName!): updateTaskChecklistName(input: UpdateTaskChecklistName!):
TaskChecklist! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT) TaskChecklist! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_CHECKLIST)
createTaskChecklistItem(input: CreateTaskChecklistItem!): createTaskChecklistItem(input: CreateTaskChecklistItem!):
TaskChecklistItem! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT) TaskChecklistItem! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_CHECKLIST)
updateTaskChecklistItemName(input: UpdateTaskChecklistItemName!):
TaskChecklistItem! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
setTaskChecklistItemComplete(input: SetTaskChecklistItemComplete!):
TaskChecklistItem! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
deleteTaskChecklistItem(input: DeleteTaskChecklistItem!):
DeleteTaskChecklistItemPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
updateTaskChecklistLocation(input: UpdateTaskChecklistLocation!): updateTaskChecklistLocation(input: UpdateTaskChecklistLocation!):
UpdateTaskChecklistLocationPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT) UpdateTaskChecklistLocationPayload! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_CHECKLIST)
updateTaskChecklistItemName(input: UpdateTaskChecklistItemName!):
TaskChecklistItem! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_CHECKLIST_ITEM)
setTaskChecklistItemComplete(input: SetTaskChecklistItemComplete!):
TaskChecklistItem! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_CHECKLIST_ITEM)
deleteTaskChecklistItem(input: DeleteTaskChecklistItem!):
DeleteTaskChecklistItemPayload! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_CHECKLIST_ITEM)
updateTaskChecklistItemLocation(input: UpdateTaskChecklistItemLocation!): updateTaskChecklistItemLocation(input: UpdateTaskChecklistItemLocation!):
UpdateTaskChecklistItemLocationPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT) UpdateTaskChecklistItemLocationPayload! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_CHECKLIST_ITEM)
} }
input UpdateTaskChecklistItemLocation { input UpdateTaskChecklistItemLocation {
checklistID: UUID! taskChecklistID: UUID!
checklistItemID: UUID! taskChecklistItemID: UUID!
position: Float! position: Float!
} }
type UpdateTaskChecklistItemLocationPayload { type UpdateTaskChecklistItemLocationPayload {
checklistID: UUID! taskChecklistID: UUID!
prevChecklistID: UUID! prevChecklistID: UUID!
checklistItem: TaskChecklistItem! checklistItem: TaskChecklistItem!
} }
input UpdateTaskChecklistLocation { input UpdateTaskChecklistLocation {
checklistID: UUID! taskChecklistID: UUID!
position: Float! position: Float!
} }
@ -541,19 +545,19 @@ type DeleteTaskChecklistPayload {
extend type Mutation { extend type Mutation {
createTaskGroup(input: NewTaskGroup!): createTaskGroup(input: NewTaskGroup!):
TaskGroup! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT) TaskGroup! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: PROJECT)
updateTaskGroupLocation(input: NewTaskGroupLocation!): updateTaskGroupLocation(input: NewTaskGroupLocation!):
TaskGroup! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT) TaskGroup! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_GROUP)
updateTaskGroupName(input: UpdateTaskGroupName!): updateTaskGroupName(input: UpdateTaskGroupName!):
TaskGroup! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT) TaskGroup! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_GROUP)
deleteTaskGroup(input: DeleteTaskGroupInput!): deleteTaskGroup(input: DeleteTaskGroupInput!):
DeleteTaskGroupPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT) DeleteTaskGroupPayload! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_GROUP)
duplicateTaskGroup(input: DuplicateTaskGroup!): duplicateTaskGroup(input: DuplicateTaskGroup!):
DuplicateTaskGroupPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT) DuplicateTaskGroupPayload! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_GROUP)
sortTaskGroup(input: SortTaskGroup!): sortTaskGroup(input: SortTaskGroup!):
SortTaskGroupPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT) SortTaskGroupPayload! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_GROUP)
deleteTaskGroupTasks(input: DeleteTaskGroupTasks!): deleteTaskGroupTasks(input: DeleteTaskGroupTasks!):
DeleteTaskGroupTasksPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT) DeleteTaskGroupTasksPayload! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_GROUP)
} }
input DeleteTaskGroupTasks { input DeleteTaskGroupTasks {
@ -612,19 +616,31 @@ type DeleteTaskGroupPayload {
} }
input NewTaskGroup { input NewTaskGroup {
projectID: String! projectID: UUID!
name: String! name: String!
position: Float! position: Float!
} }
extend type Mutation {
addTaskLabel(input: AddTaskLabelInput):
Task! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK)
removeTaskLabel(input: RemoveTaskLabelInput):
Task! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK)
toggleTaskLabel(input: ToggleTaskLabelInput!):
ToggleTaskLabelPayload! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK)
}
input AddTaskLabelInput { input AddTaskLabelInput {
taskID: UUID! taskID: UUID!
projectLabelID: UUID! projectLabelID: UUID!
} }
input RemoveTaskLabelInput { input RemoveTaskLabelInput {
taskID: UUID!
taskLabelID: UUID! taskLabelID: UUID!
} }
input ToggleTaskLabelInput { input ToggleTaskLabelInput {
taskID: UUID! taskID: UUID!
projectLabelID: UUID! projectLabelID: UUID!
@ -634,15 +650,6 @@ type ToggleTaskLabelPayload {
active: Boolean! active: Boolean!
task: Task! task: Task!
} }
extend type Mutation {
addTaskLabel(input: AddTaskLabelInput):
Task! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
removeTaskLabel(input: RemoveTaskLabelInput):
Task! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
toggleTaskLabel(input: ToggleTaskLabelInput!):
ToggleTaskLabelPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
}
extend type Mutation { extend type Mutation {
deleteTeam(input: DeleteTeam!): deleteTeam(input: DeleteTeam!):
@ -758,7 +765,7 @@ type UpdateUserRolePayload {
} }
input NewRefreshToken { input NewRefreshToken {
userId: String! userID: UUID!
} }
input NewUserAccount { input NewUserAccount {
@ -771,7 +778,7 @@ input NewUserAccount {
} }
input LogoutUser { input LogoutUser {
userID: String! userID: UUID!
} }
input DeleteUserAccount { input DeleteUserAccount {

View File

@ -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
@ -195,19 +190,14 @@ func (r *mutationResolver) CreateTask(ctx context.Context, input NewTask) (*db.T
} }
func (r *mutationResolver) DeleteTask(ctx context.Context, input DeleteTaskInput) (*DeleteTaskPayload, error) { func (r *mutationResolver) DeleteTask(ctx context.Context, input DeleteTaskInput) (*DeleteTaskPayload, error) {
taskID, err := uuid.Parse(input.TaskID)
if err != nil {
return &DeleteTaskPayload{}, err
}
log.WithFields(log.Fields{ log.WithFields(log.Fields{
"taskID": taskID.String(), "taskID": input.TaskID,
}).Info("deleting task") }).Info("deleting task")
err = r.Repository.DeleteTaskByID(ctx, taskID) err := r.Repository.DeleteTaskByID(ctx, input.TaskID)
if err != nil { if err != nil {
return &DeleteTaskPayload{}, err return &DeleteTaskPayload{}, err
} }
return &DeleteTaskPayload{taskID.String()}, nil return &DeleteTaskPayload{input.TaskID}, nil
} }
func (r *mutationResolver) UpdateTaskDescription(ctx context.Context, input UpdateTaskDescriptionInput) (*db.Task, error) { func (r *mutationResolver) UpdateTaskDescription(ctx context.Context, input UpdateTaskDescriptionInput) (*db.Task, error) {
@ -226,11 +216,7 @@ func (r *mutationResolver) UpdateTaskLocation(ctx context.Context, input NewTask
} }
func (r *mutationResolver) UpdateTaskName(ctx context.Context, input UpdateTaskName) (*db.Task, error) { func (r *mutationResolver) UpdateTaskName(ctx context.Context, input UpdateTaskName) (*db.Task, error) {
taskID, err := uuid.Parse(input.TaskID) task, err := r.Repository.UpdateTaskName(ctx, db.UpdateTaskNameParams{input.TaskID, input.Name})
if err != nil {
return &db.Task{}, err
}
task, err := r.Repository.UpdateTaskName(ctx, db.UpdateTaskNameParams{taskID, input.Name})
return &task, err return &task, err
} }
@ -336,6 +322,16 @@ func (r *mutationResolver) CreateTaskChecklistItem(ctx context.Context, input Cr
return &taskChecklistItem, nil return &taskChecklistItem, nil
} }
func (r *mutationResolver) UpdateTaskChecklistLocation(ctx context.Context, input UpdateTaskChecklistLocation) (*UpdateTaskChecklistLocationPayload, error) {
checklist, err := r.Repository.UpdateTaskChecklistPosition(ctx, db.UpdateTaskChecklistPositionParams{Position: input.Position, TaskChecklistID: input.TaskChecklistID})
if err != nil {
return &UpdateTaskChecklistLocationPayload{}, err
}
return &UpdateTaskChecklistLocationPayload{Checklist: &checklist}, nil
}
func (r *mutationResolver) UpdateTaskChecklistItemName(ctx context.Context, input UpdateTaskChecklistItemName) (*db.TaskChecklistItem, error) { func (r *mutationResolver) UpdateTaskChecklistItemName(ctx context.Context, input UpdateTaskChecklistItemName) (*db.TaskChecklistItem, error) {
task, err := r.Repository.UpdateTaskChecklistItemName(ctx, db.UpdateTaskChecklistItemNameParams{TaskChecklistItemID: input.TaskChecklistItemID, task, err := r.Repository.UpdateTaskChecklistItemName(ctx, db.UpdateTaskChecklistItemNameParams{TaskChecklistItemID: input.TaskChecklistItemID,
Name: input.Name, Name: input.Name,
@ -375,34 +371,20 @@ func (r *mutationResolver) DeleteTaskChecklistItem(ctx context.Context, input De
}, err }, err
} }
func (r *mutationResolver) UpdateTaskChecklistLocation(ctx context.Context, input UpdateTaskChecklistLocation) (*UpdateTaskChecklistLocationPayload, error) {
checklist, err := r.Repository.UpdateTaskChecklistPosition(ctx, db.UpdateTaskChecklistPositionParams{Position: input.Position, TaskChecklistID: input.ChecklistID})
if err != nil {
return &UpdateTaskChecklistLocationPayload{}, err
}
return &UpdateTaskChecklistLocationPayload{Checklist: &checklist}, nil
}
func (r *mutationResolver) UpdateTaskChecklistItemLocation(ctx context.Context, input UpdateTaskChecklistItemLocation) (*UpdateTaskChecklistItemLocationPayload, error) { func (r *mutationResolver) UpdateTaskChecklistItemLocation(ctx context.Context, input UpdateTaskChecklistItemLocation) (*UpdateTaskChecklistItemLocationPayload, error) {
currentChecklistItem, err := r.Repository.GetTaskChecklistItemByID(ctx, input.ChecklistItemID) currentChecklistItem, err := r.Repository.GetTaskChecklistItemByID(ctx, input.TaskChecklistItemID)
checklistItem, err := r.Repository.UpdateTaskChecklistItemLocation(ctx, db.UpdateTaskChecklistItemLocationParams{TaskChecklistID: input.ChecklistID, TaskChecklistItemID: input.ChecklistItemID, Position: input.Position}) checklistItem, err := r.Repository.UpdateTaskChecklistItemLocation(ctx, db.UpdateTaskChecklistItemLocationParams{TaskChecklistID: input.TaskChecklistID, TaskChecklistItemID: input.TaskChecklistItemID, Position: input.Position})
if err != nil { if err != nil {
return &UpdateTaskChecklistItemLocationPayload{}, err return &UpdateTaskChecklistItemLocationPayload{}, err
} }
return &UpdateTaskChecklistItemLocationPayload{PrevChecklistID: currentChecklistItem.TaskChecklistID, ChecklistID: input.ChecklistID, ChecklistItem: &checklistItem}, err return &UpdateTaskChecklistItemLocationPayload{PrevChecklistID: currentChecklistItem.TaskChecklistID, TaskChecklistID: input.TaskChecklistID, ChecklistItem: &checklistItem}, err
} }
func (r *mutationResolver) CreateTaskGroup(ctx context.Context, input NewTaskGroup) (*db.TaskGroup, error) { func (r *mutationResolver) CreateTaskGroup(ctx context.Context, input NewTaskGroup) (*db.TaskGroup, error) {
createdAt := time.Now().UTC() createdAt := time.Now().UTC()
projectID, err := uuid.Parse(input.ProjectID)
if err != nil {
return &db.TaskGroup{}, err
}
project, err := r.Repository.CreateTaskGroup(ctx, project, err := r.Repository.CreateTaskGroup(ctx,
db.CreateTaskGroupParams{projectID, createdAt, input.Name, input.Position}) db.CreateTaskGroupParams{input.ProjectID, createdAt, input.Name, input.Position})
return &project, err return &project, err
} }
@ -773,12 +755,7 @@ func (r *mutationResolver) DeleteUserAccount(ctx context.Context, input DeleteUs
} }
func (r *mutationResolver) LogoutUser(ctx context.Context, input LogoutUser) (bool, error) { func (r *mutationResolver) LogoutUser(ctx context.Context, input LogoutUser) (bool, error) {
userID, err := uuid.Parse(input.UserID) err := r.Repository.DeleteRefreshTokenByUserID(ctx, input.UserID)
if err != nil {
return false, err
}
err = r.Repository.DeleteRefreshTokenByUserID(ctx, userID)
return true, err return true, err
} }
@ -978,11 +955,7 @@ func (r *queryResolver) Users(ctx context.Context) ([]db.UserAccount, error) {
} }
func (r *queryResolver) FindUser(ctx context.Context, input FindUser) (*db.UserAccount, error) { func (r *queryResolver) FindUser(ctx context.Context, input FindUser) (*db.UserAccount, error) {
userID, err := uuid.Parse(input.UserID) account, err := r.Repository.GetUserAccountByID(ctx, input.UserID)
if err != nil {
return &db.UserAccount{}, err
}
account, err := r.Repository.GetUserAccountByID(ctx, userID)
if err == sql.ErrNoRows { if err == sql.ErrNoRows {
return &db.UserAccount{}, &gqlerror.Error{ return &db.UserAccount{}, &gqlerror.Error{
Message: "User not found", Message: "User not found",

View File

@ -14,6 +14,9 @@ enum ObjectType {
TEAM TEAM
PROJECT PROJECT
TASK TASK
TASK_GROUP
TASK_CHECKLIST
TASK_CHECKLIST_ITEM
} }
directive @hasRole(roles: [RoleLevel!]!, level: ActionLevel!, type: ObjectType!) on FIELD_DEFINITION directive @hasRole(roles: [RoleLevel!]!, level: ActionLevel!, type: ObjectType!) on FIELD_DEFINITION
@ -55,7 +58,7 @@ input ProjectsFilter {
} }
input FindUser { input FindUser {
userId: String! userID: UUID!
} }
input FindProject { input FindProject {

View File

@ -1,14 +1,14 @@
extend type Mutation { extend type Mutation {
createProjectLabel(input: NewProjectLabel!): createProjectLabel(input: NewProjectLabel!):
ProjectLabel! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT) ProjectLabel! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: PROJECT)
deleteProjectLabel(input: DeleteProjectLabel!): deleteProjectLabel(input: DeleteProjectLabel!):
ProjectLabel! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT) ProjectLabel! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: PROJECT)
updateProjectLabel(input: UpdateProjectLabel!): updateProjectLabel(input: UpdateProjectLabel!):
ProjectLabel! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT) ProjectLabel! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: PROJECT)
updateProjectLabelName(input: UpdateProjectLabelName!): updateProjectLabelName(input: UpdateProjectLabelName!):
ProjectLabel! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT) ProjectLabel! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: PROJECT)
updateProjectLabelColor(input: UpdateProjectLabelColor!): updateProjectLabelColor(input: UpdateProjectLabelColor!):
ProjectLabel! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT) ProjectLabel! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: PROJECT)
} }
input NewProjectLabel { input NewProjectLabel {

View File

@ -1,28 +1,28 @@
extend type Mutation { extend type Mutation {
createTask(input: NewTask!): createTask(input: NewTask!):
Task! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT) Task! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_GROUP)
deleteTask(input: DeleteTaskInput!): deleteTask(input: DeleteTaskInput!):
DeleteTaskPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT) DeleteTaskPayload! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK)
updateTaskDescription(input: UpdateTaskDescriptionInput!): updateTaskDescription(input: UpdateTaskDescriptionInput!):
Task! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT) Task! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK)
updateTaskLocation(input: NewTaskLocation!): updateTaskLocation(input: NewTaskLocation!):
UpdateTaskLocationPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT) UpdateTaskLocationPayload! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK)
updateTaskName(input: UpdateTaskName!): updateTaskName(input: UpdateTaskName!):
Task! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT) Task! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK)
setTaskComplete(input: SetTaskComplete!): setTaskComplete(input: SetTaskComplete!):
Task! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT) Task! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK)
updateTaskDueDate(input: UpdateTaskDueDate!): updateTaskDueDate(input: UpdateTaskDueDate!):
Task! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT) Task! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK)
assignTask(input: AssignTaskInput): assignTask(input: AssignTaskInput):
Task! @hasRole(roles: [ADMIN], level: PROJECT, type: TASK) Task! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK)
unassignTask(input: UnassignTaskInput): unassignTask(input: UnassignTaskInput):
Task! @hasRole(roles: [ADMIN], level: PROJECT, type: TASK) Task! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK)
} }
input NewTask { input NewTask {
taskGroupID: String! taskGroupID: UUID!
name: String! name: String!
position: Float! position: Float!
} }
@ -64,14 +64,14 @@ input NewTaskLocation {
} }
input DeleteTaskInput { input DeleteTaskInput {
taskID: String! taskID: UUID!
} }
type DeleteTaskPayload { type DeleteTaskPayload {
taskID: String! taskID: UUID!
} }
input UpdateTaskName { input UpdateTaskName {
taskID: String! taskID: UUID!
name: String! name: String!
} }

View File

@ -1,39 +1,40 @@
extend type Mutation { extend type Mutation {
createTaskChecklist(input: CreateTaskChecklist!): createTaskChecklist(input: CreateTaskChecklist!):
TaskChecklist! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT) TaskChecklist! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK)
deleteTaskChecklist(input: DeleteTaskChecklist!): deleteTaskChecklist(input: DeleteTaskChecklist!):
DeleteTaskChecklistPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT) DeleteTaskChecklistPayload! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_CHECKLIST)
updateTaskChecklistName(input: UpdateTaskChecklistName!): updateTaskChecklistName(input: UpdateTaskChecklistName!):
TaskChecklist! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT) TaskChecklist! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_CHECKLIST)
createTaskChecklistItem(input: CreateTaskChecklistItem!): createTaskChecklistItem(input: CreateTaskChecklistItem!):
TaskChecklistItem! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT) TaskChecklistItem! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_CHECKLIST)
updateTaskChecklistItemName(input: UpdateTaskChecklistItemName!):
TaskChecklistItem! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
setTaskChecklistItemComplete(input: SetTaskChecklistItemComplete!):
TaskChecklistItem! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
deleteTaskChecklistItem(input: DeleteTaskChecklistItem!):
DeleteTaskChecklistItemPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
updateTaskChecklistLocation(input: UpdateTaskChecklistLocation!): updateTaskChecklistLocation(input: UpdateTaskChecklistLocation!):
UpdateTaskChecklistLocationPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT) UpdateTaskChecklistLocationPayload! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_CHECKLIST)
updateTaskChecklistItemName(input: UpdateTaskChecklistItemName!):
TaskChecklistItem! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_CHECKLIST_ITEM)
setTaskChecklistItemComplete(input: SetTaskChecklistItemComplete!):
TaskChecklistItem! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_CHECKLIST_ITEM)
deleteTaskChecklistItem(input: DeleteTaskChecklistItem!):
DeleteTaskChecklistItemPayload! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_CHECKLIST_ITEM)
updateTaskChecklistItemLocation(input: UpdateTaskChecklistItemLocation!): updateTaskChecklistItemLocation(input: UpdateTaskChecklistItemLocation!):
UpdateTaskChecklistItemLocationPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT) UpdateTaskChecklistItemLocationPayload! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_CHECKLIST_ITEM)
} }
input UpdateTaskChecklistItemLocation { input UpdateTaskChecklistItemLocation {
checklistID: UUID! taskChecklistID: UUID!
checklistItemID: UUID! taskChecklistItemID: UUID!
position: Float! position: Float!
} }
type UpdateTaskChecklistItemLocationPayload { type UpdateTaskChecklistItemLocationPayload {
checklistID: UUID! taskChecklistID: UUID!
prevChecklistID: UUID! prevChecklistID: UUID!
checklistItem: TaskChecklistItem! checklistItem: TaskChecklistItem!
} }
input UpdateTaskChecklistLocation { input UpdateTaskChecklistLocation {
checklistID: UUID! taskChecklistID: UUID!
position: Float! position: Float!
} }

View File

@ -1,18 +1,18 @@
extend type Mutation { extend type Mutation {
createTaskGroup(input: NewTaskGroup!): createTaskGroup(input: NewTaskGroup!):
TaskGroup! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT) TaskGroup! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: PROJECT)
updateTaskGroupLocation(input: NewTaskGroupLocation!): updateTaskGroupLocation(input: NewTaskGroupLocation!):
TaskGroup! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT) TaskGroup! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_GROUP)
updateTaskGroupName(input: UpdateTaskGroupName!): updateTaskGroupName(input: UpdateTaskGroupName!):
TaskGroup! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT) TaskGroup! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_GROUP)
deleteTaskGroup(input: DeleteTaskGroupInput!): deleteTaskGroup(input: DeleteTaskGroupInput!):
DeleteTaskGroupPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT) DeleteTaskGroupPayload! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_GROUP)
duplicateTaskGroup(input: DuplicateTaskGroup!): duplicateTaskGroup(input: DuplicateTaskGroup!):
DuplicateTaskGroupPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT) DuplicateTaskGroupPayload! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_GROUP)
sortTaskGroup(input: SortTaskGroup!): sortTaskGroup(input: SortTaskGroup!):
SortTaskGroupPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT) SortTaskGroupPayload! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_GROUP)
deleteTaskGroupTasks(input: DeleteTaskGroupTasks!): deleteTaskGroupTasks(input: DeleteTaskGroupTasks!):
DeleteTaskGroupTasksPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT) DeleteTaskGroupTasksPayload! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_GROUP)
} }
input DeleteTaskGroupTasks { input DeleteTaskGroupTasks {
@ -71,7 +71,7 @@ type DeleteTaskGroupPayload {
} }
input NewTaskGroup { input NewTaskGroup {
projectID: String! projectID: UUID!
name: String! name: String!
position: Float! position: Float!
} }

View File

@ -1,11 +1,23 @@
extend type Mutation {
addTaskLabel(input: AddTaskLabelInput):
Task! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK)
removeTaskLabel(input: RemoveTaskLabelInput):
Task! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK)
toggleTaskLabel(input: ToggleTaskLabelInput!):
ToggleTaskLabelPayload! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK)
}
input AddTaskLabelInput { input AddTaskLabelInput {
taskID: UUID! taskID: UUID!
projectLabelID: UUID! projectLabelID: UUID!
} }
input RemoveTaskLabelInput { input RemoveTaskLabelInput {
taskID: UUID!
taskLabelID: UUID! taskLabelID: UUID!
} }
input ToggleTaskLabelInput { input ToggleTaskLabelInput {
taskID: UUID! taskID: UUID!
projectLabelID: UUID! projectLabelID: UUID!
@ -15,12 +27,3 @@ type ToggleTaskLabelPayload {
active: Boolean! active: Boolean!
task: Task! task: Task!
} }
extend type Mutation {
addTaskLabel(input: AddTaskLabelInput):
Task! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
removeTaskLabel(input: RemoveTaskLabelInput):
Task! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
toggleTaskLabel(input: ToggleTaskLabelInput!):
ToggleTaskLabelPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
}

View File

@ -46,7 +46,7 @@ type UpdateUserRolePayload {
} }
input NewRefreshToken { input NewRefreshToken {
userId: String! userID: UUID!
} }
input NewUserAccount { input NewUserAccount {
@ -59,7 +59,7 @@ input NewUserAccount {
} }
input LogoutUser { input LogoutUser {
userID: String! userID: UUID!
} }
input DeleteUserAccount { input DeleteUserAccount {

View File

@ -1,2 +1,14 @@
#!/bin/bash #!/bin/sh
yarn --cwd frontend eslint $(echo $1 | sed 's/frontend\///g')
PASS=true
for FILE in "$@"
do
yarn --cwd frontend run eslint $(echo $FILE | sed 's/frontend\///g')
if [ "$?" -eq 1 ]; then
PASS=false
fi
done
if [ "$PASS" = "false" ]; then
exit 1
fi