1
0
mirror of https://github.com/mattermost/focalboard.git synced 2024-12-24 13:43:12 +02:00
focalboard/server/model/boards_and_blocks.go
Doug Lauder 605c0079eb
Multi product architecture (#3309)
* skeleton lifecycle

* bare minimum to satisfy mm-server import

* added boards_imports.go

* move boards_imports.go to correct package

* bump mmserver version; remove replace in go.mod; use module workspaces; remove logger service

* rename product.go --> boards.go

* add FileInfoStore and Cloud services for product; create minimal pluginAPI interfaces for all packages

* rename Boards -> BoardsProduct

* compile success

* remove hooks service; guard for nil BoardsApp

* update to latest mmserver ver

* upgrade mmserver to master tip

* upgrade mmserver to master tip

* bump plugin-api to master tip

* fix users service

* fix OnActivate crash; normalize AppError returns

* fileBackend interface for server/app

* feature flag

* bump mmserver version

* fix linter errors

* make go.work when linting

* fix go.work creation for CI

* add execute flag for script

* fix more linter errors

* always create a go.work

* fix ci go.work

* OS agnostic go.work generator

* fix path

* fix path again

* partially disable cypress test

* fix case Id --> ID

* bump mmserver version

* include  in go.work for dev

* addressed review comments.

Co-authored-by: Mattermod <mattermod@users.noreply.github.com>
2022-07-15 07:51:50 +02:00

173 lines
4.0 KiB
Go

package model
import (
"encoding/json"
"errors"
"fmt"
"io"
"github.com/mattermost/focalboard/server/utils"
"github.com/mattermost/mattermost-server/v6/shared/mlog"
)
var ErrNoBoardsInBoardsAndBlocks = errors.New("at least one board is required")
var ErrNoBlocksInBoardsAndBlocks = errors.New("at least one block is required")
var ErrNoTeamInBoardsAndBlocks = errors.New("team ID cannot be empty")
var ErrBoardIDsAndPatchesMissmatchInBoardsAndBlocks = errors.New("board ids and patches need to match")
var ErrBlockIDsAndPatchesMissmatchInBoardsAndBlocks = errors.New("block ids and patches need to match")
type BlockDoesntBelongToAnyBoardErr struct {
blockID string
}
func (e BlockDoesntBelongToAnyBoardErr) Error() string {
return fmt.Sprintf("block %s doesn't belong to any board", e.blockID)
}
// BoardsAndBlocks is used to operate over boards and blocks at the
// same time
// swagger:model
type BoardsAndBlocks struct {
// The boards
// required: false
Boards []*Board `json:"boards"`
// The blocks
// required: false
Blocks []Block `json:"blocks"`
}
func (bab *BoardsAndBlocks) IsValid() error {
if len(bab.Boards) == 0 {
return ErrNoBoardsInBoardsAndBlocks
}
if len(bab.Blocks) == 0 {
return ErrNoBlocksInBoardsAndBlocks
}
boardsMap := map[string]bool{}
for _, board := range bab.Boards {
boardsMap[board.ID] = true
}
for _, block := range bab.Blocks {
if _, ok := boardsMap[block.BoardID]; !ok {
return BlockDoesntBelongToAnyBoardErr{block.ID}
}
}
return nil
}
// DeleteBoardsAndBlocks is used to list the boards and blocks to
// delete on a request
// swagger:model
type DeleteBoardsAndBlocks struct {
// The boards
// required: true
Boards []string `json:"boards"`
// The blocks
// required: true
Blocks []string `json:"blocks"`
}
func NewDeleteBoardsAndBlocksFromBabs(babs *BoardsAndBlocks) *DeleteBoardsAndBlocks {
boardIDs := make([]string, 0, len(babs.Boards))
blockIDs := make([]string, 0, len(babs.Boards))
for _, board := range babs.Boards {
boardIDs = append(boardIDs, board.ID)
}
for _, block := range babs.Blocks {
blockIDs = append(blockIDs, block.ID)
}
return &DeleteBoardsAndBlocks{
Boards: boardIDs,
Blocks: blockIDs,
}
}
func (dbab *DeleteBoardsAndBlocks) IsValid() error {
if len(dbab.Boards) == 0 {
return ErrNoBoardsInBoardsAndBlocks
}
return nil
}
// PatchBoardsAndBlocks is used to patch multiple boards and blocks on
// a single request
// swagger:model
type PatchBoardsAndBlocks struct {
// The board IDs to patch
// required: true
BoardIDs []string `json:"boardIDs"`
// The board patches
// required: true
BoardPatches []*BoardPatch `json:"boardPatches"`
// The block IDs to patch
// required: true
BlockIDs []string `json:"blockIDs"`
// The block patches
// required: true
BlockPatches []*BlockPatch `json:"blockPatches"`
}
func (dbab *PatchBoardsAndBlocks) IsValid() error {
if len(dbab.BoardIDs) == 0 {
return ErrNoBoardsInBoardsAndBlocks
}
if len(dbab.BoardIDs) != len(dbab.BoardPatches) {
return ErrBoardIDsAndPatchesMissmatchInBoardsAndBlocks
}
if len(dbab.BlockIDs) != len(dbab.BlockPatches) {
return ErrBlockIDsAndPatchesMissmatchInBoardsAndBlocks
}
return nil
}
func GenerateBoardsAndBlocksIDs(bab *BoardsAndBlocks, logger mlog.LoggerIFace) (*BoardsAndBlocks, error) {
if err := bab.IsValid(); err != nil {
return nil, err
}
blocksByBoard := map[string][]Block{}
for _, block := range bab.Blocks {
blocksByBoard[block.BoardID] = append(blocksByBoard[block.BoardID], block)
}
boards := []*Board{}
blocks := []Block{}
for _, board := range bab.Boards {
newID := utils.NewID(utils.IDTypeBoard)
for _, block := range blocksByBoard[board.ID] {
block.BoardID = newID
blocks = append(blocks, block)
}
board.ID = newID
boards = append(boards, board)
}
newBab := &BoardsAndBlocks{
Boards: boards,
Blocks: GenerateBlockIDs(blocks, logger),
}
return newBab, nil
}
func BoardsAndBlocksFromJSON(data io.Reader) *BoardsAndBlocks {
var bab *BoardsAndBlocks
_ = json.NewDecoder(data).Decode(&bab)
return bab
}