1package board
  2
  3import (
  4	"fmt"
  5
  6	"github.com/git-bug/git-bug/entities/bug"
  7	"github.com/git-bug/git-bug/entities/identity"
  8	"github.com/git-bug/git-bug/entity"
  9	"github.com/git-bug/git-bug/entity/dag"
 10)
 11
 12// ItemEntityType indicate the type of entity board item
 13type ItemEntityType string
 14
 15const (
 16	EntityTypeBug ItemEntityType = "bug"
 17)
 18
 19var _ Operation = &AddItemEntityOperation{}
 20
 21type AddItemEntityOperation struct {
 22	dag.OpBase
 23	ColumnId   entity.Id        `json:"column"`
 24	EntityType ItemEntityType   `json:"entity_type"`
 25	EntityId   entity.Id        `json:"entity_id"`
 26	entity     entity.Interface // not serialized
 27}
 28
 29func (op *AddItemEntityOperation) Id() entity.Id {
 30	return dag.IdOperation(op, &op.OpBase)
 31}
 32
 33func (op *AddItemEntityOperation) Validate() error {
 34	if err := op.OpBase.Validate(op, AddItemEntityOp); err != nil {
 35		return err
 36	}
 37
 38	if err := op.ColumnId.Validate(); err != nil {
 39		return err
 40	}
 41
 42	switch op.EntityType {
 43	case EntityTypeBug:
 44	default:
 45		return fmt.Errorf("unknown entity type")
 46	}
 47
 48	if err := op.EntityId.Validate(); err != nil {
 49		return err
 50	}
 51
 52	return nil
 53}
 54
 55func (op *AddItemEntityOperation) Apply(snapshot *Snapshot) {
 56	if op.entity == nil {
 57		// entity was not found while unmarshalling/resolving
 58		return
 59	}
 60
 61	// Recreate the combined Id to match on
 62	combinedId := entity.CombineIds(snapshot.Id(), op.ColumnId)
 63
 64	// search the column
 65	for _, column := range snapshot.Columns {
 66		if column.CombinedId == combinedId {
 67			switch op.EntityType {
 68			case EntityTypeBug:
 69				column.Items = append(column.Items, &BugItem{
 70					combinedId: entity.CombineIds(snapshot.Id(), op.Id()),
 71					Bug:        op.entity.(dag.CompileTo[*bug.Snapshot]),
 72				})
 73			}
 74			snapshot.addParticipant(op.Author())
 75			return
 76		}
 77	}
 78}
 79
 80func NewAddItemEntityOp(author identity.Interface, unixTime int64, columnId entity.Id, entityType ItemEntityType, e entity.Interface) *AddItemEntityOperation {
 81	// Note: due to import cycle we are not able to sanity check the type of the entity here;
 82	// proceed with caution!
 83	return &AddItemEntityOperation{
 84		OpBase:     dag.NewOpBase(AddItemEntityOp, author, unixTime),
 85		ColumnId:   columnId,
 86		EntityType: entityType,
 87		EntityId:   e.Id(),
 88		entity:     e,
 89	}
 90}
 91
 92// AddItemEntity is a convenience function to add an entity item to a Board
 93func AddItemEntity(b ReadWrite, author identity.Interface, unixTime int64, columnId entity.Id, entityType ItemEntityType, e entity.Interface, metadata map[string]string) (entity.CombinedId, *AddItemEntityOperation, error) {
 94	op := NewAddItemEntityOp(author, unixTime, columnId, entityType, e)
 95	for key, val := range metadata {
 96		op.SetMetadata(key, val)
 97	}
 98	if err := op.Validate(); err != nil {
 99		return entity.UnsetCombinedId, nil, err
100	}
101	b.Append(op)
102	return entity.CombineIds(b.Id(), op.Id()), op, nil
103}