board.go
TLDR
The file board.go
contains definitions for several types, methods, and functions related to boards in a project. It includes the definition of the Board
struct, methods to interact with board properties, definitions for board patches and board members, and functions for parsing JSON data into board-related structs.
Methods
GetPropertyString
This method takes a property name as input and returns its corresponding value as a string. It returns an error if the property does not exist or is not of type string.
Patch
This method takes a BoardPatch
object as input and applies the specified updates to a Board
. It returns an updated version of the board.
Classes
Board
This class represents a board in the project. It contains various properties such as ID, team ID, channel ID, created by, modified by, type, minimum role, title, description, icon, and more. It also includes methods for checking the validity of the board and parsing board data from JSON.
BoardPatch
This class represents a patch for modifying boards. It contains properties such as type, minimum role, title, description, icon, show description, channel ID, updated properties, deleted properties, updated card properties, and deleted card properties. It includes a method for checking the validity of the patch and a method for applying the patch to a board.
BoardMember
This class represents the membership information of a user on a board. It includes properties such as board ID, user ID, roles, minimum role, scheme admin, scheme editor, scheme commenter, scheme viewer, and synthetic.
package model
import (
"encoding/json"
"io"
"time"
)
type BoardType string
type BoardRole string
type BoardSearchField string
const (
BoardTypeOpen BoardType = "O"
BoardTypePrivate BoardType = "P"
)
const (
BoardRoleNone BoardRole = ""
BoardRoleViewer BoardRole = "viewer"
BoardRoleCommenter BoardRole = "commenter"
BoardRoleEditor BoardRole = "editor"
BoardRoleAdmin BoardRole = "admin"
)
const (
BoardSearchFieldNone BoardSearchField = ""
BoardSearchFieldTitle BoardSearchField = "title"
BoardSearchFieldPropertyName BoardSearchField = "property_name"
)
// Board groups a set of blocks and its layout
// swagger:model
type Board struct {
// The ID for the board
// required: true
ID string `json:"id"`
// The ID of the team that the board belongs to
// required: true
TeamID string `json:"teamId"`
// The ID of the channel that the board was created from
// required: false
ChannelID string `json:"channelId"`
// The ID of the user that created the board
// required: true
CreatedBy string `json:"createdBy"`
// The ID of the last user that updated the board
// required: true
ModifiedBy string `json:"modifiedBy"`
// The type of the board
// required: true
Type BoardType `json:"type"`
// The minimum role applied when somebody joins the board
// required: true
MinimumRole BoardRole `json:"minimumRole"`
// The title of the board
// required: false
Title string `json:"title"`
// The description of the board
// required: false
Description string `json:"description"`
// The icon of the board
// required: false
Icon string `json:"icon"`
// Indicates if the board shows the description on the interface
// required: false
ShowDescription bool `json:"showDescription"`
// Marks the template boards
// required: false
IsTemplate bool `json:"isTemplate"`
// Marks the template boards
// required: false
TemplateVersion int `json:"templateVersion"`
// The properties of the board
// required: false
Properties map[string]interface{} `json:"properties"`
// The properties of the board cards
// required: false
CardProperties []map[string]interface{} `json:"cardProperties"`
// The creation time in miliseconds since the current epoch
// required: true
CreateAt int64 `json:"createAt"`
// The last modified time in miliseconds since the current epoch
// required: true
UpdateAt int64 `json:"updateAt"`
// The deleted time in miliseconds since the current epoch. Set to indicate this block is deleted
// required: false
DeleteAt int64 `json:"deleteAt"`
}
// GetPropertyString returns the value of the specified property as a string,
// or error if the property does not exist or is not of type string.
func (b *Board) GetPropertyString(propName string) (string, error) {
val, ok := b.Properties[propName]
if !ok {
return "", NewErrNotFound(propName)
}
s, ok := val.(string)
if !ok {
return "", ErrInvalidPropertyValueType
}
return s, nil
}
// BoardPatch is a patch for modify boards
// swagger:model
type BoardPatch struct {
// The type of the board
// required: false
Type *BoardType `json:"type"`
// The minimum role applied when somebody joins the board
// required: false
MinimumRole *BoardRole `json:"minimumRole"`
// The title of the board
// required: false
Title *string `json:"title"`
// The description of the board
// required: false
Description *string `json:"description"`
// The icon of the board
// required: false
Icon *string `json:"icon"`
// Indicates if the board shows the description on the interface
// required: false
ShowDescription *bool `json:"showDescription"`
// Indicates if the board shows the description on the interface
// required: false
ChannelID *string `json:"channelId"`
// The board updated properties
// required: false
UpdatedProperties map[string]interface{} `json:"updatedProperties"`
// The board removed properties
// required: false
DeletedProperties []string `json:"deletedProperties"`
// The board updated card properties
// required: false
UpdatedCardProperties []map[string]interface{} `json:"updatedCardProperties"`
// The board removed card properties
// required: false
DeletedCardProperties []string `json:"deletedCardProperties"`
}
// BoardMember stores the information of the membership of a user on a board
// swagger:model
type BoardMember struct {
// The ID of the board
// required: true
BoardID string `json:"boardId"`
// The ID of the user
// required: true
UserID string `json:"userId"`
// The independent roles of the user on the board
// required: false
Roles string `json:"roles"`
// Minimum role because the board configuration
// required: false
MinimumRole string `json:"minimumRole"`
// Marks the user as an admin of the board
// required: true
SchemeAdmin bool `json:"schemeAdmin"`
// Marks the user as an editor of the board
// required: true
SchemeEditor bool `json:"schemeEditor"`
// Marks the user as an commenter of the board
// required: true
SchemeCommenter bool `json:"schemeCommenter"`
// Marks the user as an viewer of the board
// required: true
SchemeViewer bool `json:"schemeViewer"`
// Marks the membership as generated by an access group
// required: true
Synthetic bool `json:"synthetic"`
}
// BoardMetadata contains metadata for a Board
// swagger:model
type BoardMetadata struct {
// The ID for the board
// required: true
BoardID string `json:"boardId"`
// The most recent time a descendant of this board was added, modified, or deleted
// required: true
DescendantLastUpdateAt int64 `json:"descendantLastUpdateAt"`
// The earliest time a descendant of this board was added, modified, or deleted
// required: true
DescendantFirstUpdateAt int64 `json:"descendantFirstUpdateAt"`
// The ID of the user that created the board
// required: true
CreatedBy string `json:"createdBy"`
// The ID of the user that last modified the most recently modified descendant
// required: true
LastModifiedBy string `json:"lastModifiedBy"`
}
func BoardFromJSON(data io.Reader) *Board {
var board *Board
_ = json.NewDecoder(data).Decode(&board)
return board
}
func BoardsFromJSON(data io.Reader) []*Board {
var boards []*Board
_ = json.NewDecoder(data).Decode(&boards)
return boards
}
func BoardMemberFromJSON(data io.Reader) *BoardMember {
var boardMember *BoardMember
_ = json.NewDecoder(data).Decode(&boardMember)
return boardMember
}
func BoardMembersFromJSON(data io.Reader) []*BoardMember {
var boardMembers []*BoardMember
_ = json.NewDecoder(data).Decode(&boardMembers)
return boardMembers
}
func BoardMetadataFromJSON(data io.Reader) *BoardMetadata {
var boardMetadata *BoardMetadata
_ = json.NewDecoder(data).Decode(&boardMetadata)
return boardMetadata
}
// Patch returns an updated version of the board.
func (p *BoardPatch) Patch(board *Board) *Board {
if p.Type != nil {
board.Type = *p.Type
}
if p.Title != nil {
board.Title = *p.Title
}
if p.MinimumRole != nil {
board.MinimumRole = *p.MinimumRole
}
if p.Description != nil {
board.Description = *p.Description
}
if p.Icon != nil {
board.Icon = *p.Icon
}
if p.ShowDescription != nil {
board.ShowDescription = *p.ShowDescription
}
if p.ChannelID != nil {
board.ChannelID = *p.ChannelID
}
for key, property := range p.UpdatedProperties {
board.Properties[key] = property
}
for _, key := range p.DeletedProperties {
delete(board.Properties, key)
}
if len(p.UpdatedCardProperties) != 0 || len(p.DeletedCardProperties) != 0 {
// first we accumulate all properties indexed by, and maintain their order
keyOrder := []string{}
cardPropertyMap := map[string]map[string]interface{}{}
for _, prop := range board.CardProperties {
id, ok := prop["id"].(string)
if !ok {
// bad property, skipping
continue
}
cardPropertyMap[id] = prop
keyOrder = append(keyOrder, id)
}
// if there are properties marked for removal, we delete them
for _, propertyID := range p.DeletedCardProperties {
delete(cardPropertyMap, propertyID)
}
// if there are properties marked for update, we replace the
// existing ones or add them
for _, newprop := range p.UpdatedCardProperties {
id, ok := newprop["id"].(string)
if !ok {
// bad new property, skipping
continue
}
_, exists := cardPropertyMap[id]
if !exists {
keyOrder = append(keyOrder, id)
}
cardPropertyMap[id] = newprop
}
// and finally we flatten and save the updated properties
newCardProperties := []map[string]interface{}{}
for _, key := range keyOrder {
p, exists := cardPropertyMap[key]
if exists {
newCardProperties = append(newCardProperties, p)
}
}
board.CardProperties = newCardProperties
}
return board
}
func IsBoardTypeValid(t BoardType) bool {
return t == BoardTypeOpen || t == BoardTypePrivate
}
func IsBoardMinimumRoleValid(r BoardRole) bool {
return r == BoardRoleNone || r == BoardRoleAdmin || r == BoardRoleEditor || r == BoardRoleCommenter || r == BoardRoleViewer
}
func (p *BoardPatch) IsValid() error {
if p.Type != nil && !IsBoardTypeValid(*p.Type) {
return InvalidBoardErr{"invalid-board-type"}
}
if p.MinimumRole != nil && !IsBoardMinimumRoleValid(*p.MinimumRole) {
return InvalidBoardErr{"invalid-board-minimum-role"}
}
return nil
}
type InvalidBoardErr struct {
msg string
}
func (ibe InvalidBoardErr) Error() string {
return ibe.msg
}
func (b *Board) IsValid() error {
if b.TeamID == "" {
return InvalidBoardErr{"empty-team-id"}
}
if !IsBoardTypeValid(b.Type) {
return InvalidBoardErr{"invalid-board-type"}
}
if !IsBoardMinimumRoleValid(b.MinimumRole) {
return InvalidBoardErr{"invalid-board-minimum-role"}
}
return nil
}
// BoardMemberHistoryEntry stores the information of the membership of a user on a board
// swagger:model
type BoardMemberHistoryEntry struct {
// The ID of the board
// required: true
BoardID string `json:"boardId"`
// The ID of the user
// required: true
UserID string `json:"userId"`
// The action that added this history entry (created or deleted)
// required: false
Action string `json:"action"`
// The insertion time
// required: true
InsertAt time.Time `json:"insertAt"`
}
func BoardSearchFieldFromString(field string) (BoardSearchField, error) {
switch field {
case string(BoardSearchFieldTitle):
return BoardSearchFieldTitle, nil
case string(BoardSearchFieldPropertyName):
return BoardSearchFieldPropertyName, nil
}
return BoardSearchFieldNone, ErrInvalidBoardSearchField
}