1package board
2
3import (
4 "fmt"
5
6 "github.com/MichaelMure/git-bug/entities/common"
7 "github.com/MichaelMure/git-bug/entities/identity"
8 "github.com/MichaelMure/git-bug/entity"
9 "github.com/MichaelMure/git-bug/entity/dag"
10 "github.com/MichaelMure/git-bug/repository"
11 "github.com/MichaelMure/git-bug/util/text"
12 "github.com/MichaelMure/git-bug/util/timestamp"
13)
14
15var _ Operation = &AddItemDraftOperation{}
16
17type AddItemDraftOperation struct {
18 dag.OpBase
19 ColumnId entity.Id `json:"column"`
20 Title string `json:"title"`
21 Message string `json:"message"`
22 Files []repository.Hash `json:"files"`
23}
24
25func (op *AddItemDraftOperation) Id() entity.Id {
26 return dag.IdOperation(op, &op.OpBase)
27}
28
29func (op *AddItemDraftOperation) GetFiles() []repository.Hash {
30 return op.Files
31}
32
33func (op *AddItemDraftOperation) Validate() error {
34 if err := op.OpBase.Validate(op, AddItemDraftOp); err != nil {
35 return err
36 }
37
38 if err := op.ColumnId.Validate(); err != nil {
39 return err
40 }
41
42 if text.Empty(op.Title) {
43 return fmt.Errorf("title is empty")
44 }
45 if !text.SafeOneLine(op.Title) {
46 return fmt.Errorf("title has unsafe characters")
47 }
48
49 if !text.Safe(op.Message) {
50 return fmt.Errorf("message is not fully printable")
51 }
52
53 for _, file := range op.Files {
54 if !file.IsValid() {
55 return fmt.Errorf("invalid file hash")
56 }
57 }
58
59 return nil
60}
61
62func (op *AddItemDraftOperation) Apply(snapshot *Snapshot) {
63 snapshot.addActor(op.Author())
64
65 for _, column := range snapshot.Columns {
66 if column.Id == op.ColumnId {
67 column.Items = append(column.Items, &Draft{
68 combinedId: entity.CombineIds(snapshot.id, op.Id()),
69 author: op.Author(),
70 status: common.OpenStatus,
71 title: op.Title,
72 message: op.Message,
73 unixTime: timestamp.Timestamp(op.UnixTime),
74 })
75 return
76 }
77 }
78}
79
80func NewAddItemDraftOp(author identity.Interface, unixTime int64, columnId entity.Id, title, message string, files []repository.Hash) *AddItemDraftOperation {
81 return &AddItemDraftOperation{
82 OpBase: dag.NewOpBase(AddItemDraftOp, author, unixTime),
83 ColumnId: columnId,
84 Title: title,
85 Message: message,
86 Files: files,
87 }
88}
89
90// AddItemDraft is a convenience function to add a draft item to a Board
91func AddItemDraft(b Interface, author identity.Interface, unixTime int64, columnId entity.Id, title, message string, files []repository.Hash, metadata map[string]string) (entity.CombinedId, *AddItemDraftOperation, error) {
92 op := NewAddItemDraftOp(author, unixTime, columnId, title, message, files)
93 for key, val := range metadata {
94 op.SetMetadata(key, val)
95 }
96 if err := op.Validate(); err != nil {
97 return entity.UnsetCombinedId, nil, err
98 }
99 b.Append(op)
100 return entity.CombineIds(b.Id(), op.Id()), op, nil
101}