|
|
package resolvers
// This file will be automatically regenerated based on the schema, any resolver implementations
// will be copied through when generating and any unknown code will be moved to the end.
import ( "context" "errors" "strings" "time"
"git.aiterp.net/stufflog/server/graph/graphcore" "git.aiterp.net/stufflog/server/graph/graphutil" "git.aiterp.net/stufflog/server/graph/loaders" "git.aiterp.net/stufflog/server/internal/slerrors" "git.aiterp.net/stufflog/server/models" )
func (r *issueTaskResolver) EstimatedUnits(ctx context.Context, obj *models.IssueTask) (*int, error) { // TODO: Data loader
activity, err := loaders.ActivityLoaderFromContext(ctx).Load(obj.ActivityID) if err != nil { return nil, err } if !activity.Countable || activity.UnitIsTimeSpent { return nil, nil }
return &obj.EstimatedUnits, nil }
func (r *issueTaskResolver) Issue(ctx context.Context, obj *models.IssueTask) (*models.Issue, error) { return loaders.IssueLoaderFromContext(ctx).Load(obj.IssueID) }
func (r *issueTaskResolver) Activity(ctx context.Context, obj *models.IssueTask) (*models.Activity, error) { return loaders.ActivityLoaderFromContext(ctx).Load(obj.ActivityID) }
func (r *issueTaskResolver) Status(ctx context.Context, obj *models.IssueTask) (*models.ProjectStatus, error) { // The project ID is always the prefix before the first dash in the issue ID.
split := strings.SplitN(obj.IssueID, "-", 2) if len(split) == 0 { return nil, errors.New("invalid issue ID") } projectID := split[0]
// Shortcut: if description isn't needed, resolve this with issue's properties.
if !graphutil.SelectsAnyField(ctx, "description") { return &models.ProjectStatus{ ProjectID: projectID, Stage: obj.StatusStage, Name: obj.StatusName, Description: "FAKE", }, nil }
// Find it in the database. TODO: DataLoader
status, err := r.Database.ProjectStatuses().Find(ctx, projectID, obj.StatusName) if slerrors.IsNotFound(err) { return &models.ProjectStatus{ ProjectID: projectID, Stage: obj.StatusStage, Name: obj.StatusName, Description: "(Deleted or unknown status)", }, nil } else if err != nil { return nil, err }
// If the stage doesn't match, sneakily correct it for next time.
if status.Stage != obj.StatusStage { updatedTask := *obj updatedTask.StatusStage = status.Stage _ = r.Database.IssueTasks().Save(ctx, updatedTask) }
return status, nil }
func (r *issueTaskResolver) RemainingTime(ctx context.Context, obj *models.IssueTask) (time.Duration, error) { loader := loaders.LogsByIssueLoaderFromContext(ctx) logs, err := loader.Load(obj.IssueID) if err != nil { return 0, err }
remaining := obj.EstimatedTime for _, log := range logs { if task := log.Task(obj.ID); task != nil { remaining -= task.Duration } }
return remaining, nil }
func (r *issueTaskResolver) RemainingUnits(ctx context.Context, obj *models.IssueTask) (*int, error) { activity, err := loaders.ActivityLoaderFromContext(ctx).Load(obj.ActivityID) if err != nil { return nil, err } if !activity.Countable || activity.UnitIsTimeSpent { return nil, nil }
loader := loaders.LogsByIssueLoaderFromContext(ctx) logs, err := loader.Load(obj.IssueID) if err != nil { return nil, err }
remaining := obj.EstimatedUnits for _, log := range logs { if task := log.Task(obj.ID); task != nil && task.Units != nil { remaining -= *task.Units } }
return &remaining, nil }
// IssueTask returns graphcore.IssueTaskResolver implementation.
func (r *Resolver) IssueTask() graphcore.IssueTaskResolver { return &issueTaskResolver{r} }
type issueTaskResolver struct{ *Resolver }
|