Skip to content

Commit

Permalink
fix: fix the actions of votes when different events are triggered (#4616
Browse files Browse the repository at this point in the history
)
  • Loading branch information
mateo-ivc authored Dec 3, 2024
1 parent 5535b5c commit adc6e24
Show file tree
Hide file tree
Showing 19 changed files with 447 additions and 346 deletions.
3 changes: 0 additions & 3 deletions server/src/api/board_templates.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package api

import (
"database/sql"
"fmt"
"net/http"

"github.com/go-chi/render"
Expand Down Expand Up @@ -45,8 +44,6 @@ func (s *Server) getBoardTemplate(w http.ResponseWriter, r *http.Request) {
common.Throw(w, r, common.NotFoundError)
return
}
c := r.Context()
fmt.Println(c)
log.Errorw("unable to get board template", err)
common.Throw(w, r, common.InternalServerError)
}
Expand Down
32 changes: 16 additions & 16 deletions server/src/api/boards_listen_on_board.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,35 +8,35 @@ import (

"github.com/google/uuid"
"github.com/gorilla/websocket"
dto2 "scrumlr.io/server/common/dto"
"scrumlr.io/server/common/dto"
"scrumlr.io/server/logger"
"scrumlr.io/server/realtime"
)

type BoardSubscription struct {
subscription chan *realtime.BoardEvent
clients map[uuid.UUID]*websocket.Conn
boardParticipants []*dto2.BoardSession
boardSettings *dto2.Board
boardColumns []*dto2.Column
boardNotes []*dto2.Note
boardReactions []*dto2.Reaction
boardParticipants []*dto.BoardSession
boardSettings *dto.Board
boardColumns []*dto.Column
boardNotes []*dto.Note
boardReactions []*dto.Reaction
}

type InitEvent struct {
Type realtime.BoardEventType `json:"type"`
Data dto2.FullBoard `json:"data"`
Data dto.FullBoard `json:"data"`
}

type EventData struct {
Board *dto2.Board `json:"board"`
Columns []*dto2.Column `json:"columns"`
Notes []*dto2.Note `json:"notes"`
Reactions []*dto2.Reaction `json:"reactions"`
Votings []*dto2.Voting `json:"votings"`
Votes []*dto2.Vote `json:"votes"`
Sessions []*dto2.BoardSession `json:"participants"`
Requests []*dto2.BoardSessionRequest `json:"requests"`
Board *dto.Board `json:"board"`
Columns []*dto.Column `json:"columns"`
Notes []*dto.Note `json:"notes"`
Reactions []*dto.Reaction `json:"reactions"`
Votings []*dto.Voting `json:"votings"`
Votes []*dto.Vote `json:"votes"`
Sessions []*dto.BoardSession `json:"participants"`
Requests []*dto.BoardSessionRequest `json:"requests"`
}

func (s *Server) openBoardSocket(w http.ResponseWriter, r *http.Request) {
Expand Down Expand Up @@ -97,7 +97,7 @@ func (s *Server) openBoardSocket(w http.ResponseWriter, r *http.Request) {
}
}

