checkpoint: column repositioning implementation
This commit is contained in:
parent
73547c49c6
commit
4286d8fcc2
2 changed files with 83 additions and 7 deletions
|
@ -11,6 +11,7 @@ import (
|
|||
bolt "go.etcd.io/bbolt"
|
||||
)
|
||||
|
||||
// Board is probably the heart of Pelican.
|
||||
type Board struct {
|
||||
db *bolt.DB
|
||||
}
|
||||
|
@ -90,9 +91,7 @@ func (b *Board) StatusList() ([]Status, error) {
|
|||
return statuses, nil
|
||||
}
|
||||
|
||||
// Status returns a single status from the db.
|
||||
// TODO: Add a test case that handles when a status does not exist.
|
||||
// Or use in delete status case.
|
||||
// Status returns a single status from the database.
|
||||
func (b *Board) Status(statusID int) (Status, error) {
|
||||
data, err := db.Read(b.db, db.StatusBucket, statusID)
|
||||
if err != nil {
|
||||
|
@ -116,6 +115,7 @@ func (b *Board) Status(statusID int) (Status, error) {
|
|||
return status, nil
|
||||
}
|
||||
|
||||
// StatusArgs is an argument type for creating or updating statuses.
|
||||
type StatusArgs struct {
|
||||
Name string
|
||||
Position int
|
||||
|
@ -198,21 +198,44 @@ func (b *Board) DeleteStatus(statusID int) error {
|
|||
return fmt.Errorf("unable to delete the status from the database; %w", err)
|
||||
}
|
||||
|
||||
if err := b.normaliseStatusesPositionValues(); err != nil {
|
||||
if err := b.normaliseStatusesPositionValuesFromDatabase(); err != nil {
|
||||
return fmt.Errorf("unable to normalise the statuses position values; %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// normaliseStatusesPositionValues retrieves the ordered list of statuses from the database and sets
|
||||
// each status' positional value based on its position in the list.
|
||||
func (b *Board) normaliseStatusesPositionValues() error {
|
||||
// RepositionStatus re-positions a status on the Kanban board.
|
||||
func (b *Board) RepositionStatus(currentPosition, targetPosition int) error {
|
||||
statuses, err := b.StatusList()
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to get the list of statuses; %w", err)
|
||||
}
|
||||
|
||||
statuses = moveAndShuffle(statuses, currentPosition, targetPosition)
|
||||
|
||||
if err := b.normaliseStatusesPositionValues(statuses); err != nil {
|
||||
return fmt.Errorf("unable to normalise the statuses position values; %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// normaliseStatusesPositionValuesFromDatabase retrieves the ordered list of statuses from the database and sets
|
||||
// each status' positional value based on its position in the list before saving the updates to the database.
|
||||
func (b *Board) normaliseStatusesPositionValuesFromDatabase() error {
|
||||
statuses, err := b.StatusList()
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to get the list of statuses; %w", err)
|
||||
}
|
||||
|
||||
return b.normaliseStatusesPositionValues(statuses)
|
||||
}
|
||||
|
||||
// normaliseStatusesPositionValues takes a list of statuses and sets
|
||||
// each status' positional value based on its position in the list before
|
||||
// saving the updates to the database.
|
||||
func (b *Board) normaliseStatusesPositionValues(statuses []Status) error {
|
||||
for i, status := range statuses {
|
||||
updateArgs := UpdateStatusArgs{
|
||||
StatusID: status.ID,
|
||||
|
@ -230,6 +253,7 @@ func (b *Board) normaliseStatusesPositionValues() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// MoveToStatusArgs is an argument type for moving a card between statuses.
|
||||
type MoveToStatusArgs struct {
|
||||
CardID int
|
||||
CurrentStatusID int
|
||||
|
@ -260,6 +284,7 @@ func (b *Board) MoveToStatus(args MoveToStatusArgs) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// CardArgs is an argument type for creating or updating cards.
|
||||
type CardArgs struct {
|
||||
NewTitle string
|
||||
NewDescription string
|
||||
|
@ -360,6 +385,7 @@ func (b *Board) CardList(ids []int) ([]Card, error) {
|
|||
return cards, nil
|
||||
}
|
||||
|
||||
// UpdateCardArgs is an argument type for updating a card.
|
||||
type UpdateCardArgs struct {
|
||||
CardID int
|
||||
CardArgs
|
||||
|
@ -387,6 +413,7 @@ func (b *Board) UpdateCard(args UpdateCardArgs) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// DeleteCardArgs is an argument type for deleting a card.
|
||||
type DeleteCardArgs struct {
|
||||
CardID int
|
||||
StatusID int
|
||||
|
|
49
internal/board/shuffle.go
Normal file
49
internal/board/shuffle.go
Normal file
|
@ -0,0 +1,49 @@
|
|||
package board
|
||||
|
||||
type shuffleDirection int
|
||||
|
||||
const (
|
||||
forwards shuffleDirection = iota
|
||||
backwards
|
||||
)
|
||||
|
||||
// moveAndShuffle creates a new list where the element specified at the index of the current
|
||||
// position is moved to the index of the target position. Elements within the range of the
|
||||
// old and new positions will then shuffle forwards or backwards in the list depending on the
|
||||
// direction of the move.
|
||||
// This is currently used to move specified columns forwards or backwards on the Kanban board.
|
||||
// When a column changes position the other columns shuffle forward or backwards as required.
|
||||
func moveAndShuffle(input []Status, currentPosition, targetPosition int) []Status {
|
||||
var shuffle shuffleDirection
|
||||
|
||||
if targetPosition < currentPosition {
|
||||
// affected elements will need to shuffle backwards if the focused
|
||||
// element moves towards the beginning of the list...
|
||||
shuffle = backwards
|
||||
} else {
|
||||
// ...or else the elements need to shuffle forwards if the focused
|
||||
// element moves towards the end of the list.
|
||||
shuffle = forwards
|
||||
}
|
||||
|
||||
output := make([]Status, len(input))
|
||||
|
||||
for ind := range input {
|
||||
switch {
|
||||
case (shuffle == backwards) && (ind < targetPosition || ind > currentPosition):
|
||||
output[ind] = input[ind]
|
||||
case (shuffle == backwards) && (ind == currentPosition):
|
||||
output[targetPosition] = input[ind]
|
||||
case (shuffle == backwards):
|
||||
output[ind+1] = input[ind]
|
||||
case (shuffle == forwards) && (ind < currentPosition || ind > targetPosition):
|
||||
output[ind] = input[ind]
|
||||
case (shuffle == forwards) && (ind == currentPosition):
|
||||
output[targetPosition] = input[ind]
|
||||
case (shuffle == forwards):
|
||||
output[ind-1] = input[ind]
|
||||
}
|
||||
}
|
||||
|
||||
return output
|
||||
}
|
Loading…
Reference in a new issue