feat: redesign project sharing & initial registration

redesigned the project sharing popup to be a multi select dropdown
that populates the options by using the input as a fuzzy search filter
on the current users & invited users.

users can now also be directly invited by email from the project share
window. if invited this way, then the user will receive an email
that sends them to a registration page, then a confirmation page.

the initial registration was always redone so that it uses a similar
system to the above in that it now will accept the first registered
user if there are no other accounts (besides 'system').
This commit is contained in:
Jordan Knott
2020-10-20 18:52:09 -05:00
parent 6c7203a4aa
commit 7b6624ecc3
75 changed files with 5041 additions and 859 deletions

View File

@ -19,6 +19,7 @@ import (
"github.com/google/uuid"
"github.com/jordanknott/taskcafe/internal/auth"
"github.com/jordanknott/taskcafe/internal/db"
"github.com/jordanknott/taskcafe/internal/logger"
"github.com/jordanknott/taskcafe/internal/utils"
log "github.com/sirupsen/logrus"
"github.com/vektah/gqlparser/v2/gqlerror"
@ -63,10 +64,10 @@ func NewHandler(repo db.Repository) http.Handler {
default:
fieldName = "ProjectID"
}
log.WithFields(log.Fields{"typeArg": typeArg, "fieldName": fieldName}).Info("getting field by name")
logger.New(ctx).WithFields(log.Fields{"typeArg": typeArg, "fieldName": fieldName}).Info("getting field by name")
subjectField := val.FieldByName(fieldName)
if !subjectField.IsValid() {
log.Error("subject field name does not exist on input type")
logger.New(ctx).Error("subject field name does not exist on input type")
return nil, errors.New("subject field name does not exist on input type")
}
if fieldName == "TeamID" && subjectField.IsNil() {
@ -76,13 +77,13 @@ func NewHandler(repo db.Repository) http.Handler {
}
subjectID, ok = subjectField.Interface().(uuid.UUID)
if !ok {
log.Error("error while casting subject UUID")
logger.New(ctx).Error("error while casting subject UUID")
return nil, errors.New("error while casting subject uuid")
}
var err error
if level == ActionLevelProject {
log.WithFields(log.Fields{"subjectID": subjectID}).Info("fetching subject ID by typeArg")
logger.New(ctx).WithFields(log.Fields{"subjectID": subjectID}).Info("fetching subject ID by typeArg")
if typeArg == ObjectTypeTask {
subjectID, err = repo.GetProjectIDForTask(ctx, subjectID)
}
@ -96,7 +97,7 @@ func NewHandler(repo db.Repository) http.Handler {
subjectID, err = repo.GetProjectIDForTaskChecklistItem(ctx, subjectID)
}
if err != nil {
log.WithError(err).Error("error while getting subject ID")
logger.New(ctx).WithError(err).Error("error while getting subject ID")
return nil, err
}
projectRoles, err := GetProjectRoles(ctx, repo, subjectID)
@ -109,13 +110,13 @@ func NewHandler(repo db.Repository) http.Handler {
},
}
}
log.WithError(err).Error("error while getting project roles")
logger.New(ctx).WithError(err).Error("error while getting project roles")
return nil, err
}
for _, validRole := range roles {
log.WithFields(log.Fields{"validRole": validRole}).Info("checking role")
logger.New(ctx).WithFields(log.Fields{"validRole": validRole}).Info("checking role")
if CompareRoleLevel(projectRoles.TeamRole, validRole) || CompareRoleLevel(projectRoles.ProjectRole, validRole) {
log.WithFields(log.Fields{"teamRole": projectRoles.TeamRole, "projectRole": projectRoles.ProjectRole}).Info("is team or project role")
logger.New(ctx).WithFields(log.Fields{"teamRole": projectRoles.TeamRole, "projectRole": projectRoles.ProjectRole}).Info("is team or project role")
return next(ctx)
}
}
@ -132,7 +133,7 @@ func NewHandler(repo db.Repository) http.Handler {
}
role, err := repo.GetTeamRoleForUserID(ctx, db.GetTeamRoleForUserIDParams{UserID: userID, TeamID: subjectID})
if err != nil {
log.WithError(err).Error("error while getting team roles for user ID")
logger.New(ctx).WithError(err).Error("error while getting team roles for user ID")
return nil, err
}
for _, validRole := range roles {