mirror of
https://github.com/MichaelMure/git-bug.git
synced 2024-12-14 17:51:44 +03:00
Expose actors and participants in snapshot and bug excerpt
Append operations authors to each list on Apply() call Expose actors and participants in graphql Add actor/participant query filter and documentation
This commit is contained in:
parent
5b0a92dea4
commit
2a5fbc4dc9
@ -29,6 +29,9 @@ func (op *AddCommentOperation) Hash() (git.Hash, error) {
|
||||
}
|
||||
|
||||
func (op *AddCommentOperation) Apply(snapshot *Snapshot) {
|
||||
snapshot.addActor(op.Author)
|
||||
snapshot.addParticipant(op.Author)
|
||||
|
||||
hash, err := op.Hash()
|
||||
if err != nil {
|
||||
// Should never error unless a programming error happened
|
||||
|
@ -30,6 +30,9 @@ func (op *CreateOperation) Hash() (git.Hash, error) {
|
||||
}
|
||||
|
||||
func (op *CreateOperation) Apply(snapshot *Snapshot) {
|
||||
snapshot.addActor(op.Author)
|
||||
snapshot.addParticipant(op.Author)
|
||||
|
||||
hash, err := op.Hash()
|
||||
if err != nil {
|
||||
// Should never error unless a programming error happened
|
||||
|
@ -35,8 +35,10 @@ func TestCreate(t *testing.T) {
|
||||
Comments: []Comment{
|
||||
comment,
|
||||
},
|
||||
Author: rene,
|
||||
CreatedAt: create.Time(),
|
||||
Author: rene,
|
||||
Participants: []identity.Interface{rene},
|
||||
Actors: []identity.Interface{rene},
|
||||
CreatedAt: create.Time(),
|
||||
Timeline: []TimelineItem{
|
||||
&CreateTimelineItem{
|
||||
CommentTimelineItem: NewCommentTimelineItem(hash, comment),
|
||||
|
@ -33,6 +33,8 @@ func (op *EditCommentOperation) Apply(snapshot *Snapshot) {
|
||||
// Todo: currently any message can be edited, even by a different author
|
||||
// crypto signature are needed.
|
||||
|
||||
snapshot.addActor(op.Author)
|
||||
|
||||
var target TimelineItem
|
||||
var commentIndex int
|
||||
|
||||
|
@ -31,6 +31,8 @@ func (op *LabelChangeOperation) Hash() (git.Hash, error) {
|
||||
|
||||
// Apply apply the operation
|
||||
func (op *LabelChangeOperation) Apply(snapshot *Snapshot) {
|
||||
snapshot.addActor(op.Author)
|
||||
|
||||
// Add in the set
|
||||
AddLoop:
|
||||
for _, added := range op.Added {
|
||||
|
@ -27,6 +27,7 @@ func (op *SetStatusOperation) Hash() (git.Hash, error) {
|
||||
|
||||
func (op *SetStatusOperation) Apply(snapshot *Snapshot) {
|
||||
snapshot.Status = op.Status
|
||||
snapshot.addActor(op.Author)
|
||||
|
||||
hash, err := op.Hash()
|
||||
if err != nil {
|
||||
|
@ -31,6 +31,7 @@ func (op *SetTitleOperation) Hash() (git.Hash, error) {
|
||||
|
||||
func (op *SetTitleOperation) Apply(snapshot *Snapshot) {
|
||||
snapshot.Title = op.Title
|
||||
snapshot.addActor(op.Author)
|
||||
|
||||
hash, err := op.Hash()
|
||||
if err != nil {
|
||||
|
@ -12,12 +12,14 @@ import (
|
||||
type Snapshot struct {
|
||||
id string
|
||||
|
||||
Status Status
|
||||
Title string
|
||||
Comments []Comment
|
||||
Labels []Label
|
||||
Author identity.Interface
|
||||
CreatedAt time.Time
|
||||
Status Status
|
||||
Title string
|
||||
Comments []Comment
|
||||
Labels []Label
|
||||
Author identity.Interface
|
||||
Actors []identity.Interface
|
||||
Participants []identity.Interface
|
||||
CreatedAt time.Time
|
||||
|
||||
Timeline []TimelineItem
|
||||
|
||||
@ -62,3 +64,25 @@ func (snap *Snapshot) SearchTimelineItem(hash git.Hash) (TimelineItem, error) {
|
||||
|
||||
return nil, fmt.Errorf("timeline item not found")
|
||||
}
|
||||
|
||||
// append the operation author to the actors list
|
||||
func (snap *Snapshot) addActor(actor identity.Interface) {
|
||||
for _, a := range snap.Actors {
|
||||
if actor.Id() == a.Id() {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
snap.Actors = append(snap.Actors, actor)
|
||||
}
|
||||
|
||||
// append the operation author to the participants list
|
||||
func (snap *Snapshot) addParticipant(participant identity.Interface) {
|
||||
for _, p := range snap.Participants {
|
||||
if participant.Id() == p.Id() {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
snap.Participants = append(snap.Participants, participant)
|
||||
}
|
||||
|
22
cache/bug_excerpt.go
vendored
22
cache/bug_excerpt.go
vendored
@ -23,10 +23,12 @@ type BugExcerpt struct {
|
||||
CreateUnixTime int64
|
||||
EditUnixTime int64
|
||||
|
||||
Status bug.Status
|
||||
Labels []bug.Label
|
||||
Title string
|
||||
LenComments int
|
||||
Status bug.Status
|
||||
Labels []bug.Label
|
||||
Title string
|
||||
LenComments int
|
||||
Actors []string
|
||||
Participants []string
|
||||
|
||||
// If author is identity.Bare, LegacyAuthor is set
|
||||
// If author is identity.Identity, AuthorId is set and data is deported
|
||||
@ -44,6 +46,16 @@ type LegacyAuthorExcerpt struct {
|
||||
}
|
||||
|
||||
func NewBugExcerpt(b bug.Interface, snap *bug.Snapshot) *BugExcerpt {
|
||||
participantsIds := make([]string, len(snap.Participants))
|
||||
for i, participant := range snap.Participants {
|
||||
participantsIds[i] = participant.Id()
|
||||
}
|
||||
|
||||
actorsIds := make([]string, len(snap.Actors))
|
||||
for i, actor := range snap.Actors {
|
||||
actorsIds[i] = actor.Id()
|
||||
}
|
||||
|
||||
e := &BugExcerpt{
|
||||
Id: b.Id(),
|
||||
CreateLamportTime: b.CreateLamportTime(),
|
||||
@ -52,6 +64,8 @@ func NewBugExcerpt(b bug.Interface, snap *bug.Snapshot) *BugExcerpt {
|
||||
EditUnixTime: snap.LastEditUnix(),
|
||||
Status: snap.Status,
|
||||
Labels: snap.Labels,
|
||||
Actors: actorsIds,
|
||||
Participants: participantsIds,
|
||||
Title: snap.Title,
|
||||
LenComments: len(snap.Comments),
|
||||
CreateMetadata: b.FirstOp().AllMetadata(),
|
||||
|
54
cache/filter.go
vendored
54
cache/filter.go
vendored
@ -55,6 +55,40 @@ func LabelFilter(label string) Filter {
|
||||
}
|
||||
}
|
||||
|
||||
// ActorFilter return a Filter that match a bug actor
|
||||
func ActorFilter(actor string) Filter {
|
||||
return func(repoCache *RepoCache, excerpt *BugExcerpt) bool {
|
||||
for _, identityExcerpt := range repoCache.identitiesExcerpts {
|
||||
if strings.Contains(strings.ToLower(identityExcerpt.Name), actor) ||
|
||||
actor == identityExcerpt.Id || actor == identityExcerpt.Login {
|
||||
for _, actorId := range excerpt.Actors {
|
||||
if identityExcerpt.Id == actorId {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// ParticipantFilter return a Filter that match a bug participant
|
||||
func ParticipantFilter(participant string) Filter {
|
||||
return func(repoCache *RepoCache, excerpt *BugExcerpt) bool {
|
||||
for _, identityExcerpt := range repoCache.identitiesExcerpts {
|
||||
if strings.Contains(strings.ToLower(identityExcerpt.Name), participant) ||
|
||||
participant == identityExcerpt.Id || participant == identityExcerpt.Login {
|
||||
for _, participantId := range excerpt.Participants {
|
||||
if identityExcerpt.Id == participantId {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// TitleFilter return a Filter that match if the title contains the given query
|
||||
func TitleFilter(query string) Filter {
|
||||
return func(repo *RepoCache, excerpt *BugExcerpt) bool {
|
||||
@ -74,11 +108,13 @@ func NoLabelFilter() Filter {
|
||||
|
||||
// Filters is a collection of Filter that implement a complex filter
|
||||
type Filters struct {
|
||||
Status []Filter
|
||||
Author []Filter
|
||||
Label []Filter
|
||||
Title []Filter
|
||||
NoFilters []Filter
|
||||
Status []Filter
|
||||
Author []Filter
|
||||
Actor []Filter
|
||||
Participant []Filter
|
||||
Label []Filter
|
||||
Title []Filter
|
||||
NoFilters []Filter
|
||||
}
|
||||
|
||||
// Match check if a bug match the set of filters
|
||||
@ -91,6 +127,14 @@ func (f *Filters) Match(repoCache *RepoCache, excerpt *BugExcerpt) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
if match := f.orMatch(f.Participant, repoCache, excerpt); !match {
|
||||
return false
|
||||
}
|
||||
|
||||
if match := f.orMatch(f.Actor, repoCache, excerpt); !match {
|
||||
return false
|
||||
}
|
||||
|
||||
if match := f.andMatch(f.Label, repoCache, excerpt); !match {
|
||||
return false
|
||||
}
|
||||
|
10
cache/query.go
vendored
10
cache/query.go
vendored
@ -56,13 +56,21 @@ func ParseQuery(query string) (*Query, error) {
|
||||
f := AuthorFilter(qualifierQuery)
|
||||
result.Author = append(result.Author, f)
|
||||
|
||||
case "actor":
|
||||
f := ActorFilter(qualifierQuery)
|
||||
result.Actor = append(result.Actor, f)
|
||||
|
||||
case "participant":
|
||||
f := ParticipantFilter(qualifierQuery)
|
||||
result.Participant = append(result.Participant, f)
|
||||
|
||||
case "label":
|
||||
f := LabelFilter(qualifierQuery)
|
||||
result.Label = append(result.Label, f)
|
||||
|
||||
case "title":
|
||||
f := TitleFilter(qualifierQuery)
|
||||
result.Label = append(result.Title, f)
|
||||
result.Title = append(result.Title, f)
|
||||
|
||||
case "no":
|
||||
err := result.parseNoFilter(qualifierQuery)
|
||||
|
3
cache/query_test.go
vendored
3
cache/query_test.go
vendored
@ -19,6 +19,9 @@ func TestQueryParse(t *testing.T) {
|
||||
{"author:rene", true},
|
||||
{`author:"René Descartes"`, true},
|
||||
|
||||
{"actor:bernhard", true},
|
||||
{"participant:leonhard", true},
|
||||
|
||||
{"label:hello", true},
|
||||
{`label:"Good first issue"`, true},
|
||||
|
||||
|
@ -33,6 +33,27 @@ You can filter based on the person who opened the bug.
|
||||
| `author:QUERY` | `author:descartes` matches bugs opened by `René Descartes` or `Robert Descartes` |
|
||||
| | `author:"rené descartes"` matches bugs opened by `René Descartes` |
|
||||
|
||||
### Filtering by participant
|
||||
|
||||
You can filter based on the person who participated in the bug (Opened the bug or added a comment).
|
||||
|
||||
| Qualifier | Example |
|
||||
| --- | --- |
|
||||
| `participant:QUERY` | `participant:descartes` matches bugs opened or commented by `René Descartes` or `Robert Descartes` |
|
||||
| | `participant:"rené descartes"` matches bugs opened or commented by `René Descartes` |
|
||||
|
||||
### Filtering by actor
|
||||
|
||||
You can filter based on the person who interacted with the bug.
|
||||
|
||||
| Qualifier | Example |
|
||||
| --- | --- |
|
||||
| `actor:QUERY` | `actor:descartes` matches bugs edited by `René Descartes` or `Robert Descartes` |
|
||||
| | `actor:"rené descartes"` matches bugs edited by `René Descartes` |
|
||||
| `
|
||||
|
||||
**NOTE**: interaction with bugs include: opening the bug, adding comments, adding/removing labels etc...
|
||||
|
||||
### Filtering by label
|
||||
|
||||
You can filter based on the bug's label.
|
||||
|
@ -81,17 +81,19 @@ type ComplexityRoot struct {
|
||||
}
|
||||
|
||||
Bug struct {
|
||||
Id func(childComplexity int) int
|
||||
HumanId func(childComplexity int) int
|
||||
Status func(childComplexity int) int
|
||||
Title func(childComplexity int) int
|
||||
Labels func(childComplexity int) int
|
||||
Author func(childComplexity int) int
|
||||
CreatedAt func(childComplexity int) int
|
||||
LastEdit func(childComplexity int) int
|
||||
Comments func(childComplexity int, after *string, before *string, first *int, last *int) int
|
||||
Timeline func(childComplexity int, after *string, before *string, first *int, last *int) int
|
||||
Operations func(childComplexity int, after *string, before *string, first *int, last *int) int
|
||||
Id func(childComplexity int) int
|
||||
HumanId func(childComplexity int) int
|
||||
Status func(childComplexity int) int
|
||||
Title func(childComplexity int) int
|
||||
Labels func(childComplexity int) int
|
||||
Author func(childComplexity int) int
|
||||
Actors func(childComplexity int) int
|
||||
Participants func(childComplexity int) int
|
||||
CreatedAt func(childComplexity int) int
|
||||
LastEdit func(childComplexity int) int
|
||||
Comments func(childComplexity int, after *string, before *string, first *int, last *int) int
|
||||
Timeline func(childComplexity int, after *string, before *string, first *int, last *int) int
|
||||
Operations func(childComplexity int, after *string, before *string, first *int, last *int) int
|
||||
}
|
||||
|
||||
BugConnection struct {
|
||||
@ -293,6 +295,9 @@ type AddCommentTimelineItemResolver interface {
|
||||
type BugResolver interface {
|
||||
Status(ctx context.Context, obj *bug.Snapshot) (models.Status, error)
|
||||
|
||||
Actors(ctx context.Context, obj *bug.Snapshot) ([]*identity.Interface, error)
|
||||
Participants(ctx context.Context, obj *bug.Snapshot) ([]*identity.Interface, error)
|
||||
|
||||
LastEdit(ctx context.Context, obj *bug.Snapshot) (time.Time, error)
|
||||
Comments(ctx context.Context, obj *bug.Snapshot, after *string, before *string, first *int, last *int) (models.CommentConnection, error)
|
||||
Timeline(ctx context.Context, obj *bug.Snapshot, after *string, before *string, first *int, last *int) (models.TimelineItemConnection, error)
|
||||
@ -1239,6 +1244,20 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
|
||||
|
||||
return e.complexity.Bug.Author(childComplexity), true
|
||||
|
||||
case "Bug.actors":
|
||||
if e.complexity.Bug.Actors == nil {
|
||||
break
|
||||
}
|
||||
|
||||
return e.complexity.Bug.Actors(childComplexity), true
|
||||
|
||||
case "Bug.participants":
|
||||
if e.complexity.Bug.Participants == nil {
|
||||
break
|
||||
}
|
||||
|
||||
return e.complexity.Bug.Participants(childComplexity), true
|
||||
|
||||
case "Bug.createdAt":
|
||||
if e.complexity.Bug.CreatedAt == nil {
|
||||
break
|
||||
@ -2779,6 +2798,24 @@ func (ec *executionContext) _Bug(ctx context.Context, sel ast.SelectionSet, obj
|
||||
if out.Values[i] == graphql.Null {
|
||||
invalid = true
|
||||
}
|
||||
case "actors":
|
||||
wg.Add(1)
|
||||
go func(i int, field graphql.CollectedField) {
|
||||
out.Values[i] = ec._Bug_actors(ctx, field, obj)
|
||||
if out.Values[i] == graphql.Null {
|
||||
invalid = true
|
||||
}
|
||||
wg.Done()
|
||||
}(i, field)
|
||||
case "participants":
|
||||
wg.Add(1)
|
||||
go func(i int, field graphql.CollectedField) {
|
||||
out.Values[i] = ec._Bug_participants(ctx, field, obj)
|
||||
if out.Values[i] == graphql.Null {
|
||||
invalid = true
|
||||
}
|
||||
wg.Done()
|
||||
}(i, field)
|
||||
case "createdAt":
|
||||
out.Values[i] = ec._Bug_createdAt(ctx, field, obj)
|
||||
if out.Values[i] == graphql.Null {
|
||||
@ -3003,6 +3040,134 @@ func (ec *executionContext) _Bug_author(ctx context.Context, field graphql.Colle
|
||||
return ec._Identity(ctx, field.Selections, &res)
|
||||
}
|
||||
|
||||
// nolint: vetshadow
|
||||
func (ec *executionContext) _Bug_actors(ctx context.Context, field graphql.CollectedField, obj *bug.Snapshot) graphql.Marshaler {
|
||||
ctx = ec.Tracer.StartFieldExecution(ctx, field)
|
||||
defer func() { ec.Tracer.EndFieldExecution(ctx) }()
|
||||
rctx := &graphql.ResolverContext{
|
||||
Object: "Bug",
|
||||
Args: nil,
|
||||
Field: field,
|
||||
}
|
||||
ctx = graphql.WithResolverContext(ctx, rctx)
|
||||
ctx = ec.Tracer.StartFieldResolverExecution(ctx, rctx)
|
||||
resTmp := ec.FieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) {
|
||||
ctx = rctx // use context from middleware stack in children
|
||||
return ec.resolvers.Bug().Actors(rctx, obj)
|
||||
})
|
||||
if resTmp == nil {
|
||||
if !ec.HasError(rctx) {
|
||||
ec.Errorf(ctx, "must not be null")
|
||||
}
|
||||
return graphql.Null
|
||||
}
|
||||
res := resTmp.([]*identity.Interface)
|
||||
rctx.Result = res
|
||||
ctx = ec.Tracer.StartFieldChildExecution(ctx)
|
||||
|
||||
arr1 := make(graphql.Array, len(res))
|
||||
var wg sync.WaitGroup
|
||||
|
||||
isLen1 := len(res) == 1
|
||||
if !isLen1 {
|
||||
wg.Add(len(res))
|
||||
}
|
||||
|
||||
for idx1 := range res {
|
||||
idx1 := idx1
|
||||
rctx := &graphql.ResolverContext{
|
||||
Index: &idx1,
|
||||
Result: res[idx1],
|
||||
}
|
||||
ctx := graphql.WithResolverContext(ctx, rctx)
|
||||
f := func(idx1 int) {
|
||||
if !isLen1 {
|
||||
defer wg.Done()
|
||||
}
|
||||
arr1[idx1] = func() graphql.Marshaler {
|
||||
|
||||
if res[idx1] == nil {
|
||||
return graphql.Null
|
||||
}
|
||||
|
||||
return ec._Identity(ctx, field.Selections, res[idx1])
|
||||
}()
|
||||
}
|
||||
if isLen1 {
|
||||
f(idx1)
|
||||
} else {
|
||||
go f(idx1)
|
||||
}
|
||||
|
||||
}
|
||||
wg.Wait()
|
||||
return arr1
|
||||
}
|
||||
|
||||
// nolint: vetshadow
|
||||
func (ec *executionContext) _Bug_participants(ctx context.Context, field graphql.CollectedField, obj *bug.Snapshot) graphql.Marshaler {
|
||||
ctx = ec.Tracer.StartFieldExecution(ctx, field)
|
||||
defer func() { ec.Tracer.EndFieldExecution(ctx) }()
|
||||
rctx := &graphql.ResolverContext{
|
||||
Object: "Bug",
|
||||
Args: nil,
|
||||
Field: field,
|
||||
}
|
||||
ctx = graphql.WithResolverContext(ctx, rctx)
|
||||
ctx = ec.Tracer.StartFieldResolverExecution(ctx, rctx)
|
||||
resTmp := ec.FieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) {
|
||||
ctx = rctx // use context from middleware stack in children
|
||||
return ec.resolvers.Bug().Participants(rctx, obj)
|
||||
})
|
||||
if resTmp == nil {
|
||||
if !ec.HasError(rctx) {
|
||||
ec.Errorf(ctx, "must not be null")
|
||||
}
|
||||
return graphql.Null
|
||||
}
|
||||
res := resTmp.([]*identity.Interface)
|
||||
rctx.Result = res
|
||||
ctx = ec.Tracer.StartFieldChildExecution(ctx)
|
||||
|
||||
arr1 := make(graphql.Array, len(res))
|
||||
var wg sync.WaitGroup
|
||||
|
||||
isLen1 := len(res) == 1
|
||||
if !isLen1 {
|
||||
wg.Add(len(res))
|
||||
}
|
||||
|
||||
for idx1 := range res {
|
||||
idx1 := idx1
|
||||
rctx := &graphql.ResolverContext{
|
||||
Index: &idx1,
|
||||
Result: res[idx1],
|
||||
}
|
||||
ctx := graphql.WithResolverContext(ctx, rctx)
|
||||
f := func(idx1 int) {
|
||||
if !isLen1 {
|
||||
defer wg.Done()
|
||||
}
|
||||
arr1[idx1] = func() graphql.Marshaler {
|
||||
|
||||
if res[idx1] == nil {
|
||||
return graphql.Null
|
||||
}
|
||||
|
||||
return ec._Identity(ctx, field.Selections, res[idx1])
|
||||
}()
|
||||
}
|
||||
if isLen1 {
|
||||
f(idx1)
|
||||
} else {
|
||||
go f(idx1)
|
||||
}
|
||||
|
||||
}
|
||||
wg.Wait()
|
||||
return arr1
|
||||
}
|
||||
|
||||
// nolint: vetshadow
|
||||
func (ec *executionContext) _Bug_createdAt(ctx context.Context, field graphql.CollectedField, obj *bug.Snapshot) graphql.Marshaler {
|
||||
ctx = ec.Tracer.StartFieldExecution(ctx, field)
|
||||
@ -9637,6 +9802,8 @@ type Bug {
|
||||
title: String!
|
||||
labels: [Label!]!
|
||||
author: Identity!
|
||||
actors: [Identity]!
|
||||
participants: [Identity]!
|
||||
createdAt: Time!
|
||||
lastEdit: Time!
|
||||
|
||||
|
@ -50,6 +50,16 @@ func TestQueries(t *testing.T) {
|
||||
email
|
||||
avatarUrl
|
||||
}
|
||||
actors {
|
||||
name
|
||||
email
|
||||
avatarUrl
|
||||
}
|
||||
participants {
|
||||
name
|
||||
email
|
||||
avatarUrl
|
||||
}
|
||||
|
||||
createdAt
|
||||
humanId
|
||||
@ -112,7 +122,7 @@ func TestQueries(t *testing.T) {
|
||||
}
|
||||
}`
|
||||
|
||||
type Person struct {
|
||||
type Identity struct {
|
||||
Name string `json:"name"`
|
||||
Email string `json:"email"`
|
||||
AvatarUrl string `json:"avatarUrl"`
|
||||
@ -123,13 +133,15 @@ func TestQueries(t *testing.T) {
|
||||
AllBugs struct {
|
||||
PageInfo models.PageInfo
|
||||
Nodes []struct {
|
||||
Author Person
|
||||
CreatedAt string `json:"createdAt"`
|
||||
HumanId string `json:"humanId"`
|
||||
Id string
|
||||
LastEdit string `json:"lastEdit"`
|
||||
Status string
|
||||
Title string
|
||||
Author Identity
|
||||
Actors []Identity
|
||||
Participants []Identity
|
||||
CreatedAt string `json:"createdAt"`
|
||||
HumanId string `json:"humanId"`
|
||||
Id string
|
||||
LastEdit string `json:"lastEdit"`
|
||||
Status string
|
||||
Title string
|
||||
|
||||
Comments struct {
|
||||
PageInfo models.PageInfo
|
||||
@ -142,7 +154,7 @@ func TestQueries(t *testing.T) {
|
||||
Operations struct {
|
||||
PageInfo models.PageInfo
|
||||
Nodes []struct {
|
||||
Author Person
|
||||
Author Identity
|
||||
Date string
|
||||
Title string
|
||||
Files []string
|
||||
|
@ -8,6 +8,7 @@ import (
|
||||
"github.com/MichaelMure/git-bug/graphql/connections"
|
||||
"github.com/MichaelMure/git-bug/graphql/graph"
|
||||
"github.com/MichaelMure/git-bug/graphql/models"
|
||||
"github.com/MichaelMure/git-bug/identity"
|
||||
)
|
||||
|
||||
var _ graph.BugResolver = &bugResolver{}
|
||||
@ -102,3 +103,23 @@ func (bugResolver) Timeline(ctx context.Context, obj *bug.Snapshot, after *strin
|
||||
func (bugResolver) LastEdit(ctx context.Context, obj *bug.Snapshot) (time.Time, error) {
|
||||
return obj.LastEditTime(), nil
|
||||
}
|
||||
|
||||
func (bugResolver) Actors(ctx context.Context, obj *bug.Snapshot) ([]*identity.Interface, error) {
|
||||
actorsp := make([]*identity.Interface, len(obj.Actors))
|
||||
|
||||
for i, actor := range obj.Actors {
|
||||
actorsp[i] = &actor
|
||||
}
|
||||
|
||||
return actorsp, nil
|
||||
}
|
||||
|
||||
func (bugResolver) Participants(ctx context.Context, obj *bug.Snapshot) ([]*identity.Interface, error) {
|
||||
participantsp := make([]*identity.Interface, len(obj.Participants))
|
||||
|
||||
for i, participant := range obj.Participants {
|
||||
participantsp[i] = &participant
|
||||
}
|
||||
|
||||
return participantsp, nil
|
||||
}
|
||||
|
@ -36,6 +36,8 @@ type Bug {
|
||||
title: String!
|
||||
labels: [Label!]!
|
||||
author: Identity!
|
||||
actors: [Identity]!
|
||||
participants: [Identity]!
|
||||
createdAt: Time!
|
||||
lastEdit: Time!
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user