feature: add labels & remove old types
This commit is contained in:
		@@ -86,10 +86,12 @@ type ComplexityRoot struct {
 | 
				
			|||||||
		DeleteTaskGroup         func(childComplexity int, input DeleteTaskGroupInput) int
 | 
							DeleteTaskGroup         func(childComplexity int, input DeleteTaskGroupInput) int
 | 
				
			||||||
		LogoutUser              func(childComplexity int, input LogoutUser) int
 | 
							LogoutUser              func(childComplexity int, input LogoutUser) int
 | 
				
			||||||
		RemoveTaskLabel         func(childComplexity int, input *RemoveTaskLabelInput) int
 | 
							RemoveTaskLabel         func(childComplexity int, input *RemoveTaskLabelInput) int
 | 
				
			||||||
 | 
							ToggleTaskLabel         func(childComplexity int, input ToggleTaskLabelInput) int
 | 
				
			||||||
		UnassignTask            func(childComplexity int, input *UnassignTaskInput) int
 | 
							UnassignTask            func(childComplexity int, input *UnassignTaskInput) int
 | 
				
			||||||
		UpdateProjectLabel      func(childComplexity int, input UpdateProjectLabel) int
 | 
							UpdateProjectLabel      func(childComplexity int, input UpdateProjectLabel) int
 | 
				
			||||||
		UpdateProjectLabelColor func(childComplexity int, input UpdateProjectLabelColor) int
 | 
							UpdateProjectLabelColor func(childComplexity int, input UpdateProjectLabelColor) int
 | 
				
			||||||
		UpdateProjectLabelName  func(childComplexity int, input UpdateProjectLabelName) int
 | 
							UpdateProjectLabelName  func(childComplexity int, input UpdateProjectLabelName) int
 | 
				
			||||||
 | 
							UpdateProjectName       func(childComplexity int, input *UpdateProjectName) int
 | 
				
			||||||
		UpdateTaskDescription   func(childComplexity int, input UpdateTaskDescriptionInput) int
 | 
							UpdateTaskDescription   func(childComplexity int, input UpdateTaskDescriptionInput) int
 | 
				
			||||||
		UpdateTaskGroupLocation func(childComplexity int, input NewTaskGroupLocation) int
 | 
							UpdateTaskGroupLocation func(childComplexity int, input NewTaskGroupLocation) int
 | 
				
			||||||
		UpdateTaskLocation      func(childComplexity int, input NewTaskLocation) int
 | 
							UpdateTaskLocation      func(childComplexity int, input NewTaskLocation) int
 | 
				
			||||||
@@ -167,10 +169,8 @@ type ComplexityRoot struct {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	TaskLabel struct {
 | 
						TaskLabel struct {
 | 
				
			||||||
		AssignedDate func(childComplexity int) int
 | 
							AssignedDate func(childComplexity int) int
 | 
				
			||||||
		ColorHex       func(childComplexity int) int
 | 
					 | 
				
			||||||
		ID           func(childComplexity int) int
 | 
							ID           func(childComplexity int) int
 | 
				
			||||||
		Name           func(childComplexity int) int
 | 
							ProjectLabel func(childComplexity int) int
 | 
				
			||||||
		ProjectLabelID func(childComplexity int) int
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Team struct {
 | 
						Team struct {
 | 
				
			||||||
@@ -179,6 +179,11 @@ type ComplexityRoot struct {
 | 
				
			|||||||
		Name      func(childComplexity int) int
 | 
							Name      func(childComplexity int) int
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ToggleTaskLabelPayload struct {
 | 
				
			||||||
 | 
							Active func(childComplexity int) int
 | 
				
			||||||
 | 
							Task   func(childComplexity int) int
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	UserAccount struct {
 | 
						UserAccount struct {
 | 
				
			||||||
		CreatedAt   func(childComplexity int) int
 | 
							CreatedAt   func(childComplexity int) int
 | 
				
			||||||
		Email       func(childComplexity int) int
 | 
							Email       func(childComplexity int) int
 | 
				
			||||||
@@ -198,6 +203,7 @@ type MutationResolver interface {
 | 
				
			|||||||
	CreateUserAccount(ctx context.Context, input NewUserAccount) (*pg.UserAccount, error)
 | 
						CreateUserAccount(ctx context.Context, input NewUserAccount) (*pg.UserAccount, error)
 | 
				
			||||||
	CreateTeam(ctx context.Context, input NewTeam) (*pg.Team, error)
 | 
						CreateTeam(ctx context.Context, input NewTeam) (*pg.Team, error)
 | 
				
			||||||
	CreateProject(ctx context.Context, input NewProject) (*pg.Project, error)
 | 
						CreateProject(ctx context.Context, input NewProject) (*pg.Project, error)
 | 
				
			||||||
 | 
						UpdateProjectName(ctx context.Context, input *UpdateProjectName) (*pg.Project, error)
 | 
				
			||||||
	CreateProjectLabel(ctx context.Context, input NewProjectLabel) (*pg.ProjectLabel, error)
 | 
						CreateProjectLabel(ctx context.Context, input NewProjectLabel) (*pg.ProjectLabel, error)
 | 
				
			||||||
	DeleteProjectLabel(ctx context.Context, input DeleteProjectLabel) (*pg.ProjectLabel, error)
 | 
						DeleteProjectLabel(ctx context.Context, input DeleteProjectLabel) (*pg.ProjectLabel, error)
 | 
				
			||||||
	UpdateProjectLabel(ctx context.Context, input UpdateProjectLabel) (*pg.ProjectLabel, error)
 | 
						UpdateProjectLabel(ctx context.Context, input UpdateProjectLabel) (*pg.ProjectLabel, error)
 | 
				
			||||||
@@ -208,6 +214,7 @@ type MutationResolver interface {
 | 
				
			|||||||
	DeleteTaskGroup(ctx context.Context, input DeleteTaskGroupInput) (*DeleteTaskGroupPayload, error)
 | 
						DeleteTaskGroup(ctx context.Context, input DeleteTaskGroupInput) (*DeleteTaskGroupPayload, error)
 | 
				
			||||||
	AddTaskLabel(ctx context.Context, input *AddTaskLabelInput) (*pg.Task, error)
 | 
						AddTaskLabel(ctx context.Context, input *AddTaskLabelInput) (*pg.Task, error)
 | 
				
			||||||
	RemoveTaskLabel(ctx context.Context, input *RemoveTaskLabelInput) (*pg.Task, error)
 | 
						RemoveTaskLabel(ctx context.Context, input *RemoveTaskLabelInput) (*pg.Task, error)
 | 
				
			||||||
 | 
						ToggleTaskLabel(ctx context.Context, input ToggleTaskLabelInput) (*ToggleTaskLabelPayload, error)
 | 
				
			||||||
	CreateTask(ctx context.Context, input NewTask) (*pg.Task, error)
 | 
						CreateTask(ctx context.Context, input NewTask) (*pg.Task, error)
 | 
				
			||||||
	UpdateTaskDescription(ctx context.Context, input UpdateTaskDescriptionInput) (*pg.Task, error)
 | 
						UpdateTaskDescription(ctx context.Context, input UpdateTaskDescriptionInput) (*pg.Task, error)
 | 
				
			||||||
	UpdateTaskLocation(ctx context.Context, input NewTaskLocation) (*pg.Task, error)
 | 
						UpdateTaskLocation(ctx context.Context, input NewTaskLocation) (*pg.Task, error)
 | 
				
			||||||
@@ -261,9 +268,7 @@ type TaskGroupResolver interface {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
type TaskLabelResolver interface {
 | 
					type TaskLabelResolver interface {
 | 
				
			||||||
	ID(ctx context.Context, obj *pg.TaskLabel) (uuid.UUID, error)
 | 
						ID(ctx context.Context, obj *pg.TaskLabel) (uuid.UUID, error)
 | 
				
			||||||
 | 
						ProjectLabel(ctx context.Context, obj *pg.TaskLabel) (*pg.ProjectLabel, error)
 | 
				
			||||||
	ColorHex(ctx context.Context, obj *pg.TaskLabel) (string, error)
 | 
					 | 
				
			||||||
	Name(ctx context.Context, obj *pg.TaskLabel) (*string, error)
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
type TeamResolver interface {
 | 
					type TeamResolver interface {
 | 
				
			||||||
	ID(ctx context.Context, obj *pg.Team) (uuid.UUID, error)
 | 
						ID(ctx context.Context, obj *pg.Team) (uuid.UUID, error)
 | 
				
			||||||
@@ -513,6 +518,18 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		return e.complexity.Mutation.RemoveTaskLabel(childComplexity, args["input"].(*RemoveTaskLabelInput)), true
 | 
							return e.complexity.Mutation.RemoveTaskLabel(childComplexity, args["input"].(*RemoveTaskLabelInput)), true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case "Mutation.toggleTaskLabel":
 | 
				
			||||||
 | 
							if e.complexity.Mutation.ToggleTaskLabel == nil {
 | 
				
			||||||
 | 
								break
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							args, err := ec.field_Mutation_toggleTaskLabel_args(context.TODO(), rawArgs)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return 0, false
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return e.complexity.Mutation.ToggleTaskLabel(childComplexity, args["input"].(ToggleTaskLabelInput)), true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	case "Mutation.unassignTask":
 | 
						case "Mutation.unassignTask":
 | 
				
			||||||
		if e.complexity.Mutation.UnassignTask == nil {
 | 
							if e.complexity.Mutation.UnassignTask == nil {
 | 
				
			||||||
			break
 | 
								break
 | 
				
			||||||
@@ -561,6 +578,18 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		return e.complexity.Mutation.UpdateProjectLabelName(childComplexity, args["input"].(UpdateProjectLabelName)), true
 | 
							return e.complexity.Mutation.UpdateProjectLabelName(childComplexity, args["input"].(UpdateProjectLabelName)), true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case "Mutation.updateProjectName":
 | 
				
			||||||
 | 
							if e.complexity.Mutation.UpdateProjectName == nil {
 | 
				
			||||||
 | 
								break
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							args, err := ec.field_Mutation_updateProjectName_args(context.TODO(), rawArgs)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return 0, false
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return e.complexity.Mutation.UpdateProjectName(childComplexity, args["input"].(*UpdateProjectName)), true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	case "Mutation.updateTaskDescription":
 | 
						case "Mutation.updateTaskDescription":
 | 
				
			||||||
		if e.complexity.Mutation.UpdateTaskDescription == nil {
 | 
							if e.complexity.Mutation.UpdateTaskDescription == nil {
 | 
				
			||||||
			break
 | 
								break
 | 
				
			||||||
@@ -951,13 +980,6 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		return e.complexity.TaskLabel.AssignedDate(childComplexity), true
 | 
							return e.complexity.TaskLabel.AssignedDate(childComplexity), true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	case "TaskLabel.colorHex":
 | 
					 | 
				
			||||||
		if e.complexity.TaskLabel.ColorHex == nil {
 | 
					 | 
				
			||||||
			break
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		return e.complexity.TaskLabel.ColorHex(childComplexity), true
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	case "TaskLabel.id":
 | 
						case "TaskLabel.id":
 | 
				
			||||||
		if e.complexity.TaskLabel.ID == nil {
 | 
							if e.complexity.TaskLabel.ID == nil {
 | 
				
			||||||
			break
 | 
								break
 | 
				
			||||||
@@ -965,19 +987,12 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		return e.complexity.TaskLabel.ID(childComplexity), true
 | 
							return e.complexity.TaskLabel.ID(childComplexity), true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	case "TaskLabel.name":
 | 
						case "TaskLabel.projectLabel":
 | 
				
			||||||
		if e.complexity.TaskLabel.Name == nil {
 | 
							if e.complexity.TaskLabel.ProjectLabel == nil {
 | 
				
			||||||
			break
 | 
								break
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		return e.complexity.TaskLabel.Name(childComplexity), true
 | 
							return e.complexity.TaskLabel.ProjectLabel(childComplexity), true
 | 
				
			||||||
 | 
					 | 
				
			||||||
	case "TaskLabel.projectLabelID":
 | 
					 | 
				
			||||||
		if e.complexity.TaskLabel.ProjectLabelID == nil {
 | 
					 | 
				
			||||||
			break
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		return e.complexity.TaskLabel.ProjectLabelID(childComplexity), true
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	case "Team.createdAt":
 | 
						case "Team.createdAt":
 | 
				
			||||||
		if e.complexity.Team.CreatedAt == nil {
 | 
							if e.complexity.Team.CreatedAt == nil {
 | 
				
			||||||
@@ -1000,6 +1015,20 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		return e.complexity.Team.Name(childComplexity), true
 | 
							return e.complexity.Team.Name(childComplexity), true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case "ToggleTaskLabelPayload.active":
 | 
				
			||||||
 | 
							if e.complexity.ToggleTaskLabelPayload.Active == nil {
 | 
				
			||||||
 | 
								break
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return e.complexity.ToggleTaskLabelPayload.Active(childComplexity), true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case "ToggleTaskLabelPayload.task":
 | 
				
			||||||
 | 
							if e.complexity.ToggleTaskLabelPayload.Task == nil {
 | 
				
			||||||
 | 
								break
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return e.complexity.ToggleTaskLabelPayload.Task(childComplexity), true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	case "UserAccount.createdAt":
 | 
						case "UserAccount.createdAt":
 | 
				
			||||||
		if e.complexity.UserAccount.CreatedAt == nil {
 | 
							if e.complexity.UserAccount.CreatedAt == nil {
 | 
				
			||||||
			break
 | 
								break
 | 
				
			||||||
@@ -1132,10 +1161,8 @@ type LabelColor {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
type TaskLabel {
 | 
					type TaskLabel {
 | 
				
			||||||
  id: ID!
 | 
					  id: ID!
 | 
				
			||||||
  projectLabelID: UUID!
 | 
					  projectLabel: ProjectLabel!
 | 
				
			||||||
  assignedDate: Time!
 | 
					  assignedDate: Time!
 | 
				
			||||||
  colorHex: String!
 | 
					 | 
				
			||||||
  name: String
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type ProfileIcon {
 | 
					type ProfileIcon {
 | 
				
			||||||
@@ -1319,11 +1346,10 @@ input UpdateTaskDescriptionInput {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
input AddTaskLabelInput {
 | 
					input AddTaskLabelInput {
 | 
				
			||||||
  taskID: UUID!
 | 
					  taskID: UUID!
 | 
				
			||||||
  labelColorID: UUID!
 | 
					  projectLabelID: UUID!
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
input RemoveTaskLabelInput {
 | 
					input RemoveTaskLabelInput {
 | 
				
			||||||
  taskID: UUID!
 | 
					 | 
				
			||||||
  taskLabelID: UUID!
 | 
					  taskLabelID: UUID!
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1353,6 +1379,21 @@ input UpdateProjectLabelColor {
 | 
				
			|||||||
  labelColorID: UUID!
 | 
					  labelColorID: UUID!
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					input ToggleTaskLabelInput {
 | 
				
			||||||
 | 
					  taskID: UUID!
 | 
				
			||||||
 | 
					  projectLabelID: UUID!
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type ToggleTaskLabelPayload {
 | 
				
			||||||
 | 
					  active: Boolean!
 | 
				
			||||||
 | 
					  task: Task!
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					input UpdateProjectName {
 | 
				
			||||||
 | 
					  projectID: UUID!
 | 
				
			||||||
 | 
					  name: String!
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type Mutation {
 | 
					type Mutation {
 | 
				
			||||||
  createRefreshToken(input: NewRefreshToken!): RefreshToken!
 | 
					  createRefreshToken(input: NewRefreshToken!): RefreshToken!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1361,6 +1402,7 @@ type Mutation {
 | 
				
			|||||||
  createTeam(input: NewTeam!): Team!
 | 
					  createTeam(input: NewTeam!): Team!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  createProject(input: NewProject!): Project!
 | 
					  createProject(input: NewProject!): Project!
 | 
				
			||||||
 | 
					  updateProjectName(input: UpdateProjectName): Project!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  createProjectLabel(input: NewProjectLabel!): ProjectLabel!
 | 
					  createProjectLabel(input: NewProjectLabel!): ProjectLabel!
 | 
				
			||||||
  deleteProjectLabel(input: DeleteProjectLabel!): ProjectLabel!
 | 
					  deleteProjectLabel(input: DeleteProjectLabel!): ProjectLabel!
 | 
				
			||||||
@@ -1374,6 +1416,7 @@ type Mutation {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  addTaskLabel(input: AddTaskLabelInput): Task!
 | 
					  addTaskLabel(input: AddTaskLabelInput): Task!
 | 
				
			||||||
  removeTaskLabel(input: RemoveTaskLabelInput): Task!
 | 
					  removeTaskLabel(input: RemoveTaskLabelInput): Task!
 | 
				
			||||||
 | 
					  toggleTaskLabel(input: ToggleTaskLabelInput!): ToggleTaskLabelPayload!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  createTask(input: NewTask!): Task!
 | 
					  createTask(input: NewTask!): Task!
 | 
				
			||||||
  updateTaskDescription(input: UpdateTaskDescriptionInput!): Task!
 | 
					  updateTaskDescription(input: UpdateTaskDescriptionInput!): Task!
 | 
				
			||||||
@@ -1589,6 +1632,20 @@ func (ec *executionContext) field_Mutation_removeTaskLabel_args(ctx context.Cont
 | 
				
			|||||||
	return args, nil
 | 
						return args, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (ec *executionContext) field_Mutation_toggleTaskLabel_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
 | 
				
			||||||
 | 
						var err error
 | 
				
			||||||
 | 
						args := map[string]interface{}{}
 | 
				
			||||||
 | 
						var arg0 ToggleTaskLabelInput
 | 
				
			||||||
 | 
						if tmp, ok := rawArgs["input"]; ok {
 | 
				
			||||||
 | 
							arg0, err = ec.unmarshalNToggleTaskLabelInput2githubᚗcomᚋjordanknottᚋprojectᚑcitadelᚋapiᚋgraphᚐToggleTaskLabelInput(ctx, tmp)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return nil, err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						args["input"] = arg0
 | 
				
			||||||
 | 
						return args, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (ec *executionContext) field_Mutation_unassignTask_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
 | 
					func (ec *executionContext) field_Mutation_unassignTask_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
 | 
				
			||||||
	var err error
 | 
						var err error
 | 
				
			||||||
	args := map[string]interface{}{}
 | 
						args := map[string]interface{}{}
 | 
				
			||||||
@@ -1645,6 +1702,20 @@ func (ec *executionContext) field_Mutation_updateProjectLabel_args(ctx context.C
 | 
				
			|||||||
	return args, nil
 | 
						return args, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (ec *executionContext) field_Mutation_updateProjectName_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
 | 
				
			||||||
 | 
						var err error
 | 
				
			||||||
 | 
						args := map[string]interface{}{}
 | 
				
			||||||
 | 
						var arg0 *UpdateProjectName
 | 
				
			||||||
 | 
						if tmp, ok := rawArgs["input"]; ok {
 | 
				
			||||||
 | 
							arg0, err = ec.unmarshalOUpdateProjectName2ᚖgithubᚗcomᚋjordanknottᚋprojectᚑcitadelᚋapiᚋgraphᚐUpdateProjectName(ctx, tmp)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return nil, err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						args["input"] = arg0
 | 
				
			||||||
 | 
						return args, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (ec *executionContext) field_Mutation_updateTaskDescription_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
 | 
					func (ec *executionContext) field_Mutation_updateTaskDescription_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
 | 
				
			||||||
	var err error
 | 
						var err error
 | 
				
			||||||
	args := map[string]interface{}{}
 | 
						args := map[string]interface{}{}
 | 
				
			||||||
@@ -2243,6 +2314,47 @@ func (ec *executionContext) _Mutation_createProject(ctx context.Context, field g
 | 
				
			|||||||
	return ec.marshalNProject2ᚖgithubᚗcomᚋjordanknottᚋprojectᚑcitadelᚋapiᚋpgᚐProject(ctx, field.Selections, res)
 | 
						return ec.marshalNProject2ᚖgithubᚗcomᚋjordanknottᚋprojectᚑcitadelᚋapiᚋpgᚐProject(ctx, field.Selections, res)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (ec *executionContext) _Mutation_updateProjectName(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
 | 
				
			||||||
 | 
						defer func() {
 | 
				
			||||||
 | 
							if r := recover(); r != nil {
 | 
				
			||||||
 | 
								ec.Error(ctx, ec.Recover(ctx, r))
 | 
				
			||||||
 | 
								ret = graphql.Null
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}()
 | 
				
			||||||
 | 
						fc := &graphql.FieldContext{
 | 
				
			||||||
 | 
							Object:   "Mutation",
 | 
				
			||||||
 | 
							Field:    field,
 | 
				
			||||||
 | 
							Args:     nil,
 | 
				
			||||||
 | 
							IsMethod: true,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ctx = graphql.WithFieldContext(ctx, fc)
 | 
				
			||||||
 | 
						rawArgs := field.ArgumentMap(ec.Variables)
 | 
				
			||||||
 | 
						args, err := ec.field_Mutation_updateProjectName_args(ctx, rawArgs)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							ec.Error(ctx, err)
 | 
				
			||||||
 | 
							return graphql.Null
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						fc.Args = args
 | 
				
			||||||
 | 
						resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
 | 
				
			||||||
 | 
							ctx = rctx // use context from middleware stack in children
 | 
				
			||||||
 | 
							return ec.resolvers.Mutation().UpdateProjectName(rctx, args["input"].(*UpdateProjectName))
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							ec.Error(ctx, err)
 | 
				
			||||||
 | 
							return graphql.Null
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if resTmp == nil {
 | 
				
			||||||
 | 
							if !graphql.HasFieldError(ctx, fc) {
 | 
				
			||||||
 | 
								ec.Errorf(ctx, "must not be null")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return graphql.Null
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						res := resTmp.(*pg.Project)
 | 
				
			||||||
 | 
						fc.Result = res
 | 
				
			||||||
 | 
						return ec.marshalNProject2ᚖgithubᚗcomᚋjordanknottᚋprojectᚑcitadelᚋapiᚋpgᚐProject(ctx, field.Selections, res)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (ec *executionContext) _Mutation_createProjectLabel(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
 | 
					func (ec *executionContext) _Mutation_createProjectLabel(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
 | 
				
			||||||
	defer func() {
 | 
						defer func() {
 | 
				
			||||||
		if r := recover(); r != nil {
 | 
							if r := recover(); r != nil {
 | 
				
			||||||
@@ -2653,6 +2765,47 @@ func (ec *executionContext) _Mutation_removeTaskLabel(ctx context.Context, field
 | 
				
			|||||||
	return ec.marshalNTask2ᚖgithubᚗcomᚋjordanknottᚋprojectᚑcitadelᚋapiᚋpgᚐTask(ctx, field.Selections, res)
 | 
						return ec.marshalNTask2ᚖgithubᚗcomᚋjordanknottᚋprojectᚑcitadelᚋapiᚋpgᚐTask(ctx, field.Selections, res)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (ec *executionContext) _Mutation_toggleTaskLabel(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
 | 
				
			||||||
 | 
						defer func() {
 | 
				
			||||||
 | 
							if r := recover(); r != nil {
 | 
				
			||||||
 | 
								ec.Error(ctx, ec.Recover(ctx, r))
 | 
				
			||||||
 | 
								ret = graphql.Null
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}()
 | 
				
			||||||
 | 
						fc := &graphql.FieldContext{
 | 
				
			||||||
 | 
							Object:   "Mutation",
 | 
				
			||||||
 | 
							Field:    field,
 | 
				
			||||||
 | 
							Args:     nil,
 | 
				
			||||||
 | 
							IsMethod: true,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ctx = graphql.WithFieldContext(ctx, fc)
 | 
				
			||||||
 | 
						rawArgs := field.ArgumentMap(ec.Variables)
 | 
				
			||||||
 | 
						args, err := ec.field_Mutation_toggleTaskLabel_args(ctx, rawArgs)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							ec.Error(ctx, err)
 | 
				
			||||||
 | 
							return graphql.Null
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						fc.Args = args
 | 
				
			||||||
 | 
						resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
 | 
				
			||||||
 | 
							ctx = rctx // use context from middleware stack in children
 | 
				
			||||||
 | 
							return ec.resolvers.Mutation().ToggleTaskLabel(rctx, args["input"].(ToggleTaskLabelInput))
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							ec.Error(ctx, err)
 | 
				
			||||||
 | 
							return graphql.Null
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if resTmp == nil {
 | 
				
			||||||
 | 
							if !graphql.HasFieldError(ctx, fc) {
 | 
				
			||||||
 | 
								ec.Errorf(ctx, "must not be null")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return graphql.Null
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						res := resTmp.(*ToggleTaskLabelPayload)
 | 
				
			||||||
 | 
						fc.Result = res
 | 
				
			||||||
 | 
						return ec.marshalNToggleTaskLabelPayload2ᚖgithubᚗcomᚋjordanknottᚋprojectᚑcitadelᚋapiᚋgraphᚐToggleTaskLabelPayload(ctx, field.Selections, res)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (ec *executionContext) _Mutation_createTask(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
 | 
					func (ec *executionContext) _Mutation_createTask(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
 | 
				
			||||||
	defer func() {
 | 
						defer func() {
 | 
				
			||||||
		if r := recover(); r != nil {
 | 
							if r := recover(); r != nil {
 | 
				
			||||||
@@ -4627,7 +4780,7 @@ func (ec *executionContext) _TaskLabel_id(ctx context.Context, field graphql.Col
 | 
				
			|||||||
	return ec.marshalNID2githubᚗcomᚋgoogleᚋuuidᚐUUID(ctx, field.Selections, res)
 | 
						return ec.marshalNID2githubᚗcomᚋgoogleᚋuuidᚐUUID(ctx, field.Selections, res)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (ec *executionContext) _TaskLabel_projectLabelID(ctx context.Context, field graphql.CollectedField, obj *pg.TaskLabel) (ret graphql.Marshaler) {
 | 
					func (ec *executionContext) _TaskLabel_projectLabel(ctx context.Context, field graphql.CollectedField, obj *pg.TaskLabel) (ret graphql.Marshaler) {
 | 
				
			||||||
	defer func() {
 | 
						defer func() {
 | 
				
			||||||
		if r := recover(); r != nil {
 | 
							if r := recover(); r != nil {
 | 
				
			||||||
			ec.Error(ctx, ec.Recover(ctx, r))
 | 
								ec.Error(ctx, ec.Recover(ctx, r))
 | 
				
			||||||
@@ -4638,13 +4791,13 @@ func (ec *executionContext) _TaskLabel_projectLabelID(ctx context.Context, field
 | 
				
			|||||||
		Object:   "TaskLabel",
 | 
							Object:   "TaskLabel",
 | 
				
			||||||
		Field:    field,
 | 
							Field:    field,
 | 
				
			||||||
		Args:     nil,
 | 
							Args:     nil,
 | 
				
			||||||
		IsMethod: false,
 | 
							IsMethod: true,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ctx = graphql.WithFieldContext(ctx, fc)
 | 
						ctx = graphql.WithFieldContext(ctx, fc)
 | 
				
			||||||
	resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
 | 
						resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
 | 
				
			||||||
		ctx = rctx // use context from middleware stack in children
 | 
							ctx = rctx // use context from middleware stack in children
 | 
				
			||||||
		return obj.ProjectLabelID, nil
 | 
							return ec.resolvers.TaskLabel().ProjectLabel(rctx, obj)
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		ec.Error(ctx, err)
 | 
							ec.Error(ctx, err)
 | 
				
			||||||
@@ -4656,9 +4809,9 @@ func (ec *executionContext) _TaskLabel_projectLabelID(ctx context.Context, field
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
		return graphql.Null
 | 
							return graphql.Null
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	res := resTmp.(uuid.UUID)
 | 
						res := resTmp.(*pg.ProjectLabel)
 | 
				
			||||||
	fc.Result = res
 | 
						fc.Result = res
 | 
				
			||||||
	return ec.marshalNUUID2githubᚗcomᚋgoogleᚋuuidᚐUUID(ctx, field.Selections, res)
 | 
						return ec.marshalNProjectLabel2ᚖgithubᚗcomᚋjordanknottᚋprojectᚑcitadelᚋapiᚋpgᚐProjectLabel(ctx, field.Selections, res)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (ec *executionContext) _TaskLabel_assignedDate(ctx context.Context, field graphql.CollectedField, obj *pg.TaskLabel) (ret graphql.Marshaler) {
 | 
					func (ec *executionContext) _TaskLabel_assignedDate(ctx context.Context, field graphql.CollectedField, obj *pg.TaskLabel) (ret graphql.Marshaler) {
 | 
				
			||||||
@@ -4695,71 +4848,6 @@ func (ec *executionContext) _TaskLabel_assignedDate(ctx context.Context, field g
 | 
				
			|||||||
	return ec.marshalNTime2timeᚐTime(ctx, field.Selections, res)
 | 
						return ec.marshalNTime2timeᚐTime(ctx, field.Selections, res)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (ec *executionContext) _TaskLabel_colorHex(ctx context.Context, field graphql.CollectedField, obj *pg.TaskLabel) (ret graphql.Marshaler) {
 | 
					 | 
				
			||||||
	defer func() {
 | 
					 | 
				
			||||||
		if r := recover(); r != nil {
 | 
					 | 
				
			||||||
			ec.Error(ctx, ec.Recover(ctx, r))
 | 
					 | 
				
			||||||
			ret = graphql.Null
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}()
 | 
					 | 
				
			||||||
	fc := &graphql.FieldContext{
 | 
					 | 
				
			||||||
		Object:   "TaskLabel",
 | 
					 | 
				
			||||||
		Field:    field,
 | 
					 | 
				
			||||||
		Args:     nil,
 | 
					 | 
				
			||||||
		IsMethod: true,
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	ctx = graphql.WithFieldContext(ctx, fc)
 | 
					 | 
				
			||||||
	resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
 | 
					 | 
				
			||||||
		ctx = rctx // use context from middleware stack in children
 | 
					 | 
				
			||||||
		return ec.resolvers.TaskLabel().ColorHex(rctx, obj)
 | 
					 | 
				
			||||||
	})
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		ec.Error(ctx, err)
 | 
					 | 
				
			||||||
		return graphql.Null
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if resTmp == nil {
 | 
					 | 
				
			||||||
		if !graphql.HasFieldError(ctx, fc) {
 | 
					 | 
				
			||||||
			ec.Errorf(ctx, "must not be null")
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return graphql.Null
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	res := resTmp.(string)
 | 
					 | 
				
			||||||
	fc.Result = res
 | 
					 | 
				
			||||||
	return ec.marshalNString2string(ctx, field.Selections, res)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (ec *executionContext) _TaskLabel_name(ctx context.Context, field graphql.CollectedField, obj *pg.TaskLabel) (ret graphql.Marshaler) {
 | 
					 | 
				
			||||||
	defer func() {
 | 
					 | 
				
			||||||
		if r := recover(); r != nil {
 | 
					 | 
				
			||||||
			ec.Error(ctx, ec.Recover(ctx, r))
 | 
					 | 
				
			||||||
			ret = graphql.Null
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}()
 | 
					 | 
				
			||||||
	fc := &graphql.FieldContext{
 | 
					 | 
				
			||||||
		Object:   "TaskLabel",
 | 
					 | 
				
			||||||
		Field:    field,
 | 
					 | 
				
			||||||
		Args:     nil,
 | 
					 | 
				
			||||||
		IsMethod: true,
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	ctx = graphql.WithFieldContext(ctx, fc)
 | 
					 | 
				
			||||||
	resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
 | 
					 | 
				
			||||||
		ctx = rctx // use context from middleware stack in children
 | 
					 | 
				
			||||||
		return ec.resolvers.TaskLabel().Name(rctx, obj)
 | 
					 | 
				
			||||||
	})
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		ec.Error(ctx, err)
 | 
					 | 
				
			||||||
		return graphql.Null
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if resTmp == nil {
 | 
					 | 
				
			||||||
		return graphql.Null
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	res := resTmp.(*string)
 | 
					 | 
				
			||||||
	fc.Result = res
 | 
					 | 
				
			||||||
	return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (ec *executionContext) _Team_id(ctx context.Context, field graphql.CollectedField, obj *pg.Team) (ret graphql.Marshaler) {
 | 
					func (ec *executionContext) _Team_id(ctx context.Context, field graphql.CollectedField, obj *pg.Team) (ret graphql.Marshaler) {
 | 
				
			||||||
	defer func() {
 | 
						defer func() {
 | 
				
			||||||
		if r := recover(); r != nil {
 | 
							if r := recover(); r != nil {
 | 
				
			||||||
@@ -4862,6 +4950,74 @@ func (ec *executionContext) _Team_name(ctx context.Context, field graphql.Collec
 | 
				
			|||||||
	return ec.marshalNString2string(ctx, field.Selections, res)
 | 
						return ec.marshalNString2string(ctx, field.Selections, res)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (ec *executionContext) _ToggleTaskLabelPayload_active(ctx context.Context, field graphql.CollectedField, obj *ToggleTaskLabelPayload) (ret graphql.Marshaler) {
 | 
				
			||||||
 | 
						defer func() {
 | 
				
			||||||
 | 
							if r := recover(); r != nil {
 | 
				
			||||||
 | 
								ec.Error(ctx, ec.Recover(ctx, r))
 | 
				
			||||||
 | 
								ret = graphql.Null
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}()
 | 
				
			||||||
 | 
						fc := &graphql.FieldContext{
 | 
				
			||||||
 | 
							Object:   "ToggleTaskLabelPayload",
 | 
				
			||||||
 | 
							Field:    field,
 | 
				
			||||||
 | 
							Args:     nil,
 | 
				
			||||||
 | 
							IsMethod: false,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ctx = graphql.WithFieldContext(ctx, fc)
 | 
				
			||||||
 | 
						resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
 | 
				
			||||||
 | 
							ctx = rctx // use context from middleware stack in children
 | 
				
			||||||
 | 
							return obj.Active, nil
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							ec.Error(ctx, err)
 | 
				
			||||||
 | 
							return graphql.Null
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if resTmp == nil {
 | 
				
			||||||
 | 
							if !graphql.HasFieldError(ctx, fc) {
 | 
				
			||||||
 | 
								ec.Errorf(ctx, "must not be null")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return graphql.Null
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						res := resTmp.(bool)
 | 
				
			||||||
 | 
						fc.Result = res
 | 
				
			||||||
 | 
						return ec.marshalNBoolean2bool(ctx, field.Selections, res)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (ec *executionContext) _ToggleTaskLabelPayload_task(ctx context.Context, field graphql.CollectedField, obj *ToggleTaskLabelPayload) (ret graphql.Marshaler) {
 | 
				
			||||||
 | 
						defer func() {
 | 
				
			||||||
 | 
							if r := recover(); r != nil {
 | 
				
			||||||
 | 
								ec.Error(ctx, ec.Recover(ctx, r))
 | 
				
			||||||
 | 
								ret = graphql.Null
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}()
 | 
				
			||||||
 | 
						fc := &graphql.FieldContext{
 | 
				
			||||||
 | 
							Object:   "ToggleTaskLabelPayload",
 | 
				
			||||||
 | 
							Field:    field,
 | 
				
			||||||
 | 
							Args:     nil,
 | 
				
			||||||
 | 
							IsMethod: false,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ctx = graphql.WithFieldContext(ctx, fc)
 | 
				
			||||||
 | 
						resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
 | 
				
			||||||
 | 
							ctx = rctx // use context from middleware stack in children
 | 
				
			||||||
 | 
							return obj.Task, nil
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							ec.Error(ctx, err)
 | 
				
			||||||
 | 
							return graphql.Null
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if resTmp == nil {
 | 
				
			||||||
 | 
							if !graphql.HasFieldError(ctx, fc) {
 | 
				
			||||||
 | 
								ec.Errorf(ctx, "must not be null")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return graphql.Null
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						res := resTmp.(*pg.Task)
 | 
				
			||||||
 | 
						fc.Result = res
 | 
				
			||||||
 | 
						return ec.marshalNTask2ᚖgithubᚗcomᚋjordanknottᚋprojectᚑcitadelᚋapiᚋpgᚐTask(ctx, field.Selections, res)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (ec *executionContext) _UserAccount_id(ctx context.Context, field graphql.CollectedField, obj *pg.UserAccount) (ret graphql.Marshaler) {
 | 
					func (ec *executionContext) _UserAccount_id(ctx context.Context, field graphql.CollectedField, obj *pg.UserAccount) (ret graphql.Marshaler) {
 | 
				
			||||||
	defer func() {
 | 
						defer func() {
 | 
				
			||||||
		if r := recover(); r != nil {
 | 
							if r := recover(); r != nil {
 | 
				
			||||||
@@ -6167,9 +6323,9 @@ func (ec *executionContext) unmarshalInputAddTaskLabelInput(ctx context.Context,
 | 
				
			|||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				return it, err
 | 
									return it, err
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		case "labelColorID":
 | 
							case "projectLabelID":
 | 
				
			||||||
			var err error
 | 
								var err error
 | 
				
			||||||
			it.LabelColorID, err = ec.unmarshalNUUID2githubᚗcomᚋgoogleᚋuuidᚐUUID(ctx, v)
 | 
								it.ProjectLabelID, err = ec.unmarshalNUUID2githubᚗcomᚋgoogleᚋuuidᚐUUID(ctx, v)
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				return it, err
 | 
									return it, err
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
@@ -6609,6 +6765,24 @@ func (ec *executionContext) unmarshalInputRemoveTaskLabelInput(ctx context.Conte
 | 
				
			|||||||
	var it RemoveTaskLabelInput
 | 
						var it RemoveTaskLabelInput
 | 
				
			||||||
	var asMap = obj.(map[string]interface{})
 | 
						var asMap = obj.(map[string]interface{})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for k, v := range asMap {
 | 
				
			||||||
 | 
							switch k {
 | 
				
			||||||
 | 
							case "taskLabelID":
 | 
				
			||||||
 | 
								var err error
 | 
				
			||||||
 | 
								it.TaskLabelID, err = ec.unmarshalNUUID2githubᚗcomᚋgoogleᚋuuidᚐUUID(ctx, v)
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									return it, err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return it, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (ec *executionContext) unmarshalInputToggleTaskLabelInput(ctx context.Context, obj interface{}) (ToggleTaskLabelInput, error) {
 | 
				
			||||||
 | 
						var it ToggleTaskLabelInput
 | 
				
			||||||
 | 
						var asMap = obj.(map[string]interface{})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for k, v := range asMap {
 | 
						for k, v := range asMap {
 | 
				
			||||||
		switch k {
 | 
							switch k {
 | 
				
			||||||
		case "taskID":
 | 
							case "taskID":
 | 
				
			||||||
@@ -6617,9 +6791,9 @@ func (ec *executionContext) unmarshalInputRemoveTaskLabelInput(ctx context.Conte
 | 
				
			|||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				return it, err
 | 
									return it, err
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		case "taskLabelID":
 | 
							case "projectLabelID":
 | 
				
			||||||
			var err error
 | 
								var err error
 | 
				
			||||||
			it.TaskLabelID, err = ec.unmarshalNUUID2githubᚗcomᚋgoogleᚋuuidᚐUUID(ctx, v)
 | 
								it.ProjectLabelID, err = ec.unmarshalNUUID2githubᚗcomᚋgoogleᚋuuidᚐUUID(ctx, v)
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				return it, err
 | 
									return it, err
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
@@ -6731,6 +6905,30 @@ func (ec *executionContext) unmarshalInputUpdateProjectLabelName(ctx context.Con
 | 
				
			|||||||
	return it, nil
 | 
						return it, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (ec *executionContext) unmarshalInputUpdateProjectName(ctx context.Context, obj interface{}) (UpdateProjectName, error) {
 | 
				
			||||||
 | 
						var it UpdateProjectName
 | 
				
			||||||
 | 
						var asMap = obj.(map[string]interface{})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for k, v := range asMap {
 | 
				
			||||||
 | 
							switch k {
 | 
				
			||||||
 | 
							case "projectID":
 | 
				
			||||||
 | 
								var err error
 | 
				
			||||||
 | 
								it.ProjectID, err = ec.unmarshalNUUID2githubᚗcomᚋgoogleᚋuuidᚐUUID(ctx, v)
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									return it, err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							case "name":
 | 
				
			||||||
 | 
								var err error
 | 
				
			||||||
 | 
								it.Name, err = ec.unmarshalNString2string(ctx, v)
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									return it, err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return it, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (ec *executionContext) unmarshalInputUpdateTaskDescriptionInput(ctx context.Context, obj interface{}) (UpdateTaskDescriptionInput, error) {
 | 
					func (ec *executionContext) unmarshalInputUpdateTaskDescriptionInput(ctx context.Context, obj interface{}) (UpdateTaskDescriptionInput, error) {
 | 
				
			||||||
	var it UpdateTaskDescriptionInput
 | 
						var it UpdateTaskDescriptionInput
 | 
				
			||||||
	var asMap = obj.(map[string]interface{})
 | 
						var asMap = obj.(map[string]interface{})
 | 
				
			||||||
@@ -6937,6 +7135,11 @@ func (ec *executionContext) _Mutation(ctx context.Context, sel ast.SelectionSet)
 | 
				
			|||||||
			if out.Values[i] == graphql.Null {
 | 
								if out.Values[i] == graphql.Null {
 | 
				
			||||||
				invalids++
 | 
									invalids++
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
							case "updateProjectName":
 | 
				
			||||||
 | 
								out.Values[i] = ec._Mutation_updateProjectName(ctx, field)
 | 
				
			||||||
 | 
								if out.Values[i] == graphql.Null {
 | 
				
			||||||
 | 
									invalids++
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		case "createProjectLabel":
 | 
							case "createProjectLabel":
 | 
				
			||||||
			out.Values[i] = ec._Mutation_createProjectLabel(ctx, field)
 | 
								out.Values[i] = ec._Mutation_createProjectLabel(ctx, field)
 | 
				
			||||||
			if out.Values[i] == graphql.Null {
 | 
								if out.Values[i] == graphql.Null {
 | 
				
			||||||
@@ -6987,6 +7190,11 @@ func (ec *executionContext) _Mutation(ctx context.Context, sel ast.SelectionSet)
 | 
				
			|||||||
			if out.Values[i] == graphql.Null {
 | 
								if out.Values[i] == graphql.Null {
 | 
				
			||||||
				invalids++
 | 
									invalids++
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
							case "toggleTaskLabel":
 | 
				
			||||||
 | 
								out.Values[i] = ec._Mutation_toggleTaskLabel(ctx, field)
 | 
				
			||||||
 | 
								if out.Values[i] == graphql.Null {
 | 
				
			||||||
 | 
									invalids++
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		case "createTask":
 | 
							case "createTask":
 | 
				
			||||||
			out.Values[i] = ec._Mutation_createTask(ctx, field)
 | 
								out.Values[i] = ec._Mutation_createTask(ctx, field)
 | 
				
			||||||
			if out.Values[i] == graphql.Null {
 | 
								if out.Values[i] == graphql.Null {
 | 
				
			||||||
@@ -7691,17 +7899,7 @@ func (ec *executionContext) _TaskLabel(ctx context.Context, sel ast.SelectionSet
 | 
				
			|||||||
				}
 | 
									}
 | 
				
			||||||
				return res
 | 
									return res
 | 
				
			||||||
			})
 | 
								})
 | 
				
			||||||
		case "projectLabelID":
 | 
							case "projectLabel":
 | 
				
			||||||
			out.Values[i] = ec._TaskLabel_projectLabelID(ctx, field, obj)
 | 
					 | 
				
			||||||
			if out.Values[i] == graphql.Null {
 | 
					 | 
				
			||||||
				atomic.AddUint32(&invalids, 1)
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		case "assignedDate":
 | 
					 | 
				
			||||||
			out.Values[i] = ec._TaskLabel_assignedDate(ctx, field, obj)
 | 
					 | 
				
			||||||
			if out.Values[i] == graphql.Null {
 | 
					 | 
				
			||||||
				atomic.AddUint32(&invalids, 1)
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		case "colorHex":
 | 
					 | 
				
			||||||
			field := field
 | 
								field := field
 | 
				
			||||||
			out.Concurrently(i, func() (res graphql.Marshaler) {
 | 
								out.Concurrently(i, func() (res graphql.Marshaler) {
 | 
				
			||||||
				defer func() {
 | 
									defer func() {
 | 
				
			||||||
@@ -7709,23 +7907,17 @@ func (ec *executionContext) _TaskLabel(ctx context.Context, sel ast.SelectionSet
 | 
				
			|||||||
						ec.Error(ctx, ec.Recover(ctx, r))
 | 
											ec.Error(ctx, ec.Recover(ctx, r))
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
				}()
 | 
									}()
 | 
				
			||||||
				res = ec._TaskLabel_colorHex(ctx, field, obj)
 | 
									res = ec._TaskLabel_projectLabel(ctx, field, obj)
 | 
				
			||||||
				if res == graphql.Null {
 | 
									if res == graphql.Null {
 | 
				
			||||||
					atomic.AddUint32(&invalids, 1)
 | 
										atomic.AddUint32(&invalids, 1)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				return res
 | 
									return res
 | 
				
			||||||
			})
 | 
								})
 | 
				
			||||||
		case "name":
 | 
							case "assignedDate":
 | 
				
			||||||
			field := field
 | 
								out.Values[i] = ec._TaskLabel_assignedDate(ctx, field, obj)
 | 
				
			||||||
			out.Concurrently(i, func() (res graphql.Marshaler) {
 | 
								if out.Values[i] == graphql.Null {
 | 
				
			||||||
				defer func() {
 | 
									atomic.AddUint32(&invalids, 1)
 | 
				
			||||||
					if r := recover(); r != nil {
 | 
					 | 
				
			||||||
						ec.Error(ctx, ec.Recover(ctx, r))
 | 
					 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
				}()
 | 
					 | 
				
			||||||
				res = ec._TaskLabel_name(ctx, field, obj)
 | 
					 | 
				
			||||||
				return res
 | 
					 | 
				
			||||||
			})
 | 
					 | 
				
			||||||
		default:
 | 
							default:
 | 
				
			||||||
			panic("unknown field " + strconv.Quote(field.Name))
 | 
								panic("unknown field " + strconv.Quote(field.Name))
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -7783,6 +7975,38 @@ func (ec *executionContext) _Team(ctx context.Context, sel ast.SelectionSet, obj
 | 
				
			|||||||
	return out
 | 
						return out
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var toggleTaskLabelPayloadImplementors = []string{"ToggleTaskLabelPayload"}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (ec *executionContext) _ToggleTaskLabelPayload(ctx context.Context, sel ast.SelectionSet, obj *ToggleTaskLabelPayload) graphql.Marshaler {
 | 
				
			||||||
 | 
						fields := graphql.CollectFields(ec.OperationContext, sel, toggleTaskLabelPayloadImplementors)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						out := graphql.NewFieldSet(fields)
 | 
				
			||||||
 | 
						var invalids uint32
 | 
				
			||||||
 | 
						for i, field := range fields {
 | 
				
			||||||
 | 
							switch field.Name {
 | 
				
			||||||
 | 
							case "__typename":
 | 
				
			||||||
 | 
								out.Values[i] = graphql.MarshalString("ToggleTaskLabelPayload")
 | 
				
			||||||
 | 
							case "active":
 | 
				
			||||||
 | 
								out.Values[i] = ec._ToggleTaskLabelPayload_active(ctx, field, obj)
 | 
				
			||||||
 | 
								if out.Values[i] == graphql.Null {
 | 
				
			||||||
 | 
									invalids++
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							case "task":
 | 
				
			||||||
 | 
								out.Values[i] = ec._ToggleTaskLabelPayload_task(ctx, field, obj)
 | 
				
			||||||
 | 
								if out.Values[i] == graphql.Null {
 | 
				
			||||||
 | 
									invalids++
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								panic("unknown field " + strconv.Quote(field.Name))
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						out.Dispatch()
 | 
				
			||||||
 | 
						if invalids > 0 {
 | 
				
			||||||
 | 
							return graphql.Null
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return out
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var userAccountImplementors = []string{"UserAccount"}
 | 
					var userAccountImplementors = []string{"UserAccount"}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (ec *executionContext) _UserAccount(ctx context.Context, sel ast.SelectionSet, obj *pg.UserAccount) graphql.Marshaler {
 | 
					func (ec *executionContext) _UserAccount(ctx context.Context, sel ast.SelectionSet, obj *pg.UserAccount) graphql.Marshaler {
 | 
				
			||||||
@@ -8668,6 +8892,24 @@ func (ec *executionContext) marshalNTime2timeᚐTime(ctx context.Context, sel as
 | 
				
			|||||||
	return res
 | 
						return res
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (ec *executionContext) unmarshalNToggleTaskLabelInput2githubᚗcomᚋjordanknottᚋprojectᚑcitadelᚋapiᚋgraphᚐToggleTaskLabelInput(ctx context.Context, v interface{}) (ToggleTaskLabelInput, error) {
 | 
				
			||||||
 | 
						return ec.unmarshalInputToggleTaskLabelInput(ctx, v)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (ec *executionContext) marshalNToggleTaskLabelPayload2githubᚗcomᚋjordanknottᚋprojectᚑcitadelᚋapiᚋgraphᚐToggleTaskLabelPayload(ctx context.Context, sel ast.SelectionSet, v ToggleTaskLabelPayload) graphql.Marshaler {
 | 
				
			||||||
 | 
						return ec._ToggleTaskLabelPayload(ctx, sel, &v)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (ec *executionContext) marshalNToggleTaskLabelPayload2ᚖgithubᚗcomᚋjordanknottᚋprojectᚑcitadelᚋapiᚋgraphᚐToggleTaskLabelPayload(ctx context.Context, sel ast.SelectionSet, v *ToggleTaskLabelPayload) graphql.Marshaler {
 | 
				
			||||||
 | 
						if v == nil {
 | 
				
			||||||
 | 
							if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {
 | 
				
			||||||
 | 
								ec.Errorf(ctx, "must not be null")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return graphql.Null
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return ec._ToggleTaskLabelPayload(ctx, sel, v)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (ec *executionContext) unmarshalNUUID2githubᚗcomᚋgoogleᚋuuidᚐUUID(ctx context.Context, v interface{}) (uuid.UUID, error) {
 | 
					func (ec *executionContext) unmarshalNUUID2githubᚗcomᚋgoogleᚋuuidᚐUUID(ctx context.Context, v interface{}) (uuid.UUID, error) {
 | 
				
			||||||
	return UnmarshalUUID(v)
 | 
						return UnmarshalUUID(v)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -9085,6 +9327,18 @@ func (ec *executionContext) unmarshalOUnassignTaskInput2ᚖgithubᚗcomᚋjordan
 | 
				
			|||||||
	return &res, err
 | 
						return &res, err
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (ec *executionContext) unmarshalOUpdateProjectName2githubᚗcomᚋjordanknottᚋprojectᚑcitadelᚋapiᚋgraphᚐUpdateProjectName(ctx context.Context, v interface{}) (UpdateProjectName, error) {
 | 
				
			||||||
 | 
						return ec.unmarshalInputUpdateProjectName(ctx, v)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (ec *executionContext) unmarshalOUpdateProjectName2ᚖgithubᚗcomᚋjordanknottᚋprojectᚑcitadelᚋapiᚋgraphᚐUpdateProjectName(ctx context.Context, v interface{}) (*UpdateProjectName, error) {
 | 
				
			||||||
 | 
						if v == nil {
 | 
				
			||||||
 | 
							return nil, nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						res, err := ec.unmarshalOUpdateProjectName2githubᚗcomᚋjordanknottᚋprojectᚑcitadelᚋapiᚋgraphᚐUpdateProjectName(ctx, v)
 | 
				
			||||||
 | 
						return &res, err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (ec *executionContext) marshalO__EnumValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValueᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.EnumValue) graphql.Marshaler {
 | 
					func (ec *executionContext) marshalO__EnumValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValueᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.EnumValue) graphql.Marshaler {
 | 
				
			||||||
	if v == nil {
 | 
						if v == nil {
 | 
				
			||||||
		return graphql.Null
 | 
							return graphql.Null
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,7 +9,7 @@ import (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
type AddTaskLabelInput struct {
 | 
					type AddTaskLabelInput struct {
 | 
				
			||||||
	TaskID         uuid.UUID `json:"taskID"`
 | 
						TaskID         uuid.UUID `json:"taskID"`
 | 
				
			||||||
	LabelColorID uuid.UUID `json:"labelColorID"`
 | 
						ProjectLabelID uuid.UUID `json:"projectLabelID"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type AssignTaskInput struct {
 | 
					type AssignTaskInput struct {
 | 
				
			||||||
@@ -125,10 +125,19 @@ type ProjectsFilter struct {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type RemoveTaskLabelInput struct {
 | 
					type RemoveTaskLabelInput struct {
 | 
				
			||||||
	TaskID      uuid.UUID `json:"taskID"`
 | 
					 | 
				
			||||||
	TaskLabelID uuid.UUID `json:"taskLabelID"`
 | 
						TaskLabelID uuid.UUID `json:"taskLabelID"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type ToggleTaskLabelInput struct {
 | 
				
			||||||
 | 
						TaskID         uuid.UUID `json:"taskID"`
 | 
				
			||||||
 | 
						ProjectLabelID uuid.UUID `json:"projectLabelID"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type ToggleTaskLabelPayload struct {
 | 
				
			||||||
 | 
						Active bool     `json:"active"`
 | 
				
			||||||
 | 
						Task   *pg.Task `json:"task"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type UnassignTaskInput struct {
 | 
					type UnassignTaskInput struct {
 | 
				
			||||||
	TaskID uuid.UUID `json:"taskID"`
 | 
						TaskID uuid.UUID `json:"taskID"`
 | 
				
			||||||
	UserID uuid.UUID `json:"userID"`
 | 
						UserID uuid.UUID `json:"userID"`
 | 
				
			||||||
@@ -150,6 +159,11 @@ type UpdateProjectLabelName struct {
 | 
				
			|||||||
	Name           string    `json:"name"`
 | 
						Name           string    `json:"name"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type UpdateProjectName struct {
 | 
				
			||||||
 | 
						ProjectID uuid.UUID `json:"projectID"`
 | 
				
			||||||
 | 
						Name      string    `json:"name"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type UpdateTaskDescriptionInput struct {
 | 
					type UpdateTaskDescriptionInput struct {
 | 
				
			||||||
	TaskID      uuid.UUID `json:"taskID"`
 | 
						TaskID      uuid.UUID `json:"taskID"`
 | 
				
			||||||
	Description string    `json:"description"`
 | 
						Description string    `json:"description"`
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -17,10 +17,8 @@ type LabelColor {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
type TaskLabel {
 | 
					type TaskLabel {
 | 
				
			||||||
  id: ID!
 | 
					  id: ID!
 | 
				
			||||||
  projectLabelID: UUID!
 | 
					  projectLabel: ProjectLabel!
 | 
				
			||||||
  assignedDate: Time!
 | 
					  assignedDate: Time!
 | 
				
			||||||
  colorHex: String!
 | 
					 | 
				
			||||||
  name: String
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type ProfileIcon {
 | 
					type ProfileIcon {
 | 
				
			||||||
@@ -204,11 +202,10 @@ input UpdateTaskDescriptionInput {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
input AddTaskLabelInput {
 | 
					input AddTaskLabelInput {
 | 
				
			||||||
  taskID: UUID!
 | 
					  taskID: UUID!
 | 
				
			||||||
  labelColorID: UUID!
 | 
					  projectLabelID: UUID!
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
input RemoveTaskLabelInput {
 | 
					input RemoveTaskLabelInput {
 | 
				
			||||||
  taskID: UUID!
 | 
					 | 
				
			||||||
  taskLabelID: UUID!
 | 
					  taskLabelID: UUID!
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -238,6 +235,21 @@ input UpdateProjectLabelColor {
 | 
				
			|||||||
  labelColorID: UUID!
 | 
					  labelColorID: UUID!
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					input ToggleTaskLabelInput {
 | 
				
			||||||
 | 
					  taskID: UUID!
 | 
				
			||||||
 | 
					  projectLabelID: UUID!
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type ToggleTaskLabelPayload {
 | 
				
			||||||
 | 
					  active: Boolean!
 | 
				
			||||||
 | 
					  task: Task!
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					input UpdateProjectName {
 | 
				
			||||||
 | 
					  projectID: UUID!
 | 
				
			||||||
 | 
					  name: String!
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type Mutation {
 | 
					type Mutation {
 | 
				
			||||||
  createRefreshToken(input: NewRefreshToken!): RefreshToken!
 | 
					  createRefreshToken(input: NewRefreshToken!): RefreshToken!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -246,6 +258,7 @@ type Mutation {
 | 
				
			|||||||
  createTeam(input: NewTeam!): Team!
 | 
					  createTeam(input: NewTeam!): Team!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  createProject(input: NewProject!): Project!
 | 
					  createProject(input: NewProject!): Project!
 | 
				
			||||||
 | 
					  updateProjectName(input: UpdateProjectName): Project!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  createProjectLabel(input: NewProjectLabel!): ProjectLabel!
 | 
					  createProjectLabel(input: NewProjectLabel!): ProjectLabel!
 | 
				
			||||||
  deleteProjectLabel(input: DeleteProjectLabel!): ProjectLabel!
 | 
					  deleteProjectLabel(input: DeleteProjectLabel!): ProjectLabel!
 | 
				
			||||||
@@ -259,6 +272,7 @@ type Mutation {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  addTaskLabel(input: AddTaskLabelInput): Task!
 | 
					  addTaskLabel(input: AddTaskLabelInput): Task!
 | 
				
			||||||
  removeTaskLabel(input: RemoveTaskLabelInput): Task!
 | 
					  removeTaskLabel(input: RemoveTaskLabelInput): Task!
 | 
				
			||||||
 | 
					  toggleTaskLabel(input: ToggleTaskLabelInput!): ToggleTaskLabelPayload!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  createTask(input: NewTask!): Task!
 | 
					  createTask(input: NewTask!): Task!
 | 
				
			||||||
  updateTaskDescription(input: UpdateTaskDescriptionInput!): Task!
 | 
					  updateTaskDescription(input: UpdateTaskDescriptionInput!): Task!
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -49,6 +49,14 @@ func (r *mutationResolver) CreateProject(ctx context.Context, input NewProject)
 | 
				
			|||||||
	return &project, err
 | 
						return &project, err
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (r *mutationResolver) UpdateProjectName(ctx context.Context, input *UpdateProjectName) (*pg.Project, error) {
 | 
				
			||||||
 | 
						project, err := r.Repository.UpdateProjectNameByID(ctx, pg.UpdateProjectNameByIDParams{ProjectID: input.ProjectID, Name: input.Name})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return &pg.Project{}, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return &project, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (r *mutationResolver) CreateProjectLabel(ctx context.Context, input NewProjectLabel) (*pg.ProjectLabel, error) {
 | 
					func (r *mutationResolver) CreateProjectLabel(ctx context.Context, input NewProjectLabel) (*pg.ProjectLabel, error) {
 | 
				
			||||||
	createdAt := time.Now().UTC()
 | 
						createdAt := time.Now().UTC()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -130,7 +138,7 @@ func (r *mutationResolver) DeleteTaskGroup(ctx context.Context, input DeleteTask
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func (r *mutationResolver) AddTaskLabel(ctx context.Context, input *AddTaskLabelInput) (*pg.Task, error) {
 | 
					func (r *mutationResolver) AddTaskLabel(ctx context.Context, input *AddTaskLabelInput) (*pg.Task, error) {
 | 
				
			||||||
	assignedDate := time.Now().UTC()
 | 
						assignedDate := time.Now().UTC()
 | 
				
			||||||
	_, err := r.Repository.CreateTaskLabelForTask(ctx, pg.CreateTaskLabelForTaskParams{input.TaskID, input.LabelColorID, assignedDate})
 | 
						_, err := r.Repository.CreateTaskLabelForTask(ctx, pg.CreateTaskLabelForTaskParams{input.TaskID, input.ProjectLabelID, assignedDate})
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return &pg.Task{}, err
 | 
							return &pg.Task{}, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -139,7 +147,56 @@ func (r *mutationResolver) AddTaskLabel(ctx context.Context, input *AddTaskLabel
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (r *mutationResolver) RemoveTaskLabel(ctx context.Context, input *RemoveTaskLabelInput) (*pg.Task, error) {
 | 
					func (r *mutationResolver) RemoveTaskLabel(ctx context.Context, input *RemoveTaskLabelInput) (*pg.Task, error) {
 | 
				
			||||||
	panic(fmt.Errorf("not implemented"))
 | 
						taskLabel, err := r.Repository.GetTaskLabelByID(ctx, input.TaskLabelID)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return &pg.Task{}, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						task, err := r.Repository.GetTaskByID(ctx, taskLabel.TaskID)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return &pg.Task{}, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						err = r.Repository.DeleteTaskLabelByID(ctx, input.TaskLabelID)
 | 
				
			||||||
 | 
						return &task, err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (r *mutationResolver) ToggleTaskLabel(ctx context.Context, input ToggleTaskLabelInput) (*ToggleTaskLabelPayload, error) {
 | 
				
			||||||
 | 
						task, err := r.Repository.GetTaskByID(ctx, input.TaskID)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return &ToggleTaskLabelPayload{}, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						_, err = r.Repository.GetTaskLabelForTaskByProjectLabelID(ctx, pg.GetTaskLabelForTaskByProjectLabelIDParams{TaskID: input.TaskID, ProjectLabelID: input.ProjectLabelID})
 | 
				
			||||||
 | 
						createdAt := time.Now().UTC()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if err == sql.ErrNoRows {
 | 
				
			||||||
 | 
							log.WithFields(log.Fields{"err": err}).Warning("no rows")
 | 
				
			||||||
 | 
							_, err := r.Repository.CreateTaskLabelForTask(ctx, pg.CreateTaskLabelForTaskParams{
 | 
				
			||||||
 | 
								TaskID:         input.TaskID,
 | 
				
			||||||
 | 
								ProjectLabelID: input.ProjectLabelID,
 | 
				
			||||||
 | 
								AssignedDate:   createdAt,
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return &ToggleTaskLabelPayload{}, err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							payload := ToggleTaskLabelPayload{Active: true, Task: &task}
 | 
				
			||||||
 | 
							return &payload, nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return &ToggleTaskLabelPayload{}, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						err = r.Repository.DeleteTaskLabelForTaskByProjectLabelID(ctx, pg.DeleteTaskLabelForTaskByProjectLabelIDParams{
 | 
				
			||||||
 | 
							TaskID:         input.TaskID,
 | 
				
			||||||
 | 
							ProjectLabelID: input.ProjectLabelID,
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return &ToggleTaskLabelPayload{}, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						payload := ToggleTaskLabelPayload{Active: false, Task: &task}
 | 
				
			||||||
 | 
						return &payload, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (r *mutationResolver) CreateTask(ctx context.Context, input NewTask) (*pg.Task, error) {
 | 
					func (r *mutationResolver) CreateTask(ctx context.Context, input NewTask) (*pg.Task, error) {
 | 
				
			||||||
@@ -434,28 +491,9 @@ func (r *taskLabelResolver) ID(ctx context.Context, obj *pg.TaskLabel) (uuid.UUI
 | 
				
			|||||||
	return obj.TaskLabelID, nil
 | 
						return obj.TaskLabelID, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (r *taskLabelResolver) ColorHex(ctx context.Context, obj *pg.TaskLabel) (string, error) {
 | 
					func (r *taskLabelResolver) ProjectLabel(ctx context.Context, obj *pg.TaskLabel) (*pg.ProjectLabel, error) {
 | 
				
			||||||
	projectLabel, err := r.Repository.GetProjectLabelByID(ctx, obj.ProjectLabelID)
 | 
						projectLabel, err := r.Repository.GetProjectLabelByID(ctx, obj.ProjectLabelID)
 | 
				
			||||||
	if err != nil {
 | 
						return &projectLabel, err
 | 
				
			||||||
		return "", err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	labelColor, err := r.Repository.GetLabelColorByID(ctx, projectLabel.LabelColorID)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return "", err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return labelColor.ColorHex, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (r *taskLabelResolver) Name(ctx context.Context, obj *pg.TaskLabel) (*string, error) {
 | 
					 | 
				
			||||||
	projectLabel, err := r.Repository.GetProjectLabelByID(ctx, obj.ProjectLabelID)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	name := projectLabel.Name
 | 
					 | 
				
			||||||
	if !name.Valid {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return &name.String, err
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (r *teamResolver) ID(ctx context.Context, obj *pg.Team) (uuid.UUID, error) {
 | 
					func (r *teamResolver) ID(ctx context.Context, obj *pg.Team) (uuid.UUID, error) {
 | 
				
			||||||
@@ -523,6 +561,28 @@ type userAccountResolver struct{ *Resolver }
 | 
				
			|||||||
//  - When renaming or deleting a resolver the old code will be put in here. You can safely delete
 | 
					//  - When renaming or deleting a resolver the old code will be put in here. You can safely delete
 | 
				
			||||||
//    it when you're done.
 | 
					//    it when you're done.
 | 
				
			||||||
//  - You have helper methods in this file. Move them out to keep these resolver files clean.
 | 
					//  - You have helper methods in this file. Move them out to keep these resolver files clean.
 | 
				
			||||||
 | 
					func (r *taskLabelResolver) ColorHex(ctx context.Context, obj *pg.TaskLabel) (string, error) {
 | 
				
			||||||
 | 
						projectLabel, err := r.Repository.GetProjectLabelByID(ctx, obj.ProjectLabelID)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return "", err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						labelColor, err := r.Repository.GetLabelColorByID(ctx, projectLabel.LabelColorID)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return "", err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return labelColor.ColorHex, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					func (r *taskLabelResolver) Name(ctx context.Context, obj *pg.TaskLabel) (*string, error) {
 | 
				
			||||||
 | 
						projectLabel, err := r.Repository.GetProjectLabelByID(ctx, obj.ProjectLabelID)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						name := projectLabel.Name
 | 
				
			||||||
 | 
						if !name.Valid {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return &name.String, err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
func (r *projectLabelResolver) ColorHex(ctx context.Context, obj *pg.ProjectLabel) (string, error) {
 | 
					func (r *projectLabelResolver) ColorHex(ctx context.Context, obj *pg.ProjectLabel) (string, error) {
 | 
				
			||||||
	labelColor, err := r.Repository.GetLabelColorByID(ctx, obj.LabelColorID)
 | 
						labelColor, err := r.Repository.GetLabelColorByID(ctx, obj.LabelColorID)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					ALTER TABLE task_label ADD UNIQUE (project_label_id, task_id);
 | 
				
			||||||
@@ -22,6 +22,13 @@ type Repository interface {
 | 
				
			|||||||
	GetUserAccountByUsername(ctx context.Context, username string) (UserAccount, error)
 | 
						GetUserAccountByUsername(ctx context.Context, username string) (UserAccount, error)
 | 
				
			||||||
	GetAllUserAccounts(ctx context.Context) ([]UserAccount, error)
 | 
						GetAllUserAccounts(ctx context.Context) ([]UserAccount, error)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						GetTaskLabelByID(ctx context.Context, taskLabelID uuid.UUID) (TaskLabel, error)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						DeleteTaskLabelForTaskByProjectLabelID(ctx context.Context, arg DeleteTaskLabelForTaskByProjectLabelIDParams) error
 | 
				
			||||||
 | 
						GetTaskLabelForTaskByProjectLabelID(ctx context.Context, arg GetTaskLabelForTaskByProjectLabelIDParams) (TaskLabel, error)
 | 
				
			||||||
 | 
						UpdateProjectNameByID(ctx context.Context, arg UpdateProjectNameByIDParams) (Project, error)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						DeleteTaskLabelByID(ctx context.Context, taskLabelID uuid.UUID) error
 | 
				
			||||||
	CreateProjectLabel(ctx context.Context, arg CreateProjectLabelParams) (ProjectLabel, error)
 | 
						CreateProjectLabel(ctx context.Context, arg CreateProjectLabelParams) (ProjectLabel, error)
 | 
				
			||||||
	GetProjectLabelsForProject(ctx context.Context, projectID uuid.UUID) ([]ProjectLabel, error)
 | 
						GetProjectLabelsForProject(ctx context.Context, projectID uuid.UUID) ([]ProjectLabel, error)
 | 
				
			||||||
	GetProjectLabelByID(ctx context.Context, projectLabelID uuid.UUID) (ProjectLabel, error)
 | 
						GetProjectLabelByID(ctx context.Context, projectLabelID uuid.UUID) (ProjectLabel, error)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -121,3 +121,25 @@ func (q *Queries) GetProjectByID(ctx context.Context, projectID uuid.UUID) (Proj
 | 
				
			|||||||
	)
 | 
						)
 | 
				
			||||||
	return i, err
 | 
						return i, err
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const updateProjectNameByID = `-- name: UpdateProjectNameByID :one
 | 
				
			||||||
 | 
					UPDATE project SET name = $2 WHERE project_id = $1 RETURNING project_id, team_id, created_at, name, owner
 | 
				
			||||||
 | 
					`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type UpdateProjectNameByIDParams struct {
 | 
				
			||||||
 | 
						ProjectID uuid.UUID `json:"project_id"`
 | 
				
			||||||
 | 
						Name      string    `json:"name"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (q *Queries) UpdateProjectNameByID(ctx context.Context, arg UpdateProjectNameByIDParams) (Project, error) {
 | 
				
			||||||
 | 
						row := q.db.QueryRowContext(ctx, updateProjectNameByID, arg.ProjectID, arg.Name)
 | 
				
			||||||
 | 
						var i Project
 | 
				
			||||||
 | 
						err := row.Scan(
 | 
				
			||||||
 | 
							&i.ProjectID,
 | 
				
			||||||
 | 
							&i.TeamID,
 | 
				
			||||||
 | 
							&i.CreatedAt,
 | 
				
			||||||
 | 
							&i.Name,
 | 
				
			||||||
 | 
							&i.Owner,
 | 
				
			||||||
 | 
						)
 | 
				
			||||||
 | 
						return i, err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -27,6 +27,8 @@ type Querier interface {
 | 
				
			|||||||
	DeleteTaskAssignedByID(ctx context.Context, arg DeleteTaskAssignedByIDParams) (TaskAssigned, error)
 | 
						DeleteTaskAssignedByID(ctx context.Context, arg DeleteTaskAssignedByIDParams) (TaskAssigned, error)
 | 
				
			||||||
	DeleteTaskByID(ctx context.Context, taskID uuid.UUID) error
 | 
						DeleteTaskByID(ctx context.Context, taskID uuid.UUID) error
 | 
				
			||||||
	DeleteTaskGroupByID(ctx context.Context, taskGroupID uuid.UUID) (int64, error)
 | 
						DeleteTaskGroupByID(ctx context.Context, taskGroupID uuid.UUID) (int64, error)
 | 
				
			||||||
 | 
						DeleteTaskLabelByID(ctx context.Context, taskLabelID uuid.UUID) error
 | 
				
			||||||
 | 
						DeleteTaskLabelForTaskByProjectLabelID(ctx context.Context, arg DeleteTaskLabelForTaskByProjectLabelIDParams) error
 | 
				
			||||||
	DeleteTasksByTaskGroupID(ctx context.Context, taskGroupID uuid.UUID) (int64, error)
 | 
						DeleteTasksByTaskGroupID(ctx context.Context, taskGroupID uuid.UUID) (int64, error)
 | 
				
			||||||
	DeleteTeamByID(ctx context.Context, teamID uuid.UUID) error
 | 
						DeleteTeamByID(ctx context.Context, teamID uuid.UUID) error
 | 
				
			||||||
	GetAllOrganizations(ctx context.Context) ([]Organization, error)
 | 
						GetAllOrganizations(ctx context.Context) ([]Organization, error)
 | 
				
			||||||
@@ -46,6 +48,8 @@ type Querier interface {
 | 
				
			|||||||
	GetTaskByID(ctx context.Context, taskID uuid.UUID) (Task, error)
 | 
						GetTaskByID(ctx context.Context, taskID uuid.UUID) (Task, error)
 | 
				
			||||||
	GetTaskGroupByID(ctx context.Context, taskGroupID uuid.UUID) (TaskGroup, error)
 | 
						GetTaskGroupByID(ctx context.Context, taskGroupID uuid.UUID) (TaskGroup, error)
 | 
				
			||||||
	GetTaskGroupsForProject(ctx context.Context, projectID uuid.UUID) ([]TaskGroup, error)
 | 
						GetTaskGroupsForProject(ctx context.Context, projectID uuid.UUID) ([]TaskGroup, error)
 | 
				
			||||||
 | 
						GetTaskLabelByID(ctx context.Context, taskLabelID uuid.UUID) (TaskLabel, error)
 | 
				
			||||||
 | 
						GetTaskLabelForTaskByProjectLabelID(ctx context.Context, arg GetTaskLabelForTaskByProjectLabelIDParams) (TaskLabel, error)
 | 
				
			||||||
	GetTaskLabelsForTaskID(ctx context.Context, taskID uuid.UUID) ([]TaskLabel, error)
 | 
						GetTaskLabelsForTaskID(ctx context.Context, taskID uuid.UUID) ([]TaskLabel, error)
 | 
				
			||||||
	GetTasksForTaskGroupID(ctx context.Context, taskGroupID uuid.UUID) ([]Task, error)
 | 
						GetTasksForTaskGroupID(ctx context.Context, taskGroupID uuid.UUID) ([]Task, error)
 | 
				
			||||||
	GetTeamByID(ctx context.Context, teamID uuid.UUID) (Team, error)
 | 
						GetTeamByID(ctx context.Context, teamID uuid.UUID) (Team, error)
 | 
				
			||||||
@@ -55,6 +59,7 @@ type Querier interface {
 | 
				
			|||||||
	UpdateProjectLabel(ctx context.Context, arg UpdateProjectLabelParams) (ProjectLabel, error)
 | 
						UpdateProjectLabel(ctx context.Context, arg UpdateProjectLabelParams) (ProjectLabel, error)
 | 
				
			||||||
	UpdateProjectLabelColor(ctx context.Context, arg UpdateProjectLabelColorParams) (ProjectLabel, error)
 | 
						UpdateProjectLabelColor(ctx context.Context, arg UpdateProjectLabelColorParams) (ProjectLabel, error)
 | 
				
			||||||
	UpdateProjectLabelName(ctx context.Context, arg UpdateProjectLabelNameParams) (ProjectLabel, error)
 | 
						UpdateProjectLabelName(ctx context.Context, arg UpdateProjectLabelNameParams) (ProjectLabel, error)
 | 
				
			||||||
 | 
						UpdateProjectNameByID(ctx context.Context, arg UpdateProjectNameByIDParams) (Project, error)
 | 
				
			||||||
	UpdateTaskDescription(ctx context.Context, arg UpdateTaskDescriptionParams) (Task, error)
 | 
						UpdateTaskDescription(ctx context.Context, arg UpdateTaskDescriptionParams) (Task, error)
 | 
				
			||||||
	UpdateTaskGroupLocation(ctx context.Context, arg UpdateTaskGroupLocationParams) (TaskGroup, error)
 | 
						UpdateTaskGroupLocation(ctx context.Context, arg UpdateTaskGroupLocationParams) (TaskGroup, error)
 | 
				
			||||||
	UpdateTaskLocation(ctx context.Context, arg UpdateTaskLocationParams) (Task, error)
 | 
						UpdateTaskLocation(ctx context.Context, arg UpdateTaskLocationParams) (Task, error)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -33,6 +33,66 @@ func (q *Queries) CreateTaskLabelForTask(ctx context.Context, arg CreateTaskLabe
 | 
				
			|||||||
	return i, err
 | 
						return i, err
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const deleteTaskLabelByID = `-- name: DeleteTaskLabelByID :exec
 | 
				
			||||||
 | 
					DELETE FROM task_label WHERE task_label_id = $1
 | 
				
			||||||
 | 
					`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (q *Queries) DeleteTaskLabelByID(ctx context.Context, taskLabelID uuid.UUID) error {
 | 
				
			||||||
 | 
						_, err := q.db.ExecContext(ctx, deleteTaskLabelByID, taskLabelID)
 | 
				
			||||||
 | 
						return err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const deleteTaskLabelForTaskByProjectLabelID = `-- name: DeleteTaskLabelForTaskByProjectLabelID :exec
 | 
				
			||||||
 | 
					DELETE FROM task_label WHERE project_label_id = $2 AND task_id = $1
 | 
				
			||||||
 | 
					`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type DeleteTaskLabelForTaskByProjectLabelIDParams struct {
 | 
				
			||||||
 | 
						TaskID         uuid.UUID `json:"task_id"`
 | 
				
			||||||
 | 
						ProjectLabelID uuid.UUID `json:"project_label_id"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (q *Queries) DeleteTaskLabelForTaskByProjectLabelID(ctx context.Context, arg DeleteTaskLabelForTaskByProjectLabelIDParams) error {
 | 
				
			||||||
 | 
						_, err := q.db.ExecContext(ctx, deleteTaskLabelForTaskByProjectLabelID, arg.TaskID, arg.ProjectLabelID)
 | 
				
			||||||
 | 
						return err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const getTaskLabelByID = `-- name: GetTaskLabelByID :one
 | 
				
			||||||
 | 
					SELECT task_label_id, task_id, project_label_id, assigned_date FROM task_label WHERE task_label_id = $1
 | 
				
			||||||
 | 
					`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (q *Queries) GetTaskLabelByID(ctx context.Context, taskLabelID uuid.UUID) (TaskLabel, error) {
 | 
				
			||||||
 | 
						row := q.db.QueryRowContext(ctx, getTaskLabelByID, taskLabelID)
 | 
				
			||||||
 | 
						var i TaskLabel
 | 
				
			||||||
 | 
						err := row.Scan(
 | 
				
			||||||
 | 
							&i.TaskLabelID,
 | 
				
			||||||
 | 
							&i.TaskID,
 | 
				
			||||||
 | 
							&i.ProjectLabelID,
 | 
				
			||||||
 | 
							&i.AssignedDate,
 | 
				
			||||||
 | 
						)
 | 
				
			||||||
 | 
						return i, err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const getTaskLabelForTaskByProjectLabelID = `-- name: GetTaskLabelForTaskByProjectLabelID :one
 | 
				
			||||||
 | 
					SELECT task_label_id, task_id, project_label_id, assigned_date FROM task_label WHERE task_id = $1 AND project_label_id = $2
 | 
				
			||||||
 | 
					`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type GetTaskLabelForTaskByProjectLabelIDParams struct {
 | 
				
			||||||
 | 
						TaskID         uuid.UUID `json:"task_id"`
 | 
				
			||||||
 | 
						ProjectLabelID uuid.UUID `json:"project_label_id"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (q *Queries) GetTaskLabelForTaskByProjectLabelID(ctx context.Context, arg GetTaskLabelForTaskByProjectLabelIDParams) (TaskLabel, error) {
 | 
				
			||||||
 | 
						row := q.db.QueryRowContext(ctx, getTaskLabelForTaskByProjectLabelID, arg.TaskID, arg.ProjectLabelID)
 | 
				
			||||||
 | 
						var i TaskLabel
 | 
				
			||||||
 | 
						err := row.Scan(
 | 
				
			||||||
 | 
							&i.TaskLabelID,
 | 
				
			||||||
 | 
							&i.TaskID,
 | 
				
			||||||
 | 
							&i.ProjectLabelID,
 | 
				
			||||||
 | 
							&i.AssignedDate,
 | 
				
			||||||
 | 
						)
 | 
				
			||||||
 | 
						return i, err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const getTaskLabelsForTaskID = `-- name: GetTaskLabelsForTaskID :many
 | 
					const getTaskLabelsForTaskID = `-- name: GetTaskLabelsForTaskID :many
 | 
				
			||||||
SELECT task_label_id, task_id, project_label_id, assigned_date FROM task_label WHERE task_id = $1
 | 
					SELECT task_label_id, task_id, project_label_id, assigned_date FROM task_label WHERE task_id = $1
 | 
				
			||||||
`
 | 
					`
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,3 +9,6 @@ SELECT * FROM project WHERE project_id = $1;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
-- name: CreateProject :one
 | 
					-- name: CreateProject :one
 | 
				
			||||||
INSERT INTO project(owner, team_id, created_at, name) VALUES ($1, $2, $3, $4) RETURNING *;
 | 
					INSERT INTO project(owner, team_id, created_at, name) VALUES ($1, $2, $3, $4) RETURNING *;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-- name: UpdateProjectNameByID :one
 | 
				
			||||||
 | 
					UPDATE project SET name = $2 WHERE project_id = $1 RETURNING *;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,3 +4,15 @@ INSERT INTO task_label (task_id, project_label_id, assigned_date)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
-- name: GetTaskLabelsForTaskID :many
 | 
					-- name: GetTaskLabelsForTaskID :many
 | 
				
			||||||
SELECT * FROM task_label WHERE task_id = $1;
 | 
					SELECT * FROM task_label WHERE task_id = $1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-- name: GetTaskLabelByID :one
 | 
				
			||||||
 | 
					SELECT * FROM task_label WHERE task_label_id = $1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-- name: DeleteTaskLabelByID :exec
 | 
				
			||||||
 | 
					DELETE FROM task_label WHERE task_label_id = $1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-- name: GetTaskLabelForTaskByProjectLabelID :one
 | 
				
			||||||
 | 
					SELECT * FROM task_label WHERE task_id = $1 AND project_label_id = $2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-- name: DeleteTaskLabelForTaskByProjectLabelID :exec
 | 
				
			||||||
 | 
					DELETE FROM task_label WHERE project_label_id = $2 AND task_id = $1;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,8 +8,9 @@ import { useMeQuery } from 'shared/generated/graphql';
 | 
				
			|||||||
type GlobalTopNavbarProps = {
 | 
					type GlobalTopNavbarProps = {
 | 
				
			||||||
  name: string;
 | 
					  name: string;
 | 
				
			||||||
  projectMembers?: null | Array<TaskUser>;
 | 
					  projectMembers?: null | Array<TaskUser>;
 | 
				
			||||||
 | 
					  onSaveProjectName?: (projectName: string) => void;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
const GlobalTopNavbar: React.FC<GlobalTopNavbarProps> = ({ name, projectMembers }) => {
 | 
					const GlobalTopNavbar: React.FC<GlobalTopNavbarProps> = ({ name, projectMembers, onSaveProjectName }) => {
 | 
				
			||||||
  const { loading, data } = useMeQuery();
 | 
					  const { loading, data } = useMeQuery();
 | 
				
			||||||
  const history = useHistory();
 | 
					  const history = useHistory();
 | 
				
			||||||
  const { userID, setUserID } = useContext(UserIDContext);
 | 
					  const { userID, setUserID } = useContext(UserIDContext);
 | 
				
			||||||
@@ -52,6 +53,7 @@ const GlobalTopNavbar: React.FC<GlobalTopNavbarProps> = ({ name, projectMembers
 | 
				
			|||||||
        onNotificationClick={() => {}}
 | 
					        onNotificationClick={() => {}}
 | 
				
			||||||
        projectMembers={projectMembers}
 | 
					        projectMembers={projectMembers}
 | 
				
			||||||
        onProfileClick={onProfileClick}
 | 
					        onProfileClick={onProfileClick}
 | 
				
			||||||
 | 
					        onSaveProjectName={onSaveProjectName}
 | 
				
			||||||
      />
 | 
					      />
 | 
				
			||||||
      {menu.isOpen && (
 | 
					      {menu.isOpen && (
 | 
				
			||||||
        <DropdownMenu
 | 
					        <DropdownMenu
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -56,17 +56,6 @@ const Details: React.FC<DetailsProps> = ({
 | 
				
			|||||||
  if (!data) {
 | 
					  if (!data) {
 | 
				
			||||||
    return <div>loading</div>;
 | 
					    return <div>loading</div>;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  const taskMembers = data.findTask.assigned.map(assigned => {
 | 
					 | 
				
			||||||
    return {
 | 
					 | 
				
			||||||
      userID: assigned.id,
 | 
					 | 
				
			||||||
      displayName: `${assigned.firstName} ${assigned.lastName}`,
 | 
					 | 
				
			||||||
      profileIcon: {
 | 
					 | 
				
			||||||
        url: null,
 | 
					 | 
				
			||||||
        initials: assigned.profileIcon.initials ?? null,
 | 
					 | 
				
			||||||
        bgColor: assigned.profileIcon.bgColor ?? null,
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <>
 | 
					    <>
 | 
				
			||||||
      <Modal
 | 
					      <Modal
 | 
				
			||||||
@@ -77,24 +66,19 @@ const Details: React.FC<DetailsProps> = ({
 | 
				
			|||||||
        renderContent={() => {
 | 
					        renderContent={() => {
 | 
				
			||||||
          return (
 | 
					          return (
 | 
				
			||||||
            <TaskDetails
 | 
					            <TaskDetails
 | 
				
			||||||
              task={{
 | 
					              task={data.findTask}
 | 
				
			||||||
                ...data.findTask,
 | 
					 | 
				
			||||||
                taskID: data.findTask.id,
 | 
					 | 
				
			||||||
                taskGroup: { taskGroupID: data.findTask.taskGroup.id },
 | 
					 | 
				
			||||||
                members: taskMembers,
 | 
					 | 
				
			||||||
                description: data.findTask.description ?? '',
 | 
					 | 
				
			||||||
                labels: [],
 | 
					 | 
				
			||||||
              }}
 | 
					 | 
				
			||||||
              onTaskNameChange={onTaskNameChange}
 | 
					              onTaskNameChange={onTaskNameChange}
 | 
				
			||||||
              onTaskDescriptionChange={onTaskDescriptionChange}
 | 
					              onTaskDescriptionChange={onTaskDescriptionChange}
 | 
				
			||||||
              onDeleteTask={onDeleteTask}
 | 
					              onDeleteTask={onDeleteTask}
 | 
				
			||||||
              onCloseModal={() => history.push(projectURL)}
 | 
					              onCloseModal={() => history.push(projectURL)}
 | 
				
			||||||
              onMemberProfile={($targetRef, memberID) => {
 | 
					              onMemberProfile={($targetRef, memberID) => {
 | 
				
			||||||
 | 
					                const member = data.findTask.assigned.find(m => m.id === memberID);
 | 
				
			||||||
 | 
					                const profileIcon = member ? member.profileIcon : null;
 | 
				
			||||||
                showPopup(
 | 
					                showPopup(
 | 
				
			||||||
                  $targetRef,
 | 
					                  $targetRef,
 | 
				
			||||||
                  <Popup title={null} onClose={() => {}} tab={0}>
 | 
					                  <Popup title={null} onClose={() => {}} tab={0}>
 | 
				
			||||||
                    <MiniProfile
 | 
					                    <MiniProfile
 | 
				
			||||||
                      profileIcon={taskMembers[0].profileIcon}
 | 
					                      profileIcon={profileIcon}
 | 
				
			||||||
                      displayName="Jordan Knott"
 | 
					                      displayName="Jordan Knott"
 | 
				
			||||||
                      username="@jordanthedev"
 | 
					                      username="@jordanthedev"
 | 
				
			||||||
                      bio="None"
 | 
					                      bio="None"
 | 
				
			||||||
@@ -111,7 +95,7 @@ const Details: React.FC<DetailsProps> = ({
 | 
				
			|||||||
                  <Popup title="Members" tab={0} onClose={() => {}}>
 | 
					                  <Popup title="Members" tab={0} onClose={() => {}}>
 | 
				
			||||||
                    <MemberManager
 | 
					                    <MemberManager
 | 
				
			||||||
                      availableMembers={availableMembers}
 | 
					                      availableMembers={availableMembers}
 | 
				
			||||||
                      activeMembers={taskMembers}
 | 
					                      activeMembers={data.findTask.assigned}
 | 
				
			||||||
                      onMemberChange={(member, isActive) => {
 | 
					                      onMemberChange={(member, isActive) => {
 | 
				
			||||||
                        if (isActive) {
 | 
					                        if (isActive) {
 | 
				
			||||||
                          assignTask({ variables: { taskID: data.findTask.id, userID: userID ?? '' } });
 | 
					                          assignTask({ variables: { taskID: data.findTask.id, userID: userID ?? '' } });
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,7 +5,6 @@ import Lists from 'shared/components/Lists';
 | 
				
			|||||||
import { Board } from './Styles';
 | 
					import { Board } from './Styles';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type KanbanBoardProps = {
 | 
					type KanbanBoardProps = {
 | 
				
			||||||
  listsData: BoardState;
 | 
					 | 
				
			||||||
  onOpenListActionsPopup: ($targetRef: React.RefObject<HTMLElement>, taskGroupID: string) => void;
 | 
					  onOpenListActionsPopup: ($targetRef: React.RefObject<HTMLElement>, taskGroupID: string) => void;
 | 
				
			||||||
  onCardDrop: (task: Task) => void;
 | 
					  onCardDrop: (task: Task) => void;
 | 
				
			||||||
  onListDrop: (taskGroup: TaskGroup) => void;
 | 
					  onListDrop: (taskGroup: TaskGroup) => void;
 | 
				
			||||||
@@ -16,7 +15,6 @@ type KanbanBoardProps = {
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const KanbanBoard: React.FC<KanbanBoardProps> = ({
 | 
					const KanbanBoard: React.FC<KanbanBoardProps> = ({
 | 
				
			||||||
  listsData,
 | 
					 | 
				
			||||||
  onOpenListActionsPopup,
 | 
					  onOpenListActionsPopup,
 | 
				
			||||||
  onQuickEditorOpen,
 | 
					  onQuickEditorOpen,
 | 
				
			||||||
  onCardCreate,
 | 
					  onCardCreate,
 | 
				
			||||||
@@ -27,25 +25,7 @@ const KanbanBoard: React.FC<KanbanBoardProps> = ({
 | 
				
			|||||||
}) => {
 | 
					}) => {
 | 
				
			||||||
  const match = useRouteMatch();
 | 
					  const match = useRouteMatch();
 | 
				
			||||||
  const history = useHistory();
 | 
					  const history = useHistory();
 | 
				
			||||||
  return (
 | 
					  return <Board></Board>;
 | 
				
			||||||
    <Board>
 | 
					 | 
				
			||||||
      <Lists
 | 
					 | 
				
			||||||
        onCardClick={task => {
 | 
					 | 
				
			||||||
          history.push(`${match.url}/c/${task.taskID}`);
 | 
					 | 
				
			||||||
        }}
 | 
					 | 
				
			||||||
        onExtraMenuOpen={(taskGroupID, $targetRef) => {
 | 
					 | 
				
			||||||
          onOpenListActionsPopup($targetRef, taskGroupID);
 | 
					 | 
				
			||||||
        }}
 | 
					 | 
				
			||||||
        onQuickEditorOpen={onQuickEditorOpen}
 | 
					 | 
				
			||||||
        onCardCreate={onCardCreate}
 | 
					 | 
				
			||||||
        onCardDrop={onCardDrop}
 | 
					 | 
				
			||||||
        onListDrop={onListDrop}
 | 
					 | 
				
			||||||
        {...listsData}
 | 
					 | 
				
			||||||
        onCreateList={onCreateList}
 | 
					 | 
				
			||||||
        onCardMemberClick={onCardMemberClick}
 | 
					 | 
				
			||||||
      />
 | 
					 | 
				
			||||||
    </Board>
 | 
					 | 
				
			||||||
  );
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default KanbanBoard;
 | 
					export default KanbanBoard;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,11 +1,12 @@
 | 
				
			|||||||
import React, { useState, useRef } from 'react';
 | 
					import React, { useState, useRef } from 'react';
 | 
				
			||||||
import * as BoardStateUtils from 'shared/utils/boardState';
 | 
					 | 
				
			||||||
import GlobalTopNavbar from 'App/TopNavbar';
 | 
					import GlobalTopNavbar from 'App/TopNavbar';
 | 
				
			||||||
import styled from 'styled-components/macro';
 | 
					import styled from 'styled-components/macro';
 | 
				
			||||||
import { Bolt, ToggleOn, Tags } from 'shared/icons';
 | 
					import { Bolt, ToggleOn, Tags } from 'shared/icons';
 | 
				
			||||||
import { usePopup, Popup } from 'shared/components/PopupMenu';
 | 
					import { usePopup, Popup } from 'shared/components/PopupMenu';
 | 
				
			||||||
import { useParams, Route, useRouteMatch, useHistory, RouteComponentProps } from 'react-router-dom';
 | 
					import { useParams, Route, useRouteMatch, useHistory, RouteComponentProps } from 'react-router-dom';
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
 | 
					  useToggleTaskLabelMutation,
 | 
				
			||||||
 | 
					  useUpdateProjectNameMutation,
 | 
				
			||||||
  useFindProjectQuery,
 | 
					  useFindProjectQuery,
 | 
				
			||||||
  useUpdateTaskNameMutation,
 | 
					  useUpdateTaskNameMutation,
 | 
				
			||||||
  useUpdateProjectLabelMutation,
 | 
					  useUpdateProjectLabelMutation,
 | 
				
			||||||
@@ -29,12 +30,14 @@ import ListActions from 'shared/components/ListActions';
 | 
				
			|||||||
import MemberManager from 'shared/components/MemberManager';
 | 
					import MemberManager from 'shared/components/MemberManager';
 | 
				
			||||||
import { LabelsPopup } from 'shared/components/PopupMenu/PopupMenu.stories';
 | 
					import { LabelsPopup } from 'shared/components/PopupMenu/PopupMenu.stories';
 | 
				
			||||||
import KanbanBoard from 'Projects/Project/KanbanBoard';
 | 
					import KanbanBoard from 'Projects/Project/KanbanBoard';
 | 
				
			||||||
 | 
					import SimpleLists from 'shared/components/Lists';
 | 
				
			||||||
import { mixin } from 'shared/utils/styles';
 | 
					import { mixin } from 'shared/utils/styles';
 | 
				
			||||||
import LabelManager from 'shared/components/PopupMenu/LabelManager';
 | 
					import LabelManager from 'shared/components/PopupMenu/LabelManager';
 | 
				
			||||||
import LabelEditor from 'shared/components/PopupMenu/LabelEditor';
 | 
					import LabelEditor from 'shared/components/PopupMenu/LabelEditor';
 | 
				
			||||||
import produce from 'immer';
 | 
					import produce from 'immer';
 | 
				
			||||||
import MiniProfile from 'shared/components/MiniProfile';
 | 
					import MiniProfile from 'shared/components/MiniProfile';
 | 
				
			||||||
import Details from './Details';
 | 
					import Details from './Details';
 | 
				
			||||||
 | 
					import { useApolloClient } from '@apollo/react-hooks';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const getCacheData = (client: any, projectID: string) => {
 | 
					const getCacheData = (client: any, projectID: string) => {
 | 
				
			||||||
  const cacheData: any = client.readQuery({
 | 
					  const cacheData: any = client.readQuery({
 | 
				
			||||||
@@ -85,12 +88,20 @@ const ProjectMembers = styled.div`
 | 
				
			|||||||
`;
 | 
					`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type LabelManagerEditorProps = {
 | 
					type LabelManagerEditorProps = {
 | 
				
			||||||
  labels: React.RefObject<Array<Label>>;
 | 
					  labels: React.RefObject<Array<ProjectLabel>>;
 | 
				
			||||||
 | 
					  taskLabels: null | React.RefObject<Array<TaskLabel>>;
 | 
				
			||||||
  projectID: string;
 | 
					  projectID: string;
 | 
				
			||||||
  labelColors: Array<LabelColor>;
 | 
					  labelColors: Array<LabelColor>;
 | 
				
			||||||
 | 
					  onLabelToggle?: (labelId: string) => void;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const LabelManagerEditor: React.FC<LabelManagerEditorProps> = ({ labels: labelsRef, projectID, labelColors }) => {
 | 
					const LabelManagerEditor: React.FC<LabelManagerEditorProps> = ({
 | 
				
			||||||
 | 
					  labels: labelsRef,
 | 
				
			||||||
 | 
					  projectID,
 | 
				
			||||||
 | 
					  labelColors,
 | 
				
			||||||
 | 
					  onLabelToggle,
 | 
				
			||||||
 | 
					  taskLabels: taskLabelsRef,
 | 
				
			||||||
 | 
					}) => {
 | 
				
			||||||
  const [currentLabel, setCurrentLabel] = useState('');
 | 
					  const [currentLabel, setCurrentLabel] = useState('');
 | 
				
			||||||
  const [createProjectLabel] = useCreateProjectLabelMutation({
 | 
					  const [createProjectLabel] = useCreateProjectLabelMutation({
 | 
				
			||||||
    update: (client, newLabelData) => {
 | 
					    update: (client, newLabelData) => {
 | 
				
			||||||
@@ -116,12 +127,16 @@ const LabelManagerEditor: React.FC<LabelManagerEditorProps> = ({ labels: labelsR
 | 
				
			|||||||
    },
 | 
					    },
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
  const labels = labelsRef.current ? labelsRef.current : [];
 | 
					  const labels = labelsRef.current ? labelsRef.current : [];
 | 
				
			||||||
 | 
					  const taskLabels = taskLabelsRef && taskLabelsRef.current ? taskLabelsRef.current : [];
 | 
				
			||||||
 | 
					  const [currentTaskLabels, setCurrentTaskLabels] = useState(taskLabels);
 | 
				
			||||||
 | 
					  console.log(taskLabels);
 | 
				
			||||||
  const { setTab } = usePopup();
 | 
					  const { setTab } = usePopup();
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <>
 | 
					    <>
 | 
				
			||||||
      <Popup title="Labels" tab={0} onClose={() => {}}>
 | 
					      <Popup title="Labels" tab={0} onClose={() => {}}>
 | 
				
			||||||
        <LabelManager
 | 
					        <LabelManager
 | 
				
			||||||
          labels={labels}
 | 
					          labels={labels}
 | 
				
			||||||
 | 
					          taskLabels={currentTaskLabels}
 | 
				
			||||||
          onLabelCreate={() => {
 | 
					          onLabelCreate={() => {
 | 
				
			||||||
            setTab(2);
 | 
					            setTab(2);
 | 
				
			||||||
          }}
 | 
					          }}
 | 
				
			||||||
@@ -130,18 +145,34 @@ const LabelManagerEditor: React.FC<LabelManagerEditorProps> = ({ labels: labelsR
 | 
				
			|||||||
            setTab(1);
 | 
					            setTab(1);
 | 
				
			||||||
          }}
 | 
					          }}
 | 
				
			||||||
          onLabelToggle={labelId => {
 | 
					          onLabelToggle={labelId => {
 | 
				
			||||||
 | 
					            if (onLabelToggle) {
 | 
				
			||||||
 | 
					              if (currentTaskLabels.find(t => t.projectLabel.id === labelId)) {
 | 
				
			||||||
 | 
					                setCurrentTaskLabels(currentTaskLabels.filter(t => t.projectLabel.id !== labelId));
 | 
				
			||||||
 | 
					              } else {
 | 
				
			||||||
 | 
					                const newProjectLabel = labels.find(l => l.id === labelId);
 | 
				
			||||||
 | 
					                if (newProjectLabel) {
 | 
				
			||||||
 | 
					                  setCurrentTaskLabels([
 | 
				
			||||||
 | 
					                    ...currentTaskLabels,
 | 
				
			||||||
 | 
					                    { id: '', assignedDate: '', projectLabel: { ...newProjectLabel } },
 | 
				
			||||||
 | 
					                  ]);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					              setCurrentLabel(labelId);
 | 
				
			||||||
 | 
					              onLabelToggle(labelId);
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
              setCurrentLabel(labelId);
 | 
					              setCurrentLabel(labelId);
 | 
				
			||||||
              setTab(1);
 | 
					              setTab(1);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
          }}
 | 
					          }}
 | 
				
			||||||
        />
 | 
					        />
 | 
				
			||||||
      </Popup>
 | 
					      </Popup>
 | 
				
			||||||
      <Popup onClose={() => {}} title="Edit label" tab={1}>
 | 
					      <Popup onClose={() => {}} title="Edit label" tab={1}>
 | 
				
			||||||
        <LabelEditor
 | 
					        <LabelEditor
 | 
				
			||||||
          labelColors={labelColors}
 | 
					          labelColors={labelColors}
 | 
				
			||||||
          label={labels.find(label => label.labelId === currentLabel) ?? null}
 | 
					          label={labels.find(label => label.id === currentLabel) ?? null}
 | 
				
			||||||
          onLabelEdit={(projectLabelID, name, color) => {
 | 
					          onLabelEdit={(projectLabelID, name, color) => {
 | 
				
			||||||
            if (projectLabelID) {
 | 
					            if (projectLabelID) {
 | 
				
			||||||
              updateProjectLabel({ variables: { projectLabelID, labelColorID: color.id, name } });
 | 
					              updateProjectLabel({ variables: { projectLabelID, labelColorID: color.id, name: name ?? '' } });
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            setTab(0);
 | 
					            setTab(0);
 | 
				
			||||||
          }}
 | 
					          }}
 | 
				
			||||||
@@ -156,7 +187,7 @@ const LabelManagerEditor: React.FC<LabelManagerEditorProps> = ({ labels: labelsR
 | 
				
			|||||||
          labelColors={labelColors}
 | 
					          labelColors={labelColors}
 | 
				
			||||||
          label={null}
 | 
					          label={null}
 | 
				
			||||||
          onLabelEdit={(_labelId, name, color) => {
 | 
					          onLabelEdit={(_labelId, name, color) => {
 | 
				
			||||||
            createProjectLabel({ variables: { projectID, labelColorID: color.id, name } });
 | 
					            createProjectLabel({ variables: { projectID, labelColorID: color.id, name: name ?? '' } });
 | 
				
			||||||
            setTab(0);
 | 
					            setTab(0);
 | 
				
			||||||
          }}
 | 
					          }}
 | 
				
			||||||
        />
 | 
					        />
 | 
				
			||||||
@@ -169,10 +200,7 @@ interface ProjectParams {
 | 
				
			|||||||
  projectID: string;
 | 
					  projectID: string;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const initialState: BoardState = { tasks: {}, columns: {} };
 | 
					 | 
				
			||||||
const initialPopupState = { left: 0, top: 0, isOpen: false, taskGroupID: '' };
 | 
					 | 
				
			||||||
const initialQuickCardEditorState: QuickCardEditorState = { isOpen: false, top: 0, left: 0 };
 | 
					const initialQuickCardEditorState: QuickCardEditorState = { isOpen: false, top: 0, left: 0 };
 | 
				
			||||||
const initialTaskDetailsState = { isOpen: false, taskID: '' };
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
const ProjectBar = styled.div`
 | 
					const ProjectBar = styled.div`
 | 
				
			||||||
  display: flex;
 | 
					  display: flex;
 | 
				
			||||||
@@ -209,18 +237,16 @@ const ProjectActionText = styled.span`
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
const Project = () => {
 | 
					const Project = () => {
 | 
				
			||||||
  const { projectID } = useParams<ProjectParams>();
 | 
					  const { projectID } = useParams<ProjectParams>();
 | 
				
			||||||
 | 
					  const history = useHistory();
 | 
				
			||||||
  const match = useRouteMatch();
 | 
					  const match = useRouteMatch();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const [updateTaskDescription] = useUpdateTaskDescriptionMutation();
 | 
					  const [updateTaskDescription] = useUpdateTaskDescriptionMutation();
 | 
				
			||||||
  const [listsData, setListsData] = useState(initialState);
 | 
					 | 
				
			||||||
  const [quickCardEditor, setQuickCardEditor] = useState(initialQuickCardEditorState);
 | 
					  const [quickCardEditor, setQuickCardEditor] = useState(initialQuickCardEditorState);
 | 
				
			||||||
  const [updateTaskLocation] = useUpdateTaskLocationMutation();
 | 
					  const [updateTaskLocation] = useUpdateTaskLocationMutation();
 | 
				
			||||||
  const [updateTaskGroupLocation] = useUpdateTaskGroupLocationMutation();
 | 
					  const [updateTaskGroupLocation] = useUpdateTaskGroupLocationMutation({});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const [deleteTaskGroup] = useDeleteTaskGroupMutation({
 | 
					  const [deleteTaskGroup] = useDeleteTaskGroupMutation({
 | 
				
			||||||
    onCompleted: deletedTaskGroupData => {
 | 
					    onCompleted: deletedTaskGroupData => {},
 | 
				
			||||||
      setListsData(BoardStateUtils.deleteTaskGroup(listsData, deletedTaskGroupData.deleteTaskGroup.taskGroup.id));
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    update: (client, deletedTaskGroupData) => {
 | 
					    update: (client, deletedTaskGroupData) => {
 | 
				
			||||||
      const cacheData = getCacheData(client, projectID);
 | 
					      const cacheData = getCacheData(client, projectID);
 | 
				
			||||||
      const newData = {
 | 
					      const newData = {
 | 
				
			||||||
@@ -235,14 +261,7 @@ const Project = () => {
 | 
				
			|||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const [createTaskGroup] = useCreateTaskGroupMutation({
 | 
					  const [createTaskGroup] = useCreateTaskGroupMutation({
 | 
				
			||||||
    onCompleted: newTaskGroupData => {
 | 
					    onCompleted: newTaskGroupData => {},
 | 
				
			||||||
      const newTaskGroup = {
 | 
					 | 
				
			||||||
        taskGroupID: newTaskGroupData.createTaskGroup.id,
 | 
					 | 
				
			||||||
        tasks: [],
 | 
					 | 
				
			||||||
        ...newTaskGroupData.createTaskGroup,
 | 
					 | 
				
			||||||
      };
 | 
					 | 
				
			||||||
      setListsData(BoardStateUtils.addTaskGroup(listsData, newTaskGroup));
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    update: (client, newTaskGroupData) => {
 | 
					    update: (client, newTaskGroupData) => {
 | 
				
			||||||
      const cacheData = getCacheData(client, projectID);
 | 
					      const cacheData = getCacheData(client, projectID);
 | 
				
			||||||
      const newData = {
 | 
					      const newData = {
 | 
				
			||||||
@@ -255,15 +274,7 @@ const Project = () => {
 | 
				
			|||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const [createTask] = useCreateTaskMutation({
 | 
					  const [createTask] = useCreateTaskMutation({
 | 
				
			||||||
    onCompleted: newTaskData => {
 | 
					    onCompleted: newTaskData => {},
 | 
				
			||||||
      const newTask = {
 | 
					 | 
				
			||||||
        ...newTaskData.createTask,
 | 
					 | 
				
			||||||
        taskID: newTaskData.createTask.id,
 | 
					 | 
				
			||||||
        taskGroup: { taskGroupID: newTaskData.createTask.taskGroup.id },
 | 
					 | 
				
			||||||
        labels: [],
 | 
					 | 
				
			||||||
      };
 | 
					 | 
				
			||||||
      setListsData(BoardStateUtils.addTask(listsData, newTask));
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    update: (client, newTaskData) => {
 | 
					    update: (client, newTaskData) => {
 | 
				
			||||||
      const cacheData = getCacheData(client, projectID);
 | 
					      const cacheData = getCacheData(client, projectID);
 | 
				
			||||||
      const newTaskGroups = produce(cacheData.findProject.taskGroups, (draftState: any) => {
 | 
					      const newTaskGroups = produce(cacheData.findProject.taskGroups, (draftState: any) => {
 | 
				
			||||||
@@ -284,26 +295,27 @@ const Project = () => {
 | 
				
			|||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const [deleteTask] = useDeleteTaskMutation({
 | 
					  const [deleteTask] = useDeleteTaskMutation({
 | 
				
			||||||
    onCompleted: deletedTask => {
 | 
					    onCompleted: deletedTask => {},
 | 
				
			||||||
      setListsData(BoardStateUtils.deleteTask(listsData, deletedTask.deleteTask.taskID));
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const [updateTaskName] = useUpdateTaskNameMutation({
 | 
					  const [updateTaskName] = useUpdateTaskNameMutation({
 | 
				
			||||||
    onCompleted: newTaskData => {
 | 
					    onCompleted: newTaskData => {},
 | 
				
			||||||
      setListsData(
 | 
					  });
 | 
				
			||||||
        BoardStateUtils.updateTaskName(listsData, newTaskData.updateTaskName.id, newTaskData.updateTaskName.name),
 | 
					  const [toggleTaskLabel] = useToggleTaskLabelMutation({
 | 
				
			||||||
      );
 | 
					    onCompleted: newTaskLabel => {
 | 
				
			||||||
 | 
					      taskLabelsRef.current = newTaskLabel.toggleTaskLabel.task.labels;
 | 
				
			||||||
 | 
					      console.log(taskLabelsRef.current);
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
  const { loading, data, refetch } = useFindProjectQuery({
 | 
					  const { loading, data, refetch } = useFindProjectQuery({
 | 
				
			||||||
    variables: { projectId: projectID },
 | 
					    variables: { projectId: projectID },
 | 
				
			||||||
 | 
					    onCompleted: newData => {},
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const onCardCreate = (taskGroupID: string, name: string) => {
 | 
					  const onCardCreate = (taskGroupID: string, name: string) => {
 | 
				
			||||||
    const taskGroupTasks = Object.values(listsData.tasks).filter(
 | 
					    if (data) {
 | 
				
			||||||
      (task: Task) => task.taskGroup.taskGroupID === taskGroupID,
 | 
					      const taskGroupTasks = data.findProject.taskGroups.filter(t => t.id === taskGroupID);
 | 
				
			||||||
    );
 | 
					      if (taskGroupTasks) {
 | 
				
			||||||
        let position = 65535;
 | 
					        let position = 65535;
 | 
				
			||||||
        if (taskGroupTasks.length !== 0) {
 | 
					        if (taskGroupTasks.length !== 0) {
 | 
				
			||||||
          const [lastTask] = taskGroupTasks.sort((a: any, b: any) => a.position - b.position).slice(-1);
 | 
					          const [lastTask] = taskGroupTasks.sort((a: any, b: any) => a.position - b.position).slice(-1);
 | 
				
			||||||
@@ -311,131 +323,116 @@ const Project = () => {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        createTask({ variables: { taskGroupID, name, position } });
 | 
					        createTask({ variables: { taskGroupID, name, position } });
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const onCreateTask = (taskGroupID: string, name: string) => {
 | 
				
			||||||
 | 
					    if (data) {
 | 
				
			||||||
 | 
					      const taskGroup = data.findProject.taskGroups.find(t => t.id === taskGroupID);
 | 
				
			||||||
 | 
					      console.log(`taskGroup ${taskGroup}`);
 | 
				
			||||||
 | 
					      if (taskGroup) {
 | 
				
			||||||
 | 
					        let position = 65535;
 | 
				
			||||||
 | 
					        if (taskGroup.tasks.length !== 0) {
 | 
				
			||||||
 | 
					          const [lastTask] = taskGroup.tasks.sort((a: any, b: any) => a.position - b.position).slice(-1);
 | 
				
			||||||
 | 
					          position = Math.ceil(lastTask.position) * 2 + 1;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        console.log(`position ${position}`);
 | 
				
			||||||
 | 
					        createTask({ variables: { taskGroupID, name, position } });
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const onCardDrop = (droppedTask: Task) => {
 | 
					  const onCardDrop = (droppedTask: Task) => {
 | 
				
			||||||
    updateTaskLocation({
 | 
					    updateTaskLocation({
 | 
				
			||||||
      variables: {
 | 
					      variables: {
 | 
				
			||||||
        taskID: droppedTask.taskID,
 | 
					        taskID: droppedTask.id,
 | 
				
			||||||
        taskGroupID: droppedTask.taskGroup.taskGroupID,
 | 
					        taskGroupID: droppedTask.taskGroup.id,
 | 
				
			||||||
        position: droppedTask.position,
 | 
					        position: droppedTask.position,
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
      optimisticResponse: {
 | 
					      optimisticResponse: {
 | 
				
			||||||
        updateTaskLocation: {
 | 
					        updateTaskLocation: {
 | 
				
			||||||
          name: droppedTask.name,
 | 
					          name: droppedTask.name,
 | 
				
			||||||
          id: droppedTask.taskID,
 | 
					          id: droppedTask.id,
 | 
				
			||||||
          position: droppedTask.position,
 | 
					          position: droppedTask.position,
 | 
				
			||||||
          createdAt: '',
 | 
					          createdAt: '',
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    setListsData(BoardStateUtils.updateTask(listsData, droppedTask));
 | 
					 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
  const onListDrop = (droppedColumn: TaskGroup) => {
 | 
					  const onListDrop = (droppedColumn: TaskGroup) => {
 | 
				
			||||||
    console.log(`list drop ${droppedColumn.taskGroupID}`);
 | 
					    console.log(`list drop ${droppedColumn.id}`);
 | 
				
			||||||
 | 
					    const cacheData = getCacheData(client, projectID);
 | 
				
			||||||
 | 
					    const newData = produce(cacheData, (draftState: any) => {
 | 
				
			||||||
 | 
					      const taskGroupIdx = cacheData.findProject.taskGroups.findIndex((t: any) => t.id === droppedColumn.id);
 | 
				
			||||||
 | 
					      cacheData.findProject.taskGroups[taskGroupIdx].position = droppedColumn.position;
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    writeCacheData(client, projectID, cacheData, newData);
 | 
				
			||||||
    updateTaskGroupLocation({
 | 
					    updateTaskGroupLocation({
 | 
				
			||||||
      variables: { taskGroupID: droppedColumn.taskGroupID, position: droppedColumn.position },
 | 
					      variables: { taskGroupID: droppedColumn.id, position: droppedColumn.position },
 | 
				
			||||||
      optimisticResponse: {
 | 
					      optimisticResponse: {
 | 
				
			||||||
        updateTaskGroupLocation: {
 | 
					        updateTaskGroupLocation: {
 | 
				
			||||||
          id: droppedColumn.taskGroupID,
 | 
					          id: droppedColumn.id,
 | 
				
			||||||
          position: droppedColumn.position,
 | 
					          position: droppedColumn.position,
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    // setListsData(BoardStateUtils.updateTaskGroup(listsData, droppedColumn));
 | 
					 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const onCreateList = (listName: string) => {
 | 
					  const onCreateList = (listName: string) => {
 | 
				
			||||||
    const [lastColumn] = Object.values(listsData.columns)
 | 
					    if (data) {
 | 
				
			||||||
      .sort((a, b) => a.position - b.position)
 | 
					      const [lastColumn] = data.findProject.taskGroups.sort((a, b) => a.position - b.position).slice(-1);
 | 
				
			||||||
      .slice(-1);
 | 
					 | 
				
			||||||
      let position = 65535;
 | 
					      let position = 65535;
 | 
				
			||||||
      if (lastColumn) {
 | 
					      if (lastColumn) {
 | 
				
			||||||
        position = lastColumn.position * 2 + 1;
 | 
					        position = lastColumn.position * 2 + 1;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      createTaskGroup({ variables: { projectID, name: listName, position } });
 | 
					      createTaskGroup({ variables: { projectID, name: listName, position } });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const [assignTask] = useAssignTaskMutation();
 | 
					  const [assignTask] = useAssignTaskMutation();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const [updateProjectName] = useUpdateProjectNameMutation();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const client = useApolloClient();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const { showPopup, hidePopup } = usePopup();
 | 
					  const { showPopup, hidePopup } = usePopup();
 | 
				
			||||||
  const $labelsRef = useRef<HTMLDivElement>(null);
 | 
					  const $labelsRef = useRef<HTMLDivElement>(null);
 | 
				
			||||||
  const labelsRef = useRef<Array<Label>>([]);
 | 
					  const labelsRef = useRef<Array<ProjectLabel>>([]);
 | 
				
			||||||
 | 
					  const taskLabelsRef = useRef<Array<TaskLabel>>([]);
 | 
				
			||||||
  if (loading) {
 | 
					  if (loading) {
 | 
				
			||||||
    return (
 | 
					    return (
 | 
				
			||||||
      <>
 | 
					      <>
 | 
				
			||||||
        <GlobalTopNavbar name="Project" />
 | 
					        <GlobalTopNavbar onSaveProjectName={projectName => {}} name="Loading..." />
 | 
				
			||||||
        <Title>Error Loading</Title>
 | 
					 | 
				
			||||||
      </>
 | 
					      </>
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  if (data) {
 | 
					  if (data) {
 | 
				
			||||||
    console.log(data);
 | 
					 | 
				
			||||||
    const currentListsData: BoardState = { tasks: {}, columns: {} };
 | 
					 | 
				
			||||||
    data.findProject.taskGroups.forEach(taskGroup => {
 | 
					 | 
				
			||||||
      currentListsData.columns[taskGroup.id] = {
 | 
					 | 
				
			||||||
        taskGroupID: taskGroup.id,
 | 
					 | 
				
			||||||
        name: taskGroup.name,
 | 
					 | 
				
			||||||
        position: taskGroup.position,
 | 
					 | 
				
			||||||
        tasks: [],
 | 
					 | 
				
			||||||
      };
 | 
					 | 
				
			||||||
      taskGroup.tasks.forEach(task => {
 | 
					 | 
				
			||||||
        const taskMembers = task.assigned.map(assigned => {
 | 
					 | 
				
			||||||
          return {
 | 
					 | 
				
			||||||
            userID: assigned.id,
 | 
					 | 
				
			||||||
            displayName: `${assigned.firstName} ${assigned.lastName}`,
 | 
					 | 
				
			||||||
            profileIcon: {
 | 
					 | 
				
			||||||
              url: null,
 | 
					 | 
				
			||||||
              initials: assigned.profileIcon.initials ?? '',
 | 
					 | 
				
			||||||
              bgColor: assigned.profileIcon.bgColor ?? '#7367F0',
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
          };
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
        currentListsData.tasks[task.id] = {
 | 
					 | 
				
			||||||
          taskID: task.id,
 | 
					 | 
				
			||||||
          taskGroup: {
 | 
					 | 
				
			||||||
            taskGroupID: taskGroup.id,
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
          name: task.name,
 | 
					 | 
				
			||||||
          labels: [],
 | 
					 | 
				
			||||||
          position: task.position,
 | 
					 | 
				
			||||||
          description: task.description ?? undefined,
 | 
					 | 
				
			||||||
          members: taskMembers,
 | 
					 | 
				
			||||||
        };
 | 
					 | 
				
			||||||
      });
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
    const availableMembers = data.findProject.members.map(member => {
 | 
					 | 
				
			||||||
      return {
 | 
					 | 
				
			||||||
        displayName: `${member.firstName} ${member.lastName}`,
 | 
					 | 
				
			||||||
        profileIcon: {
 | 
					 | 
				
			||||||
          url: null,
 | 
					 | 
				
			||||||
          initials: member.profileIcon.initials ?? null,
 | 
					 | 
				
			||||||
          bgColor: member.profileIcon.bgColor ?? null,
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        userID: member.id,
 | 
					 | 
				
			||||||
      };
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
    const onQuickEditorOpen = (e: ContextMenuEvent) => {
 | 
					    const onQuickEditorOpen = (e: ContextMenuEvent) => {
 | 
				
			||||||
      const currentTask = Object.values(currentListsData.tasks).find(task => task.taskID === e.taskID);
 | 
					      const taskGroup = data.findProject.taskGroups.find(t => t.id === e.taskGroupID);
 | 
				
			||||||
 | 
					      const currentTask = taskGroup ? taskGroup.tasks.find(t => t.id === e.taskID) : null;
 | 
				
			||||||
 | 
					      if (currentTask) {
 | 
				
			||||||
        setQuickCardEditor({
 | 
					        setQuickCardEditor({
 | 
				
			||||||
          top: e.top,
 | 
					          top: e.top,
 | 
				
			||||||
          left: e.left,
 | 
					          left: e.left,
 | 
				
			||||||
          isOpen: true,
 | 
					          isOpen: true,
 | 
				
			||||||
          task: currentTask,
 | 
					          task: currentTask,
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    labelsRef.current = data.findProject.labels.map(label => {
 | 
					    labelsRef.current = data.findProject.labels;
 | 
				
			||||||
      return {
 | 
					
 | 
				
			||||||
        labelId: label.id,
 | 
					 | 
				
			||||||
        name: label.name ?? '',
 | 
					 | 
				
			||||||
        labelColor: label.labelColor,
 | 
					 | 
				
			||||||
        active: false,
 | 
					 | 
				
			||||||
      };
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
    return (
 | 
					    return (
 | 
				
			||||||
      <>
 | 
					      <>
 | 
				
			||||||
        <GlobalTopNavbar projectMembers={availableMembers} name={data.findProject.name} />
 | 
					        <GlobalTopNavbar
 | 
				
			||||||
 | 
					          onSaveProjectName={projectName => {
 | 
				
			||||||
 | 
					            updateProjectName({ variables: { projectID, name: projectName } });
 | 
				
			||||||
 | 
					          }}
 | 
				
			||||||
 | 
					          projectMembers={data.findProject.members}
 | 
				
			||||||
 | 
					          name={data.findProject.name}
 | 
				
			||||||
 | 
					        />
 | 
				
			||||||
        <ProjectBar>
 | 
					        <ProjectBar>
 | 
				
			||||||
          <ProjectActions>
 | 
					          <ProjectActions>
 | 
				
			||||||
            <ProjectAction
 | 
					            <ProjectAction
 | 
				
			||||||
@@ -443,7 +440,12 @@ const Project = () => {
 | 
				
			|||||||
              onClick={() => {
 | 
					              onClick={() => {
 | 
				
			||||||
                showPopup(
 | 
					                showPopup(
 | 
				
			||||||
                  $labelsRef,
 | 
					                  $labelsRef,
 | 
				
			||||||
                  <LabelManagerEditor labelColors={data.labelColors} labels={labelsRef} projectID={projectID} />,
 | 
					                  <LabelManagerEditor
 | 
				
			||||||
 | 
					                    taskLabels={null}
 | 
				
			||||||
 | 
					                    labelColors={data.labelColors}
 | 
				
			||||||
 | 
					                    labels={labelsRef}
 | 
				
			||||||
 | 
					                    projectID={projectID}
 | 
				
			||||||
 | 
					                  />,
 | 
				
			||||||
                );
 | 
					                );
 | 
				
			||||||
              }}
 | 
					              }}
 | 
				
			||||||
            >
 | 
					            >
 | 
				
			||||||
@@ -460,18 +462,53 @@ const Project = () => {
 | 
				
			|||||||
            </ProjectAction>
 | 
					            </ProjectAction>
 | 
				
			||||||
          </ProjectActions>
 | 
					          </ProjectActions>
 | 
				
			||||||
        </ProjectBar>
 | 
					        </ProjectBar>
 | 
				
			||||||
        <KanbanBoard
 | 
					        <SimpleLists
 | 
				
			||||||
          listsData={currentListsData}
 | 
					          onTaskClick={task => {
 | 
				
			||||||
          onCardDrop={onCardDrop}
 | 
					            history.push(`${match.url}/c/${task.id}`);
 | 
				
			||||||
          onListDrop={onListDrop}
 | 
					          }}
 | 
				
			||||||
          onCardCreate={onCardCreate}
 | 
					          onTaskDrop={droppedTask => {
 | 
				
			||||||
          onCreateList={onCreateList}
 | 
					            updateTaskLocation({
 | 
				
			||||||
 | 
					              variables: {
 | 
				
			||||||
 | 
					                taskID: droppedTask.id,
 | 
				
			||||||
 | 
					                taskGroupID: droppedTask.taskGroup.id,
 | 
				
			||||||
 | 
					                position: droppedTask.position,
 | 
				
			||||||
 | 
					              },
 | 
				
			||||||
 | 
					              optimisticResponse: {
 | 
				
			||||||
 | 
					                __typename: 'Mutation',
 | 
				
			||||||
 | 
					                updateTaskLocation: {
 | 
				
			||||||
 | 
					                  name: droppedTask.name,
 | 
				
			||||||
 | 
					                  id: droppedTask.id,
 | 
				
			||||||
 | 
					                  position: droppedTask.position,
 | 
				
			||||||
 | 
					                  createdAt: '',
 | 
				
			||||||
 | 
					                  __typename: 'Task',
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					              },
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					          }}
 | 
				
			||||||
 | 
					          onTaskGroupDrop={droppedTaskGroup => {
 | 
				
			||||||
 | 
					            updateTaskGroupLocation({
 | 
				
			||||||
 | 
					              variables: { taskGroupID: droppedTaskGroup.id, position: droppedTaskGroup.position },
 | 
				
			||||||
 | 
					              optimisticResponse: {
 | 
				
			||||||
 | 
					                __typename: 'Mutation',
 | 
				
			||||||
 | 
					                updateTaskGroupLocation: {
 | 
				
			||||||
 | 
					                  id: droppedTaskGroup.id,
 | 
				
			||||||
 | 
					                  position: droppedTaskGroup.position,
 | 
				
			||||||
 | 
					                  __typename: 'TaskGroup',
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					              },
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					          }}
 | 
				
			||||||
 | 
					          taskGroups={data.findProject.taskGroups}
 | 
				
			||||||
 | 
					          onCreateTask={onCreateTask}
 | 
				
			||||||
 | 
					          onCreateTaskGroup={onCreateList}
 | 
				
			||||||
          onCardMemberClick={($targetRef, taskID, memberID) => {
 | 
					          onCardMemberClick={($targetRef, taskID, memberID) => {
 | 
				
			||||||
 | 
					            const member = data.findProject.members.find(m => m.id === memberID);
 | 
				
			||||||
 | 
					            const profileIcon = member ? member.profileIcon : null;
 | 
				
			||||||
            showPopup(
 | 
					            showPopup(
 | 
				
			||||||
              $targetRef,
 | 
					              $targetRef,
 | 
				
			||||||
              <Popup title={null} onClose={() => {}} tab={0}>
 | 
					              <Popup title={null} onClose={() => {}} tab={0}>
 | 
				
			||||||
                <MiniProfile
 | 
					                <MiniProfile
 | 
				
			||||||
                  profileIcon={availableMembers[0].profileIcon}
 | 
					                  profileIcon={profileIcon}
 | 
				
			||||||
                  displayName="Jordan Knott"
 | 
					                  displayName="Jordan Knott"
 | 
				
			||||||
                  username="@jordanthedev"
 | 
					                  username="@jordanthedev"
 | 
				
			||||||
                  bio="None"
 | 
					                  bio="None"
 | 
				
			||||||
@@ -483,7 +520,7 @@ const Project = () => {
 | 
				
			|||||||
            );
 | 
					            );
 | 
				
			||||||
          }}
 | 
					          }}
 | 
				
			||||||
          onQuickEditorOpen={onQuickEditorOpen}
 | 
					          onQuickEditorOpen={onQuickEditorOpen}
 | 
				
			||||||
          onOpenListActionsPopup={($targetRef, taskGroupID) => {
 | 
					          onExtraMenuOpen={(taskGroupID: string, $targetRef: any) => {
 | 
				
			||||||
            showPopup(
 | 
					            showPopup(
 | 
				
			||||||
              $targetRef,
 | 
					              $targetRef,
 | 
				
			||||||
              <Popup title="List actions" tab={0} onClose={() => {}}>
 | 
					              <Popup title="List actions" tab={0} onClose={() => {}}>
 | 
				
			||||||
@@ -501,8 +538,8 @@ const Project = () => {
 | 
				
			|||||||
        {quickCardEditor.isOpen && (
 | 
					        {quickCardEditor.isOpen && (
 | 
				
			||||||
          <QuickCardEditor
 | 
					          <QuickCardEditor
 | 
				
			||||||
            isOpen
 | 
					            isOpen
 | 
				
			||||||
            taskID={quickCardEditor.task ? quickCardEditor.task.taskID : ''}
 | 
					            taskID={quickCardEditor.task ? quickCardEditor.task.id : ''}
 | 
				
			||||||
            taskGroupID={quickCardEditor.task ? quickCardEditor.task.taskGroup.taskGroupID : ''}
 | 
					            taskGroupID={quickCardEditor.task ? quickCardEditor.task.taskGroup.id : ''}
 | 
				
			||||||
            cardTitle={quickCardEditor.task ? quickCardEditor.task.name : ''}
 | 
					            cardTitle={quickCardEditor.task ? quickCardEditor.task.name : ''}
 | 
				
			||||||
            onCloseEditor={() => setQuickCardEditor(initialQuickCardEditorState)}
 | 
					            onCloseEditor={() => setQuickCardEditor(initialQuickCardEditorState)}
 | 
				
			||||||
            onEditCard={(_listId: string, cardId: string, cardName: string) => {
 | 
					            onEditCard={(_listId: string, cardId: string, cardName: string) => {
 | 
				
			||||||
@@ -537,19 +574,33 @@ const Project = () => {
 | 
				
			|||||||
          render={(routeProps: RouteComponentProps<TaskRouteProps>) => (
 | 
					          render={(routeProps: RouteComponentProps<TaskRouteProps>) => (
 | 
				
			||||||
            <Details
 | 
					            <Details
 | 
				
			||||||
              refreshCache={() => {}}
 | 
					              refreshCache={() => {}}
 | 
				
			||||||
              availableMembers={availableMembers}
 | 
					              availableMembers={data.findProject.members}
 | 
				
			||||||
              projectURL={match.url}
 | 
					              projectURL={match.url}
 | 
				
			||||||
              taskID={routeProps.match.params.taskID}
 | 
					              taskID={routeProps.match.params.taskID}
 | 
				
			||||||
              onTaskNameChange={(updatedTask, newName) => {
 | 
					              onTaskNameChange={(updatedTask, newName) => {
 | 
				
			||||||
                updateTaskName({ variables: { taskID: updatedTask.taskID, name: newName } });
 | 
					                updateTaskName({ variables: { taskID: updatedTask.id, name: newName } });
 | 
				
			||||||
              }}
 | 
					              }}
 | 
				
			||||||
              onTaskDescriptionChange={(updatedTask, newDescription) => {
 | 
					              onTaskDescriptionChange={(updatedTask, newDescription) => {
 | 
				
			||||||
                updateTaskDescription({ variables: { taskID: updatedTask.taskID, description: newDescription } });
 | 
					                updateTaskDescription({ variables: { taskID: updatedTask.id, description: newDescription } });
 | 
				
			||||||
              }}
 | 
					              }}
 | 
				
			||||||
              onDeleteTask={deletedTask => {
 | 
					              onDeleteTask={deletedTask => {
 | 
				
			||||||
                deleteTask({ variables: { taskID: deletedTask.taskID } });
 | 
					                deleteTask({ variables: { taskID: deletedTask.id } });
 | 
				
			||||||
 | 
					              }}
 | 
				
			||||||
 | 
					              onOpenAddLabelPopup={(task, $targetRef) => {
 | 
				
			||||||
 | 
					                taskLabelsRef.current = task.labels;
 | 
				
			||||||
 | 
					                showPopup(
 | 
				
			||||||
 | 
					                  $targetRef,
 | 
				
			||||||
 | 
					                  <LabelManagerEditor
 | 
				
			||||||
 | 
					                    onLabelToggle={labelID => {
 | 
				
			||||||
 | 
					                      toggleTaskLabel({ variables: { taskID: task.id, projectLabelID: labelID } });
 | 
				
			||||||
 | 
					                    }}
 | 
				
			||||||
 | 
					                    labelColors={data.labelColors}
 | 
				
			||||||
 | 
					                    labels={labelsRef}
 | 
				
			||||||
 | 
					                    taskLabels={taskLabelsRef}
 | 
				
			||||||
 | 
					                    projectID={projectID}
 | 
				
			||||||
 | 
					                  />,
 | 
				
			||||||
 | 
					                );
 | 
				
			||||||
              }}
 | 
					              }}
 | 
				
			||||||
              onOpenAddLabelPopup={(task, $targetRef) => {}}
 | 
					 | 
				
			||||||
            />
 | 
					            />
 | 
				
			||||||
          )}
 | 
					          )}
 | 
				
			||||||
        />
 | 
					        />
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -41,7 +41,7 @@ const Projects = () => {
 | 
				
			|||||||
    const { projects } = data;
 | 
					    const { projects } = data;
 | 
				
			||||||
    return (
 | 
					    return (
 | 
				
			||||||
      <>
 | 
					      <>
 | 
				
			||||||
        <GlobalTopNavbar name="Projects" />
 | 
					        <GlobalTopNavbar onSaveProjectName={() => {}} name="Projects" />
 | 
				
			||||||
        <ProjectGrid>
 | 
					        <ProjectGrid>
 | 
				
			||||||
          {projects.map(project => (
 | 
					          {projects.map(project => (
 | 
				
			||||||
            <ProjectLink key={project.id} to={`/projects/${project.id}`}>
 | 
					            <ProjectLink key={project.id} to={`/projects/${project.id}`}>
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										79
									
								
								web/src/citadel.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										79
									
								
								web/src/citadel.d.ts
									
									
									
									
										vendored
									
									
								
							@@ -3,18 +3,6 @@ interface JWTToken {
 | 
				
			|||||||
  iat: string;
 | 
					  iat: string;
 | 
				
			||||||
  exp: string;
 | 
					  exp: string;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
interface ColumnState {
 | 
					 | 
				
			||||||
  [key: string]: TaskGroup;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
interface TaskState {
 | 
					 | 
				
			||||||
  [key: string]: Task;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
interface BoardState {
 | 
					 | 
				
			||||||
  columns: ColumnState;
 | 
					 | 
				
			||||||
  tasks: TaskState;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
interface DraggableElement {
 | 
					interface DraggableElement {
 | 
				
			||||||
  id: string;
 | 
					  id: string;
 | 
				
			||||||
@@ -28,66 +16,13 @@ type ContextMenuEvent = {
 | 
				
			|||||||
  taskGroupID: string;
 | 
					  taskGroupID: string;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type InnerTaskGroup = {
 | 
					 | 
				
			||||||
  taskGroupID: string;
 | 
					 | 
				
			||||||
  name?: string;
 | 
					 | 
				
			||||||
  position?: number;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type ProfileIcon = {
 | 
					 | 
				
			||||||
  url: string | null;
 | 
					 | 
				
			||||||
  initials: string | null;
 | 
					 | 
				
			||||||
  bgColor: string | null;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type TaskUser = {
 | 
					type TaskUser = {
 | 
				
			||||||
  userID: string;
 | 
					  id: string;
 | 
				
			||||||
  displayName: string;
 | 
					  firstName: string;
 | 
				
			||||||
 | 
					  lastName: string;
 | 
				
			||||||
  profileIcon: ProfileIcon;
 | 
					  profileIcon: ProfileIcon;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type Task = {
 | 
					 | 
				
			||||||
  taskID: string;
 | 
					 | 
				
			||||||
  taskGroup: InnerTaskGroup;
 | 
					 | 
				
			||||||
  name: string;
 | 
					 | 
				
			||||||
  position: number;
 | 
					 | 
				
			||||||
  labels: Label[];
 | 
					 | 
				
			||||||
  description?: string | null;
 | 
					 | 
				
			||||||
  members?: Array<TaskUser>;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type TaskGroup = {
 | 
					 | 
				
			||||||
  taskGroupID: string;
 | 
					 | 
				
			||||||
  name: string;
 | 
					 | 
				
			||||||
  position: number;
 | 
					 | 
				
			||||||
  tasks: Task[];
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type Project = {
 | 
					 | 
				
			||||||
  projectID: string;
 | 
					 | 
				
			||||||
  name: string;
 | 
					 | 
				
			||||||
  color?: string;
 | 
					 | 
				
			||||||
  teamTitle?: string;
 | 
					 | 
				
			||||||
  taskGroups: TaskGroup[];
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type Organization = {
 | 
					 | 
				
			||||||
  name: string;
 | 
					 | 
				
			||||||
  teams: Team[];
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type Team = {
 | 
					 | 
				
			||||||
  name: string;
 | 
					 | 
				
			||||||
  projects: Project[];
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type Label = {
 | 
					 | 
				
			||||||
  labelId: string;
 | 
					 | 
				
			||||||
  name: string;
 | 
					 | 
				
			||||||
  labelColor: LabelColor;
 | 
					 | 
				
			||||||
  active: boolean;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type RefreshTokenResponse = {
 | 
					type RefreshTokenResponse = {
 | 
				
			||||||
  accessToken: string;
 | 
					  accessToken: string;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
@@ -117,17 +52,9 @@ type ElementSize = {
 | 
				
			|||||||
  height: number;
 | 
					  height: number;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type LabelColor = {
 | 
					 | 
				
			||||||
  id: string;
 | 
					 | 
				
			||||||
  name: string;
 | 
					 | 
				
			||||||
  colorHex: string;
 | 
					 | 
				
			||||||
  position: number;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type OnCardMemberClick = ($targetRef: RefObject<HTMLElement>, taskID: string, memberID: string) => void;
 | 
					type OnCardMemberClick = ($targetRef: RefObject<HTMLElement>, taskID: string, memberID: string) => void;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type ElementBounds = {
 | 
					type ElementBounds = {
 | 
				
			||||||
  size: ElementSize;
 | 
					  size: ElementSize;
 | 
				
			||||||
  position: ElementPosition;
 | 
					  position: ElementPosition;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										66
									
								
								web/src/projects.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								web/src/projects.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,66 @@
 | 
				
			|||||||
 | 
					type ProfileIcon = {
 | 
				
			||||||
 | 
					  url?: string | null;
 | 
				
			||||||
 | 
					  initials?: string | null;
 | 
				
			||||||
 | 
					  bgColor?: string | null;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type TaskGroup = {
 | 
				
			||||||
 | 
					  id: string;
 | 
				
			||||||
 | 
					  name: string;
 | 
				
			||||||
 | 
					  position: number;
 | 
				
			||||||
 | 
					  tasks: Task[];
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type LabelColor = {
 | 
				
			||||||
 | 
					  id: string;
 | 
				
			||||||
 | 
					  name: string;
 | 
				
			||||||
 | 
					  colorHex: string;
 | 
				
			||||||
 | 
					  position: number;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type InnerTaskGroup = {
 | 
				
			||||||
 | 
					  id: string;
 | 
				
			||||||
 | 
					  name?: string;
 | 
				
			||||||
 | 
					  position?: number;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type TaskLabel = {
 | 
				
			||||||
 | 
					  id: string;
 | 
				
			||||||
 | 
					  assignedDate: string;
 | 
				
			||||||
 | 
					  projectLabel: ProjectLabel;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Task = {
 | 
				
			||||||
 | 
					  id: string;
 | 
				
			||||||
 | 
					  taskGroup: InnerTaskGroup;
 | 
				
			||||||
 | 
					  name: string;
 | 
				
			||||||
 | 
					  position: number;
 | 
				
			||||||
 | 
					  labels: TaskLabel[];
 | 
				
			||||||
 | 
					  description?: string | null;
 | 
				
			||||||
 | 
					  assigned?: Array<TaskUser>;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Project = {
 | 
				
			||||||
 | 
					  projectID: string;
 | 
				
			||||||
 | 
					  name: string;
 | 
				
			||||||
 | 
					  color?: string;
 | 
				
			||||||
 | 
					  teamTitle?: string;
 | 
				
			||||||
 | 
					  taskGroups: TaskGroup[];
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Organization = {
 | 
				
			||||||
 | 
					  name: string;
 | 
				
			||||||
 | 
					  teams: Team[];
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Team = {
 | 
				
			||||||
 | 
					  name: string;
 | 
				
			||||||
 | 
					  projects: Project[];
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type ProjectLabel = {
 | 
				
			||||||
 | 
					  id: string;
 | 
				
			||||||
 | 
					  createdDate: string;
 | 
				
			||||||
 | 
					  name?: string | null;
 | 
				
			||||||
 | 
					  labelColor: LabelColor;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
@@ -14,28 +14,17 @@ export default {
 | 
				
			|||||||
  },
 | 
					  },
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const labelData = [
 | 
					const labelData: Array<ProjectLabel> = [
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    labelId: 'development',
 | 
					    id: 'development',
 | 
				
			||||||
    name: 'Development',
 | 
					    name: 'Development',
 | 
				
			||||||
 | 
					    createdDate: new Date().toString(),
 | 
				
			||||||
    labelColor: {
 | 
					    labelColor: {
 | 
				
			||||||
      id: '1',
 | 
					      id: '1',
 | 
				
			||||||
      colorHex: LabelColors.BLUE,
 | 
					      colorHex: LabelColors.BLUE,
 | 
				
			||||||
      name: 'blue',
 | 
					      name: 'blue',
 | 
				
			||||||
      position: 1,
 | 
					      position: 1,
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    active: false,
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    labelId: 'general',
 | 
					 | 
				
			||||||
    name: 'General',
 | 
					 | 
				
			||||||
    labelColor: {
 | 
					 | 
				
			||||||
      id: '2',
 | 
					 | 
				
			||||||
      colorHex: LabelColors.PINK,
 | 
					 | 
				
			||||||
      name: 'pink',
 | 
					 | 
				
			||||||
      position: 2,
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    active: false,
 | 
					 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
];
 | 
					];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -47,10 +47,10 @@ const Member: React.FC<MemberProps> = ({ onCardMemberClick, taskID, member }) =>
 | 
				
			|||||||
      onClick={e => {
 | 
					      onClick={e => {
 | 
				
			||||||
        if (onCardMemberClick) {
 | 
					        if (onCardMemberClick) {
 | 
				
			||||||
          e.stopPropagation();
 | 
					          e.stopPropagation();
 | 
				
			||||||
          onCardMemberClick($targetRef, taskID, member.userID);
 | 
					          onCardMemberClick($targetRef, taskID, member.id);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      }}
 | 
					      }}
 | 
				
			||||||
      key={member.userID}
 | 
					      key={member.id}
 | 
				
			||||||
      bgColor={member.profileIcon.bgColor ?? '#7367F0'}
 | 
					      bgColor={member.profileIcon.bgColor ?? '#7367F0'}
 | 
				
			||||||
    >
 | 
					    >
 | 
				
			||||||
      <CardMemberInitials>{member.profileIcon.initials}</CardMemberInitials>
 | 
					      <CardMemberInitials>{member.profileIcon.initials}</CardMemberInitials>
 | 
				
			||||||
@@ -68,7 +68,7 @@ type Props = {
 | 
				
			|||||||
  dueDate?: DueDate;
 | 
					  dueDate?: DueDate;
 | 
				
			||||||
  checklists?: Checklist;
 | 
					  checklists?: Checklist;
 | 
				
			||||||
  watched?: boolean;
 | 
					  watched?: boolean;
 | 
				
			||||||
  labels?: Label[];
 | 
					  labels?: Array<ProjectLabel>;
 | 
				
			||||||
  wrapperProps?: any;
 | 
					  wrapperProps?: any;
 | 
				
			||||||
  members?: Array<TaskUser> | null;
 | 
					  members?: Array<TaskUser> | null;
 | 
				
			||||||
  onCardMemberClick?: OnCardMemberClick;
 | 
					  onCardMemberClick?: OnCardMemberClick;
 | 
				
			||||||
@@ -136,7 +136,7 @@ const Card = React.forwardRef(
 | 
				
			|||||||
            <ListCardLabels>
 | 
					            <ListCardLabels>
 | 
				
			||||||
              {labels &&
 | 
					              {labels &&
 | 
				
			||||||
                labels.map(label => (
 | 
					                labels.map(label => (
 | 
				
			||||||
                  <ListCardLabel color={label.labelColor.colorHex} key={label.name}>
 | 
					                  <ListCardLabel color={label.labelColor.colorHex} key={label.id}>
 | 
				
			||||||
                    {label.name}
 | 
					                    {label.name}
 | 
				
			||||||
                  </ListCardLabel>
 | 
					                  </ListCardLabel>
 | 
				
			||||||
                ))}
 | 
					                ))}
 | 
				
			||||||
@@ -169,7 +169,7 @@ const Card = React.forwardRef(
 | 
				
			|||||||
            <CardMembers>
 | 
					            <CardMembers>
 | 
				
			||||||
              {members &&
 | 
					              {members &&
 | 
				
			||||||
                members.map(member => (
 | 
					                members.map(member => (
 | 
				
			||||||
                  <Member key={member.userID} taskID={taskID} member={member} onCardMemberClick={onCardMemberClick} />
 | 
					                  <Member key={member.id} taskID={taskID} member={member} onCardMemberClick={onCardMemberClick} />
 | 
				
			||||||
                ))}
 | 
					                ))}
 | 
				
			||||||
            </CardMembers>
 | 
					            </CardMembers>
 | 
				
			||||||
          </ListCardDetails>
 | 
					          </ListCardDetails>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -17,21 +17,35 @@ export const Default = () => {
 | 
				
			|||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <DueDateManager
 | 
					    <DueDateManager
 | 
				
			||||||
      task={{
 | 
					      task={{
 | 
				
			||||||
        taskID: '1',
 | 
					        id: '1',
 | 
				
			||||||
        taskGroup: { name: 'General', taskGroupID: '1' },
 | 
					        taskGroup: { name: 'General', id: '1', position: 1 },
 | 
				
			||||||
        name: 'Hello, world',
 | 
					        name: 'Hello, world',
 | 
				
			||||||
        position: 1,
 | 
					        position: 1,
 | 
				
			||||||
        labels: [
 | 
					        labels: [
 | 
				
			||||||
          {
 | 
					          {
 | 
				
			||||||
            labelId: 'soft-skills',
 | 
					            id: 'soft-skills',
 | 
				
			||||||
            labelColor: { id: '1', colorHex: '#fff', name: 'white', position: 1 },
 | 
					            assignedDate: new Date().toString(),
 | 
				
			||||||
            active: true,
 | 
					            projectLabel: {
 | 
				
			||||||
 | 
					              createdDate: new Date().toString(),
 | 
				
			||||||
 | 
					              id: 'label-soft-skills',
 | 
				
			||||||
              name: 'Soft Skills',
 | 
					              name: 'Soft Skills',
 | 
				
			||||||
 | 
					              labelColor: {
 | 
				
			||||||
 | 
					                id: '1',
 | 
				
			||||||
 | 
					                name: 'white',
 | 
				
			||||||
 | 
					                colorHex: '#fff',
 | 
				
			||||||
 | 
					                position: 1,
 | 
				
			||||||
 | 
					              },
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
          },
 | 
					          },
 | 
				
			||||||
        ],
 | 
					        ],
 | 
				
			||||||
        description: 'hello!',
 | 
					        description: 'hello!',
 | 
				
			||||||
        members: [
 | 
					        assigned: [
 | 
				
			||||||
          { userID: '1', profileIcon: { url: null, initials: null, bgColor: null }, displayName: 'Jordan Knott' },
 | 
					          {
 | 
				
			||||||
 | 
					            id: '1',
 | 
				
			||||||
 | 
					            profileIcon: { url: null, initials: null, bgColor: null },
 | 
				
			||||||
 | 
					            firstName: 'Jordan',
 | 
				
			||||||
 | 
					            lastName: 'Knott',
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
        ],
 | 
					        ],
 | 
				
			||||||
      }}
 | 
					      }}
 | 
				
			||||||
      onCancel={action('cancel')}
 | 
					      onCancel={action('cancel')}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,28 +16,17 @@ export default {
 | 
				
			|||||||
  },
 | 
					  },
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const labelData = [
 | 
					const labelData: Array<ProjectLabel> = [
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    labelId: 'development',
 | 
					    id: 'development',
 | 
				
			||||||
    name: 'Development',
 | 
					    name: 'Development',
 | 
				
			||||||
 | 
					    createdDate: new Date().toString(),
 | 
				
			||||||
    labelColor: {
 | 
					    labelColor: {
 | 
				
			||||||
      id: '1',
 | 
					      id: '1',
 | 
				
			||||||
      colorHex: LabelColors.BLUE,
 | 
					      colorHex: LabelColors.BLUE,
 | 
				
			||||||
      name: 'blue',
 | 
					      name: 'blue',
 | 
				
			||||||
      position: 1,
 | 
					      position: 1,
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    active: false,
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    labelId: 'general',
 | 
					 | 
				
			||||||
    name: 'General',
 | 
					 | 
				
			||||||
    labelColor: {
 | 
					 | 
				
			||||||
      id: '2',
 | 
					 | 
				
			||||||
      colorHex: LabelColors.PINK,
 | 
					 | 
				
			||||||
      name: 'pink',
 | 
					 | 
				
			||||||
      position: 2,
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    active: false,
 | 
					 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
];
 | 
					];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -68,7 +57,6 @@ export const Default = () => {
 | 
				
			|||||||
      isComposerOpen={false}
 | 
					      isComposerOpen={false}
 | 
				
			||||||
      onSaveName={action('on save name')}
 | 
					      onSaveName={action('on save name')}
 | 
				
			||||||
      onOpenComposer={action('on open composer')}
 | 
					      onOpenComposer={action('on open composer')}
 | 
				
			||||||
      tasks={[]}
 | 
					 | 
				
			||||||
      onExtraMenuOpen={action('extra menu open')}
 | 
					      onExtraMenuOpen={action('extra menu open')}
 | 
				
			||||||
    >
 | 
					    >
 | 
				
			||||||
      <ListCards>
 | 
					      <ListCards>
 | 
				
			||||||
@@ -94,7 +82,6 @@ export const WithCardComposer = () => {
 | 
				
			|||||||
      isComposerOpen
 | 
					      isComposerOpen
 | 
				
			||||||
      onSaveName={action('on save name')}
 | 
					      onSaveName={action('on save name')}
 | 
				
			||||||
      onOpenComposer={action('on open composer')}
 | 
					      onOpenComposer={action('on open composer')}
 | 
				
			||||||
      tasks={[]}
 | 
					 | 
				
			||||||
      onExtraMenuOpen={action('extra menu open')}
 | 
					      onExtraMenuOpen={action('extra menu open')}
 | 
				
			||||||
    >
 | 
					    >
 | 
				
			||||||
      <ListCards>
 | 
					      <ListCards>
 | 
				
			||||||
@@ -121,7 +108,6 @@ export const WithCard = () => {
 | 
				
			|||||||
      isComposerOpen={false}
 | 
					      isComposerOpen={false}
 | 
				
			||||||
      onSaveName={action('on save name')}
 | 
					      onSaveName={action('on save name')}
 | 
				
			||||||
      onOpenComposer={action('on open composer')}
 | 
					      onOpenComposer={action('on open composer')}
 | 
				
			||||||
      tasks={[]}
 | 
					 | 
				
			||||||
      onExtraMenuOpen={action('extra menu open')}
 | 
					      onExtraMenuOpen={action('extra menu open')}
 | 
				
			||||||
    >
 | 
					    >
 | 
				
			||||||
      <ListCards>
 | 
					      <ListCards>
 | 
				
			||||||
@@ -160,7 +146,6 @@ export const WithCardAndComposer = () => {
 | 
				
			|||||||
      isComposerOpen
 | 
					      isComposerOpen
 | 
				
			||||||
      onSaveName={action('on save name')}
 | 
					      onSaveName={action('on save name')}
 | 
				
			||||||
      onOpenComposer={action('on open composer')}
 | 
					      onOpenComposer={action('on open composer')}
 | 
				
			||||||
      tasks={[]}
 | 
					 | 
				
			||||||
      onExtraMenuOpen={action('extra menu open')}
 | 
					      onExtraMenuOpen={action('extra menu open')}
 | 
				
			||||||
    >
 | 
					    >
 | 
				
			||||||
      <ListCards>
 | 
					      <ListCards>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -97,9 +97,7 @@ export const Header = styled.div<{ isEditing: boolean }>`
 | 
				
			|||||||
    props.isEditing &&
 | 
					    props.isEditing &&
 | 
				
			||||||
    css`
 | 
					    css`
 | 
				
			||||||
      & ${HeaderName} {
 | 
					      & ${HeaderName} {
 | 
				
			||||||
        background: #fff;
 | 
					        box-shadow: rgb(115, 103, 240) 0px 0px 0px 1px;
 | 
				
			||||||
        border: none;
 | 
					 | 
				
			||||||
        box-shadow: inset 0 0 0 2px #0079bf;
 | 
					 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    `}
 | 
					    `}
 | 
				
			||||||
`;
 | 
					`;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -22,7 +22,6 @@ type Props = {
 | 
				
			|||||||
  onSaveName: (name: string) => void;
 | 
					  onSaveName: (name: string) => void;
 | 
				
			||||||
  isComposerOpen: boolean;
 | 
					  isComposerOpen: boolean;
 | 
				
			||||||
  onOpenComposer: (id: string) => void;
 | 
					  onOpenComposer: (id: string) => void;
 | 
				
			||||||
  tasks: Task[];
 | 
					 | 
				
			||||||
  wrapperProps?: any;
 | 
					  wrapperProps?: any;
 | 
				
			||||||
  headerProps?: any;
 | 
					  headerProps?: any;
 | 
				
			||||||
  index?: number;
 | 
					  index?: number;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -70,14 +70,12 @@ export const Default = () => {
 | 
				
			|||||||
      ...listsData,
 | 
					      ...listsData,
 | 
				
			||||||
      tasks: {
 | 
					      tasks: {
 | 
				
			||||||
        ...listsData.tasks,
 | 
					        ...listsData.tasks,
 | 
				
			||||||
        [droppedTask.taskID]: droppedTask,
 | 
					        [droppedTask.id]: droppedTask,
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
    console.log(newState);
 | 
					 | 
				
			||||||
    setListsData(newState);
 | 
					    setListsData(newState);
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
  const onListDrop = (droppedColumn: any) => {
 | 
					  const onListDrop = (droppedColumn: any) => {
 | 
				
			||||||
    console.log(droppedColumn);
 | 
					 | 
				
			||||||
    const newState = {
 | 
					    const newState = {
 | 
				
			||||||
      ...listsData,
 | 
					      ...listsData,
 | 
				
			||||||
      columns: {
 | 
					      columns: {
 | 
				
			||||||
@@ -85,44 +83,9 @@ export const Default = () => {
 | 
				
			|||||||
        [droppedColumn.taskGroupID]: droppedColumn,
 | 
					        [droppedColumn.taskGroupID]: droppedColumn,
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
    console.log(newState);
 | 
					 | 
				
			||||||
    setListsData(newState);
 | 
					    setListsData(newState);
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
  return (
 | 
					  return <span />;
 | 
				
			||||||
    <Lists
 | 
					 | 
				
			||||||
      {...listsData}
 | 
					 | 
				
			||||||
      onCardClick={action('card click')}
 | 
					 | 
				
			||||||
      onExtraMenuOpen={action('extra menu open')}
 | 
					 | 
				
			||||||
      onQuickEditorOpen={action('card composer open')}
 | 
					 | 
				
			||||||
      onCardDrop={onCardDrop}
 | 
					 | 
				
			||||||
      onListDrop={onListDrop}
 | 
					 | 
				
			||||||
      onCardMemberClick={action('card member click')}
 | 
					 | 
				
			||||||
      onCardCreate={action('card create')}
 | 
					 | 
				
			||||||
      onCreateList={listName => {
 | 
					 | 
				
			||||||
        const [lastColumn] = Object.values(listsData.columns)
 | 
					 | 
				
			||||||
          .sort((a, b) => a.position - b.position)
 | 
					 | 
				
			||||||
          .slice(-1);
 | 
					 | 
				
			||||||
        let position = 1;
 | 
					 | 
				
			||||||
        if (lastColumn) {
 | 
					 | 
				
			||||||
          position = lastColumn.position + 1;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        const taskGroupID = Math.random().toString();
 | 
					 | 
				
			||||||
        const newListsData = {
 | 
					 | 
				
			||||||
          ...listsData,
 | 
					 | 
				
			||||||
          columns: {
 | 
					 | 
				
			||||||
            ...listsData.columns,
 | 
					 | 
				
			||||||
            [taskGroupID]: {
 | 
					 | 
				
			||||||
              taskGroupID,
 | 
					 | 
				
			||||||
              name: listName,
 | 
					 | 
				
			||||||
              position,
 | 
					 | 
				
			||||||
              tasks: [],
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
        };
 | 
					 | 
				
			||||||
        setListsData(newListsData);
 | 
					 | 
				
			||||||
      }}
 | 
					 | 
				
			||||||
    />
 | 
					 | 
				
			||||||
  );
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const createColumn = (id: any, name: any, position: any) => {
 | 
					const createColumn = (id: any, name: any, position: any) => {
 | 
				
			||||||
@@ -202,13 +165,13 @@ export const ListsWithManyList = () => {
 | 
				
			|||||||
  };
 | 
					  };
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <Lists
 | 
					    <Lists
 | 
				
			||||||
      {...listsData}
 | 
					      taskGroups={[]}
 | 
				
			||||||
      onCardClick={action('card click')}
 | 
					      onTaskClick={action('card click')}
 | 
				
			||||||
      onQuickEditorOpen={action('card composer open')}
 | 
					      onQuickEditorOpen={action('card composer open')}
 | 
				
			||||||
      onCardCreate={action('card create')}
 | 
					      onCreateTask={action('card create')}
 | 
				
			||||||
      onCardDrop={onCardDrop}
 | 
					      onTaskDrop={onCardDrop}
 | 
				
			||||||
      onListDrop={onListDrop}
 | 
					      onTaskGroupDrop={onListDrop}
 | 
				
			||||||
      onCreateList={action('create list')}
 | 
					      onCreateTaskGroup={action('create list')}
 | 
				
			||||||
      onExtraMenuOpen={action('extra menu open')}
 | 
					      onExtraMenuOpen={action('extra menu open')}
 | 
				
			||||||
      onCardMemberClick={action('card member click')}
 | 
					      onCardMemberClick={action('card member click')}
 | 
				
			||||||
    />
 | 
					    />
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,5 +11,7 @@ export const Container = styled.div`
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
export const BoardWrapper = styled.div`
 | 
					export const BoardWrapper = styled.div`
 | 
				
			||||||
  display: flex;
 | 
					  display: flex;
 | 
				
			||||||
 | 
					  margin-top: 12px;
 | 
				
			||||||
 | 
					  margin-left: 8px;
 | 
				
			||||||
`;
 | 
					`;
 | 
				
			||||||
export default Container;
 | 
					export default Container;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -13,37 +13,29 @@ import {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import { Container, BoardWrapper } from './Styles';
 | 
					import { Container, BoardWrapper } from './Styles';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
interface Columns {
 | 
					interface SimpleProps {
 | 
				
			||||||
  [key: string]: TaskGroup;
 | 
					  taskGroups: Array<TaskGroup>;
 | 
				
			||||||
}
 | 
					  onTaskDrop: (task: Task) => void;
 | 
				
			||||||
interface Tasks {
 | 
					  onTaskGroupDrop: (taskGroup: TaskGroup) => void;
 | 
				
			||||||
  [key: string]: Task;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
type Props = {
 | 
					  onTaskClick: (task: Task) => void;
 | 
				
			||||||
  columns: Columns;
 | 
					  onCreateTask: (taskGroupID: string, name: string) => void;
 | 
				
			||||||
  tasks: Tasks;
 | 
					 | 
				
			||||||
  onCardClick: (task: Task) => void;
 | 
					 | 
				
			||||||
  onCardDrop: (task: Task) => void;
 | 
					 | 
				
			||||||
  onListDrop: (taskGroup: TaskGroup) => void;
 | 
					 | 
				
			||||||
  onCardCreate: (taskGroupID: string, name: string) => void;
 | 
					 | 
				
			||||||
  onQuickEditorOpen: (e: ContextMenuEvent) => void;
 | 
					  onQuickEditorOpen: (e: ContextMenuEvent) => void;
 | 
				
			||||||
  onCreateList: (listName: string) => void;
 | 
					  onCreateTaskGroup: (listName: string) => void;
 | 
				
			||||||
  onExtraMenuOpen: (taskGroupID: string, $targetRef: React.RefObject<HTMLElement>) => void;
 | 
					  onExtraMenuOpen: (taskGroupID: string, $targetRef: React.RefObject<HTMLElement>) => void;
 | 
				
			||||||
  onCardMemberClick: OnCardMemberClick;
 | 
					  onCardMemberClick: OnCardMemberClick;
 | 
				
			||||||
};
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const Lists: React.FC<Props> = ({
 | 
					const SimpleLists: React.FC<SimpleProps> = ({
 | 
				
			||||||
  columns,
 | 
					  taskGroups,
 | 
				
			||||||
  tasks,
 | 
					  onTaskDrop,
 | 
				
			||||||
  onCardClick,
 | 
					  onTaskGroupDrop,
 | 
				
			||||||
  onCardDrop,
 | 
					  onTaskClick,
 | 
				
			||||||
  onListDrop,
 | 
					  onCreateTask,
 | 
				
			||||||
  onCardCreate,
 | 
					 | 
				
			||||||
  onQuickEditorOpen,
 | 
					  onQuickEditorOpen,
 | 
				
			||||||
  onCreateList,
 | 
					  onCreateTaskGroup,
 | 
				
			||||||
  onCardMemberClick,
 | 
					 | 
				
			||||||
  onExtraMenuOpen,
 | 
					  onExtraMenuOpen,
 | 
				
			||||||
 | 
					  onCardMemberClick,
 | 
				
			||||||
}) => {
 | 
					}) => {
 | 
				
			||||||
  const onDragEnd = ({ draggableId, source, destination, type }: DropResult) => {
 | 
					  const onDragEnd = ({ draggableId, source, destination, type }: DropResult) => {
 | 
				
			||||||
    if (typeof destination === 'undefined') return;
 | 
					    if (typeof destination === 'undefined') return;
 | 
				
			||||||
@@ -51,29 +43,24 @@ const Lists: React.FC<Props> = ({
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    const isList = type === 'column';
 | 
					    const isList = type === 'column';
 | 
				
			||||||
    const isSameList = destination.droppableId === source.droppableId;
 | 
					    const isSameList = destination.droppableId === source.droppableId;
 | 
				
			||||||
    const droppedDraggable: DraggableElement = isList
 | 
					    let droppedDraggable: DraggableElement | null = null;
 | 
				
			||||||
      ? {
 | 
					    let beforeDropDraggables: Array<DraggableElement> | null = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (isList) {
 | 
				
			||||||
 | 
					      const droppedGroup = taskGroups.find(taskGroup => taskGroup.id === draggableId);
 | 
				
			||||||
 | 
					      if (droppedGroup) {
 | 
				
			||||||
 | 
					        droppedDraggable = {
 | 
				
			||||||
          id: draggableId,
 | 
					          id: draggableId,
 | 
				
			||||||
          position: columns[draggableId].position,
 | 
					          position: droppedGroup.position,
 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      : {
 | 
					 | 
				
			||||||
          id: draggableId,
 | 
					 | 
				
			||||||
          position: tasks[draggableId].position,
 | 
					 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
    const beforeDropDraggables = isList
 | 
					        beforeDropDraggables = getSortedDraggables(
 | 
				
			||||||
      ? getSortedDraggables(
 | 
					          taskGroups.map(taskGroup => {
 | 
				
			||||||
          Object.values(columns).map(column => {
 | 
					            return { id: taskGroup.id, position: taskGroup.position };
 | 
				
			||||||
            return { id: column.taskGroupID, position: column.position };
 | 
					 | 
				
			||||||
          }),
 | 
					 | 
				
			||||||
        )
 | 
					 | 
				
			||||||
      : getSortedDraggables(
 | 
					 | 
				
			||||||
          Object.values(tasks)
 | 
					 | 
				
			||||||
            .filter((t: any) => t.taskGroup.taskGroupID === destination.droppableId)
 | 
					 | 
				
			||||||
            .map(task => {
 | 
					 | 
				
			||||||
              return { id: task.taskID, position: task.position };
 | 
					 | 
				
			||||||
          }),
 | 
					          }),
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
 | 
					        if (droppedDraggable === null || beforeDropDraggables === null) {
 | 
				
			||||||
 | 
					          throw new Error('before drop draggables is null');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        const afterDropDraggables = getAfterDropDraggableList(
 | 
					        const afterDropDraggables = getAfterDropDraggableList(
 | 
				
			||||||
          beforeDropDraggables,
 | 
					          beforeDropDraggables,
 | 
				
			||||||
          droppedDraggable,
 | 
					          droppedDraggable,
 | 
				
			||||||
@@ -82,32 +69,51 @@ const Lists: React.FC<Props> = ({
 | 
				
			|||||||
          destination,
 | 
					          destination,
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
        const newPosition = getNewDraggablePosition(afterDropDraggables, destination.index);
 | 
					        const newPosition = getNewDraggablePosition(afterDropDraggables, destination.index);
 | 
				
			||||||
 | 
					        onTaskGroupDrop({
 | 
				
			||||||
    if (isList) {
 | 
					          ...droppedGroup,
 | 
				
			||||||
      const droppedList = columns[droppedDraggable.id];
 | 
					 | 
				
			||||||
      onListDrop({
 | 
					 | 
				
			||||||
        ...droppedList,
 | 
					 | 
				
			||||||
          position: newPosition,
 | 
					          position: newPosition,
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
      } else {
 | 
					      } else {
 | 
				
			||||||
      const droppedCard = tasks[droppedDraggable.id];
 | 
					        throw { error: 'task group can not be found' };
 | 
				
			||||||
      const newCard = {
 | 
					 | 
				
			||||||
        ...droppedCard,
 | 
					 | 
				
			||||||
        position: newPosition,
 | 
					 | 
				
			||||||
        taskGroup: {
 | 
					 | 
				
			||||||
          taskGroupID: destination.droppableId,
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
      };
 | 
					 | 
				
			||||||
      onCardDrop(newCard);
 | 
					 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
  };
 | 
					    } else {
 | 
				
			||||||
 | 
					      const targetGroup = taskGroups.findIndex(
 | 
				
			||||||
 | 
					        taskGroup => taskGroup.tasks.findIndex(task => task.id === draggableId) !== -1,
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					      const droppedTask = taskGroups[targetGroup].tasks.find(task => task.id === draggableId);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const orderedColumns = getSortedDraggables(
 | 
					      if (droppedTask) {
 | 
				
			||||||
    Object.values(columns).map(column => {
 | 
					        droppedDraggable = {
 | 
				
			||||||
      return { id: column.taskGroupID, position: column.position };
 | 
					          id: draggableId,
 | 
				
			||||||
 | 
					          position: droppedTask.position,
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					        beforeDropDraggables = getSortedDraggables(
 | 
				
			||||||
 | 
					          taskGroups[targetGroup].tasks.map(task => {
 | 
				
			||||||
 | 
					            return { id: task.id, position: task.position };
 | 
				
			||||||
          }),
 | 
					          }),
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
  console.log(orderedColumns);
 | 
					        if (droppedDraggable === null || beforeDropDraggables === null) {
 | 
				
			||||||
 | 
					          throw new Error('before drop draggables is null');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        const afterDropDraggables = getAfterDropDraggableList(
 | 
				
			||||||
 | 
					          beforeDropDraggables,
 | 
				
			||||||
 | 
					          droppedDraggable,
 | 
				
			||||||
 | 
					          isList,
 | 
				
			||||||
 | 
					          isSameList,
 | 
				
			||||||
 | 
					          destination,
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        const newPosition = getNewDraggablePosition(afterDropDraggables, destination.index);
 | 
				
			||||||
 | 
					        const newTask = {
 | 
				
			||||||
 | 
					          ...droppedTask,
 | 
				
			||||||
 | 
					          position: newPosition,
 | 
				
			||||||
 | 
					          taskGroup: {
 | 
				
			||||||
 | 
					            id: destination.droppableId,
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					        onTaskDrop(newTask);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const [currentComposer, setCurrentComposer] = useState('');
 | 
					  const [currentComposer, setCurrentComposer] = useState('');
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
@@ -116,34 +122,35 @@ const Lists: React.FC<Props> = ({
 | 
				
			|||||||
        <Droppable direction="horizontal" type="column" droppableId="root">
 | 
					        <Droppable direction="horizontal" type="column" droppableId="root">
 | 
				
			||||||
          {provided => (
 | 
					          {provided => (
 | 
				
			||||||
            <Container {...provided.droppableProps} ref={provided.innerRef}>
 | 
					            <Container {...provided.droppableProps} ref={provided.innerRef}>
 | 
				
			||||||
              {orderedColumns.map((columnDraggable, index: number) => {
 | 
					              {taskGroups
 | 
				
			||||||
                const column = columns[columnDraggable.id];
 | 
					                .slice()
 | 
				
			||||||
                const columnCards = Object.values(tasks)
 | 
					                .sort((a: any, b: any) => a.position - b.position)
 | 
				
			||||||
                  .filter((t: Task) => t.taskGroup.taskGroupID === column.taskGroupID)
 | 
					                .map((taskGroup: TaskGroup, index: number) => {
 | 
				
			||||||
                  .sort((a, b) => a.position - b.position);
 | 
					 | 
				
			||||||
                  return (
 | 
					                  return (
 | 
				
			||||||
                  <Draggable draggableId={column.taskGroupID} key={column.taskGroupID} index={index}>
 | 
					                    <Draggable draggableId={taskGroup.id} key={taskGroup.id} index={index}>
 | 
				
			||||||
                      {columnDragProvided => (
 | 
					                      {columnDragProvided => (
 | 
				
			||||||
                      <Droppable type="tasks" droppableId={column.taskGroupID}>
 | 
					                        <Droppable type="tasks" droppableId={taskGroup.id}>
 | 
				
			||||||
                          {(columnDropProvided, snapshot) => (
 | 
					                          {(columnDropProvided, snapshot) => (
 | 
				
			||||||
                            <List
 | 
					                            <List
 | 
				
			||||||
                            name={column.name}
 | 
					                              name={taskGroup.name}
 | 
				
			||||||
                              onOpenComposer={id => setCurrentComposer(id)}
 | 
					                              onOpenComposer={id => setCurrentComposer(id)}
 | 
				
			||||||
                            isComposerOpen={currentComposer === column.taskGroupID}
 | 
					                              isComposerOpen={currentComposer === taskGroup.id}
 | 
				
			||||||
                              onSaveName={name => {}}
 | 
					                              onSaveName={name => {}}
 | 
				
			||||||
                            tasks={columnCards}
 | 
					 | 
				
			||||||
                              ref={columnDragProvided.innerRef}
 | 
					                              ref={columnDragProvided.innerRef}
 | 
				
			||||||
                              wrapperProps={columnDragProvided.draggableProps}
 | 
					                              wrapperProps={columnDragProvided.draggableProps}
 | 
				
			||||||
                              headerProps={columnDragProvided.dragHandleProps}
 | 
					                              headerProps={columnDragProvided.dragHandleProps}
 | 
				
			||||||
                              onExtraMenuOpen={onExtraMenuOpen}
 | 
					                              onExtraMenuOpen={onExtraMenuOpen}
 | 
				
			||||||
                            id={column.taskGroupID}
 | 
					                              id={taskGroup.id}
 | 
				
			||||||
                            key={column.taskGroupID}
 | 
					                              key={taskGroup.id}
 | 
				
			||||||
                              index={index}
 | 
					                              index={index}
 | 
				
			||||||
                            >
 | 
					                            >
 | 
				
			||||||
                              <ListCards ref={columnDropProvided.innerRef} {...columnDropProvided.droppableProps}>
 | 
					                              <ListCards ref={columnDropProvided.innerRef} {...columnDropProvided.droppableProps}>
 | 
				
			||||||
                              {columnCards.map((task: Task, taskIndex: any) => {
 | 
					                                {taskGroup.tasks
 | 
				
			||||||
 | 
					                                  .slice()
 | 
				
			||||||
 | 
					                                  .sort((a: any, b: any) => a.position - b.position)
 | 
				
			||||||
 | 
					                                  .map((task: Task, taskIndex: any) => {
 | 
				
			||||||
                                    return (
 | 
					                                    return (
 | 
				
			||||||
                                  <Draggable key={task.taskID} draggableId={task.taskID} index={taskIndex}>
 | 
					                                      <Draggable key={task.id} draggableId={task.id} index={taskIndex}>
 | 
				
			||||||
                                        {taskProvided => {
 | 
					                                        {taskProvided => {
 | 
				
			||||||
                                          return (
 | 
					                                          return (
 | 
				
			||||||
                                            <Card
 | 
					                                            <Card
 | 
				
			||||||
@@ -152,13 +159,15 @@ const Lists: React.FC<Props> = ({
 | 
				
			|||||||
                                                ...taskProvided.dragHandleProps,
 | 
					                                                ...taskProvided.dragHandleProps,
 | 
				
			||||||
                                              }}
 | 
					                                              }}
 | 
				
			||||||
                                              ref={taskProvided.innerRef}
 | 
					                                              ref={taskProvided.innerRef}
 | 
				
			||||||
                                          taskID={task.taskID}
 | 
					                                              taskID={task.id}
 | 
				
			||||||
                                          taskGroupID={column.taskGroupID}
 | 
					                                              taskGroupID={taskGroup.id}
 | 
				
			||||||
                                              description=""
 | 
					                                              description=""
 | 
				
			||||||
 | 
					                                              labels={task.labels.map(label => label.projectLabel)}
 | 
				
			||||||
                                              title={task.name}
 | 
					                                              title={task.name}
 | 
				
			||||||
                                          labels={task.labels}
 | 
					                                              members={task.assigned}
 | 
				
			||||||
                                          members={task.members}
 | 
					                                              onClick={() => {
 | 
				
			||||||
                                          onClick={() => onCardClick(task)}
 | 
					                                                onTaskClick(task);
 | 
				
			||||||
 | 
					                                              }}
 | 
				
			||||||
                                              onCardMemberClick={onCardMemberClick}
 | 
					                                              onCardMemberClick={onCardMemberClick}
 | 
				
			||||||
                                              onContextMenu={onQuickEditorOpen}
 | 
					                                              onContextMenu={onQuickEditorOpen}
 | 
				
			||||||
                                            />
 | 
					                                            />
 | 
				
			||||||
@@ -168,13 +177,13 @@ const Lists: React.FC<Props> = ({
 | 
				
			|||||||
                                    );
 | 
					                                    );
 | 
				
			||||||
                                  })}
 | 
					                                  })}
 | 
				
			||||||
                                {columnDropProvided.placeholder}
 | 
					                                {columnDropProvided.placeholder}
 | 
				
			||||||
                              {currentComposer === column.taskGroupID && (
 | 
					                                {currentComposer === taskGroup.id && (
 | 
				
			||||||
                                  <CardComposer
 | 
					                                  <CardComposer
 | 
				
			||||||
                                    onClose={() => {
 | 
					                                    onClose={() => {
 | 
				
			||||||
                                      setCurrentComposer('');
 | 
					                                      setCurrentComposer('');
 | 
				
			||||||
                                    }}
 | 
					                                    }}
 | 
				
			||||||
                                    onCreateCard={name => {
 | 
					                                    onCreateCard={name => {
 | 
				
			||||||
                                    onCardCreate(column.taskGroupID, name);
 | 
					                                      onCreateTask(taskGroup.id, name);
 | 
				
			||||||
                                    }}
 | 
					                                    }}
 | 
				
			||||||
                                    isOpen
 | 
					                                    isOpen
 | 
				
			||||||
                                  />
 | 
					                                  />
 | 
				
			||||||
@@ -192,9 +201,13 @@ const Lists: React.FC<Props> = ({
 | 
				
			|||||||
          )}
 | 
					          )}
 | 
				
			||||||
        </Droppable>
 | 
					        </Droppable>
 | 
				
			||||||
      </DragDropContext>
 | 
					      </DragDropContext>
 | 
				
			||||||
      <AddList onSave={onCreateList} />
 | 
					      <AddList
 | 
				
			||||||
 | 
					        onSave={listName => {
 | 
				
			||||||
 | 
					          onCreateTaskGroup(listName);
 | 
				
			||||||
 | 
					        }}
 | 
				
			||||||
 | 
					      />
 | 
				
			||||||
    </BoardWrapper>
 | 
					    </BoardWrapper>
 | 
				
			||||||
  );
 | 
					  );
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default Lists;
 | 
					export default SimpleLists;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -39,16 +39,18 @@ const MemberManager: React.FC<MemberManagerProps> = ({
 | 
				
			|||||||
      <BoardMembersList>
 | 
					      <BoardMembersList>
 | 
				
			||||||
        {availableMembers
 | 
					        {availableMembers
 | 
				
			||||||
          .filter(
 | 
					          .filter(
 | 
				
			||||||
            member => currentSearch === '' || member.displayName.toLowerCase().startsWith(currentSearch.toLowerCase()),
 | 
					            member =>
 | 
				
			||||||
 | 
					              currentSearch === '' ||
 | 
				
			||||||
 | 
					              `${member.firstName} ${member.lastName}`.toLowerCase().startsWith(currentSearch.toLowerCase()),
 | 
				
			||||||
          )
 | 
					          )
 | 
				
			||||||
          .map(member => {
 | 
					          .map(member => {
 | 
				
			||||||
            return (
 | 
					            return (
 | 
				
			||||||
              <BoardMembersListItem key={member.userID}>
 | 
					              <BoardMembersListItem key={member.id}>
 | 
				
			||||||
                <BoardMemberListItemContent
 | 
					                <BoardMemberListItemContent
 | 
				
			||||||
                  onClick={() => {
 | 
					                  onClick={() => {
 | 
				
			||||||
                    const isActive = activeMembers.findIndex(m => m.userID === member.userID) !== -1;
 | 
					                    const isActive = activeMembers.findIndex(m => m.id === member.id) !== -1;
 | 
				
			||||||
                    if (isActive) {
 | 
					                    if (isActive) {
 | 
				
			||||||
                      setActiveMembers(activeMembers.filter(m => m.userID !== member.userID));
 | 
					                      setActiveMembers(activeMembers.filter(m => m.id !== member.id));
 | 
				
			||||||
                    } else {
 | 
					                    } else {
 | 
				
			||||||
                      setActiveMembers([...activeMembers, member]);
 | 
					                      setActiveMembers([...activeMembers, member]);
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
@@ -56,8 +58,8 @@ const MemberManager: React.FC<MemberManagerProps> = ({
 | 
				
			|||||||
                  }}
 | 
					                  }}
 | 
				
			||||||
                >
 | 
					                >
 | 
				
			||||||
                  <ProfileIcon>JK</ProfileIcon>
 | 
					                  <ProfileIcon>JK</ProfileIcon>
 | 
				
			||||||
                  <MemberName>{member.displayName}</MemberName>
 | 
					                  <MemberName>{`${member.firstName} ${member.lastName}`}</MemberName>
 | 
				
			||||||
                  {activeMembers.findIndex(m => m.userID === member.userID) !== -1 && (
 | 
					                  {activeMembers.findIndex(m => m.id === member.id) !== -1 && (
 | 
				
			||||||
                    <ActiveIconWrapper>
 | 
					                    <ActiveIconWrapper>
 | 
				
			||||||
                      <Checkmark size={16} color="#42526e" />
 | 
					                      <Checkmark size={16} color="#42526e" />
 | 
				
			||||||
                    </ActiveIconWrapper>
 | 
					                    </ActiveIconWrapper>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,14 +16,14 @@ type MiniProfileProps = {
 | 
				
			|||||||
  displayName: string;
 | 
					  displayName: string;
 | 
				
			||||||
  username: string;
 | 
					  username: string;
 | 
				
			||||||
  bio: string;
 | 
					  bio: string;
 | 
				
			||||||
  profileIcon: ProfileIcon;
 | 
					  profileIcon: ProfileIcon | null;
 | 
				
			||||||
  onRemoveFromTask: () => void;
 | 
					  onRemoveFromTask: () => void;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
const MiniProfile: React.FC<MiniProfileProps> = ({ displayName, username, bio, profileIcon, onRemoveFromTask }) => {
 | 
					const MiniProfile: React.FC<MiniProfileProps> = ({ displayName, username, bio, profileIcon, onRemoveFromTask }) => {
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <>
 | 
					    <>
 | 
				
			||||||
      <Profile>
 | 
					      <Profile>
 | 
				
			||||||
        <ProfileIcon bgColor={profileIcon.bgColor ?? ''}>{profileIcon.initials}</ProfileIcon>
 | 
					        {profileIcon && <ProfileIcon bgColor={profileIcon.bgColor ?? ''}>{profileIcon.initials}</ProfileIcon>}
 | 
				
			||||||
        <ProfileInfo>
 | 
					        <ProfileInfo>
 | 
				
			||||||
          <InfoTitle>{displayName}</InfoTitle>
 | 
					          <InfoTitle>{displayName}</InfoTitle>
 | 
				
			||||||
          <InfoUsername>{username}</InfoUsername>
 | 
					          <InfoUsername>{username}</InfoUsername>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,7 +5,7 @@ import { SaveButton, DeleteButton, LabelBox, EditLabelForm, FieldLabel, FieldNam
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
type Props = {
 | 
					type Props = {
 | 
				
			||||||
  labelColors: Array<LabelColor>;
 | 
					  labelColors: Array<LabelColor>;
 | 
				
			||||||
  label: Label | null;
 | 
					  label: ProjectLabel | null;
 | 
				
			||||||
  onLabelEdit: (labelId: string | null, labelName: string, labelColor: LabelColor) => void;
 | 
					  onLabelEdit: (labelId: string | null, labelName: string, labelColor: LabelColor) => void;
 | 
				
			||||||
  onLabelDelete?: (labelId: string) => void;
 | 
					  onLabelDelete?: (labelId: string) => void;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
@@ -32,7 +32,7 @@ const LabelManager = ({ labelColors, label, onLabelEdit, onLabelDelete }: Props)
 | 
				
			|||||||
        onChange={e => {
 | 
					        onChange={e => {
 | 
				
			||||||
          setCurrentLabel(e.currentTarget.value);
 | 
					          setCurrentLabel(e.currentTarget.value);
 | 
				
			||||||
        }}
 | 
					        }}
 | 
				
			||||||
        value={currentLabel}
 | 
					        value={currentLabel ?? ''}
 | 
				
			||||||
      />
 | 
					      />
 | 
				
			||||||
      <FieldLabel>Select a color</FieldLabel>
 | 
					      <FieldLabel>Select a color</FieldLabel>
 | 
				
			||||||
      <div>
 | 
					      <div>
 | 
				
			||||||
@@ -56,7 +56,7 @@ const LabelManager = ({ labelColors, label, onLabelEdit, onLabelDelete }: Props)
 | 
				
			|||||||
            e.preventDefault();
 | 
					            e.preventDefault();
 | 
				
			||||||
            console.log(currentColor);
 | 
					            console.log(currentColor);
 | 
				
			||||||
            if (currentColor) {
 | 
					            if (currentColor) {
 | 
				
			||||||
              onLabelEdit(label ? label.labelId : null, currentLabel, currentColor);
 | 
					              onLabelEdit(label ? label.id : null, currentLabel ?? '', currentColor);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
          }}
 | 
					          }}
 | 
				
			||||||
        />
 | 
					        />
 | 
				
			||||||
@@ -66,7 +66,7 @@ const LabelManager = ({ labelColors, label, onLabelEdit, onLabelDelete }: Props)
 | 
				
			|||||||
            type="submit"
 | 
					            type="submit"
 | 
				
			||||||
            onClick={e => {
 | 
					            onClick={e => {
 | 
				
			||||||
              e.preventDefault();
 | 
					              e.preventDefault();
 | 
				
			||||||
              onLabelDelete(label.labelId);
 | 
					              onLabelDelete(label.id);
 | 
				
			||||||
            }}
 | 
					            }}
 | 
				
			||||||
          />
 | 
					          />
 | 
				
			||||||
        )}
 | 
					        )}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,12 +14,14 @@ import {
 | 
				
			|||||||
} from './Styles';
 | 
					} from './Styles';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type Props = {
 | 
					type Props = {
 | 
				
			||||||
  labels?: Label[];
 | 
					  labels?: Array<ProjectLabel>;
 | 
				
			||||||
 | 
					  taskLabels?: Array<TaskLabel>;
 | 
				
			||||||
  onLabelToggle: (labelId: string) => void;
 | 
					  onLabelToggle: (labelId: string) => void;
 | 
				
			||||||
  onLabelEdit: (labelId: string) => void;
 | 
					  onLabelEdit: (labelId: string) => void;
 | 
				
			||||||
  onLabelCreate: () => void;
 | 
					  onLabelCreate: () => void;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
const LabelManager: React.FC<Props> = ({ labels, onLabelToggle, onLabelEdit, onLabelCreate }) => {
 | 
					
 | 
				
			||||||
 | 
					const LabelManager: React.FC<Props> = ({ labels, taskLabels, onLabelToggle, onLabelEdit, onLabelCreate }) => {
 | 
				
			||||||
  const $fieldName = useRef<HTMLInputElement>(null);
 | 
					  const $fieldName = useRef<HTMLInputElement>(null);
 | 
				
			||||||
  const [currentLabel, setCurrentLabel] = useState('');
 | 
					  const [currentLabel, setCurrentLabel] = useState('');
 | 
				
			||||||
  const [currentSearch, setCurrentSearch] = useState('');
 | 
					  const [currentSearch, setCurrentSearch] = useState('');
 | 
				
			||||||
@@ -44,27 +46,31 @@ const LabelManager: React.FC<Props> = ({ labels, onLabelToggle, onLabelEdit, onL
 | 
				
			|||||||
        <Labels>
 | 
					        <Labels>
 | 
				
			||||||
          {labels &&
 | 
					          {labels &&
 | 
				
			||||||
            labels
 | 
					            labels
 | 
				
			||||||
              .filter(label => currentSearch === '' || label.name.toLowerCase().startsWith(currentSearch.toLowerCase()))
 | 
					              .filter(
 | 
				
			||||||
 | 
					                label =>
 | 
				
			||||||
 | 
					                  currentSearch === '' ||
 | 
				
			||||||
 | 
					                  (label.name && label.name.toLowerCase().startsWith(currentSearch.toLowerCase())),
 | 
				
			||||||
 | 
					              )
 | 
				
			||||||
              .map(label => (
 | 
					              .map(label => (
 | 
				
			||||||
                <Label key={label.labelId}>
 | 
					                <Label key={label.id}>
 | 
				
			||||||
                  <LabelIcon
 | 
					                  <LabelIcon
 | 
				
			||||||
                    onClick={() => {
 | 
					                    onClick={() => {
 | 
				
			||||||
                      onLabelEdit(label.labelId);
 | 
					                      onLabelEdit(label.id);
 | 
				
			||||||
                    }}
 | 
					                    }}
 | 
				
			||||||
                  >
 | 
					                  >
 | 
				
			||||||
                    <Pencil color="#c2c6dc" />
 | 
					                    <Pencil color="#c2c6dc" />
 | 
				
			||||||
                  </LabelIcon>
 | 
					                  </LabelIcon>
 | 
				
			||||||
                  <CardLabel
 | 
					                  <CardLabel
 | 
				
			||||||
                    key={label.labelId}
 | 
					                    key={label.id}
 | 
				
			||||||
                    color={label.labelColor.colorHex}
 | 
					                    color={label.labelColor.colorHex}
 | 
				
			||||||
                    active={currentLabel === label.labelId}
 | 
					                    active={currentLabel === label.id}
 | 
				
			||||||
                    onMouseEnter={() => {
 | 
					                    onMouseEnter={() => {
 | 
				
			||||||
                      setCurrentLabel(label.labelId);
 | 
					                      setCurrentLabel(label.id);
 | 
				
			||||||
                    }}
 | 
					                    }}
 | 
				
			||||||
                    onClick={() => onLabelToggle(label.labelId)}
 | 
					                    onClick={() => onLabelToggle(label.id)}
 | 
				
			||||||
                  >
 | 
					                  >
 | 
				
			||||||
                    {label.name}
 | 
					                    {label.name}
 | 
				
			||||||
                    {label.active && (
 | 
					                    {taskLabels && taskLabels.find(t => t.projectLabel.id === label.id) && (
 | 
				
			||||||
                      <ActiveIcon>
 | 
					                      <ActiveIcon>
 | 
				
			||||||
                        <Checkmark color="#fff" />
 | 
					                        <Checkmark color="#fff" />
 | 
				
			||||||
                      </ActiveIcon>
 | 
					                      </ActiveIcon>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,12 +7,13 @@ import ListActions from 'shared/components/ListActions';
 | 
				
			|||||||
import MemberManager from 'shared/components/MemberManager';
 | 
					import MemberManager from 'shared/components/MemberManager';
 | 
				
			||||||
import DueDateManager from 'shared/components/DueDateManager';
 | 
					import DueDateManager from 'shared/components/DueDateManager';
 | 
				
			||||||
import MiniProfile from 'shared/components/MiniProfile';
 | 
					import MiniProfile from 'shared/components/MiniProfile';
 | 
				
			||||||
import styled from 'styled-components';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
import PopupMenu, { PopupProvider, usePopup, Popup } from '.';
 | 
					import styled from 'styled-components';
 | 
				
			||||||
 | 
					import produce from 'immer';
 | 
				
			||||||
import NormalizeStyles from 'App/NormalizeStyles';
 | 
					import NormalizeStyles from 'App/NormalizeStyles';
 | 
				
			||||||
import BaseStyles from 'App/BaseStyles';
 | 
					import BaseStyles from 'App/BaseStyles';
 | 
				
			||||||
import produce from 'immer';
 | 
					
 | 
				
			||||||
 | 
					import PopupMenu, { PopupProvider, usePopup, Popup } from '.';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default {
 | 
					export default {
 | 
				
			||||||
  component: PopupMenu,
 | 
					  component: PopupMenu,
 | 
				
			||||||
@@ -24,28 +25,17 @@ export default {
 | 
				
			|||||||
    ],
 | 
					    ],
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
const labelData = [
 | 
					const labelData: Array<ProjectLabel> = [
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    labelId: 'development',
 | 
					    id: 'development',
 | 
				
			||||||
    name: 'Development',
 | 
					    name: 'Development',
 | 
				
			||||||
 | 
					    createdDate: new Date().toString(),
 | 
				
			||||||
    labelColor: {
 | 
					    labelColor: {
 | 
				
			||||||
      id: '1',
 | 
					      id: '1',
 | 
				
			||||||
      name: 'white',
 | 
					 | 
				
			||||||
      colorHex: LabelColors.BLUE,
 | 
					      colorHex: LabelColors.BLUE,
 | 
				
			||||||
 | 
					      name: 'blue',
 | 
				
			||||||
      position: 1,
 | 
					      position: 1,
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    active: false,
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    labelId: 'general',
 | 
					 | 
				
			||||||
    name: 'General',
 | 
					 | 
				
			||||||
    labelColor: {
 | 
					 | 
				
			||||||
      id: '1',
 | 
					 | 
				
			||||||
      name: 'white',
 | 
					 | 
				
			||||||
      colorHex: LabelColors.PINK,
 | 
					 | 
				
			||||||
      position: 1,
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    active: false,
 | 
					 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
];
 | 
					];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -74,9 +64,9 @@ const LabelManagerEditor = () => {
 | 
				
			|||||||
          onLabelToggle={labelId => {
 | 
					          onLabelToggle={labelId => {
 | 
				
			||||||
            setLabels(
 | 
					            setLabels(
 | 
				
			||||||
              produce(labels, draftState => {
 | 
					              produce(labels, draftState => {
 | 
				
			||||||
                const idx = labels.findIndex(label => label.labelId === labelId);
 | 
					                const idx = labels.findIndex(label => label.id === labelId);
 | 
				
			||||||
                if (idx !== -1) {
 | 
					                if (idx !== -1) {
 | 
				
			||||||
                  draftState[idx] = { ...draftState[idx], active: !labels[idx].active };
 | 
					                  draftState[idx] = { ...draftState[idx] };
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
              }),
 | 
					              }),
 | 
				
			||||||
            );
 | 
					            );
 | 
				
			||||||
@@ -86,13 +76,21 @@ const LabelManagerEditor = () => {
 | 
				
			|||||||
      <Popup onClose={action('on close')} title="Edit label" tab={1}>
 | 
					      <Popup onClose={action('on close')} title="Edit label" tab={1}>
 | 
				
			||||||
        <LabelEditor
 | 
					        <LabelEditor
 | 
				
			||||||
          labelColors={[{ id: '1', colorHex: '#c2c6dc', position: 1, name: 'gray' }]}
 | 
					          labelColors={[{ id: '1', colorHex: '#c2c6dc', position: 1, name: 'gray' }]}
 | 
				
			||||||
          label={labels.find(label => label.labelId === currentLabel) ?? null}
 | 
					          label={labels.find(label => label.id === currentLabel) ?? null}
 | 
				
			||||||
          onLabelEdit={(_labelId, name, color) => {
 | 
					          onLabelEdit={(_labelId, name, color) => {
 | 
				
			||||||
            setLabels(
 | 
					            setLabels(
 | 
				
			||||||
              produce(labels, draftState => {
 | 
					              produce(labels, draftState => {
 | 
				
			||||||
                const idx = labels.findIndex(label => label.labelId === currentLabel);
 | 
					                const idx = labels.findIndex(label => label.id === currentLabel);
 | 
				
			||||||
                if (idx !== -1) {
 | 
					                if (idx !== -1) {
 | 
				
			||||||
                  draftState[idx] = { ...draftState[idx], name, labelColor: color };
 | 
					                  draftState[idx] = {
 | 
				
			||||||
 | 
					                    ...draftState[idx],
 | 
				
			||||||
 | 
					                    name,
 | 
				
			||||||
 | 
					                    labelColor: {
 | 
				
			||||||
 | 
					                      ...draftState[idx].labelColor,
 | 
				
			||||||
 | 
					                      name: color.name ?? '',
 | 
				
			||||||
 | 
					                      colorHex: color.colorHex,
 | 
				
			||||||
 | 
					                    },
 | 
				
			||||||
 | 
					                  };
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
              }),
 | 
					              }),
 | 
				
			||||||
            );
 | 
					            );
 | 
				
			||||||
@@ -105,7 +103,20 @@ const LabelManagerEditor = () => {
 | 
				
			|||||||
          label={null}
 | 
					          label={null}
 | 
				
			||||||
          labelColors={[{ id: '1', colorHex: '#c2c6dc', position: 1, name: 'gray' }]}
 | 
					          labelColors={[{ id: '1', colorHex: '#c2c6dc', position: 1, name: 'gray' }]}
 | 
				
			||||||
          onLabelEdit={(_labelId, name, color) => {
 | 
					          onLabelEdit={(_labelId, name, color) => {
 | 
				
			||||||
            setLabels([...labels, { labelId: name, name, labelColor: color, active: false }]);
 | 
					            setLabels([
 | 
				
			||||||
 | 
					              ...labels,
 | 
				
			||||||
 | 
					              {
 | 
				
			||||||
 | 
					                id: name,
 | 
				
			||||||
 | 
					                name,
 | 
				
			||||||
 | 
					                createdDate: new Date().toString(),
 | 
				
			||||||
 | 
					                labelColor: {
 | 
				
			||||||
 | 
					                  id: color.id,
 | 
				
			||||||
 | 
					                  colorHex: color.colorHex,
 | 
				
			||||||
 | 
					                  name: color.name ?? '',
 | 
				
			||||||
 | 
					                  position: 1,
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					              },
 | 
				
			||||||
 | 
					            ]);
 | 
				
			||||||
            setTab(0);
 | 
					            setTab(0);
 | 
				
			||||||
          }}
 | 
					          }}
 | 
				
			||||||
        />
 | 
					        />
 | 
				
			||||||
@@ -214,7 +225,12 @@ export const MemberManagerPopup = () => {
 | 
				
			|||||||
        <PopupMenu title="Members" top={popupData.top} onClose={() => setPopupData(initalState)} left={popupData.left}>
 | 
					        <PopupMenu title="Members" top={popupData.top} onClose={() => setPopupData(initalState)} left={popupData.left}>
 | 
				
			||||||
          <MemberManager
 | 
					          <MemberManager
 | 
				
			||||||
            availableMembers={[
 | 
					            availableMembers={[
 | 
				
			||||||
              { userID: '1', displayName: 'Jordan Knott', profileIcon: { bgColor: null, url: null, initials: null } },
 | 
					              {
 | 
				
			||||||
 | 
					                id: '1',
 | 
				
			||||||
 | 
					                firstName: 'Jordan',
 | 
				
			||||||
 | 
					                lastName: 'Knott',
 | 
				
			||||||
 | 
					                profileIcon: { bgColor: null, url: null, initials: null },
 | 
				
			||||||
 | 
					              },
 | 
				
			||||||
            ]}
 | 
					            ]}
 | 
				
			||||||
            activeMembers={[]}
 | 
					            activeMembers={[]}
 | 
				
			||||||
            onMemberChange={action('member change')}
 | 
					            onMemberChange={action('member change')}
 | 
				
			||||||
@@ -251,26 +267,35 @@ export const DueDateManagerPopup = () => {
 | 
				
			|||||||
        <PopupMenu title="Due Date" top={popupData.top} onClose={() => setPopupData(initalState)} left={popupData.left}>
 | 
					        <PopupMenu title="Due Date" top={popupData.top} onClose={() => setPopupData(initalState)} left={popupData.left}>
 | 
				
			||||||
          <DueDateManager
 | 
					          <DueDateManager
 | 
				
			||||||
            task={{
 | 
					            task={{
 | 
				
			||||||
              taskID: '1',
 | 
					              id: '1',
 | 
				
			||||||
              taskGroup: { name: 'General', taskGroupID: '1' },
 | 
					              taskGroup: { name: 'General', id: '1', position: 1 },
 | 
				
			||||||
              name: 'Hello, world',
 | 
					              name: 'Hello, world',
 | 
				
			||||||
              position: 1,
 | 
					              position: 1,
 | 
				
			||||||
              labels: [
 | 
					              labels: [
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                  labelId: 'soft-skills',
 | 
					                  id: 'soft-skills',
 | 
				
			||||||
 | 
					                  assignedDate: new Date().toString(),
 | 
				
			||||||
 | 
					                  projectLabel: {
 | 
				
			||||||
 | 
					                    createdDate: new Date().toString(),
 | 
				
			||||||
 | 
					                    id: 'label-soft-skills',
 | 
				
			||||||
 | 
					                    name: 'Soft Skills',
 | 
				
			||||||
                    labelColor: {
 | 
					                    labelColor: {
 | 
				
			||||||
                      id: '1',
 | 
					                      id: '1',
 | 
				
			||||||
                      name: 'white',
 | 
					                      name: 'white',
 | 
				
			||||||
                      colorHex: '#fff',
 | 
					                      colorHex: '#fff',
 | 
				
			||||||
                      position: 1,
 | 
					                      position: 1,
 | 
				
			||||||
                    },
 | 
					                    },
 | 
				
			||||||
                  active: true,
 | 
					                  },
 | 
				
			||||||
                  name: 'Soft Skills',
 | 
					 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
              ],
 | 
					              ],
 | 
				
			||||||
              description: 'hello!',
 | 
					              description: 'hello!',
 | 
				
			||||||
              members: [
 | 
					              assigned: [
 | 
				
			||||||
                { userID: '1', profileIcon: { bgColor: null, url: null, initials: null }, displayName: 'Jordan Knott' },
 | 
					                {
 | 
				
			||||||
 | 
					                  id: '1',
 | 
				
			||||||
 | 
					                  profileIcon: { bgColor: null, url: null, initials: null },
 | 
				
			||||||
 | 
					                  firstName: 'Jordan',
 | 
				
			||||||
 | 
					                  lastName: 'Knott',
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
              ],
 | 
					              ],
 | 
				
			||||||
            }}
 | 
					            }}
 | 
				
			||||||
            onCancel={action('cancel')}
 | 
					            onCancel={action('cancel')}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -17,28 +17,17 @@ export default {
 | 
				
			|||||||
  },
 | 
					  },
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const labelData = [
 | 
					const labelData: Array<ProjectLabel> = [
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    labelId: 'development',
 | 
					    id: 'development',
 | 
				
			||||||
    name: 'Development',
 | 
					    name: 'Development',
 | 
				
			||||||
 | 
					    createdDate: 'date',
 | 
				
			||||||
    labelColor: {
 | 
					    labelColor: {
 | 
				
			||||||
      id: '1',
 | 
					      id: 'label-color-blue',
 | 
				
			||||||
      name: 'white',
 | 
					 | 
				
			||||||
      colorHex: LabelColors.BLUE,
 | 
					      colorHex: LabelColors.BLUE,
 | 
				
			||||||
 | 
					      name: 'blue',
 | 
				
			||||||
      position: 1,
 | 
					      position: 1,
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    active: false,
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    labelId: 'general',
 | 
					 | 
				
			||||||
    name: 'General',
 | 
					 | 
				
			||||||
    labelColor: {
 | 
					 | 
				
			||||||
      id: '1',
 | 
					 | 
				
			||||||
      name: 'white',
 | 
					 | 
				
			||||||
      colorHex: LabelColors.PINK,
 | 
					 | 
				
			||||||
      position: 1,
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    active: false,
 | 
					 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
];
 | 
					];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -70,7 +59,6 @@ export const Default = () => {
 | 
				
			|||||||
        isComposerOpen={false}
 | 
					        isComposerOpen={false}
 | 
				
			||||||
        onSaveName={action('on save name')}
 | 
					        onSaveName={action('on save name')}
 | 
				
			||||||
        onOpenComposer={action('on open composer')}
 | 
					        onOpenComposer={action('on open composer')}
 | 
				
			||||||
        tasks={[]}
 | 
					 | 
				
			||||||
        onExtraMenuOpen={(taskGroupID, $targetRef) => console.log(taskGroupID, $targetRef)}
 | 
					        onExtraMenuOpen={(taskGroupID, $targetRef) => console.log(taskGroupID, $targetRef)}
 | 
				
			||||||
      >
 | 
					      >
 | 
				
			||||||
        <ListCards>
 | 
					        <ListCards>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -22,7 +22,7 @@ type Props = {
 | 
				
			|||||||
  onEditCard: (taskGroupID: string, taskID: string, cardName: string) => void;
 | 
					  onEditCard: (taskGroupID: string, taskID: string, cardName: string) => void;
 | 
				
			||||||
  onOpenPopup: (popupType: number, top: number, left: number) => void;
 | 
					  onOpenPopup: (popupType: number, top: number, left: number) => void;
 | 
				
			||||||
  onArchiveCard: (taskGroupID: string, taskID: string) => void;
 | 
					  onArchiveCard: (taskGroupID: string, taskID: string) => void;
 | 
				
			||||||
  labels?: Label[];
 | 
					  labels?: Array<ProjectLabel>;
 | 
				
			||||||
  isOpen: boolean;
 | 
					  isOpen: boolean;
 | 
				
			||||||
  top: number;
 | 
					  top: number;
 | 
				
			||||||
  left: number;
 | 
					  left: number;
 | 
				
			||||||
@@ -72,7 +72,7 @@ const QuickCardEditor = ({
 | 
				
			|||||||
          <ListCardLabels>
 | 
					          <ListCardLabels>
 | 
				
			||||||
            {labels &&
 | 
					            {labels &&
 | 
				
			||||||
              labels.map(label => (
 | 
					              labels.map(label => (
 | 
				
			||||||
                <ListCardLabel color={label.labelColor.colorHex} key={label.name}>
 | 
					                <ListCardLabel color={label.labelColor.colorHex} key={label.id}>
 | 
				
			||||||
                  {label.name}
 | 
					                  {label.name}
 | 
				
			||||||
                </ListCardLabel>
 | 
					                </ListCardLabel>
 | 
				
			||||||
              ))}
 | 
					              ))}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -31,7 +31,7 @@ type TaskAssigneeProps = {
 | 
				
			|||||||
const TaskAssignee: React.FC<TaskAssigneeProps> = ({ member, onMemberProfile, size }) => {
 | 
					const TaskAssignee: React.FC<TaskAssigneeProps> = ({ member, onMemberProfile, size }) => {
 | 
				
			||||||
  const $memberRef = useRef<HTMLDivElement>(null);
 | 
					  const $memberRef = useRef<HTMLDivElement>(null);
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <TaskDetailAssignee ref={$memberRef} onClick={() => onMemberProfile($memberRef, member.userID)} key={member.userID}>
 | 
					    <TaskDetailAssignee ref={$memberRef} onClick={() => onMemberProfile($memberRef, member.id)} key={member.id}>
 | 
				
			||||||
      <ProfileIcon size={size}>{member.profileIcon.initials ?? ''}</ProfileIcon>
 | 
					      <ProfileIcon size={size}>{member.profileIcon.initials ?? ''}</ProfileIcon>
 | 
				
			||||||
    </TaskDetailAssignee>
 | 
					    </TaskDetailAssignee>
 | 
				
			||||||
  );
 | 
					  );
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -244,11 +244,11 @@ export const TaskDetailLabels = styled.div`
 | 
				
			|||||||
  flex-wrap: wrap;
 | 
					  flex-wrap: wrap;
 | 
				
			||||||
`;
 | 
					`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const TaskDetailLabel = styled.div`
 | 
					export const TaskDetailLabel = styled.div<{ color: string }>`
 | 
				
			||||||
  &:hover {
 | 
					  &:hover {
 | 
				
			||||||
    opacity: 0.8;
 | 
					    opacity: 0.8;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  background-color: #00c2e0;
 | 
					  background-color: ${props => props.color};
 | 
				
			||||||
  color: #fff;
 | 
					  color: #fff;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  cursor: pointer;
 | 
					  cursor: pointer;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -29,29 +29,34 @@ export const Default = () => {
 | 
				
			|||||||
          return (
 | 
					          return (
 | 
				
			||||||
            <TaskDetails
 | 
					            <TaskDetails
 | 
				
			||||||
              task={{
 | 
					              task={{
 | 
				
			||||||
                taskID: '1',
 | 
					                id: '1',
 | 
				
			||||||
                taskGroup: { name: 'General', taskGroupID: '1' },
 | 
					                taskGroup: { name: 'General', id: '1' },
 | 
				
			||||||
                name: 'Hello, world',
 | 
					                name: 'Hello, world',
 | 
				
			||||||
                position: 1,
 | 
					                position: 1,
 | 
				
			||||||
                labels: [
 | 
					                labels: [
 | 
				
			||||||
                  {
 | 
					                  {
 | 
				
			||||||
                    labelId: 'soft-skills',
 | 
					                    id: 'soft-skills',
 | 
				
			||||||
 | 
					                    assignedDate: new Date().toString(),
 | 
				
			||||||
 | 
					                    projectLabel: {
 | 
				
			||||||
 | 
					                      createdDate: new Date().toString(),
 | 
				
			||||||
 | 
					                      id: 'label-soft-skills',
 | 
				
			||||||
 | 
					                      name: 'Soft Skills',
 | 
				
			||||||
                      labelColor: {
 | 
					                      labelColor: {
 | 
				
			||||||
                        id: '1',
 | 
					                        id: '1',
 | 
				
			||||||
                        name: 'white',
 | 
					                        name: 'white',
 | 
				
			||||||
                        colorHex: '#fff',
 | 
					                        colorHex: '#fff',
 | 
				
			||||||
                        position: 1,
 | 
					                        position: 1,
 | 
				
			||||||
                      },
 | 
					                      },
 | 
				
			||||||
                    active: true,
 | 
					                    },
 | 
				
			||||||
                    name: 'Soft Skills',
 | 
					 | 
				
			||||||
                  },
 | 
					                  },
 | 
				
			||||||
                ],
 | 
					                ],
 | 
				
			||||||
                description,
 | 
					                description,
 | 
				
			||||||
                members: [
 | 
					                assigned: [
 | 
				
			||||||
                  {
 | 
					                  {
 | 
				
			||||||
                    userID: '1',
 | 
					                    id: '1',
 | 
				
			||||||
                    profileIcon: { bgColor: null, url: null, initials: null },
 | 
					                    profileIcon: { bgColor: null, url: null, initials: null },
 | 
				
			||||||
                    displayName: 'Jordan Knott',
 | 
					                    firstName: 'Jordan',
 | 
				
			||||||
 | 
					                    lastName: 'Knott',
 | 
				
			||||||
                  },
 | 
					                  },
 | 
				
			||||||
                ],
 | 
					                ],
 | 
				
			||||||
              }}
 | 
					              }}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -193,15 +193,15 @@ const TaskDetails: React.FC<TaskDetailsProps> = ({
 | 
				
			|||||||
        <TaskDetailsSidebar>
 | 
					        <TaskDetailsSidebar>
 | 
				
			||||||
          <TaskDetailSectionTitle>Assignees</TaskDetailSectionTitle>
 | 
					          <TaskDetailSectionTitle>Assignees</TaskDetailSectionTitle>
 | 
				
			||||||
          <TaskDetailAssignees>
 | 
					          <TaskDetailAssignees>
 | 
				
			||||||
            {task.members && task.members.length === 0 ? (
 | 
					            {task.assigned && task.assigned.length === 0 ? (
 | 
				
			||||||
              <UnassignedLabel ref={$unassignedRef} onClick={onUnassignedClick}>
 | 
					              <UnassignedLabel ref={$unassignedRef} onClick={onUnassignedClick}>
 | 
				
			||||||
                Unassigned
 | 
					                Unassigned
 | 
				
			||||||
              </UnassignedLabel>
 | 
					              </UnassignedLabel>
 | 
				
			||||||
            ) : (
 | 
					            ) : (
 | 
				
			||||||
              <>
 | 
					              <>
 | 
				
			||||||
                {task.members &&
 | 
					                {task.assigned &&
 | 
				
			||||||
                  task.members.map(member => (
 | 
					                  task.assigned.map(member => (
 | 
				
			||||||
                    <TaskAssignee size={32} member={member} onMemberProfile={onMemberProfile} />
 | 
					                    <TaskAssignee key={member.id} size={32} member={member} onMemberProfile={onMemberProfile} />
 | 
				
			||||||
                  ))}
 | 
					                  ))}
 | 
				
			||||||
                <TaskDetailsAddMember ref={$addMemberRef} onClick={onAddMember}>
 | 
					                <TaskDetailsAddMember ref={$addMemberRef} onClick={onAddMember}>
 | 
				
			||||||
                  <TaskDetailsAddMemberIcon>
 | 
					                  <TaskDetailsAddMemberIcon>
 | 
				
			||||||
@@ -214,7 +214,11 @@ const TaskDetails: React.FC<TaskDetailsProps> = ({
 | 
				
			|||||||
          <TaskDetailSectionTitle>Labels</TaskDetailSectionTitle>
 | 
					          <TaskDetailSectionTitle>Labels</TaskDetailSectionTitle>
 | 
				
			||||||
          <TaskDetailLabels>
 | 
					          <TaskDetailLabels>
 | 
				
			||||||
            {task.labels.map(label => {
 | 
					            {task.labels.map(label => {
 | 
				
			||||||
              return <TaskDetailLabel>{label.name}</TaskDetailLabel>;
 | 
					              return (
 | 
				
			||||||
 | 
					                <TaskDetailLabel key={label.projectLabel.id} color={label.projectLabel.labelColor.colorHex}>
 | 
				
			||||||
 | 
					                  {label.projectLabel.name}
 | 
				
			||||||
 | 
					                </TaskDetailLabel>
 | 
				
			||||||
 | 
					              );
 | 
				
			||||||
            })}
 | 
					            })}
 | 
				
			||||||
            <TaskDetailsAddLabel ref={$addLabelRef} onClick={onAddLabel}>
 | 
					            <TaskDetailsAddLabel ref={$addLabelRef} onClick={onAddLabel}>
 | 
				
			||||||
              <TaskDetailsAddLabelIcon>
 | 
					              <TaskDetailsAddLabelIcon>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,5 @@
 | 
				
			|||||||
import styled, { css } from 'styled-components';
 | 
					import styled, { css } from 'styled-components';
 | 
				
			||||||
 | 
					import TextareaAutosize from 'react-autosize-textarea';
 | 
				
			||||||
import { mixin } from 'shared/utils/styles';
 | 
					import { mixin } from 'shared/utils/styles';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const NavbarWrapper = styled.div`
 | 
					export const NavbarWrapper = styled.div`
 | 
				
			||||||
@@ -135,7 +136,36 @@ export const ProjectName = styled.h1`
 | 
				
			|||||||
  color: #c2c6dc;
 | 
					  color: #c2c6dc;
 | 
				
			||||||
  font-weight: 600;
 | 
					  font-weight: 600;
 | 
				
			||||||
  font-size: 20px;
 | 
					  font-size: 20px;
 | 
				
			||||||
  padding: 6px 10px 6px 8px;
 | 
					  padding: 3px 10px 3px 8px;
 | 
				
			||||||
 | 
					  font-family: 'Droid Sans';
 | 
				
			||||||
 | 
					  margin: -4px 0;
 | 
				
			||||||
 | 
					`;
 | 
				
			||||||
 | 
					export const ProjectNameTextarea = styled(TextareaAutosize)`
 | 
				
			||||||
 | 
					  font-family: 'Droid Sans';
 | 
				
			||||||
 | 
					  border: none;
 | 
				
			||||||
 | 
					  resize: none;
 | 
				
			||||||
 | 
					  overflow: hidden;
 | 
				
			||||||
 | 
					  overflow-wrap: break-word;
 | 
				
			||||||
 | 
					  background: transparent;
 | 
				
			||||||
 | 
					  border-radius: 3px;
 | 
				
			||||||
 | 
					  box-shadow: none;
 | 
				
			||||||
 | 
					  margin: -4px 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  letter-spacing: normal;
 | 
				
			||||||
 | 
					  word-spacing: normal;
 | 
				
			||||||
 | 
					  text-transform: none;
 | 
				
			||||||
 | 
					  text-indent: 0px;
 | 
				
			||||||
 | 
					  text-shadow: none;
 | 
				
			||||||
 | 
					  flex-direction: column;
 | 
				
			||||||
 | 
					  text-align: start;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  color: #c2c6dc;
 | 
				
			||||||
 | 
					  font-weight: 600;
 | 
				
			||||||
 | 
					  font-size: 20px;
 | 
				
			||||||
 | 
					  padding: 3px 10px 3px 8px;
 | 
				
			||||||
 | 
					  &:focus {
 | 
				
			||||||
 | 
					    box-shadow: rgb(115, 103, 240) 0px 0px 0px 1px;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
`;
 | 
					`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const ProjectSwitcher = styled.button`
 | 
					export const ProjectSwitcher = styled.button`
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,8 +1,9 @@
 | 
				
			|||||||
import React, { useRef } from 'react';
 | 
					import React, { useRef, useState, useEffect } from 'react';
 | 
				
			||||||
import { Star, Bell, Cog, AngleDown } from 'shared/icons';
 | 
					import { Star, Ellipsis, Bell, Cog, AngleDown } from 'shared/icons';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
  NotificationContainer,
 | 
					  NotificationContainer,
 | 
				
			||||||
 | 
					  ProjectNameTextarea,
 | 
				
			||||||
  InviteButton,
 | 
					  InviteButton,
 | 
				
			||||||
  GlobalActions,
 | 
					  GlobalActions,
 | 
				
			||||||
  ProjectActions,
 | 
					  ProjectActions,
 | 
				
			||||||
@@ -28,9 +29,72 @@ import TaskAssignee from 'shared/components/TaskAssignee';
 | 
				
			|||||||
import { usePopup, Popup } from 'shared/components/PopupMenu';
 | 
					import { usePopup, Popup } from 'shared/components/PopupMenu';
 | 
				
			||||||
import MiniProfile from 'shared/components/MiniProfile';
 | 
					import MiniProfile from 'shared/components/MiniProfile';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type ProjectHeadingProps = {
 | 
				
			||||||
 | 
					  projectName: string;
 | 
				
			||||||
 | 
					  onSaveProjectName?: (projectName: string) => void;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const ProjectHeading: React.FC<ProjectHeadingProps> = ({ projectName: initialProjectName, onSaveProjectName }) => {
 | 
				
			||||||
 | 
					  const [isEditProjectName, setEditProjectName] = useState(false);
 | 
				
			||||||
 | 
					  const [projectName, setProjectName] = useState(initialProjectName);
 | 
				
			||||||
 | 
					  const $projectName = useRef<HTMLTextAreaElement>(null);
 | 
				
			||||||
 | 
					  useEffect(() => {
 | 
				
			||||||
 | 
					    if (isEditProjectName && $projectName && $projectName.current) {
 | 
				
			||||||
 | 
					      $projectName.current.focus();
 | 
				
			||||||
 | 
					      $projectName.current.select();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }, [isEditProjectName]);
 | 
				
			||||||
 | 
					  useEffect(() => {
 | 
				
			||||||
 | 
					    setProjectName(initialProjectName);
 | 
				
			||||||
 | 
					  }, [initialProjectName]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const onProjectNameChange = (event: React.FormEvent<HTMLTextAreaElement>): void => {
 | 
				
			||||||
 | 
					    setProjectName(event.currentTarget.value);
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					  const onProjectNameBlur = () => {
 | 
				
			||||||
 | 
					    if (onSaveProjectName) {
 | 
				
			||||||
 | 
					      onSaveProjectName(projectName);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    setEditProjectName(false);
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					  const onProjectNameKeyDown = (e: React.KeyboardEvent) => {
 | 
				
			||||||
 | 
					    if (e.key === 'Enter') {
 | 
				
			||||||
 | 
					      e.preventDefault();
 | 
				
			||||||
 | 
					      if ($projectName && $projectName.current) {
 | 
				
			||||||
 | 
					        $projectName.current.blur();
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return (
 | 
				
			||||||
 | 
					    <>
 | 
				
			||||||
 | 
					      <Separator>»</Separator>
 | 
				
			||||||
 | 
					      {isEditProjectName ? (
 | 
				
			||||||
 | 
					        <ProjectNameTextarea
 | 
				
			||||||
 | 
					          ref={$projectName}
 | 
				
			||||||
 | 
					          onChange={onProjectNameChange}
 | 
				
			||||||
 | 
					          onKeyDown={onProjectNameKeyDown}
 | 
				
			||||||
 | 
					          onBlur={onProjectNameBlur}
 | 
				
			||||||
 | 
					          spellCheck={false}
 | 
				
			||||||
 | 
					          value={projectName}
 | 
				
			||||||
 | 
					        />
 | 
				
			||||||
 | 
					      ) : (
 | 
				
			||||||
 | 
					        <ProjectName
 | 
				
			||||||
 | 
					          onClick={() => {
 | 
				
			||||||
 | 
					            setEditProjectName(true);
 | 
				
			||||||
 | 
					          }}
 | 
				
			||||||
 | 
					        >
 | 
				
			||||||
 | 
					          {projectName}
 | 
				
			||||||
 | 
					        </ProjectName>
 | 
				
			||||||
 | 
					      )}
 | 
				
			||||||
 | 
					    </>
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type NavBarProps = {
 | 
					type NavBarProps = {
 | 
				
			||||||
  projectName: string;
 | 
					  projectName: string;
 | 
				
			||||||
  onProfileClick: (bottom: number, right: number) => void;
 | 
					  onProfileClick: (bottom: number, right: number) => void;
 | 
				
			||||||
 | 
					  onSaveProjectName?: (projectName: string) => void;
 | 
				
			||||||
  onNotificationClick: () => void;
 | 
					  onNotificationClick: () => void;
 | 
				
			||||||
  bgColor: string;
 | 
					  bgColor: string;
 | 
				
			||||||
  firstName: string;
 | 
					  firstName: string;
 | 
				
			||||||
@@ -38,8 +102,10 @@ type NavBarProps = {
 | 
				
			|||||||
  initials: string;
 | 
					  initials: string;
 | 
				
			||||||
  projectMembers?: Array<TaskUser> | null;
 | 
					  projectMembers?: Array<TaskUser> | null;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const NavBar: React.FC<NavBarProps> = ({
 | 
					const NavBar: React.FC<NavBarProps> = ({
 | 
				
			||||||
  projectName,
 | 
					  projectName,
 | 
				
			||||||
 | 
					  onSaveProjectName,
 | 
				
			||||||
  onProfileClick,
 | 
					  onProfileClick,
 | 
				
			||||||
  onNotificationClick,
 | 
					  onNotificationClick,
 | 
				
			||||||
  firstName,
 | 
					  firstName,
 | 
				
			||||||
@@ -68,14 +134,14 @@ const NavBar: React.FC<NavBarProps> = ({
 | 
				
			|||||||
      </Popup>,
 | 
					      </Popup>,
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <NavbarWrapper>
 | 
					    <NavbarWrapper>
 | 
				
			||||||
      <NavbarHeader>
 | 
					      <NavbarHeader>
 | 
				
			||||||
        <ProjectActions>
 | 
					        <ProjectActions>
 | 
				
			||||||
          <ProjectMeta>
 | 
					          <ProjectMeta>
 | 
				
			||||||
            <ProjectSwitcher>Projects</ProjectSwitcher>
 | 
					            <ProjectSwitcher>Projects</ProjectSwitcher>
 | 
				
			||||||
            <Separator>»</Separator>
 | 
					            <ProjectHeading projectName={projectName} onSaveProjectName={onSaveProjectName} />
 | 
				
			||||||
            <ProjectName>{projectName}</ProjectName>
 | 
					 | 
				
			||||||
            <ProjectSettingsButton>
 | 
					            <ProjectSettingsButton>
 | 
				
			||||||
              <AngleDown color="#c2c6dc" />
 | 
					              <AngleDown color="#c2c6dc" />
 | 
				
			||||||
            </ProjectSettingsButton>
 | 
					            </ProjectSettingsButton>
 | 
				
			||||||
@@ -94,7 +160,7 @@ const NavBar: React.FC<NavBarProps> = ({
 | 
				
			|||||||
          {projectMembers && (
 | 
					          {projectMembers && (
 | 
				
			||||||
            <ProjectMembers>
 | 
					            <ProjectMembers>
 | 
				
			||||||
              {projectMembers.map(member => (
 | 
					              {projectMembers.map(member => (
 | 
				
			||||||
                <TaskAssignee key={member.userID} size={28} member={member} onMemberProfile={onMemberProfile} />
 | 
					                <TaskAssignee key={member.id} size={28} member={member} onMemberProfile={onMemberProfile} />
 | 
				
			||||||
              ))}
 | 
					              ))}
 | 
				
			||||||
              <InviteButton>Invite</InviteButton>
 | 
					              <InviteButton>Invite</InviteButton>
 | 
				
			||||||
            </ProjectMembers>
 | 
					            </ProjectMembers>
 | 
				
			||||||
@@ -104,9 +170,7 @@ const NavBar: React.FC<NavBarProps> = ({
 | 
				
			|||||||
          </NotificationContainer>
 | 
					          </NotificationContainer>
 | 
				
			||||||
          <ProfileContainer>
 | 
					          <ProfileContainer>
 | 
				
			||||||
            <ProfileNameWrapper>
 | 
					            <ProfileNameWrapper>
 | 
				
			||||||
              <ProfileNamePrimary>
 | 
					              <ProfileNamePrimary>{`${firstName} ${lastName}`}</ProfileNamePrimary>
 | 
				
			||||||
                {firstName} {lastName}
 | 
					 | 
				
			||||||
              </ProfileNamePrimary>
 | 
					 | 
				
			||||||
              <ProfileNameSecondary>Manager</ProfileNameSecondary>
 | 
					              <ProfileNameSecondary>Manager</ProfileNameSecondary>
 | 
				
			||||||
            </ProfileNameWrapper>
 | 
					            </ProfileNameWrapper>
 | 
				
			||||||
            <ProfileIcon ref={$profileRef} onClick={handleProfileClick} bgColor={bgColor}>
 | 
					            <ProfileIcon ref={$profileRef} onClick={handleProfileClick} bgColor={bgColor}>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -34,10 +34,8 @@ export type LabelColor = {
 | 
				
			|||||||
export type TaskLabel = {
 | 
					export type TaskLabel = {
 | 
				
			||||||
   __typename?: 'TaskLabel';
 | 
					   __typename?: 'TaskLabel';
 | 
				
			||||||
  id: Scalars['ID'];
 | 
					  id: Scalars['ID'];
 | 
				
			||||||
  projectLabelID: Scalars['UUID'];
 | 
					  projectLabel: ProjectLabel;
 | 
				
			||||||
  assignedDate: Scalars['Time'];
 | 
					  assignedDate: Scalars['Time'];
 | 
				
			||||||
  colorHex: Scalars['String'];
 | 
					 | 
				
			||||||
  name?: Maybe<Scalars['String']>;
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export type ProfileIcon = {
 | 
					export type ProfileIcon = {
 | 
				
			||||||
@@ -255,11 +253,10 @@ export type UpdateTaskDescriptionInput = {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
export type AddTaskLabelInput = {
 | 
					export type AddTaskLabelInput = {
 | 
				
			||||||
  taskID: Scalars['UUID'];
 | 
					  taskID: Scalars['UUID'];
 | 
				
			||||||
  labelColorID: Scalars['UUID'];
 | 
					  projectLabelID: Scalars['UUID'];
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export type RemoveTaskLabelInput = {
 | 
					export type RemoveTaskLabelInput = {
 | 
				
			||||||
  taskID: Scalars['UUID'];
 | 
					 | 
				
			||||||
  taskLabelID: Scalars['UUID'];
 | 
					  taskLabelID: Scalars['UUID'];
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -289,12 +286,29 @@ export type UpdateProjectLabelColor = {
 | 
				
			|||||||
  labelColorID: Scalars['UUID'];
 | 
					  labelColorID: Scalars['UUID'];
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export type ToggleTaskLabelInput = {
 | 
				
			||||||
 | 
					  taskID: Scalars['UUID'];
 | 
				
			||||||
 | 
					  projectLabelID: Scalars['UUID'];
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export type ToggleTaskLabelPayload = {
 | 
				
			||||||
 | 
					   __typename?: 'ToggleTaskLabelPayload';
 | 
				
			||||||
 | 
					  active: Scalars['Boolean'];
 | 
				
			||||||
 | 
					  task: Task;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export type UpdateProjectName = {
 | 
				
			||||||
 | 
					  projectID: Scalars['UUID'];
 | 
				
			||||||
 | 
					  name: Scalars['String'];
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export type Mutation = {
 | 
					export type Mutation = {
 | 
				
			||||||
   __typename?: 'Mutation';
 | 
					   __typename?: 'Mutation';
 | 
				
			||||||
  createRefreshToken: RefreshToken;
 | 
					  createRefreshToken: RefreshToken;
 | 
				
			||||||
  createUserAccount: UserAccount;
 | 
					  createUserAccount: UserAccount;
 | 
				
			||||||
  createTeam: Team;
 | 
					  createTeam: Team;
 | 
				
			||||||
  createProject: Project;
 | 
					  createProject: Project;
 | 
				
			||||||
 | 
					  updateProjectName: Project;
 | 
				
			||||||
  createProjectLabel: ProjectLabel;
 | 
					  createProjectLabel: ProjectLabel;
 | 
				
			||||||
  deleteProjectLabel: ProjectLabel;
 | 
					  deleteProjectLabel: ProjectLabel;
 | 
				
			||||||
  updateProjectLabel: ProjectLabel;
 | 
					  updateProjectLabel: ProjectLabel;
 | 
				
			||||||
@@ -305,6 +319,7 @@ export type Mutation = {
 | 
				
			|||||||
  deleteTaskGroup: DeleteTaskGroupPayload;
 | 
					  deleteTaskGroup: DeleteTaskGroupPayload;
 | 
				
			||||||
  addTaskLabel: Task;
 | 
					  addTaskLabel: Task;
 | 
				
			||||||
  removeTaskLabel: Task;
 | 
					  removeTaskLabel: Task;
 | 
				
			||||||
 | 
					  toggleTaskLabel: ToggleTaskLabelPayload;
 | 
				
			||||||
  createTask: Task;
 | 
					  createTask: Task;
 | 
				
			||||||
  updateTaskDescription: Task;
 | 
					  updateTaskDescription: Task;
 | 
				
			||||||
  updateTaskLocation: Task;
 | 
					  updateTaskLocation: Task;
 | 
				
			||||||
@@ -336,6 +351,11 @@ export type MutationCreateProjectArgs = {
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export type MutationUpdateProjectNameArgs = {
 | 
				
			||||||
 | 
					  input?: Maybe<UpdateProjectName>;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export type MutationCreateProjectLabelArgs = {
 | 
					export type MutationCreateProjectLabelArgs = {
 | 
				
			||||||
  input: NewProjectLabel;
 | 
					  input: NewProjectLabel;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
@@ -386,6 +406,11 @@ export type MutationRemoveTaskLabelArgs = {
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export type MutationToggleTaskLabelArgs = {
 | 
				
			||||||
 | 
					  input: ToggleTaskLabelInput;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export type MutationCreateTaskArgs = {
 | 
					export type MutationCreateTaskArgs = {
 | 
				
			||||||
  input: NewTask;
 | 
					  input: NewTask;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
@@ -476,8 +501,19 @@ export type CreateTaskMutation = (
 | 
				
			|||||||
    & Pick<Task, 'id' | 'name' | 'position' | 'description'>
 | 
					    & Pick<Task, 'id' | 'name' | 'position' | 'description'>
 | 
				
			||||||
    & { taskGroup: (
 | 
					    & { taskGroup: (
 | 
				
			||||||
      { __typename?: 'TaskGroup' }
 | 
					      { __typename?: 'TaskGroup' }
 | 
				
			||||||
      & Pick<TaskGroup, 'id'>
 | 
					      & Pick<TaskGroup, 'id' | 'name' | 'position'>
 | 
				
			||||||
    ), assigned: Array<(
 | 
					    ), labels: Array<(
 | 
				
			||||||
 | 
					      { __typename?: 'TaskLabel' }
 | 
				
			||||||
 | 
					      & Pick<TaskLabel, 'id' | 'assignedDate'>
 | 
				
			||||||
 | 
					      & { projectLabel: (
 | 
				
			||||||
 | 
					        { __typename?: 'ProjectLabel' }
 | 
				
			||||||
 | 
					        & Pick<ProjectLabel, 'id' | 'name' | 'createdDate'>
 | 
				
			||||||
 | 
					        & { labelColor: (
 | 
				
			||||||
 | 
					          { __typename?: 'LabelColor' }
 | 
				
			||||||
 | 
					          & Pick<LabelColor, 'id' | 'colorHex' | 'position' | 'name'>
 | 
				
			||||||
 | 
					        ) }
 | 
				
			||||||
 | 
					      ) }
 | 
				
			||||||
 | 
					    )>, assigned: Array<(
 | 
				
			||||||
      { __typename?: 'ProjectMember' }
 | 
					      { __typename?: 'ProjectMember' }
 | 
				
			||||||
      & Pick<ProjectMember, 'id' | 'firstName' | 'lastName'>
 | 
					      & Pick<ProjectMember, 'id' | 'firstName' | 'lastName'>
 | 
				
			||||||
      & { profileIcon: (
 | 
					      & { profileIcon: (
 | 
				
			||||||
@@ -580,7 +616,21 @@ export type FindProjectQuery = (
 | 
				
			|||||||
      & { tasks: Array<(
 | 
					      & { tasks: Array<(
 | 
				
			||||||
        { __typename?: 'Task' }
 | 
					        { __typename?: 'Task' }
 | 
				
			||||||
        & Pick<Task, 'id' | 'name' | 'position' | 'description'>
 | 
					        & Pick<Task, 'id' | 'name' | 'position' | 'description'>
 | 
				
			||||||
        & { assigned: Array<(
 | 
					        & { taskGroup: (
 | 
				
			||||||
 | 
					          { __typename?: 'TaskGroup' }
 | 
				
			||||||
 | 
					          & Pick<TaskGroup, 'id' | 'name' | 'position'>
 | 
				
			||||||
 | 
					        ), labels: Array<(
 | 
				
			||||||
 | 
					          { __typename?: 'TaskLabel' }
 | 
				
			||||||
 | 
					          & Pick<TaskLabel, 'id' | 'assignedDate'>
 | 
				
			||||||
 | 
					          & { projectLabel: (
 | 
				
			||||||
 | 
					            { __typename?: 'ProjectLabel' }
 | 
				
			||||||
 | 
					            & Pick<ProjectLabel, 'id' | 'name' | 'createdDate'>
 | 
				
			||||||
 | 
					            & { labelColor: (
 | 
				
			||||||
 | 
					              { __typename?: 'LabelColor' }
 | 
				
			||||||
 | 
					              & Pick<LabelColor, 'id' | 'colorHex' | 'position' | 'name'>
 | 
				
			||||||
 | 
					            ) }
 | 
				
			||||||
 | 
					          ) }
 | 
				
			||||||
 | 
					        )>, assigned: Array<(
 | 
				
			||||||
          { __typename?: 'ProjectMember' }
 | 
					          { __typename?: 'ProjectMember' }
 | 
				
			||||||
          & Pick<ProjectMember, 'id' | 'firstName' | 'lastName'>
 | 
					          & Pick<ProjectMember, 'id' | 'firstName' | 'lastName'>
 | 
				
			||||||
          & { profileIcon: (
 | 
					          & { profileIcon: (
 | 
				
			||||||
@@ -609,7 +659,18 @@ export type FindTaskQuery = (
 | 
				
			|||||||
    & { taskGroup: (
 | 
					    & { taskGroup: (
 | 
				
			||||||
      { __typename?: 'TaskGroup' }
 | 
					      { __typename?: 'TaskGroup' }
 | 
				
			||||||
      & Pick<TaskGroup, 'id'>
 | 
					      & Pick<TaskGroup, 'id'>
 | 
				
			||||||
    ), assigned: Array<(
 | 
					    ), labels: Array<(
 | 
				
			||||||
 | 
					      { __typename?: 'TaskLabel' }
 | 
				
			||||||
 | 
					      & Pick<TaskLabel, 'id' | 'assignedDate'>
 | 
				
			||||||
 | 
					      & { projectLabel: (
 | 
				
			||||||
 | 
					        { __typename?: 'ProjectLabel' }
 | 
				
			||||||
 | 
					        & Pick<ProjectLabel, 'id' | 'name' | 'createdDate'>
 | 
				
			||||||
 | 
					        & { labelColor: (
 | 
				
			||||||
 | 
					          { __typename?: 'LabelColor' }
 | 
				
			||||||
 | 
					          & Pick<LabelColor, 'id' | 'colorHex' | 'position' | 'name'>
 | 
				
			||||||
 | 
					        ) }
 | 
				
			||||||
 | 
					      ) }
 | 
				
			||||||
 | 
					    )>, assigned: Array<(
 | 
				
			||||||
      { __typename?: 'ProjectMember' }
 | 
					      { __typename?: 'ProjectMember' }
 | 
				
			||||||
      & Pick<ProjectMember, 'id' | 'firstName' | 'lastName'>
 | 
					      & Pick<ProjectMember, 'id' | 'firstName' | 'lastName'>
 | 
				
			||||||
      & { profileIcon: (
 | 
					      & { profileIcon: (
 | 
				
			||||||
@@ -650,6 +711,36 @@ export type MeQuery = (
 | 
				
			|||||||
  ) }
 | 
					  ) }
 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export type ToggleTaskLabelMutationVariables = {
 | 
				
			||||||
 | 
					  taskID: Scalars['UUID'];
 | 
				
			||||||
 | 
					  projectLabelID: Scalars['UUID'];
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export type ToggleTaskLabelMutation = (
 | 
				
			||||||
 | 
					  { __typename?: 'Mutation' }
 | 
				
			||||||
 | 
					  & { toggleTaskLabel: (
 | 
				
			||||||
 | 
					    { __typename?: 'ToggleTaskLabelPayload' }
 | 
				
			||||||
 | 
					    & Pick<ToggleTaskLabelPayload, 'active'>
 | 
				
			||||||
 | 
					    & { task: (
 | 
				
			||||||
 | 
					      { __typename?: 'Task' }
 | 
				
			||||||
 | 
					      & Pick<Task, 'id'>
 | 
				
			||||||
 | 
					      & { labels: Array<(
 | 
				
			||||||
 | 
					        { __typename?: 'TaskLabel' }
 | 
				
			||||||
 | 
					        & Pick<TaskLabel, 'id' | 'assignedDate'>
 | 
				
			||||||
 | 
					        & { projectLabel: (
 | 
				
			||||||
 | 
					          { __typename?: 'ProjectLabel' }
 | 
				
			||||||
 | 
					          & Pick<ProjectLabel, 'id' | 'createdDate' | 'name'>
 | 
				
			||||||
 | 
					          & { labelColor: (
 | 
				
			||||||
 | 
					            { __typename?: 'LabelColor' }
 | 
				
			||||||
 | 
					            & Pick<LabelColor, 'id' | 'colorHex' | 'name' | 'position'>
 | 
				
			||||||
 | 
					          ) }
 | 
				
			||||||
 | 
					        ) }
 | 
				
			||||||
 | 
					      )> }
 | 
				
			||||||
 | 
					    ) }
 | 
				
			||||||
 | 
					  ) }
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export type UnassignTaskMutationVariables = {
 | 
					export type UnassignTaskMutationVariables = {
 | 
				
			||||||
  taskID: Scalars['UUID'];
 | 
					  taskID: Scalars['UUID'];
 | 
				
			||||||
  userID: Scalars['UUID'];
 | 
					  userID: Scalars['UUID'];
 | 
				
			||||||
@@ -687,6 +778,20 @@ export type UpdateProjectLabelMutation = (
 | 
				
			|||||||
  ) }
 | 
					  ) }
 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export type UpdateProjectNameMutationVariables = {
 | 
				
			||||||
 | 
					  projectID: Scalars['UUID'];
 | 
				
			||||||
 | 
					  name: Scalars['String'];
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export type UpdateProjectNameMutation = (
 | 
				
			||||||
 | 
					  { __typename?: 'Mutation' }
 | 
				
			||||||
 | 
					  & { updateProjectName: (
 | 
				
			||||||
 | 
					    { __typename?: 'Project' }
 | 
				
			||||||
 | 
					    & Pick<Project, 'id' | 'name'>
 | 
				
			||||||
 | 
					  ) }
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export type UpdateTaskDescriptionMutationVariables = {
 | 
					export type UpdateTaskDescriptionMutationVariables = {
 | 
				
			||||||
  taskID: Scalars['UUID'];
 | 
					  taskID: Scalars['UUID'];
 | 
				
			||||||
  description: Scalars['String'];
 | 
					  description: Scalars['String'];
 | 
				
			||||||
@@ -834,6 +939,23 @@ export const CreateTaskDocument = gql`
 | 
				
			|||||||
    description
 | 
					    description
 | 
				
			||||||
    taskGroup {
 | 
					    taskGroup {
 | 
				
			||||||
      id
 | 
					      id
 | 
				
			||||||
 | 
					      name
 | 
				
			||||||
 | 
					      position
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    labels {
 | 
				
			||||||
 | 
					      id
 | 
				
			||||||
 | 
					      assignedDate
 | 
				
			||||||
 | 
					      projectLabel {
 | 
				
			||||||
 | 
					        id
 | 
				
			||||||
 | 
					        name
 | 
				
			||||||
 | 
					        createdDate
 | 
				
			||||||
 | 
					        labelColor {
 | 
				
			||||||
 | 
					          id
 | 
				
			||||||
 | 
					          colorHex
 | 
				
			||||||
 | 
					          position
 | 
				
			||||||
 | 
					          name
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    assigned {
 | 
					    assigned {
 | 
				
			||||||
      id
 | 
					      id
 | 
				
			||||||
@@ -1032,13 +1154,13 @@ export const FindProjectDocument = gql`
 | 
				
			|||||||
    labels {
 | 
					    labels {
 | 
				
			||||||
      id
 | 
					      id
 | 
				
			||||||
      createdDate
 | 
					      createdDate
 | 
				
			||||||
 | 
					      name
 | 
				
			||||||
      labelColor {
 | 
					      labelColor {
 | 
				
			||||||
        id
 | 
					        id
 | 
				
			||||||
        name
 | 
					        name
 | 
				
			||||||
        colorHex
 | 
					        colorHex
 | 
				
			||||||
        position
 | 
					        position
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      name
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    taskGroups {
 | 
					    taskGroups {
 | 
				
			||||||
      id
 | 
					      id
 | 
				
			||||||
@@ -1049,6 +1171,26 @@ export const FindProjectDocument = gql`
 | 
				
			|||||||
        name
 | 
					        name
 | 
				
			||||||
        position
 | 
					        position
 | 
				
			||||||
        description
 | 
					        description
 | 
				
			||||||
 | 
					        taskGroup {
 | 
				
			||||||
 | 
					          id
 | 
				
			||||||
 | 
					          name
 | 
				
			||||||
 | 
					          position
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        labels {
 | 
				
			||||||
 | 
					          id
 | 
				
			||||||
 | 
					          assignedDate
 | 
				
			||||||
 | 
					          projectLabel {
 | 
				
			||||||
 | 
					            id
 | 
				
			||||||
 | 
					            name
 | 
				
			||||||
 | 
					            createdDate
 | 
				
			||||||
 | 
					            labelColor {
 | 
				
			||||||
 | 
					              id
 | 
				
			||||||
 | 
					              colorHex
 | 
				
			||||||
 | 
					              position
 | 
				
			||||||
 | 
					              name
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        assigned {
 | 
					        assigned {
 | 
				
			||||||
          id
 | 
					          id
 | 
				
			||||||
          firstName
 | 
					          firstName
 | 
				
			||||||
@@ -1106,6 +1248,21 @@ export const FindTaskDocument = gql`
 | 
				
			|||||||
    taskGroup {
 | 
					    taskGroup {
 | 
				
			||||||
      id
 | 
					      id
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    labels {
 | 
				
			||||||
 | 
					      id
 | 
				
			||||||
 | 
					      assignedDate
 | 
				
			||||||
 | 
					      projectLabel {
 | 
				
			||||||
 | 
					        id
 | 
				
			||||||
 | 
					        name
 | 
				
			||||||
 | 
					        createdDate
 | 
				
			||||||
 | 
					        labelColor {
 | 
				
			||||||
 | 
					          id
 | 
				
			||||||
 | 
					          colorHex
 | 
				
			||||||
 | 
					          position
 | 
				
			||||||
 | 
					          name
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    assigned {
 | 
					    assigned {
 | 
				
			||||||
      id
 | 
					      id
 | 
				
			||||||
      firstName
 | 
					      firstName
 | 
				
			||||||
@@ -1219,6 +1376,57 @@ export function useMeLazyQuery(baseOptions?: ApolloReactHooks.LazyQueryHookOptio
 | 
				
			|||||||
export type MeQueryHookResult = ReturnType<typeof useMeQuery>;
 | 
					export type MeQueryHookResult = ReturnType<typeof useMeQuery>;
 | 
				
			||||||
export type MeLazyQueryHookResult = ReturnType<typeof useMeLazyQuery>;
 | 
					export type MeLazyQueryHookResult = ReturnType<typeof useMeLazyQuery>;
 | 
				
			||||||
export type MeQueryResult = ApolloReactCommon.QueryResult<MeQuery, MeQueryVariables>;
 | 
					export type MeQueryResult = ApolloReactCommon.QueryResult<MeQuery, MeQueryVariables>;
 | 
				
			||||||
 | 
					export const ToggleTaskLabelDocument = gql`
 | 
				
			||||||
 | 
					    mutation toggleTaskLabel($taskID: UUID!, $projectLabelID: UUID!) {
 | 
				
			||||||
 | 
					  toggleTaskLabel(input: {taskID: $taskID, projectLabelID: $projectLabelID}) {
 | 
				
			||||||
 | 
					    active
 | 
				
			||||||
 | 
					    task {
 | 
				
			||||||
 | 
					      id
 | 
				
			||||||
 | 
					      labels {
 | 
				
			||||||
 | 
					        id
 | 
				
			||||||
 | 
					        assignedDate
 | 
				
			||||||
 | 
					        projectLabel {
 | 
				
			||||||
 | 
					          id
 | 
				
			||||||
 | 
					          createdDate
 | 
				
			||||||
 | 
					          labelColor {
 | 
				
			||||||
 | 
					            id
 | 
				
			||||||
 | 
					            colorHex
 | 
				
			||||||
 | 
					            name
 | 
				
			||||||
 | 
					            position
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          name
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					    `;
 | 
				
			||||||
 | 
					export type ToggleTaskLabelMutationFn = ApolloReactCommon.MutationFunction<ToggleTaskLabelMutation, ToggleTaskLabelMutationVariables>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * __useToggleTaskLabelMutation__
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * To run a mutation, you first call `useToggleTaskLabelMutation` within a React component and pass it any options that fit your needs.
 | 
				
			||||||
 | 
					 * When your component renders, `useToggleTaskLabelMutation` returns a tuple that includes:
 | 
				
			||||||
 | 
					 * - A mutate function that you can call at any time to execute the mutation
 | 
				
			||||||
 | 
					 * - An object with fields that represent the current status of the mutation's execution
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2;
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @example
 | 
				
			||||||
 | 
					 * const [toggleTaskLabelMutation, { data, loading, error }] = useToggleTaskLabelMutation({
 | 
				
			||||||
 | 
					 *   variables: {
 | 
				
			||||||
 | 
					 *      taskID: // value for 'taskID'
 | 
				
			||||||
 | 
					 *      projectLabelID: // value for 'projectLabelID'
 | 
				
			||||||
 | 
					 *   },
 | 
				
			||||||
 | 
					 * });
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					export function useToggleTaskLabelMutation(baseOptions?: ApolloReactHooks.MutationHookOptions<ToggleTaskLabelMutation, ToggleTaskLabelMutationVariables>) {
 | 
				
			||||||
 | 
					        return ApolloReactHooks.useMutation<ToggleTaskLabelMutation, ToggleTaskLabelMutationVariables>(ToggleTaskLabelDocument, baseOptions);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					export type ToggleTaskLabelMutationHookResult = ReturnType<typeof useToggleTaskLabelMutation>;
 | 
				
			||||||
 | 
					export type ToggleTaskLabelMutationResult = ApolloReactCommon.MutationResult<ToggleTaskLabelMutation>;
 | 
				
			||||||
 | 
					export type ToggleTaskLabelMutationOptions = ApolloReactCommon.BaseMutationOptions<ToggleTaskLabelMutation, ToggleTaskLabelMutationVariables>;
 | 
				
			||||||
export const UnassignTaskDocument = gql`
 | 
					export const UnassignTaskDocument = gql`
 | 
				
			||||||
    mutation unassignTask($taskID: UUID!, $userID: UUID!) {
 | 
					    mutation unassignTask($taskID: UUID!, $userID: UUID!) {
 | 
				
			||||||
  unassignTask(input: {taskID: $taskID, userID: $userID}) {
 | 
					  unassignTask(input: {taskID: $taskID, userID: $userID}) {
 | 
				
			||||||
@@ -1299,6 +1507,40 @@ export function useUpdateProjectLabelMutation(baseOptions?: ApolloReactHooks.Mut
 | 
				
			|||||||
export type UpdateProjectLabelMutationHookResult = ReturnType<typeof useUpdateProjectLabelMutation>;
 | 
					export type UpdateProjectLabelMutationHookResult = ReturnType<typeof useUpdateProjectLabelMutation>;
 | 
				
			||||||
export type UpdateProjectLabelMutationResult = ApolloReactCommon.MutationResult<UpdateProjectLabelMutation>;
 | 
					export type UpdateProjectLabelMutationResult = ApolloReactCommon.MutationResult<UpdateProjectLabelMutation>;
 | 
				
			||||||
export type UpdateProjectLabelMutationOptions = ApolloReactCommon.BaseMutationOptions<UpdateProjectLabelMutation, UpdateProjectLabelMutationVariables>;
 | 
					export type UpdateProjectLabelMutationOptions = ApolloReactCommon.BaseMutationOptions<UpdateProjectLabelMutation, UpdateProjectLabelMutationVariables>;
 | 
				
			||||||
 | 
					export const UpdateProjectNameDocument = gql`
 | 
				
			||||||
 | 
					    mutation updateProjectName($projectID: UUID!, $name: String!) {
 | 
				
			||||||
 | 
					  updateProjectName(input: {projectID: $projectID, name: $name}) {
 | 
				
			||||||
 | 
					    id
 | 
				
			||||||
 | 
					    name
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					    `;
 | 
				
			||||||
 | 
					export type UpdateProjectNameMutationFn = ApolloReactCommon.MutationFunction<UpdateProjectNameMutation, UpdateProjectNameMutationVariables>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * __useUpdateProjectNameMutation__
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * To run a mutation, you first call `useUpdateProjectNameMutation` within a React component and pass it any options that fit your needs.
 | 
				
			||||||
 | 
					 * When your component renders, `useUpdateProjectNameMutation` returns a tuple that includes:
 | 
				
			||||||
 | 
					 * - A mutate function that you can call at any time to execute the mutation
 | 
				
			||||||
 | 
					 * - An object with fields that represent the current status of the mutation's execution
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2;
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @example
 | 
				
			||||||
 | 
					 * const [updateProjectNameMutation, { data, loading, error }] = useUpdateProjectNameMutation({
 | 
				
			||||||
 | 
					 *   variables: {
 | 
				
			||||||
 | 
					 *      projectID: // value for 'projectID'
 | 
				
			||||||
 | 
					 *      name: // value for 'name'
 | 
				
			||||||
 | 
					 *   },
 | 
				
			||||||
 | 
					 * });
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					export function useUpdateProjectNameMutation(baseOptions?: ApolloReactHooks.MutationHookOptions<UpdateProjectNameMutation, UpdateProjectNameMutationVariables>) {
 | 
				
			||||||
 | 
					        return ApolloReactHooks.useMutation<UpdateProjectNameMutation, UpdateProjectNameMutationVariables>(UpdateProjectNameDocument, baseOptions);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					export type UpdateProjectNameMutationHookResult = ReturnType<typeof useUpdateProjectNameMutation>;
 | 
				
			||||||
 | 
					export type UpdateProjectNameMutationResult = ApolloReactCommon.MutationResult<UpdateProjectNameMutation>;
 | 
				
			||||||
 | 
					export type UpdateProjectNameMutationOptions = ApolloReactCommon.BaseMutationOptions<UpdateProjectNameMutation, UpdateProjectNameMutationVariables>;
 | 
				
			||||||
export const UpdateTaskDescriptionDocument = gql`
 | 
					export const UpdateTaskDescriptionDocument = gql`
 | 
				
			||||||
    mutation updateTaskDescription($taskID: UUID!, $description: String!) {
 | 
					    mutation updateTaskDescription($taskID: UUID!, $description: String!) {
 | 
				
			||||||
  updateTaskDescription(input: {taskID: $taskID, description: $description}) {
 | 
					  updateTaskDescription(input: {taskID: $taskID, description: $description}) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,6 +6,23 @@ mutation createTask($taskGroupID: String!, $name: String!, $position: Float!) {
 | 
				
			|||||||
    description
 | 
					    description
 | 
				
			||||||
    taskGroup {
 | 
					    taskGroup {
 | 
				
			||||||
      id
 | 
					      id
 | 
				
			||||||
 | 
					      name
 | 
				
			||||||
 | 
					      position
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    labels {
 | 
				
			||||||
 | 
					      id
 | 
				
			||||||
 | 
					      assignedDate
 | 
				
			||||||
 | 
					      projectLabel {
 | 
				
			||||||
 | 
					        id
 | 
				
			||||||
 | 
					        name
 | 
				
			||||||
 | 
					        createdDate
 | 
				
			||||||
 | 
					        labelColor {
 | 
				
			||||||
 | 
					          id
 | 
				
			||||||
 | 
					          colorHex
 | 
				
			||||||
 | 
					          position
 | 
				
			||||||
 | 
					          name
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    assigned {
 | 
					    assigned {
 | 
				
			||||||
      id
 | 
					      id
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,13 +14,13 @@ query findProject($projectId: String!) {
 | 
				
			|||||||
    labels {
 | 
					    labels {
 | 
				
			||||||
      id
 | 
					      id
 | 
				
			||||||
      createdDate
 | 
					      createdDate
 | 
				
			||||||
 | 
					      name
 | 
				
			||||||
      labelColor {
 | 
					      labelColor {
 | 
				
			||||||
        id
 | 
					        id
 | 
				
			||||||
        name
 | 
					        name
 | 
				
			||||||
        colorHex
 | 
					        colorHex
 | 
				
			||||||
        position
 | 
					        position
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      name
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    taskGroups {
 | 
					    taskGroups {
 | 
				
			||||||
      id
 | 
					      id
 | 
				
			||||||
@@ -31,6 +31,26 @@ query findProject($projectId: String!) {
 | 
				
			|||||||
        name
 | 
					        name
 | 
				
			||||||
        position
 | 
					        position
 | 
				
			||||||
        description
 | 
					        description
 | 
				
			||||||
 | 
					        taskGroup {
 | 
				
			||||||
 | 
					          id
 | 
				
			||||||
 | 
					          name
 | 
				
			||||||
 | 
					          position
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        labels {
 | 
				
			||||||
 | 
					          id
 | 
				
			||||||
 | 
					          assignedDate
 | 
				
			||||||
 | 
					          projectLabel {
 | 
				
			||||||
 | 
					            id
 | 
				
			||||||
 | 
					            name
 | 
				
			||||||
 | 
					            createdDate
 | 
				
			||||||
 | 
					            labelColor {
 | 
				
			||||||
 | 
					              id
 | 
				
			||||||
 | 
					              colorHex
 | 
				
			||||||
 | 
					              position
 | 
				
			||||||
 | 
					              name
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        assigned {
 | 
					        assigned {
 | 
				
			||||||
          id
 | 
					          id
 | 
				
			||||||
          firstName
 | 
					          firstName
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,6 +7,21 @@ query findTask($taskID: UUID!) {
 | 
				
			|||||||
    taskGroup {
 | 
					    taskGroup {
 | 
				
			||||||
      id
 | 
					      id
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    labels {
 | 
				
			||||||
 | 
					      id
 | 
				
			||||||
 | 
					      assignedDate
 | 
				
			||||||
 | 
					      projectLabel {
 | 
				
			||||||
 | 
					        id
 | 
				
			||||||
 | 
					        name
 | 
				
			||||||
 | 
					        createdDate
 | 
				
			||||||
 | 
					        labelColor {
 | 
				
			||||||
 | 
					          id
 | 
				
			||||||
 | 
					          colorHex
 | 
				
			||||||
 | 
					          position
 | 
				
			||||||
 | 
					          name
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    assigned {
 | 
					    assigned {
 | 
				
			||||||
      id
 | 
					      id
 | 
				
			||||||
      firstName
 | 
					      firstName
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										29
									
								
								web/src/shared/graphql/toggleTaskLabel.graphqls
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								web/src/shared/graphql/toggleTaskLabel.graphqls
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,29 @@
 | 
				
			|||||||
 | 
					mutation toggleTaskLabel($taskID: UUID!, $projectLabelID: UUID!) {
 | 
				
			||||||
 | 
					  toggleTaskLabel(
 | 
				
			||||||
 | 
					    input: {
 | 
				
			||||||
 | 
					      taskID: $taskID,
 | 
				
			||||||
 | 
					      projectLabelID: $projectLabelID
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  ) {
 | 
				
			||||||
 | 
					    active
 | 
				
			||||||
 | 
					    task {
 | 
				
			||||||
 | 
					      id
 | 
				
			||||||
 | 
					      labels {
 | 
				
			||||||
 | 
					        id
 | 
				
			||||||
 | 
					        assignedDate
 | 
				
			||||||
 | 
					        projectLabel {
 | 
				
			||||||
 | 
					          id
 | 
				
			||||||
 | 
					          createdDate
 | 
				
			||||||
 | 
					          labelColor {
 | 
				
			||||||
 | 
					            id
 | 
				
			||||||
 | 
					            colorHex
 | 
				
			||||||
 | 
					            name
 | 
				
			||||||
 | 
					            position
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          name
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										6
									
								
								web/src/shared/graphql/updateProjectName.graphqls
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								web/src/shared/graphql/updateProjectName.graphqls
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
				
			|||||||
 | 
					mutation updateProjectName($projectID: UUID!, $name: String!) {
 | 
				
			||||||
 | 
					  updateProjectName(input: {projectID: $projectID, name: $name}) {
 | 
				
			||||||
 | 
					    id
 | 
				
			||||||
 | 
					    name
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -3,9 +3,17 @@ import React from 'react';
 | 
				
			|||||||
type Props = {
 | 
					type Props = {
 | 
				
			||||||
  size: number | string;
 | 
					  size: number | string;
 | 
				
			||||||
  color: string;
 | 
					  color: string;
 | 
				
			||||||
 | 
					  vertical: boolean;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const Ellipsis = ({ size, color }: Props) => {
 | 
					const Ellipsis = ({ size, color, vertical }: Props) => {
 | 
				
			||||||
 | 
					  if (vertical) {
 | 
				
			||||||
 | 
					    return (
 | 
				
			||||||
 | 
					      <svg fill={color} xmlns="http://www.w3.org/2000/svg" width={size} height={size} viewBox="0 0 192 512">
 | 
				
			||||||
 | 
					        <path d="M96 184c39.8 0 72 32.2 72 72s-32.2 72-72 72-72-32.2-72-72 32.2-72 72-72zM24 80c0 39.8 32.2 72 72 72s72-32.2 72-72S135.8 8 96 8 24 40.2 24 80zm0 352c0 39.8 32.2 72 72 72s72-32.2 72-72-32.2-72-72-72-72 32.2-72 72z" />
 | 
				
			||||||
 | 
					      </svg>
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <svg fill={color} xmlns="http://www.w3.org/2000/svg" width={size} height={size} viewBox="0 0 512 512">
 | 
					    <svg fill={color} xmlns="http://www.w3.org/2000/svg" width={size} height={size} viewBox="0 0 512 512">
 | 
				
			||||||
      <path d="M328 256c0 39.8-32.2 72-72 72s-72-32.2-72-72 32.2-72 72-72 72 32.2 72 72zm104-72c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72zm-352 0c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72z" />
 | 
					      <path d="M328 256c0 39.8-32.2 72-72 72s-72-32.2-72-72 32.2-72 72-72 72 32.2 72 72zm104-72c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72zm-352 0c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72z" />
 | 
				
			||||||
@@ -16,6 +24,7 @@ const Ellipsis = ({ size, color }: Props) => {
 | 
				
			|||||||
Ellipsis.defaultProps = {
 | 
					Ellipsis.defaultProps = {
 | 
				
			||||||
  size: 16,
 | 
					  size: 16,
 | 
				
			||||||
  color: '#000',
 | 
					  color: '#000',
 | 
				
			||||||
 | 
					  vertical: false,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default Ellipsis;
 | 
					export default Ellipsis;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,50 +0,0 @@
 | 
				
			|||||||
import produce from 'immer';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export const addTask = (currentState: BoardState, newTask: Task) => {
 | 
					 | 
				
			||||||
  return produce(currentState, (draftState: BoardState) => {
 | 
					 | 
				
			||||||
    draftState.tasks[newTask.taskID] = newTask;
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export const deleteTask = (currentState: BoardState, taskID: string) => {
 | 
					 | 
				
			||||||
  return produce(currentState, (draftState: BoardState) => {
 | 
					 | 
				
			||||||
    delete draftState.tasks[taskID];
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export const addTaskGroup = (currentState: BoardState, newTaskGroup: TaskGroup) => {
 | 
					 | 
				
			||||||
  return produce(currentState, (draftState: BoardState) => {
 | 
					 | 
				
			||||||
    draftState.columns[newTaskGroup.taskGroupID] = newTaskGroup;
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export const updateTaskGroup = (currentState: BoardState, newTaskGroup: TaskGroup) => {
 | 
					 | 
				
			||||||
  return produce(currentState, (draftState: BoardState) => {
 | 
					 | 
				
			||||||
    draftState.columns[newTaskGroup.taskGroupID] = newTaskGroup;
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export const updateTask = (currentState: BoardState, newTask: Task) => {
 | 
					 | 
				
			||||||
  return produce(currentState, (draftState: BoardState) => {
 | 
					 | 
				
			||||||
    draftState.tasks[newTask.taskID] = newTask;
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export const deleteTaskGroup = (currentState: BoardState, deletedTaskGroupID: string) => {
 | 
					 | 
				
			||||||
  return produce(currentState, (draftState: BoardState) => {
 | 
					 | 
				
			||||||
    delete draftState.columns[deletedTaskGroupID];
 | 
					 | 
				
			||||||
    const filteredTasks = Object.keys(currentState.tasks)
 | 
					 | 
				
			||||||
      .filter(taskID => currentState.tasks[taskID].taskGroup.taskGroupID !== deletedTaskGroupID)
 | 
					 | 
				
			||||||
      .reduce((obj: TaskState, key: string) => {
 | 
					 | 
				
			||||||
        obj[key] = currentState.tasks[key];
 | 
					 | 
				
			||||||
        return obj;
 | 
					 | 
				
			||||||
      }, {});
 | 
					 | 
				
			||||||
    draftState.tasks = filteredTasks;
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export const updateTaskName = (currentState: BoardState, taskID: string, newName: string) => {
 | 
					 | 
				
			||||||
  return produce(currentState, (draftState: BoardState) => {
 | 
					 | 
				
			||||||
    draftState.tasks[taskID].name = newName;
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
		Reference in New Issue
	
	Block a user