126 lines
3.4 KiB
Go
126 lines
3.4 KiB
Go
package kanban
|
|
|
|
import (
|
|
"time"
|
|
"tm/pkg/mongo"
|
|
)
|
|
|
|
// Board represents a kanban board
|
|
type Board struct {
|
|
mongo.Model `bson:",inline"`
|
|
Name string `bson:"name" json:"name"`
|
|
Description string `bson:"description" json:"description"`
|
|
Columns []Column `bson:"columns" json:"columns"`
|
|
IsDefault bool `bson:"is_default" json:"is_default"` // Whether this is the default board
|
|
UserID string `bson:"user_id" json:"user_id"` // User who owns this board
|
|
}
|
|
|
|
// Column represents a column on a kanban board
|
|
type Column struct {
|
|
mongo.Model `bson:",inline"`
|
|
BoardID string `bson:"board_id" json:"board_id"`
|
|
Name string `bson:"name" json:"name"`
|
|
Order int `bson:"order" json:"order"` // Display order in the board
|
|
Color string `bson:"color" json:"color"` // Hex color code for the column
|
|
Limit *int `bson:"limit,omitempty" json:"limit,omitempty"` // WIP limit (optional)
|
|
}
|
|
|
|
// Card represents a card on a kanban board (references a tender)
|
|
type Card struct {
|
|
mongo.Model `bson:",inline"`
|
|
ColumnID string `bson:"column_id" json:"column_id"`
|
|
TenderID string `bson:"tender_id" json:"tender_id"` // Reference to the tender
|
|
Title string `bson:"title" json:"title"` // Cached title from tender
|
|
Order int `bson:"order" json:"order"` // Position within the column
|
|
Priority CardPriority `bson:"priority" json:"priority"`
|
|
Labels []string `bson:"labels,omitempty" json:"labels,omitempty"`
|
|
DueDate *int64 `bson:"due_date,omitempty" json:"due_date,omitempty"` // Unix timestamp
|
|
}
|
|
|
|
// CardPriority represents the priority level of a card
|
|
type CardPriority string
|
|
|
|
const (
|
|
CardPriorityLow CardPriority = "low"
|
|
CardPriorityMedium CardPriority = "medium"
|
|
CardPriorityHigh CardPriority = "high"
|
|
CardPriorityUrgent CardPriority = "urgent"
|
|
)
|
|
|
|
// GetID returns the board ID
|
|
func (b *Board) GetID() string {
|
|
return b.ID.Hex()
|
|
}
|
|
|
|
// GetID returns the column ID
|
|
func (c *Column) GetID() string {
|
|
return c.ID.Hex()
|
|
}
|
|
|
|
// GetID returns the card ID
|
|
func (c *Card) GetID() string {
|
|
return c.ID.Hex()
|
|
}
|
|
|
|
// IsOverLimit returns true if the column has a WIP limit and is over it
|
|
func (c *Column) IsOverLimit(cardCount int) bool {
|
|
if c.Limit == nil {
|
|
return false
|
|
}
|
|
return cardCount > *c.Limit
|
|
}
|
|
|
|
// UpdateOrder updates the column's display order
|
|
func (c *Column) UpdateOrder(order int) {
|
|
c.Order = order
|
|
c.UpdatedAt = time.Now().Unix()
|
|
}
|
|
|
|
// UpdateOrder updates the card's position within the column
|
|
func (c *Card) UpdateOrder(order int) {
|
|
c.Order = order
|
|
c.UpdatedAt = time.Now().Unix()
|
|
}
|
|
|
|
// MoveToColumn moves the card to a different column and resets order
|
|
func (c *Card) MoveToColumn(columnID string, order int) {
|
|
c.ColumnID = columnID
|
|
c.Order = order
|
|
c.UpdatedAt = time.Now().Unix()
|
|
}
|
|
|
|
// UpdatePriority updates the card's priority
|
|
func (c *Card) UpdatePriority(priority CardPriority) {
|
|
c.Priority = priority
|
|
c.UpdatedAt = time.Now().Unix()
|
|
}
|
|
|
|
// AddLabel adds a label to the card
|
|
func (c *Card) AddLabel(label string) {
|
|
if c.Labels == nil {
|
|
c.Labels = []string{}
|
|
}
|
|
// Check if label already exists
|
|
for _, l := range c.Labels {
|
|
if l == label {
|
|
return
|
|
}
|
|
}
|
|
c.Labels = append(c.Labels, label)
|
|
c.UpdatedAt = time.Now().Unix()
|
|
}
|
|
|
|
// RemoveLabel removes a label from the card
|
|
func (c *Card) RemoveLabel(label string) {
|
|
if c.Labels == nil {
|
|
return
|
|
}
|
|
for i, l := range c.Labels {
|
|
if l == label {
|
|
c.Labels = append(c.Labels[:i], c.Labels[i+1:]...)
|
|
c.UpdatedAt = time.Now().Unix()
|
|
return
|
|
}
|
|
}
|
|
}
|