stufflog graphql server
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

126 lines
3.6 KiB

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 }