func (s *Server) listenOnBoard(boardID, userID uuid.UUID, conn *websocket.Conn, initEventData dto2.FullBoard) {
func (s *Server) listenOnBoard(boardID, userID uuid.UUID, conn *websocket.Conn, initEventData dto.FullBoard) {
if _, exist := s.boardSubscriptions[boardID]; !exist {
s.boardSubscriptions[boardID] = &BoardSubscription{
clients: make(map[uuid.UUID]*websocket.Conn),
Expand Down
83 changes: 69 additions & 14 deletions server/src/api/event_filter.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package api

import (
"encoding/json"

"github.com/google/uuid"
"scrumlr.io/server/common/dto"
"scrumlr.io/server/database/types"
Expand Down Expand Up @@ -96,6 +95,21 @@ func parseParticipantUpdated(data interface{}) (*dto.BoardSession, error) {
return ret, nil
}

func parseVotesDeleted(data interface{}) ([]*dto.Vote, error) {
var ret []*dto.Vote

b, err := json.Marshal(data)
if err != nil {
return nil, err
}
err = json.Unmarshal(b, &ret)
if err != nil {
return nil, err
}
return ret, nil

}

func filterColumns(eventColumns []*dto.Column) []*dto.Column {
var visibleColumns = make([]*dto.Column, 0, len(eventColumns))
for _, column := range eventColumns {
Expand All @@ -108,7 +122,7 @@ func filterColumns(eventColumns []*dto.Column) []*dto.Column {
}

func filterNotes(eventNotes []*dto.Note, userID uuid.UUID, boardSettings *dto.Board, columns []*dto.Column) []*dto.Note {
var visibleNotes = make([]*dto.Note, 0, len(eventNotes))
var visibleNotes = make([]*dto.Note, 0)
for _, note := range eventNotes {
for _, column := range columns {
if (note.Position.Column == column.ID) && column.Visible {
Expand Down Expand Up @@ -306,12 +320,56 @@ func (boardSubscription *BoardSubscription) eventFilter(event *realtime.BoardEve
}
}

if event.Type == realtime.BoardEventVotesDeleted {
//filter deleted votes after user
votes, err := parseVotesDeleted(event.Data)
if err != nil {
logger.Get().Errorw("unable to parse deleteVotes in event filter", "board", boardSubscription.boardSettings.ID, "session", userID, "err", err)
}
userVotes := make([]*dto.Vote, 0)
for _, v := range votes {
if v.User == userID {
userVotes = append(userVotes, v)
}
}

ret := realtime.BoardEvent{
Type: event.Type,
Data: userVotes,
}

return &ret
}

// returns, if no filter match occured
return event
}

func eventInitFilter(event InitEvent, clientID uuid.UUID) InitEvent {
isMod := isModerator(clientID, event.Data.BoardSessions)

// filter to only respond with the latest voting and its votes
if len(event.Data.Votings) != 0 {
latestVoting := make([]*dto.Voting, 0)
activeNotes := make([]*dto.Vote, 0)

latestVoting = append(latestVoting, event.Data.Votings[0])

for _, v := range event.Data.Votes {
if v.Voting == latestVoting[0].ID {
if latestVoting[0].Status == types.VotingStatusOpen {
if v.User == clientID {
activeNotes = append(activeNotes, v)
}
} else {
activeNotes = append(activeNotes, v)
}
}
}
event.Data.Votings = latestVoting
event.Data.Votes = activeNotes
}

if isMod {
return event
}
Expand All @@ -329,23 +387,20 @@ func eventInitFilter(event InitEvent, clientID uuid.UUID) InitEvent {
Votes: event.Data.Votes,
},
}

// Columns
filteredColumns := filterColumns(event.Data.Columns)

// Notes
// Notes TODO: make to map for easier checks
filteredNotes := filterNotes(event.Data.Notes, clientID, event.Data.Board, event.Data.Columns)

notesMap := make(map[uuid.UUID]*dto.Note)
for _, n := range filteredNotes {
notesMap[n.ID] = n
}
// Votes
visibleVotes := make([]*dto.Vote, 0)
for _, v := range event.Data.Votes {
for _, n := range filteredNotes {
if v.Note == n.ID {
aVote := dto.Vote{
Voting: v.Voting,
Note: n.ID,
}
visibleVotes = append(visibleVotes, &aVote)
}
for _, vote := range event.Data.Votes {
if _, exists := notesMap[vote.Note]; exists {
visibleVotes = append(visibleVotes, vote)
}
}
// Votings
Expand Down
2 changes: 2 additions & 0 deletions server/src/common/dto/vote.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@ import (
type Vote struct {
Voting uuid.UUID `json:"voting"`
Note uuid.UUID `json:"note"`
User uuid.UUID `json:"user"`
}

func (v *Vote) From(vote database.Vote) *Vote {
v.Voting = vote.Voting
v.Note = vote.Note
v.User = vote.User
return v
}

Expand Down
9 changes: 9 additions & 0 deletions server/src/database/notes.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,15 @@ func (d *Database) GetNotes(board uuid.UUID, columns ...uuid.UUID) ([]Note, erro
return notes, err
}

func (d *Database) GetChildNotes(parentNote uuid.UUID) ([]Note, error) {
var notes []Note
err := d.db.NewSelect().Model((*Note)(nil)).Where("stack = ?", parentNote).Scan(context.Background(), &notes)
if err != nil {
return nil, err
}
return notes, nil
}

func (d *Database) UpdateNote(caller uuid.UUID, update NoteUpdate) (Note, error) {
boardSelect := d.db.NewSelect().Model((*Board)(nil)).Column("allow_stacking").Where("id = ?", update.Board)
sessionSelect := d.db.NewSelect().Model((*BoardSession)(nil)).Column("role").Where("\"user\" = ?", caller).Where("board = ?", update.Board)
Expand Down
6 changes: 6 additions & 0 deletions server/src/database/votings.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,3 +152,9 @@ func (d *Database) GetVotings(board uuid.UUID) ([]Voting, []Vote, error) {
votes, err := d.GetVotes(filter.VoteFilter{Board: board})
return votings, votes, err
}

func (d *Database) GetOpenVoting(board uuid.UUID) (Voting, error) {
var voting Voting
err := d.db.NewSelect().Model(&voting).Where("board = ?", board).Where("status = ?", "OPEN").Scan(context.Background())
return voting, err
}
2 changes: 1 addition & 1 deletion server/src/realtime/boards.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const (
BoardEventReactionAdded BoardEventType = "REACTION_ADDED"
BoardEventReactionDeleted BoardEventType = "REACTION_DELETED"
BoardEventReactionUpdated BoardEventType = "REACTION_UPDATED"
BoardEventVotesUpdated BoardEventType = "VOTES_UPDATED"
BoardEventVotesDeleted BoardEventType = "VOTES_DELETED"
BoardEventSessionRequestCreated BoardEventType = "REQUEST_CREATED"
BoardEventSessionRequestUpdated BoardEventType = "REQUEST_UPDATED"
BoardEventParticipantCreated BoardEventType = "PARTICIPANT_CREATED"
Expand Down
Loading

0 comments on commit adc6e24

Please sign in to comment.