feature: add ability to delete & update project labels

This commit is contained in:
Jordan Knott 2020-05-27 20:12:50 -05:00
parent cbcd8c5f82
commit 539259effd
32 changed files with 1139 additions and 143 deletions

View File

@ -81,11 +81,15 @@ type ComplexityRoot struct {
CreateTaskGroup func(childComplexity int, input NewTaskGroup) int
CreateTeam func(childComplexity int, input NewTeam) int
CreateUserAccount func(childComplexity int, input NewUserAccount) int
DeleteProjectLabel func(childComplexity int, input DeleteProjectLabel) int
DeleteTask func(childComplexity int, input DeleteTaskInput) int
DeleteTaskGroup func(childComplexity int, input DeleteTaskGroupInput) int
LogoutUser func(childComplexity int, input LogoutUser) int
RemoveTaskLabel func(childComplexity int, input *RemoveTaskLabelInput) int
UnassignTask func(childComplexity int, input *UnassignTaskInput) int
UpdateProjectLabel func(childComplexity int, input UpdateProjectLabel) int
UpdateProjectLabelColor func(childComplexity int, input UpdateProjectLabelColor) int
UpdateProjectLabelName func(childComplexity int, input UpdateProjectLabelName) int
UpdateTaskDescription func(childComplexity int, input UpdateTaskDescriptionInput) int
UpdateTaskGroupLocation func(childComplexity int, input NewTaskGroupLocation) int
UpdateTaskLocation func(childComplexity int, input NewTaskLocation) int
@ -195,6 +199,10 @@ type MutationResolver interface {
CreateTeam(ctx context.Context, input NewTeam) (*pg.Team, error)
CreateProject(ctx context.Context, input NewProject) (*pg.Project, error)
CreateProjectLabel(ctx context.Context, input NewProjectLabel) (*pg.ProjectLabel, error)
DeleteProjectLabel(ctx context.Context, input DeleteProjectLabel) (*pg.ProjectLabel, error)
UpdateProjectLabel(ctx context.Context, input UpdateProjectLabel) (*pg.ProjectLabel, error)
UpdateProjectLabelName(ctx context.Context, input UpdateProjectLabelName) (*pg.ProjectLabel, error)
UpdateProjectLabelColor(ctx context.Context, input UpdateProjectLabelColor) (*pg.ProjectLabel, error)
CreateTaskGroup(ctx context.Context, input NewTaskGroup) (*pg.TaskGroup, error)
UpdateTaskGroupLocation(ctx context.Context, input NewTaskGroupLocation) (*pg.TaskGroup, error)
DeleteTaskGroup(ctx context.Context, input DeleteTaskGroupInput) (*DeleteTaskGroupPayload, error)
@ -445,6 +453,18 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
return e.complexity.Mutation.CreateUserAccount(childComplexity, args["input"].(NewUserAccount)), true
case "Mutation.deleteProjectLabel":
if e.complexity.Mutation.DeleteProjectLabel == nil {
break
}
args, err := ec.field_Mutation_deleteProjectLabel_args(context.TODO(), rawArgs)
if err != nil {
return 0, false
}
return e.complexity.Mutation.DeleteProjectLabel(childComplexity, args["input"].(DeleteProjectLabel)), true
case "Mutation.deleteTask":
if e.complexity.Mutation.DeleteTask == nil {
break
@ -505,6 +525,42 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
return e.complexity.Mutation.UnassignTask(childComplexity, args["input"].(*UnassignTaskInput)), true
case "Mutation.updateProjectLabel":
if e.complexity.Mutation.UpdateProjectLabel == nil {
break
}
args, err := ec.field_Mutation_updateProjectLabel_args(context.TODO(), rawArgs)
if err != nil {
return 0, false
}
return e.complexity.Mutation.UpdateProjectLabel(childComplexity, args["input"].(UpdateProjectLabel)), true
case "Mutation.updateProjectLabelColor":
if e.complexity.Mutation.UpdateProjectLabelColor == nil {
break
}
args, err := ec.field_Mutation_updateProjectLabelColor_args(context.TODO(), rawArgs)
if err != nil {
return 0, false
}
return e.complexity.Mutation.UpdateProjectLabelColor(childComplexity, args["input"].(UpdateProjectLabelColor)), true
case "Mutation.updateProjectLabelName":
if e.complexity.Mutation.UpdateProjectLabelName == nil {
break
}
args, err := ec.field_Mutation_updateProjectLabelName_args(context.TODO(), rawArgs)
if err != nil {
return 0, false
}
return e.complexity.Mutation.UpdateProjectLabelName(childComplexity, args["input"].(UpdateProjectLabelName)), true
case "Mutation.updateTaskDescription":
if e.complexity.Mutation.UpdateTaskDescription == nil {
break
@ -1277,6 +1333,26 @@ input NewProjectLabel {
name: String
}
input DeleteProjectLabel {
projectLabelID: UUID!
}
input UpdateProjectLabelName {
projectLabelID: UUID!
name: String!
}
input UpdateProjectLabel {
projectLabelID: UUID!
labelColorID: UUID!
name: String!
}
input UpdateProjectLabelColor {
projectLabelID: UUID!
labelColorID: UUID!
}
type Mutation {
createRefreshToken(input: NewRefreshToken!): RefreshToken!
@ -1285,7 +1361,12 @@ type Mutation {
createTeam(input: NewTeam!): Team!
createProject(input: NewProject!): Project!
createProjectLabel(input: NewProjectLabel!): ProjectLabel!
deleteProjectLabel(input: DeleteProjectLabel!): ProjectLabel!
updateProjectLabel(input: UpdateProjectLabel!): ProjectLabel!
updateProjectLabelName(input: UpdateProjectLabelName!): ProjectLabel!
updateProjectLabelColor(input: UpdateProjectLabelColor!): ProjectLabel!
createTaskGroup(input: NewTaskGroup!): TaskGroup!
updateTaskGroupLocation(input: NewTaskGroupLocation!): TaskGroup!
@ -1438,6 +1519,20 @@ func (ec *executionContext) field_Mutation_createUserAccount_args(ctx context.Co
return args, nil
}
func (ec *executionContext) field_Mutation_deleteProjectLabel_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
var err error
args := map[string]interface{}{}
var arg0 DeleteProjectLabel
if tmp, ok := rawArgs["input"]; ok {
arg0, err = ec.unmarshalNDeleteProjectLabel2githubᚗcomᚋjordanknottᚋprojectᚑcitadelᚋapiᚋgraphᚐDeleteProjectLabel(ctx, tmp)
if err != nil {
return nil, err
}
}
args["input"] = arg0
return args, nil
}
func (ec *executionContext) field_Mutation_deleteTaskGroup_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
var err error
args := map[string]interface{}{}
@ -1508,6 +1603,48 @@ func (ec *executionContext) field_Mutation_unassignTask_args(ctx context.Context
return args, nil
}
func (ec *executionContext) field_Mutation_updateProjectLabelColor_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
var err error
args := map[string]interface{}{}
var arg0 UpdateProjectLabelColor
if tmp, ok := rawArgs["input"]; ok {
arg0, err = ec.unmarshalNUpdateProjectLabelColor2githubᚗcomᚋjordanknottᚋprojectᚑcitadelᚋapiᚋgraphᚐUpdateProjectLabelColor(ctx, tmp)
if err != nil {
return nil, err
}
}
args["input"] = arg0
return args, nil
}
func (ec *executionContext) field_Mutation_updateProjectLabelName_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
var err error
args := map[string]interface{}{}
var arg0 UpdateProjectLabelName
if tmp, ok := rawArgs["input"]; ok {
arg0, err = ec.unmarshalNUpdateProjectLabelName2githubᚗcomᚋjordanknottᚋprojectᚑcitadelᚋapiᚋgraphᚐUpdateProjectLabelName(ctx, tmp)
if err != nil {
return nil, err
}
}
args["input"] = arg0
return args, nil
}
func (ec *executionContext) field_Mutation_updateProjectLabel_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
var err error
args := map[string]interface{}{}
var arg0 UpdateProjectLabel
if tmp, ok := rawArgs["input"]; ok {
arg0, err = ec.unmarshalNUpdateProjectLabel2githubᚗcomᚋjordanknottᚋprojectᚑcitadelᚋapiᚋgraphᚐUpdateProjectLabel(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) {
var err error
args := map[string]interface{}{}
@ -2147,6 +2284,170 @@ func (ec *executionContext) _Mutation_createProjectLabel(ctx context.Context, fi
return ec.marshalNProjectLabel2ᚖgithubᚗcomᚋjordanknottᚋprojectᚑcitadelᚋapiᚋpgᚐProjectLabel(ctx, field.Selections, res)
}
func (ec *executionContext) _Mutation_deleteProjectLabel(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_deleteProjectLabel_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().DeleteProjectLabel(rctx, args["input"].(DeleteProjectLabel))
})
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.ProjectLabel)
fc.Result = res
return ec.marshalNProjectLabel2ᚖgithubᚗcomᚋjordanknottᚋprojectᚑcitadelᚋapiᚋpgᚐProjectLabel(ctx, field.Selections, res)
}
func (ec *executionContext) _Mutation_updateProjectLabel(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_updateProjectLabel_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().UpdateProjectLabel(rctx, args["input"].(UpdateProjectLabel))
})
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.ProjectLabel)
fc.Result = res
return ec.marshalNProjectLabel2ᚖgithubᚗcomᚋjordanknottᚋprojectᚑcitadelᚋapiᚋpgᚐProjectLabel(ctx, field.Selections, res)
}
func (ec *executionContext) _Mutation_updateProjectLabelName(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_updateProjectLabelName_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().UpdateProjectLabelName(rctx, args["input"].(UpdateProjectLabelName))
})
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.ProjectLabel)
fc.Result = res
return ec.marshalNProjectLabel2ᚖgithubᚗcomᚋjordanknottᚋprojectᚑcitadelᚋapiᚋpgᚐProjectLabel(ctx, field.Selections, res)
}
func (ec *executionContext) _Mutation_updateProjectLabelColor(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_updateProjectLabelColor_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().UpdateProjectLabelColor(rctx, args["input"].(UpdateProjectLabelColor))
})
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.ProjectLabel)
fc.Result = res
return ec.marshalNProjectLabel2ᚖgithubᚗcomᚋjordanknottᚋprojectᚑcitadelᚋapiᚋpgᚐProjectLabel(ctx, field.Selections, res)
}
func (ec *executionContext) _Mutation_createTaskGroup(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
@ -5902,6 +6203,24 @@ func (ec *executionContext) unmarshalInputAssignTaskInput(ctx context.Context, o
return it, nil
}
func (ec *executionContext) unmarshalInputDeleteProjectLabel(ctx context.Context, obj interface{}) (DeleteProjectLabel, error) {
var it DeleteProjectLabel
var asMap = obj.(map[string]interface{})
for k, v := range asMap {
switch k {
case "projectLabelID":
var err error
it.ProjectLabelID, err = ec.unmarshalNUUID2githubᚗcomᚋgoogleᚋuuidᚐUUID(ctx, v)
if err != nil {
return it, err
}
}
}
return it, nil
}
func (ec *executionContext) unmarshalInputDeleteTaskGroupInput(ctx context.Context, obj interface{}) (DeleteTaskGroupInput, error) {
var it DeleteTaskGroupInput
var asMap = obj.(map[string]interface{})
@ -6334,6 +6653,84 @@ func (ec *executionContext) unmarshalInputUnassignTaskInput(ctx context.Context,
return it, nil
}
func (ec *executionContext) unmarshalInputUpdateProjectLabel(ctx context.Context, obj interface{}) (UpdateProjectLabel, error) {
var it UpdateProjectLabel
var asMap = obj.(map[string]interface{})
for k, v := range asMap {
switch k {
case "projectLabelID":
var err error
it.ProjectLabelID, err = ec.unmarshalNUUID2githubᚗcomᚋgoogleᚋuuidᚐUUID(ctx, v)
if err != nil {
return it, err
}
case "labelColorID":
var err error
it.LabelColorID, 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) unmarshalInputUpdateProjectLabelColor(ctx context.Context, obj interface{}) (UpdateProjectLabelColor, error) {
var it UpdateProjectLabelColor
var asMap = obj.(map[string]interface{})
for k, v := range asMap {
switch k {
case "projectLabelID":
var err error
it.ProjectLabelID, err = ec.unmarshalNUUID2githubᚗcomᚋgoogleᚋuuidᚐUUID(ctx, v)
if err != nil {
return it, err
}
case "labelColorID":
var err error
it.LabelColorID, err = ec.unmarshalNUUID2githubᚗcomᚋgoogleᚋuuidᚐUUID(ctx, v)
if err != nil {
return it, err
}
}
}
return it, nil
}
func (ec *executionContext) unmarshalInputUpdateProjectLabelName(ctx context.Context, obj interface{}) (UpdateProjectLabelName, error) {
var it UpdateProjectLabelName
var asMap = obj.(map[string]interface{})
for k, v := range asMap {
switch k {
case "projectLabelID":
var err error
it.ProjectLabelID, 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) {
var it UpdateTaskDescriptionInput
var asMap = obj.(map[string]interface{})
@ -6545,6 +6942,26 @@ func (ec *executionContext) _Mutation(ctx context.Context, sel ast.SelectionSet)
if out.Values[i] == graphql.Null {
invalids++
}
case "deleteProjectLabel":
out.Values[i] = ec._Mutation_deleteProjectLabel(ctx, field)
if out.Values[i] == graphql.Null {
invalids++
}
case "updateProjectLabel":
out.Values[i] = ec._Mutation_updateProjectLabel(ctx, field)
if out.Values[i] == graphql.Null {
invalids++
}
case "updateProjectLabelName":
out.Values[i] = ec._Mutation_updateProjectLabelName(ctx, field)
if out.Values[i] == graphql.Null {
invalids++
}
case "updateProjectLabelColor":
out.Values[i] = ec._Mutation_updateProjectLabelColor(ctx, field)
if out.Values[i] == graphql.Null {
invalids++
}
case "createTaskGroup":
out.Values[i] = ec._Mutation_createTaskGroup(ctx, field)
if out.Values[i] == graphql.Null {
@ -7700,6 +8117,10 @@ func (ec *executionContext) marshalNBoolean2bool(ctx context.Context, sel ast.Se
return res
}
func (ec *executionContext) unmarshalNDeleteProjectLabel2githubᚗcomᚋjordanknottᚋprojectᚑcitadelᚋapiᚋgraphᚐDeleteProjectLabel(ctx context.Context, v interface{}) (DeleteProjectLabel, error) {
return ec.unmarshalInputDeleteProjectLabel(ctx, v)
}
func (ec *executionContext) unmarshalNDeleteTaskGroupInput2githubᚗcomᚋjordanknottᚋprojectᚑcitadelᚋapiᚋgraphᚐDeleteTaskGroupInput(ctx context.Context, v interface{}) (DeleteTaskGroupInput, error) {
return ec.unmarshalInputDeleteTaskGroupInput(ctx, v)
}
@ -8261,6 +8682,18 @@ func (ec *executionContext) marshalNUUID2githubᚗcomᚋgoogleᚋuuidᚐUUID(ctx
return res
}
func (ec *executionContext) unmarshalNUpdateProjectLabel2githubᚗcomᚋjordanknottᚋprojectᚑcitadelᚋapiᚋgraphᚐUpdateProjectLabel(ctx context.Context, v interface{}) (UpdateProjectLabel, error) {
return ec.unmarshalInputUpdateProjectLabel(ctx, v)
}
func (ec *executionContext) unmarshalNUpdateProjectLabelColor2githubᚗcomᚋjordanknottᚋprojectᚑcitadelᚋapiᚋgraphᚐUpdateProjectLabelColor(ctx context.Context, v interface{}) (UpdateProjectLabelColor, error) {
return ec.unmarshalInputUpdateProjectLabelColor(ctx, v)
}
func (ec *executionContext) unmarshalNUpdateProjectLabelName2githubᚗcomᚋjordanknottᚋprojectᚑcitadelᚋapiᚋgraphᚐUpdateProjectLabelName(ctx context.Context, v interface{}) (UpdateProjectLabelName, error) {
return ec.unmarshalInputUpdateProjectLabelName(ctx, v)
}
func (ec *executionContext) unmarshalNUpdateTaskDescriptionInput2githubᚗcomᚋjordanknottᚋprojectᚑcitadelᚋapiᚋgraphᚐUpdateTaskDescriptionInput(ctx context.Context, v interface{}) (UpdateTaskDescriptionInput, error) {
return ec.unmarshalInputUpdateTaskDescriptionInput(ctx, v)
}

View File

@ -17,6 +17,10 @@ type AssignTaskInput struct {
UserID uuid.UUID `json:"userID"`
}
type DeleteProjectLabel struct {
ProjectLabelID uuid.UUID `json:"projectLabelID"`
}
type DeleteTaskGroupInput struct {
TaskGroupID uuid.UUID `json:"taskGroupID"`
}
@ -130,6 +134,22 @@ type UnassignTaskInput struct {
UserID uuid.UUID `json:"userID"`
}
type UpdateProjectLabel struct {
ProjectLabelID uuid.UUID `json:"projectLabelID"`
LabelColorID uuid.UUID `json:"labelColorID"`
Name string `json:"name"`
}
type UpdateProjectLabelColor struct {
ProjectLabelID uuid.UUID `json:"projectLabelID"`
LabelColorID uuid.UUID `json:"labelColorID"`
}
type UpdateProjectLabelName struct {
ProjectLabelID uuid.UUID `json:"projectLabelID"`
Name string `json:"name"`
}
type UpdateTaskDescriptionInput struct {
TaskID uuid.UUID `json:"taskID"`
Description string `json:"description"`

View File

@ -218,6 +218,26 @@ input NewProjectLabel {
name: String
}
input DeleteProjectLabel {
projectLabelID: UUID!
}
input UpdateProjectLabelName {
projectLabelID: UUID!
name: String!
}
input UpdateProjectLabel {
projectLabelID: UUID!
labelColorID: UUID!
name: String!
}
input UpdateProjectLabelColor {
projectLabelID: UUID!
labelColorID: UUID!
}
type Mutation {
createRefreshToken(input: NewRefreshToken!): RefreshToken!
@ -226,7 +246,12 @@ type Mutation {
createTeam(input: NewTeam!): Team!
createProject(input: NewProject!): Project!
createProjectLabel(input: NewProjectLabel!): ProjectLabel!
deleteProjectLabel(input: DeleteProjectLabel!): ProjectLabel!
updateProjectLabel(input: UpdateProjectLabel!): ProjectLabel!
updateProjectLabelName(input: UpdateProjectLabelName!): ProjectLabel!
updateProjectLabelColor(input: UpdateProjectLabelColor!): ProjectLabel!
createTaskGroup(input: NewTaskGroup!): TaskGroup!
updateTaskGroupLocation(input: NewTaskGroupLocation!): TaskGroup!

View File

@ -69,6 +69,30 @@ func (r *mutationResolver) CreateProjectLabel(ctx context.Context, input NewProj
return &projectLabel, err
}
func (r *mutationResolver) DeleteProjectLabel(ctx context.Context, input DeleteProjectLabel) (*pg.ProjectLabel, error) {
label, err := r.Repository.GetProjectLabelByID(ctx, input.ProjectLabelID)
if err != nil {
return &pg.ProjectLabel{}, err
}
err = r.Repository.DeleteProjectLabelByID(ctx, input.ProjectLabelID)
return &label, err
}
func (r *mutationResolver) UpdateProjectLabel(ctx context.Context, input UpdateProjectLabel) (*pg.ProjectLabel, error) {
label, err := r.Repository.UpdateProjectLabel(ctx, pg.UpdateProjectLabelParams{ProjectLabelID: input.ProjectLabelID, LabelColorID: input.LabelColorID, Name: sql.NullString{String: input.Name, Valid: true}})
return &label, err
}
func (r *mutationResolver) UpdateProjectLabelName(ctx context.Context, input UpdateProjectLabelName) (*pg.ProjectLabel, error) {
label, err := r.Repository.UpdateProjectLabelName(ctx, pg.UpdateProjectLabelNameParams{ProjectLabelID: input.ProjectLabelID, Name: sql.NullString{String: input.Name, Valid: true}})
return &label, err
}
func (r *mutationResolver) UpdateProjectLabelColor(ctx context.Context, input UpdateProjectLabelColor) (*pg.ProjectLabel, error) {
label, err := r.Repository.UpdateProjectLabelColor(ctx, pg.UpdateProjectLabelColorParams{ProjectLabelID: input.ProjectLabelID, LabelColorID: input.LabelColorID})
return &label, err
}
func (r *mutationResolver) CreateTaskGroup(ctx context.Context, input NewTaskGroup) (*pg.TaskGroup, error) {
createdAt := time.Now().UTC()
projectID, err := uuid.Parse(input.ProjectID)

View File

@ -25,6 +25,10 @@ type Repository interface {
CreateProjectLabel(ctx context.Context, arg CreateProjectLabelParams) (ProjectLabel, error)
GetProjectLabelsForProject(ctx context.Context, projectID uuid.UUID) ([]ProjectLabel, error)
GetProjectLabelByID(ctx context.Context, projectLabelID uuid.UUID) (ProjectLabel, error)
DeleteProjectLabelByID(ctx context.Context, projectLabelID uuid.UUID) error
UpdateProjectLabelColor(ctx context.Context, arg UpdateProjectLabelColorParams) (ProjectLabel, error)
UpdateProjectLabelName(ctx context.Context, arg UpdateProjectLabelNameParams) (ProjectLabel, error)
UpdateProjectLabel(ctx context.Context, arg UpdateProjectLabelParams) (ProjectLabel, error)
GetLabelColors(ctx context.Context) ([]LabelColor, error)
CreateLabelColor(ctx context.Context, arg CreateLabelColorParams) (LabelColor, error)

View File

@ -41,6 +41,15 @@ func (q *Queries) CreateProjectLabel(ctx context.Context, arg CreateProjectLabel
return i, err
}
const deleteProjectLabelByID = `-- name: DeleteProjectLabelByID :exec
DELETE FROM project_label WHERE project_label_id = $1
`
func (q *Queries) DeleteProjectLabelByID(ctx context.Context, projectLabelID uuid.UUID) error {
_, err := q.db.ExecContext(ctx, deleteProjectLabelByID, projectLabelID)
return err
}
const getProjectLabelByID = `-- name: GetProjectLabelByID :one
SELECT project_label_id, project_id, label_color_id, created_date, name FROM project_label WHERE project_label_id = $1
`
@ -90,3 +99,70 @@ func (q *Queries) GetProjectLabelsForProject(ctx context.Context, projectID uuid
}
return items, nil
}
const updateProjectLabel = `-- name: UpdateProjectLabel :one
UPDATE project_label SET name = $2, label_color_id = $3 WHERE project_label_id = $1 RETURNING project_label_id, project_id, label_color_id, created_date, name
`
type UpdateProjectLabelParams struct {
ProjectLabelID uuid.UUID `json:"project_label_id"`
Name sql.NullString `json:"name"`
LabelColorID uuid.UUID `json:"label_color_id"`
}
func (q *Queries) UpdateProjectLabel(ctx context.Context, arg UpdateProjectLabelParams) (ProjectLabel, error) {
row := q.db.QueryRowContext(ctx, updateProjectLabel, arg.ProjectLabelID, arg.Name, arg.LabelColorID)
var i ProjectLabel
err := row.Scan(
&i.ProjectLabelID,
&i.ProjectID,
&i.LabelColorID,
&i.CreatedDate,
&i.Name,
)
return i, err
}
const updateProjectLabelColor = `-- name: UpdateProjectLabelColor :one
UPDATE project_label SET label_color_id = $2 WHERE project_label_id = $1 RETURNING project_label_id, project_id, label_color_id, created_date, name
`
type UpdateProjectLabelColorParams struct {
ProjectLabelID uuid.UUID `json:"project_label_id"`
LabelColorID uuid.UUID `json:"label_color_id"`
}
func (q *Queries) UpdateProjectLabelColor(ctx context.Context, arg UpdateProjectLabelColorParams) (ProjectLabel, error) {
row := q.db.QueryRowContext(ctx, updateProjectLabelColor, arg.ProjectLabelID, arg.LabelColorID)
var i ProjectLabel
err := row.Scan(
&i.ProjectLabelID,
&i.ProjectID,
&i.LabelColorID,
&i.CreatedDate,
&i.Name,
)
return i, err
}
const updateProjectLabelName = `-- name: UpdateProjectLabelName :one
UPDATE project_label SET name = $2 WHERE project_label_id = $1 RETURNING project_label_id, project_id, label_color_id, created_date, name
`
type UpdateProjectLabelNameParams struct {
ProjectLabelID uuid.UUID `json:"project_label_id"`
Name sql.NullString `json:"name"`
}
func (q *Queries) UpdateProjectLabelName(ctx context.Context, arg UpdateProjectLabelNameParams) (ProjectLabel, error) {
row := q.db.QueryRowContext(ctx, updateProjectLabelName, arg.ProjectLabelID, arg.Name)
var i ProjectLabel
err := row.Scan(
&i.ProjectLabelID,
&i.ProjectID,
&i.LabelColorID,
&i.CreatedDate,
&i.Name,
)
return i, err
}

View File

@ -21,6 +21,7 @@ type Querier interface {
CreateTeam(ctx context.Context, arg CreateTeamParams) (Team, error)
CreateUserAccount(ctx context.Context, arg CreateUserAccountParams) (UserAccount, error)
DeleteExpiredTokens(ctx context.Context) error
DeleteProjectLabelByID(ctx context.Context, projectLabelID uuid.UUID) error
DeleteRefreshTokenByID(ctx context.Context, tokenID uuid.UUID) error
DeleteRefreshTokenByUserID(ctx context.Context, userID uuid.UUID) error
DeleteTaskAssignedByID(ctx context.Context, arg DeleteTaskAssignedByIDParams) (TaskAssigned, error)
@ -51,6 +52,9 @@ type Querier interface {
GetTeamsForOrganization(ctx context.Context, organizationID uuid.UUID) ([]Team, error)
GetUserAccountByID(ctx context.Context, userID uuid.UUID) (UserAccount, error)
GetUserAccountByUsername(ctx context.Context, username string) (UserAccount, error)
UpdateProjectLabel(ctx context.Context, arg UpdateProjectLabelParams) (ProjectLabel, error)
UpdateProjectLabelColor(ctx context.Context, arg UpdateProjectLabelColorParams) (ProjectLabel, error)
UpdateProjectLabelName(ctx context.Context, arg UpdateProjectLabelNameParams) (ProjectLabel, error)
UpdateTaskDescription(ctx context.Context, arg UpdateTaskDescriptionParams) (Task, error)
UpdateTaskGroupLocation(ctx context.Context, arg UpdateTaskGroupLocationParams) (TaskGroup, error)
UpdateTaskLocation(ctx context.Context, arg UpdateTaskLocationParams) (Task, error)

View File

@ -7,3 +7,15 @@ SELECT * FROM project_label WHERE project_id = $1;
-- name: GetProjectLabelByID :one
SELECT * FROM project_label WHERE project_label_id = $1;
-- name: DeleteProjectLabelByID :exec
DELETE FROM project_label WHERE project_label_id = $1;
-- name: UpdateProjectLabelName :one
UPDATE project_label SET name = $2 WHERE project_label_id = $1 RETURNING *;
-- name: UpdateProjectLabelColor :one
UPDATE project_label SET label_color_id = $2 WHERE project_label_id = $1 RETURNING *;
-- name: UpdateProjectLabel :one
UPDATE project_label SET name = $2, label_color_id = $3 WHERE project_label_id = $1 RETURNING *;

View File

@ -30,6 +30,7 @@
"@types/react-router": "^5.1.4",
"@types/react-router-dom": "^5.1.3",
"@types/styled-components": "^5.0.0",
"@welldone-software/why-did-you-render": "^4.2.2",
"apollo-cache-inmemory": "^1.6.5",
"apollo-client": "^2.6.8",
"apollo-link": "^1.2.13",
@ -52,6 +53,7 @@
"react-datepicker": "^2.14.1",
"react-dom": "^16.12.0",
"react-hook-form": "^5.2.0",
"react-markdown": "^4.3.1",
"react-router": "^5.1.2",
"react-router-dom": "^5.1.2",
"react-scripts": "3.4.0",

View File

@ -16,7 +16,7 @@ const Routes = ({ history }: RoutesProps) => (
<Route exact path="/login" component={Login} />
<Route exact path="/" component={Dashboard} />
<Route exact path="/projects" component={Projects} />
<Route path="/projects/:projectId" component={Project} />
<Route path="/projects/:projectID" component={Project} />
</Switch>
);

View File

@ -41,7 +41,6 @@ const GlobalTopNavbar: React.FC<GlobalTopNavbarProps> = ({ name, projectMembers
if (!userID) {
return null;
}
console.log(data);
return (
<>
<TopNavbar
@ -50,7 +49,7 @@ const GlobalTopNavbar: React.FC<GlobalTopNavbarProps> = ({ name, projectMembers
firstName={data ? data.me.firstName : ''}
lastName={data ? data.me.lastName : ''}
initials={!data ? '' : data.me.profileIcon.initials ?? ''}
onNotificationClick={() => console.log('beep')}
onNotificationClick={() => {}}
projectMembers={projectMembers}
onProfileClick={onProfileClick}
/>

View File

@ -106,7 +106,6 @@ const Details: React.FC<DetailsProps> = ({
);
}}
onOpenAddMemberPopup={(task, $targetRef) => {
console.log(`task: ${task.taskID}`);
showPopup(
$targetRef,
<Popup title="Members" tab={0} onClose={() => {}}>
@ -114,13 +113,11 @@ const Details: React.FC<DetailsProps> = ({
availableMembers={availableMembers}
activeMembers={taskMembers}
onMemberChange={(member, isActive) => {
console.log(`is active ${member.userID} - ${isActive}`);
if (isActive) {
assignTask({ variables: { taskID: data.findTask.id, userID: userID ?? '' } });
} else {
unassignTask({ variables: { taskID: data.findTask.id, userID: userID ?? '' } });
}
console.log(member, isActive);
}}
/>
</Popup>,

View File

@ -8,7 +8,9 @@ import { useParams, Route, useRouteMatch, useHistory, RouteComponentProps } from
import {
useFindProjectQuery,
useUpdateTaskNameMutation,
useUpdateProjectLabelMutation,
useCreateTaskMutation,
useDeleteProjectLabelMutation,
useDeleteTaskMutation,
useUpdateTaskLocationMutation,
useUpdateTaskGroupLocationMutation,
@ -31,8 +33,28 @@ import { mixin } from 'shared/utils/styles';
import LabelManager from 'shared/components/PopupMenu/LabelManager';
import LabelEditor from 'shared/components/PopupMenu/LabelEditor';
import produce from 'immer';
import Details from './Details';
import MiniProfile from 'shared/components/MiniProfile';
import Details from './Details';
const getCacheData = (client: any, projectID: string) => {
const cacheData: any = client.readQuery({
query: FindProjectDocument,
variables: {
projectId: projectID,
},
});
return cacheData;
};
const writeCacheData = (client: any, projectID: string, cacheData: any, newData: any) => {
client.writeQuery({
query: FindProjectDocument,
variables: {
projectId: projectID,
},
data: { ...cacheData, findProject: newData },
});
};
type TaskRouteProps = {
taskID: string;
@ -63,15 +85,37 @@ const ProjectMembers = styled.div`
`;
type LabelManagerEditorProps = {
labels: Array<Label>;
labels: React.RefObject<Array<Label>>;
projectID: string;
labelColors: Array<LabelColor>;
};
const LabelManagerEditor: React.FC<LabelManagerEditorProps> = ({ labels: initialLabels, projectID, labelColors }) => {
const [labels, setLabels] = useState<Array<Label>>(initialLabels);
const LabelManagerEditor: React.FC<LabelManagerEditorProps> = ({ labels: labelsRef, projectID, labelColors }) => {
const [currentLabel, setCurrentLabel] = useState('');
const [createProjectLabel] = useCreateProjectLabelMutation();
const [createProjectLabel] = useCreateProjectLabelMutation({
update: (client, newLabelData) => {
const cacheData = getCacheData(client, projectID);
const newData = {
...cacheData.findProject,
labels: [...cacheData.findProject.labels, { ...newLabelData.data.createProjectLabel }],
};
writeCacheData(client, projectID, cacheData, newData);
},
});
const [updateProjectLabel] = useUpdateProjectLabelMutation();
const [deleteProjectLabel] = useDeleteProjectLabelMutation({
update: (client, newLabelData) => {
const cacheData = getCacheData(client, projectID);
const newData = {
...cacheData.findProject,
labels: cacheData.findProject.labels.filter(
(label: any) => label.id !== newLabelData.data.deleteProjectLabel.id,
),
};
writeCacheData(client, projectID, cacheData, newData);
},
});
const labels = labelsRef.current ? labelsRef.current : [];
const { setTab } = usePopup();
return (
<>
@ -95,15 +139,14 @@ const LabelManagerEditor: React.FC<LabelManagerEditorProps> = ({ labels: initial
<LabelEditor
labelColors={labelColors}
label={labels.find(label => label.labelId === currentLabel) ?? null}
onLabelEdit={(_labelId, name, color) => {
setLabels(
produce(labels, draftState => {
const idx = labels.findIndex(label => label.labelId === currentLabel);
if (idx !== -1) {
draftState[idx] = { ...draftState[idx], name, labelColor: color };
}
}),
);
onLabelEdit={(projectLabelID, name, color) => {
if (projectLabelID) {
updateProjectLabel({ variables: { projectLabelID, labelColorID: color.id, name } });
}
setTab(0);
}}
onLabelDelete={labelID => {
deleteProjectLabel({ variables: { projectLabelID: labelID } });
setTab(0);
}}
/>
@ -113,8 +156,6 @@ const LabelManagerEditor: React.FC<LabelManagerEditorProps> = ({ labels: initial
labelColors={labelColors}
label={null}
onLabelEdit={(_labelId, name, color) => {
console.log(name, color);
setLabels([...labels, { labelId: name, name, labelColor: color, active: false }]);
createProjectLabel({ variables: { projectID, labelColorID: color.id, name } });
setTab(0);
}}
@ -125,13 +166,12 @@ const LabelManagerEditor: React.FC<LabelManagerEditorProps> = ({ labels: initial
};
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 initialLabelsPopupState = { taskID: '', isOpen: false, top: 0, left: 0 };
const initialTaskDetailsState = { isOpen: false, taskID: '' };
const ProjectBar = styled.div`
@ -168,14 +208,11 @@ const ProjectActionText = styled.span`
`;
const Project = () => {
const { projectId } = useParams<ProjectParams>();
const { projectID } = useParams<ProjectParams>();
const match = useRouteMatch();
const history = useHistory();
const [updateTaskDescription] = useUpdateTaskDescriptionMutation();
const [listsData, setListsData] = useState(initialState);
const [popupData, setPopupData] = useState(initialPopupState);
const [taskDetails, setTaskDetails] = useState(initialTaskDetailsState);
const [quickCardEditor, setQuickCardEditor] = useState(initialQuickCardEditorState);
const [updateTaskLocation] = useUpdateTaskLocationMutation();
const [updateTaskGroupLocation] = useUpdateTaskGroupLocationMutation();
@ -184,6 +221,17 @@ const Project = () => {
onCompleted: deletedTaskGroupData => {
setListsData(BoardStateUtils.deleteTaskGroup(listsData, deletedTaskGroupData.deleteTaskGroup.taskGroup.id));
},
update: (client, deletedTaskGroupData) => {
const cacheData = getCacheData(client, projectID);
const newData = {
...cacheData.findProject,
taskGroups: cacheData.findProject.taskGroups.filter(
(taskGroup: any) => taskGroup.id !== deletedTaskGroupData.data.deleteTaskGroup.taskGroup.id,
),
};
writeCacheData(client, projectID, cacheData, newData);
},
});
const [createTaskGroup] = useCreateTaskGroupMutation({
@ -195,6 +243,15 @@ const Project = () => {
};
setListsData(BoardStateUtils.addTaskGroup(listsData, newTaskGroup));
},
update: (client, newTaskGroupData) => {
const cacheData = getCacheData(client, projectID);
const newData = {
...cacheData.findProject,
taskGroups: [...cacheData.findProject.taskGroups, { ...newTaskGroupData.data.createTaskGroup, tasks: [] }],
};
writeCacheData(client, projectID, cacheData, newData);
},
});
const [createTask] = useCreateTaskMutation({
@ -208,14 +265,7 @@ const Project = () => {
setListsData(BoardStateUtils.addTask(listsData, newTask));
},
update: (client, newTaskData) => {
const cacheData: any = client.readQuery({
query: FindProjectDocument,
variables: {
projectId: projectId,
},
});
console.log(cacheData);
console.log(newTaskData);
const cacheData = getCacheData(client, projectID);
const newTaskGroups = produce(cacheData.findProject.taskGroups, (draftState: any) => {
const targetIndex = draftState.findIndex(
(taskGroup: any) => taskGroup.id === newTaskData.data.createTask.taskGroup.id,
@ -225,18 +275,11 @@ const Project = () => {
tasks: [...draftState[targetIndex].tasks, { ...newTaskData.data.createTask }],
};
});
console.log(newTaskGroups);
const newData = {
...cacheData.findProject,
taskGroups: newTaskGroups,
};
client.writeQuery({
query: FindProjectDocument,
variables: {
projectId: projectId,
},
data: { findProject: newData },
});
writeCacheData(client, projectID, cacheData, newData);
},
});
@ -254,9 +297,8 @@ const Project = () => {
},
});
const { loading, data, refetch } = useFindProjectQuery({
variables: { projectId },
variables: { projectId: projectID },
});
console.log(`loading ${loading} - ${data}`);
const onCardCreate = (taskGroupID: string, name: string) => {
const taskGroupTasks = Object.values(listsData.tasks).filter(
@ -278,14 +320,29 @@ const Project = () => {
taskGroupID: droppedTask.taskGroup.taskGroupID,
position: droppedTask.position,
},
optimisticResponse: {
updateTaskLocation: {
name: droppedTask.name,
id: droppedTask.taskID,
position: droppedTask.position,
createdAt: '',
},
},
});
setListsData(BoardStateUtils.updateTask(listsData, droppedTask));
};
const onListDrop = (droppedColumn: TaskGroup) => {
console.log(`list drop ${droppedColumn.taskGroupID}`);
updateTaskGroupLocation({
variables: { taskGroupID: droppedColumn.taskGroupID, position: droppedColumn.position },
optimisticResponse: {
updateTaskGroupLocation: {
id: droppedColumn.taskGroupID,
position: droppedColumn.position,
},
},
});
setListsData(BoardStateUtils.updateTaskGroup(listsData, droppedColumn));
// setListsData(BoardStateUtils.updateTaskGroup(listsData, droppedColumn));
};
const onCreateList = (listName: string) => {
@ -296,13 +353,14 @@ const Project = () => {
if (lastColumn) {
position = lastColumn.position * 2 + 1;
}
createTaskGroup({ variables: { projectID: projectId, name: listName, position } });
createTaskGroup({ variables: { projectID, name: listName, position } });
};
const [assignTask] = useAssignTaskMutation();
const { showPopup } = usePopup();
const { showPopup, hidePopup } = usePopup();
const $labelsRef = useRef<HTMLDivElement>(null);
const labelsRef = useRef<Array<Label>>([]);
if (loading) {
return (
<>
@ -312,6 +370,7 @@ const Project = () => {
);
}
if (data) {
console.log(data);
const currentListsData: BoardState = { tasks: {}, columns: {} };
data.findProject.taskGroups.forEach(taskGroup => {
currentListsData.columns[taskGroup.id] = {
@ -358,7 +417,6 @@ const Project = () => {
});
const onQuickEditorOpen = (e: ContextMenuEvent) => {
const currentTask = Object.values(currentListsData.tasks).find(task => task.taskID === e.taskID);
console.log(`currentTask: ${currentTask?.taskID}`);
setQuickCardEditor({
top: e.top,
left: e.left,
@ -367,6 +425,14 @@ const Project = () => {
});
};
labelsRef.current = data.findProject.labels.map(label => {
return {
labelId: label.id,
name: label.name ?? '',
labelColor: label.labelColor,
active: false,
};
});
return (
<>
<GlobalTopNavbar projectMembers={availableMembers} name={data.findProject.name} />
@ -377,18 +443,7 @@ const Project = () => {
onClick={() => {
showPopup(
$labelsRef,
<LabelManagerEditor
labelColors={data.labelColors}
labels={data.findProject.labels.map(label => {
return {
labelId: label.id,
name: label.name ?? '',
labelColor: label.labelColor,
active: false,
};
})}
projectID={projectId}
/>,
<LabelManagerEditor labelColors={data.labelColors} labels={labelsRef} projectID={projectID} />,
);
}}
>
@ -436,7 +491,7 @@ const Project = () => {
taskGroupID={taskGroupID}
onArchiveTaskGroup={tgID => {
deleteTaskGroup({ variables: { taskGroupID: tgID } });
setPopupData(initialPopupState);
hidePopup();
}}
/>
</Popup>,
@ -453,17 +508,12 @@ const Project = () => {
onEditCard={(_listId: string, cardId: string, cardName: string) => {
updateTaskName({ variables: { taskID: cardId, name: cardName } });
}}
onOpenPopup={() => console.log()}
onOpenPopup={() => {}}
onArchiveCard={(_listId: string, cardId: string) =>
deleteTask({
variables: { taskID: cardId },
update: client => {
const cacheData: any = client.readQuery({
query: FindProjectDocument,
variables: {
projectId: projectId,
},
});
const cacheData = getCacheData(client, projectID);
const newData = {
...cacheData.findProject,
taskGroups: cacheData.findProject.taskGroups.map((taskGroup: any) => {
@ -473,13 +523,7 @@ const Project = () => {
};
}),
};
client.writeQuery({
query: FindProjectDocument,
variables: {
projectId: projectId,
},
data: { findProject: newData },
});
writeCacheData(client, projectID, cacheData, newData);
},
})
}
@ -492,10 +536,7 @@ const Project = () => {
path={`${match.path}/c/:taskID`}
render={(routeProps: RouteComponentProps<TaskRouteProps>) => (
<Details
refreshCache={() => {
console.log('beep 2!');
// refetch();
}}
refreshCache={() => {}}
availableMembers={availableMembers}
projectURL={match.url}
taskID={routeProps.match.params.taskID}
@ -506,7 +547,6 @@ const Project = () => {
updateTaskDescription({ variables: { taskID: updatedTask.taskID, description: newDescription } });
}}
onDeleteTask={deletedTask => {
setTaskDetails(initialTaskDetailsState);
deleteTask({ variables: { taskID: deletedTask.taskID } });
}}
onOpenAddLabelPopup={(task, $targetRef) => {}}

View File

@ -30,7 +30,6 @@ const ProjectLink = styled(Link)`
const Projects = () => {
const { loading, data } = useGetProjectsQuery();
console.log(loading, data);
if (loading) {
return (
<>

View File

@ -1,4 +1,5 @@
import React from 'react';
import ReactDOM from 'react-dom';
import { ApolloProvider } from '@apollo/react-hooks';
import { ApolloClient } from 'apollo-client';

View File

@ -168,7 +168,9 @@ const Card = React.forwardRef(
</ListCardBadges>
<CardMembers>
{members &&
members.map(member => <Member taskID={taskID} member={member} onCardMemberClick={onCardMemberClick} />)}
members.map(member => (
<Member key={member.userID} taskID={taskID} member={member} onCardMemberClick={onCardMemberClick} />
))}
</CardMembers>
</ListCardDetails>
</ListCardInnerContainer>

View File

@ -74,8 +74,6 @@ const Lists: React.FC<Props> = ({
}),
);
console.log(beforeDropDraggables);
console.log(destination);
const afterDropDraggables = getAfterDropDraggableList(
beforeDropDraggables,
droppedDraggable,
@ -83,19 +81,16 @@ const Lists: React.FC<Props> = ({
isSameList,
destination,
);
console.log(afterDropDraggables);
const newPosition = getNewDraggablePosition(afterDropDraggables, destination.index);
if (isList) {
const droppedList = columns[droppedDraggable.id];
console.log(`is list ${droppedList}`);
onListDrop({
...droppedList,
position: newPosition,
});
} else {
const droppedCard = tasks[droppedDraggable.id];
console.log(`is card ${droppedCard}`);
const newCard = {
...droppedCard,
position: newPosition,
@ -112,6 +107,7 @@ const Lists: React.FC<Props> = ({
return { id: column.taskGroupID, position: column.position };
}),
);
console.log(orderedColumns);
const [currentComposer, setCurrentComposer] = useState('');
return (
@ -134,7 +130,7 @@ const Lists: React.FC<Props> = ({
name={column.name}
onOpenComposer={id => setCurrentComposer(id)}
isComposerOpen={currentComposer === column.taskGroupID}
onSaveName={name => console.log(name)}
onSaveName={name => {}}
tasks={columnCards}
ref={columnDragProvided.innerRef}
wrapperProps={columnDragProvided.draggableProps}

View File

@ -23,7 +23,6 @@ import {
const Login = ({ onSubmit }: LoginProps) => {
const [isComplete, setComplete] = useState(true);
const { register, handleSubmit, errors, setError, formState } = useForm<LoginFormData>();
console.log(formState);
const loginSubmit = (data: LoginFormData) => {
setComplete(false);
onSubmit(data, setComplete, setError);

View File

@ -1,4 +1,4 @@
import React, { useState } from 'react';
import React, { useState, useEffect, useRef } from 'react';
import LabelColors from 'shared/constants/labelColors';
import { Checkmark } from 'shared/icons';
import { SaveButton, DeleteButton, LabelBox, EditLabelForm, FieldLabel, FieldName } from './Styles';
@ -7,16 +7,25 @@ type Props = {
labelColors: Array<LabelColor>;
label: Label | null;
onLabelEdit: (labelId: string | null, labelName: string, labelColor: LabelColor) => void;
onLabelDelete?: (labelId: string) => void;
};
const LabelManager = ({ labelColors, label, onLabelEdit }: Props) => {
console.log(label);
const LabelManager = ({ labelColors, label, onLabelEdit, onLabelDelete }: Props) => {
const $fieldName = useRef<HTMLInputElement>(null);
const [currentLabel, setCurrentLabel] = useState(label ? label.name : '');
const [currentColor, setCurrentColor] = useState<LabelColor | null>(label ? label.labelColor : null);
useEffect(() => {
if ($fieldName.current) {
$fieldName.current.focus();
}
}, []);
return (
<EditLabelForm>
<FieldLabel>Name</FieldLabel>
<FieldName
ref={$fieldName}
id="labelName"
type="text"
name="name"
@ -29,6 +38,7 @@ const LabelManager = ({ labelColors, label, onLabelEdit }: Props) => {
<div>
{labelColors.map((labelColor: LabelColor) => (
<LabelBox
key={labelColor.id}
color={labelColor.colorHex}
onClick={() => {
setCurrentColor(labelColor);
@ -40,6 +50,8 @@ const LabelManager = ({ labelColors, label, onLabelEdit }: Props) => {
</div>
<div>
<SaveButton
value="Save"
type="submit"
onClick={e => {
e.preventDefault();
console.log(currentColor);
@ -47,10 +59,17 @@ const LabelManager = ({ labelColors, label, onLabelEdit }: Props) => {
onLabelEdit(label ? label.labelId : null, currentLabel, currentColor);
}
}}
type="submit"
value="Save"
/>
<DeleteButton type="submit" value="Delete" />
{label && onLabelDelete && (
<DeleteButton
value="Delete"
type="submit"
onClick={e => {
e.preventDefault();
onLabelDelete(label.labelId);
}}
/>
)}
</div>
</EditLabelForm>
);

View File

@ -1,4 +1,4 @@
import React, { useState } from 'react';
import React, { useState, useEffect, useRef } from 'react';
import { Pencil, Checkmark } from 'shared/icons';
import {
@ -20,12 +20,19 @@ type Props = {
onLabelCreate: () => void;
};
const LabelManager: React.FC<Props> = ({ labels, onLabelToggle, onLabelEdit, onLabelCreate }) => {
const $fieldName = useRef<HTMLInputElement>(null);
const [currentLabel, setCurrentLabel] = useState('');
const [currentSearch, setCurrentSearch] = useState('');
useEffect(() => {
if ($fieldName.current) {
$fieldName.current.focus();
}
}, []);
return (
<>
<LabelSearch
type="text"
ref={$fieldName}
placeholder="search labels..."
onChange={e => {
setCurrentSearch(e.currentTarget.value);

View File

@ -248,36 +248,47 @@ export const LabelBox = styled.span<{ color: string }>`
`;
export const SaveButton = styled.input`
cursor: pointer;
background-color: #5aac44;
background: rgb(115, 103, 240);
box-shadow: none;
border: none;
color: #fff;
padding-left: 24px;
padding-right: 24px;
ursor: pointer;
cursor: pointer;
display: inline-block;
font-weight: 400;
line-height: 20px;
margin: 8px 4px 0 0;
margin-right: 4px;
padding: 6px 12px;
text-align: center;
border-radius: 3px;
`;
export const DeleteButton = styled.input`
background-color: #cf513d;
box-shadow: none;
border: none;
color: #fff;
cursor: pointer;
type="submit"font-weight: 400;
line-height: 20px;
margin: 8px 4px 0 0;
padding: 6px 12px;
text-align: center;
border-radius: 3px;
float: right;
outline: none;
border: none;
line-height: 20px;
padding: 6px 12px;
background-color: transparent;
text-align: center;
color: #c2c6dc;
font-weight: 400;
line-height: 20px;
cursor: pointer;
margin: 0 0 0 8px;
border-radius: 3px;
border-width: 1px;
border-style: solid;
border-color: transparent;
border-image: initial;
border-color: #414561;
&:hover {
color: #fff;
background: rgb(115, 103, 240);
border-color: transparent;
}
`;
export const CreateLabelButton = styled.button`

View File

@ -18,6 +18,7 @@ type PopupContextState = {
show: (target: RefObject<HTMLElement>, content: JSX.Element) => void;
setTab: (newTab: number) => void;
getCurrentTab: () => number;
hide: () => void;
};
type PopupProps = {
@ -46,11 +47,12 @@ const PopupContext = createContext<PopupContextState>({
show: () => {},
setTab: () => {},
getCurrentTab: () => 0,
hide: () => {},
});
export const usePopup = () => {
const ctx = useContext<PopupContextState>(PopupContext);
return { showPopup: ctx.show, setTab: ctx.setTab, getCurrentTab: ctx.getCurrentTab };
return { showPopup: ctx.show, setTab: ctx.setTab, getCurrentTab: ctx.getCurrentTab, hidePopup: ctx.hide };
};
type PopupState = {
@ -80,11 +82,9 @@ const defaultState = {
export const PopupProvider: React.FC = ({ children }) => {
const [currentState, setState] = useState<PopupState>(defaultState);
const show = (target: RefObject<HTMLElement>, content: JSX.Element) => {
console.log(target);
if (target && target.current) {
const bounds = target.current.getBoundingClientRect();
if (bounds.left + 304 + 30 > window.innerWidth) {
console.log('open!');
setState({
isOpen: true,
left: bounds.left + bounds.width,
@ -95,7 +95,6 @@ export const PopupProvider: React.FC = ({ children }) => {
content,
});
} else {
console.log('open NOT INVERT!');
setState({
isOpen: true,
left: bounds.left,
@ -108,6 +107,17 @@ export const PopupProvider: React.FC = ({ children }) => {
}
}
};
const hide = () => {
setState({
isOpen: false,
left: 0,
top: 0,
invert: true,
currentTab: 0,
previousTab: 0,
content: null,
});
};
const portalTarget = canUseDOM ? document.body : null; // appease flow
const setTab = (newTab: number) => {
@ -125,7 +135,7 @@ export const PopupProvider: React.FC = ({ children }) => {
};
return (
<Provider value={{ show, setTab, getCurrentTab }}>
<Provider value={{ hide, show, setTab, getCurrentTab }}>
{portalTarget &&
currentState.isOpen &&
createPortal(

View File

@ -146,6 +146,14 @@ export const TaskDetailsMarkdown = styled.div`
width: 100%;
cursor: pointer;
color: #c2c6dc;
p {
margin: 0 0 8px;
}
strong {
font-weight: 700;
}
`;
export const TaskDetailsControls = styled.div`

View File

@ -1,6 +1,7 @@
import React, { useState, useRef, useEffect } from 'react';
import { Bin, Cross, Plus } from 'shared/icons';
import useOnOutsideClick from 'shared/hooks/onOutsideClick';
import ReactMarkdown from 'react-markdown';
import TaskAssignee from 'shared/components/TaskAssignee';
import {
@ -48,7 +49,9 @@ const TaskContent: React.FC<TaskContentProps> = ({ description, onEditContent })
return description === '' ? (
<TaskDetailsAddDetailsButton onClick={onEditContent}>Add a more detailed description</TaskDetailsAddDetailsButton>
) : (
<TaskDetailsMarkdown onClick={onEditContent}>{description}</TaskDetailsMarkdown>
<TaskDetailsMarkdown onClick={onEditContent}>
<ReactMarkdown source={description} />
</TaskDetailsMarkdown>
);
};
@ -142,7 +145,6 @@ const TaskDetails: React.FC<TaskDetailsProps> = ({
const onAddLabel = () => {
onOpenAddLabelPopup(task, $addLabelRef);
};
console.log(task);
return (
<>
<TaskActions>

View File

@ -50,7 +50,6 @@ const NavBar: React.FC<NavBarProps> = ({
}) => {
const $profileRef: any = useRef(null);
const handleProfileClick = () => {
console.log('click');
const boundingRect = $profileRef.current.getBoundingClientRect();
onProfileClick(boundingRect.bottom, boundingRect.right);
};
@ -95,7 +94,7 @@ const NavBar: React.FC<NavBarProps> = ({
{projectMembers && (
<ProjectMembers>
{projectMembers.map(member => (
<TaskAssignee size={28} member={member} onMemberProfile={onMemberProfile} />
<TaskAssignee key={member.userID} size={28} member={member} onMemberProfile={onMemberProfile} />
))}
<InviteButton>Invite</InviteButton>
</ProjectMembers>

View File

@ -269,6 +269,26 @@ export type NewProjectLabel = {
name?: Maybe<Scalars['String']>;
};
export type DeleteProjectLabel = {
projectLabelID: Scalars['UUID'];
};
export type UpdateProjectLabelName = {
projectLabelID: Scalars['UUID'];
name: Scalars['String'];
};
export type UpdateProjectLabel = {
projectLabelID: Scalars['UUID'];
labelColorID: Scalars['UUID'];
name: Scalars['String'];
};
export type UpdateProjectLabelColor = {
projectLabelID: Scalars['UUID'];
labelColorID: Scalars['UUID'];
};
export type Mutation = {
__typename?: 'Mutation';
createRefreshToken: RefreshToken;
@ -276,6 +296,10 @@ export type Mutation = {
createTeam: Team;
createProject: Project;
createProjectLabel: ProjectLabel;
deleteProjectLabel: ProjectLabel;
updateProjectLabel: ProjectLabel;
updateProjectLabelName: ProjectLabel;
updateProjectLabelColor: ProjectLabel;
createTaskGroup: TaskGroup;
updateTaskGroupLocation: TaskGroup;
deleteTaskGroup: DeleteTaskGroupPayload;
@ -317,6 +341,26 @@ export type MutationCreateProjectLabelArgs = {
};
export type MutationDeleteProjectLabelArgs = {
input: DeleteProjectLabel;
};
export type MutationUpdateProjectLabelArgs = {
input: UpdateProjectLabel;
};
export type MutationUpdateProjectLabelNameArgs = {
input: UpdateProjectLabelName;
};
export type MutationUpdateProjectLabelColorArgs = {
input: UpdateProjectLabelColor;
};
export type MutationCreateTaskGroupArgs = {
input: NewTaskGroup;
};
@ -413,7 +457,7 @@ export type CreateProjectLabelMutation = (
& Pick<ProjectLabel, 'id' | 'createdDate' | 'name'>
& { labelColor: (
{ __typename?: 'LabelColor' }
& Pick<LabelColor, 'id' | 'colorHex'>
& Pick<LabelColor, 'id' | 'colorHex' | 'name' | 'position'>
) }
) }
);
@ -459,6 +503,19 @@ export type CreateTaskGroupMutation = (
) }
);
export type DeleteProjectLabelMutationVariables = {
projectLabelID: Scalars['UUID'];
};
export type DeleteProjectLabelMutation = (
{ __typename?: 'Mutation' }
& { deleteProjectLabel: (
{ __typename?: 'ProjectLabel' }
& Pick<ProjectLabel, 'id'>
) }
);
export type DeleteTaskMutationVariables = {
taskID: Scalars['String'];
};
@ -611,6 +668,25 @@ export type UnassignTaskMutation = (
) }
);
export type UpdateProjectLabelMutationVariables = {
projectLabelID: Scalars['UUID'];
labelColorID: Scalars['UUID'];
name: Scalars['String'];
};
export type UpdateProjectLabelMutation = (
{ __typename?: 'Mutation' }
& { updateProjectLabel: (
{ __typename?: 'ProjectLabel' }
& Pick<ProjectLabel, 'id' | 'createdDate' | 'name'>
& { labelColor: (
{ __typename?: 'LabelColor' }
& Pick<LabelColor, 'id' | 'colorHex' | 'name' | 'position'>
) }
) }
);
export type UpdateTaskDescriptionMutationVariables = {
taskID: Scalars['UUID'];
description: Scalars['String'];
@ -715,6 +791,8 @@ export const CreateProjectLabelDocument = gql`
labelColor {
id
colorHex
name
position
}
name
}
@ -833,6 +911,38 @@ export function useCreateTaskGroupMutation(baseOptions?: ApolloReactHooks.Mutati
export type CreateTaskGroupMutationHookResult = ReturnType<typeof useCreateTaskGroupMutation>;
export type CreateTaskGroupMutationResult = ApolloReactCommon.MutationResult<CreateTaskGroupMutation>;
export type CreateTaskGroupMutationOptions = ApolloReactCommon.BaseMutationOptions<CreateTaskGroupMutation, CreateTaskGroupMutationVariables>;
export const DeleteProjectLabelDocument = gql`
mutation deleteProjectLabel($projectLabelID: UUID!) {
deleteProjectLabel(input: {projectLabelID: $projectLabelID}) {
id
}
}
`;
export type DeleteProjectLabelMutationFn = ApolloReactCommon.MutationFunction<DeleteProjectLabelMutation, DeleteProjectLabelMutationVariables>;
/**
* __useDeleteProjectLabelMutation__
*
* To run a mutation, you first call `useDeleteProjectLabelMutation` within a React component and pass it any options that fit your needs.
* When your component renders, `useDeleteProjectLabelMutation` 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 [deleteProjectLabelMutation, { data, loading, error }] = useDeleteProjectLabelMutation({
* variables: {
* projectLabelID: // value for 'projectLabelID'
* },
* });
*/
export function useDeleteProjectLabelMutation(baseOptions?: ApolloReactHooks.MutationHookOptions<DeleteProjectLabelMutation, DeleteProjectLabelMutationVariables>) {
return ApolloReactHooks.useMutation<DeleteProjectLabelMutation, DeleteProjectLabelMutationVariables>(DeleteProjectLabelDocument, baseOptions);
}
export type DeleteProjectLabelMutationHookResult = ReturnType<typeof useDeleteProjectLabelMutation>;
export type DeleteProjectLabelMutationResult = ApolloReactCommon.MutationResult<DeleteProjectLabelMutation>;
export type DeleteProjectLabelMutationOptions = ApolloReactCommon.BaseMutationOptions<DeleteProjectLabelMutation, DeleteProjectLabelMutationVariables>;
export const DeleteTaskDocument = gql`
mutation deleteTask($taskID: String!) {
deleteTask(input: {taskID: $taskID}) {
@ -1147,6 +1257,48 @@ export function useUnassignTaskMutation(baseOptions?: ApolloReactHooks.MutationH
export type UnassignTaskMutationHookResult = ReturnType<typeof useUnassignTaskMutation>;
export type UnassignTaskMutationResult = ApolloReactCommon.MutationResult<UnassignTaskMutation>;
export type UnassignTaskMutationOptions = ApolloReactCommon.BaseMutationOptions<UnassignTaskMutation, UnassignTaskMutationVariables>;
export const UpdateProjectLabelDocument = gql`
mutation updateProjectLabel($projectLabelID: UUID!, $labelColorID: UUID!, $name: String!) {
updateProjectLabel(input: {projectLabelID: $projectLabelID, labelColorID: $labelColorID, name: $name}) {
id
createdDate
labelColor {
id
colorHex
name
position
}
name
}
}
`;
export type UpdateProjectLabelMutationFn = ApolloReactCommon.MutationFunction<UpdateProjectLabelMutation, UpdateProjectLabelMutationVariables>;
/**
* __useUpdateProjectLabelMutation__
*
* To run a mutation, you first call `useUpdateProjectLabelMutation` within a React component and pass it any options that fit your needs.
* When your component renders, `useUpdateProjectLabelMutation` 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 [updateProjectLabelMutation, { data, loading, error }] = useUpdateProjectLabelMutation({
* variables: {
* projectLabelID: // value for 'projectLabelID'
* labelColorID: // value for 'labelColorID'
* name: // value for 'name'
* },
* });
*/
export function useUpdateProjectLabelMutation(baseOptions?: ApolloReactHooks.MutationHookOptions<UpdateProjectLabelMutation, UpdateProjectLabelMutationVariables>) {
return ApolloReactHooks.useMutation<UpdateProjectLabelMutation, UpdateProjectLabelMutationVariables>(UpdateProjectLabelDocument, baseOptions);
}
export type UpdateProjectLabelMutationHookResult = ReturnType<typeof useUpdateProjectLabelMutation>;
export type UpdateProjectLabelMutationResult = ApolloReactCommon.MutationResult<UpdateProjectLabelMutation>;
export type UpdateProjectLabelMutationOptions = ApolloReactCommon.BaseMutationOptions<UpdateProjectLabelMutation, UpdateProjectLabelMutationVariables>;
export const UpdateTaskDescriptionDocument = gql`
mutation updateTaskDescription($taskID: UUID!, $description: String!) {
updateTaskDescription(input: {taskID: $taskID, description: $description}) {

View File

@ -5,6 +5,8 @@ mutation createProjectLabel($projectID: UUID!, $labelColorID: UUID!, $name: Stri
labelColor {
id
colorHex
name
position
}
name
}

View File

@ -0,0 +1,5 @@
mutation deleteProjectLabel($projectLabelID: UUID!) {
deleteProjectLabel(input: { projectLabelID:$projectLabelID }) {
id
}
}

View File

@ -0,0 +1,13 @@
mutation updateProjectLabel($projectLabelID: UUID!, $labelColorID: UUID!, $name: String!) {
updateProjectLabel(input:{projectLabelID:$projectLabelID, labelColorID: $labelColorID, name: $name}) {
id
createdDate
labelColor {
id
colorHex
name
position
}
name
}
}

View File

@ -9,9 +9,7 @@ export const moveItemWithinArray = (arr: Array<DraggableElement>, item: Draggabl
export const insertItemIntoArray = (arr: Array<DraggableElement>, item: DraggableElement, index: number) => {
const arrClone = [...arr];
console.log(arrClone, index, item);
arrClone.splice(index, 0, item);
console.log(arrClone);
return arrClone;
};
@ -32,21 +30,12 @@ export const getNewDraggablePosition = (afterDropDraggables: Array<DraggableElem
return 65535;
}
if (!prevDraggable) {
console.log(
`in front of list [n/a : ${nextDraggable.id}]: ${nextDraggable.position} / 2.0 = ${nextDraggable.position / 2.0}`,
);
return nextDraggable.position / 2.0;
}
if (!nextDraggable) {
console.log(
`end of list [${prevDraggable.id} : n/a] : ${prevDraggable.position} * 2.0 = ${prevDraggable.position * 2.0}`,
);
return prevDraggable.position * 2.0;
}
const newPos = (prevDraggable.position + nextDraggable.position) / 2.0;
console.log(
`middle of two cards [${prevDraggable.id} : ${nextDraggable.id}] : ${prevDraggable.position} + ${nextDraggable.position} / 2.0 = ${newPos}`,
);
return newPos;
};
@ -58,7 +47,6 @@ export const isPositionChanged = (source: DraggableLocation, destination: Dragga
if (!destination) return false;
const isSameList = destination.droppableId === source.droppableId;
const isSamePosition = destination.index === source.index;
console.log(`isSameList: ${isSameList} : isSamePosition: ${isSamePosition}`);
return !isSameList || !isSamePosition;
};

8
web/src/wdy.ts Normal file
View File

@ -0,0 +1,8 @@
import React from 'react';
if (process.env.NODE_ENV === 'development') {
const whyDidYouRender = require('@welldone-software/why-did-you-render');
whyDidYouRender(React, {
trackAllPureComponents: true,
});
}

View File

@ -3592,6 +3592,13 @@
text-table "^0.2.0"
webpack-log "^1.1.2"
"@welldone-software/why-did-you-render@^4.2.2":
version "4.2.2"
resolved "https://registry.yarnpkg.com/@welldone-software/why-did-you-render/-/why-did-you-render-4.2.2.tgz#720128a4f626997ece1ac455a7b13f9ef10dae0a"
integrity sha512-v08t2WXFQdnxkPodXzbPeho3FwgrlwzjwxasN+8A1LSZnkcxJpYvOF8/z+OySqehC44JT6oPB1KEnBVMrebHdw==
dependencies:
lodash "^4"
"@wry/context@^0.4.0":
version "0.4.4"
resolved "https://registry.yarnpkg.com/@wry/context/-/context-0.4.4.tgz#e50f5fa1d6cfaabf2977d1fda5ae91717f8815f8"
@ -6645,7 +6652,7 @@ dom-helpers@^5.0.1:
"@babel/runtime" "^7.6.3"
csstype "^2.6.7"
dom-serializer@0:
dom-serializer@0, dom-serializer@^0.2.1:
version "0.2.2"
resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.2.2.tgz#1afb81f533717175d478655debc5e332d9f9bb51"
integrity sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==
@ -6687,6 +6694,13 @@ domhandler@^2.3.0:
dependencies:
domelementtype "1"
domhandler@^3.0, domhandler@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-3.0.0.tgz#51cd13efca31da95bbb0c5bee3a48300e333b3e9"
integrity sha512-eKLdI5v9m67kbXQbJSNn1zjh0SDzvzWVWtX+qEI3eMjZw8daH9k8rlj1FZY9memPwjiskQFbe7vHVVJIAqoEhw==
dependencies:
domelementtype "^2.0.1"
domutils@1.5.1:
version "1.5.1"
resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.5.1.tgz#dcd8488a26f563d61079e48c9f7b7e32373682cf"
@ -6703,6 +6717,15 @@ domutils@^1.5.1, domutils@^1.7.0:
dom-serializer "0"
domelementtype "1"
domutils@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.1.0.tgz#7ade3201af43703fde154952e3a868eb4b635f16"
integrity sha512-CD9M0Dm1iaHfQ1R/TI+z3/JWp/pgub0j4jIQKH89ARR4ATAV2nbaOQS5XxU9maJP5jHaPdDDQSEHuE2UmpUTKg==
dependencies:
dom-serializer "^0.2.1"
domelementtype "^2.0.1"
domhandler "^3.0.0"
dot-case@^3.0.3:
version "3.0.3"
resolved "https://registry.yarnpkg.com/dot-case/-/dot-case-3.0.3.tgz#21d3b52efaaba2ea5fda875bb1aa8124521cf4aa"
@ -8596,6 +8619,16 @@ html-tags@^3.1.0:
resolved "https://registry.yarnpkg.com/html-tags/-/html-tags-3.1.0.tgz#7b5e6f7e665e9fb41f30007ed9e0d41e97fb2140"
integrity sha512-1qYz89hW3lFDEazhjW0yVAV87lw8lVkrJocr72XmBkMKsoSVJCQx3W8BXsC7hO2qAt8BoVjYjtAcZ9perqGnNg==
html-to-react@^1.3.4:
version "1.4.3"
resolved "https://registry.yarnpkg.com/html-to-react/-/html-to-react-1.4.3.tgz#1430a1cb581ef29533892ec70a2fdc4554b17ffd"
integrity sha512-txe09A3vxW8yEZGJXJ1is5gGDfBEVACmZDSgwDyH5EsfRdOubBwBCg63ZThZP0xBn0UE4FyvMXZXmohusCxDcg==
dependencies:
domhandler "^3.0"
htmlparser2 "^4.1.0"
lodash.camelcase "^4.3.0"
ramda "^0.27"
html-void-elements@^1.0.0:
version "1.0.5"
resolved "https://registry.yarnpkg.com/html-void-elements/-/html-void-elements-1.0.5.tgz#ce9159494e86d95e45795b166c2021c2cfca4483"
@ -8625,6 +8658,16 @@ htmlparser2@^3.3.0:
inherits "^2.0.1"
readable-stream "^3.1.1"
htmlparser2@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-4.1.0.tgz#9a4ef161f2e4625ebf7dfbe6c0a2f52d18a59e78"
integrity sha512-4zDq1a1zhE4gQso/c5LP1OtrhYTncXNSpvJYtWJBtXAETPlMfi3IFNjGuQbYLuVY4ZR0QMqRVvo4Pdy9KLyP8Q==
dependencies:
domelementtype "^2.0.1"
domhandler "^3.0.0"
domutils "^2.0.0"
entities "^2.0.0"
http-deceiver@^1.2.7:
version "1.2.7"
resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87"
@ -9067,7 +9110,7 @@ is-binary-path@~2.1.0:
dependencies:
binary-extensions "^2.0.0"
is-buffer@^1.0.2, is-buffer@^1.1.5:
is-buffer@^1.0.2, is-buffer@^1.1.4, is-buffer@^1.1.5:
version "1.1.6"
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==
@ -9302,7 +9345,7 @@ is-path-inside@^2.1.0:
dependencies:
path-is-inside "^1.0.2"
is-plain-obj@^1.0.0:
is-plain-obj@^1.0.0, is-plain-obj@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e"
integrity sha1-caUMhCnfync8kqOQpKA7OfzVHT4=
@ -10465,6 +10508,11 @@ lodash._reinterpolate@^3.0.0:
resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d"
integrity sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=
lodash.camelcase@^4.3.0:
version "4.3.0"
resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6"
integrity sha1-soqmKIorn8ZRA1x3EfZathkDMaY=
lodash.debounce@^4.0.8:
version "4.0.8"
resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af"
@ -10555,7 +10603,7 @@ lodash.xorby@^4.7.0:
resolved "https://registry.yarnpkg.com/lodash.xorby/-/lodash.xorby-4.7.0.tgz#9c19a6f9f063a6eb53dd03c1b6871799801463d7"
integrity sha1-nBmm+fBjputT3QPBtocXmYAUY9c=
lodash@4.17.15, "lodash@>=3.5 <5", lodash@^4.0.1, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.4, lodash@^4.17.5:
lodash@4.17.15, "lodash@>=3.5 <5", lodash@^4, lodash@^4.0.1, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.4, lodash@^4.17.5:
version "4.17.15"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548"
integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==
@ -10733,6 +10781,13 @@ md5.js@^1.3.4:
inherits "^2.0.1"
safe-buffer "^5.1.2"
mdast-add-list-metadata@1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/mdast-add-list-metadata/-/mdast-add-list-metadata-1.0.1.tgz#95e73640ce2fc1fa2dcb7ec443d09e2bfe7db4cf"
integrity sha512-fB/VP4MJ0LaRsog7hGPxgOrSL3gE/2uEdZyDuSEnKCv/8IkYHiDkIQSbChiJoHyxZZXZ9bzckyRk+vNxFzh8rA==
dependencies:
unist-util-visit-parents "1.1.2"
mdast-squeeze-paragraphs@^3.0.0:
version "3.0.5"
resolved "https://registry.yarnpkg.com/mdast-squeeze-paragraphs/-/mdast-squeeze-paragraphs-3.0.5.tgz#f428b6b944f8faef454db9b58f170c4183cb2e61"
@ -13183,6 +13238,11 @@ ramda@^0.21.0:
resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.21.0.tgz#a001abedb3ff61077d4ff1d577d44de77e8d0a35"
integrity sha1-oAGr7bP/YQd9T/HVd9RN536NCjU=
ramda@^0.27:
version "0.27.0"
resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.27.0.tgz#915dc29865c0800bf3f69b8fd6c279898b59de43"
integrity sha512-pVzZdDpWwWqEVVLshWUHjNwuVP7SfcmPraYuqocJp1yo2U1R7P+5QAfDhdItkuoGqIBnBYrtPp7rEPqDn9HlZA==
randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5:
version "2.1.0"
resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a"
@ -13462,7 +13522,7 @@ react-inspector@^4.0.0:
prop-types "^15.6.1"
storybook-chromatic "^2.2.2"
react-is@^16.6.0:
react-is@^16.6.0, react-is@^16.8.6:
version "16.13.1"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
@ -13477,6 +13537,20 @@ react-lifecycles-compat@^3.0.4:
resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362"
integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==
react-markdown@^4.3.1:
version "4.3.1"
resolved "https://registry.yarnpkg.com/react-markdown/-/react-markdown-4.3.1.tgz#39f0633b94a027445b86c9811142d05381300f2f"
integrity sha512-HQlWFTbDxTtNY6bjgp3C3uv1h2xcjCSi1zAEzfBW9OwJJvENSYiLXWNXN5hHLsoqai7RnZiiHzcnWdXk2Splzw==
dependencies:
html-to-react "^1.3.4"
mdast-add-list-metadata "1.0.1"
prop-types "^15.7.2"
react-is "^16.8.6"
remark-parse "^5.0.0"
unified "^6.1.5"
unist-util-visit "^1.3.0"
xtend "^4.0.1"
react-onclickoutside@^6.9.0:
version "6.9.0"
resolved "https://registry.yarnpkg.com/react-onclickoutside/-/react-onclickoutside-6.9.0.tgz#a54bc317ae8cf6131a5d78acea55a11067f37a1f"
@ -14041,6 +14115,27 @@ remark-parse@7.0.2:
vfile-location "^2.0.0"
xtend "^4.0.1"
remark-parse@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/remark-parse/-/remark-parse-5.0.0.tgz#4c077f9e499044d1d5c13f80d7a98cf7b9285d95"
integrity sha512-b3iXszZLH1TLoyUzrATcTQUZrwNl1rE70rVdSruJFlDaJ9z5aMkhrG43Pp68OgfHndL/ADz6V69Zow8cTQu+JA==
dependencies:
collapse-white-space "^1.0.2"
is-alphabetical "^1.0.0"
is-decimal "^1.0.0"
is-whitespace-character "^1.0.0"
is-word-character "^1.0.0"
markdown-escapes "^1.0.0"
parse-entities "^1.1.0"
repeat-string "^1.5.4"
state-toggle "^1.0.0"
trim "0.0.1"
trim-trailing-lines "^1.0.0"
unherit "^1.0.4"
unist-util-remove-position "^1.0.0"
vfile-location "^2.0.0"
xtend "^4.0.1"
remark-slug@^5.1.2:
version "5.1.2"
resolved "https://registry.yarnpkg.com/remark-slug/-/remark-slug-5.1.2.tgz#715ecdef8df1226786204b1887d31ab16aa24609"
@ -15870,6 +15965,18 @@ unified@8.4.2:
trough "^1.0.0"
vfile "^4.0.0"
unified@^6.1.5:
version "6.2.0"
resolved "https://registry.yarnpkg.com/unified/-/unified-6.2.0.tgz#7fbd630f719126d67d40c644b7e3f617035f6dba"
integrity sha512-1k+KPhlVtqmG99RaTbAv/usu85fcSRu3wY8X+vnsEhIxNP5VbVIDiXnLqyKIG+UMdyTg0ZX9EI6k2AfjJkHPtA==
dependencies:
bail "^1.0.0"
extend "^3.0.0"
is-plain-obj "^1.1.0"
trough "^1.0.0"
vfile "^2.0.0"
x-is-string "^0.1.0"
union-value@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847"
@ -15943,6 +16050,11 @@ unist-util-remove@^1.0.0:
dependencies:
unist-util-is "^3.0.0"
unist-util-stringify-position@^1.0.0, unist-util-stringify-position@^1.1.1:
version "1.1.2"
resolved "https://registry.yarnpkg.com/unist-util-stringify-position/-/unist-util-stringify-position-1.1.2.tgz#3f37fcf351279dcbca7480ab5889bb8a832ee1c6"
integrity sha512-pNCVrk64LZv1kElr0N1wPiHEUoXNVFERp+mlTg/s9R5Lwg87f9bM/3sQB99w+N9D/qnM9ar3+AKDBwo/gm/iQQ==
unist-util-stringify-position@^2.0.0:
version "2.0.3"
resolved "https://registry.yarnpkg.com/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz#cce3bfa1cdf85ba7375d1d5b17bdc4cada9bd9da"
@ -15950,6 +16062,11 @@ unist-util-stringify-position@^2.0.0:
dependencies:
"@types/unist" "^2.0.2"
unist-util-visit-parents@1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/unist-util-visit-parents/-/unist-util-visit-parents-1.1.2.tgz#f6e3afee8bdbf961c0e6f028ea3c0480028c3d06"
integrity sha512-yvo+MMLjEwdc3RhhPYSximset7rwjMrdt9E41Smmvg25UQIenzrN83cRnF1JMzoMi9zZOQeYXHSDf7p+IQkW3Q==
unist-util-visit-parents@^2.0.0:
version "2.1.2"
resolved "https://registry.yarnpkg.com/unist-util-visit-parents/-/unist-util-visit-parents-2.1.2.tgz#25e43e55312166f3348cae6743588781d112c1e9"
@ -15974,7 +16091,7 @@ unist-util-visit@2.0.2, unist-util-visit@^2.0.0:
unist-util-is "^4.0.0"
unist-util-visit-parents "^3.0.0"
unist-util-visit@^1.0.0, unist-util-visit@^1.1.0, unist-util-visit@^1.4.0:
unist-util-visit@^1.0.0, unist-util-visit@^1.1.0, unist-util-visit@^1.3.0, unist-util-visit@^1.4.0:
version "1.4.1"
resolved "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-1.4.1.tgz#4724aaa8486e6ee6e26d7ff3c8685960d560b1e3"
integrity sha512-AvGNk7Bb//EmJZyhtRUnNMEpId/AZ5Ph/KUpTI09WHQuDZHKovQ1oEv3mfmKpWKtoMzyMC4GLBm1Zy5k12fjIw==
@ -16192,6 +16309,13 @@ vfile-location@^2.0.0:
resolved "https://registry.yarnpkg.com/vfile-location/-/vfile-location-2.0.6.tgz#8a274f39411b8719ea5728802e10d9e0dff1519e"
integrity sha512-sSFdyCP3G6Ka0CEmN83A2YCMKIieHx0EDaj5IDP4g1pa5ZJ4FJDvpO0WODLxo4LUX4oe52gmSCK7Jw4SBghqxA==
vfile-message@^1.0.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/vfile-message/-/vfile-message-1.1.1.tgz#5833ae078a1dfa2d96e9647886cd32993ab313e1"
integrity sha512-1WmsopSGhWt5laNir+633LszXvZ+Z/lxveBf6yhGsqnQIhlhzooZae7zV6YVM1Sdkw68dtAW3ow0pOdPANugvA==
dependencies:
unist-util-stringify-position "^1.1.1"
vfile-message@^2.0.0:
version "2.0.3"
resolved "https://registry.yarnpkg.com/vfile-message/-/vfile-message-2.0.3.tgz#0dd4f6879fb240a8099b22bd3755536c92e59ba5"
@ -16200,6 +16324,16 @@ vfile-message@^2.0.0:
"@types/unist" "^2.0.0"
unist-util-stringify-position "^2.0.0"
vfile@^2.0.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/vfile/-/vfile-2.3.0.tgz#e62d8e72b20e83c324bc6c67278ee272488bf84a"
integrity sha512-ASt4mBUHcTpMKD/l5Q+WJXNtshlWxOogYyGYYrg4lt/vuRjC1EFQtlAofL5VmtVNIZJzWYFJjzGWZ0Gw8pzW1w==
dependencies:
is-buffer "^1.1.4"
replace-ext "1.0.0"
unist-util-stringify-position "^1.0.0"
vfile-message "^1.0.0"
vfile@^4.0.0:
version "4.0.3"
resolved "https://registry.yarnpkg.com/vfile/-/vfile-4.0.3.tgz#1e50b824fb5e5affd718e225c7bb1af6d97d4408"
@ -16854,6 +16988,11 @@ ws@^6.1.2, ws@^6.2.1:
dependencies:
async-limiter "~1.0.0"
x-is-string@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/x-is-string/-/x-is-string-0.1.0.tgz#474b50865af3a49a9c4657f05acd145458f77d82"
integrity sha1-R0tQhlrzpJqcRlfwWs0UVFj3fYI=
xml-name-validator@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a"