Merge branch 'main' into private-templates

This commit is contained in:
Harshil Sharma 2022-03-25 12:12:48 +05:30
commit 822ea04083
6 changed files with 27 additions and 15 deletions

View file

@ -223,7 +223,8 @@ func (p *BoardPatch) Patch(board *Board) *Board {
} }
if len(p.UpdatedCardProperties) != 0 || len(p.DeletedCardProperties) != 0 { if len(p.UpdatedCardProperties) != 0 || len(p.DeletedCardProperties) != 0 {
// first we accumulate all properties indexed by ID // first we accumulate all properties indexed by, and maintain their order
keyOrder := []string{}
cardPropertyMap := map[string]map[string]interface{}{} cardPropertyMap := map[string]map[string]interface{}{}
for _, prop := range board.CardProperties { for _, prop := range board.CardProperties {
id, ok := prop["id"].(string) id, ok := prop["id"].(string)
@ -233,6 +234,7 @@ func (p *BoardPatch) Patch(board *Board) *Board {
} }
cardPropertyMap[id] = prop cardPropertyMap[id] = prop
keyOrder = append(keyOrder, id)
} }
// if there are properties marked for removal, we delete them // if there are properties marked for removal, we delete them
@ -249,13 +251,20 @@ func (p *BoardPatch) Patch(board *Board) *Board {
continue continue
} }
_, exists := cardPropertyMap[id]
if !exists {
keyOrder = append(keyOrder, id)
}
cardPropertyMap[id] = newprop cardPropertyMap[id] = newprop
} }
// and finally we flatten and save the updated properties // and finally we flatten and save the updated properties
newCardProperties := []map[string]interface{}{} newCardProperties := []map[string]interface{}{}
for _, p := range cardPropertyMap { for _, key := range keyOrder {
newCardProperties = append(newCardProperties, p) p, exists := cardPropertyMap[key]
if exists {
newCardProperties = append(newCardProperties, p)
}
} }
board.CardProperties = newCardProperties board.CardProperties = newCardProperties

View file

@ -366,11 +366,11 @@ CREATE INDEX idx_boardmembers_user_id ON {{.prefix}}board_members(user_id);
INSERT INTO {{.prefix}}board_members ( INSERT INTO {{.prefix}}board_members (
SELECT B.Id, CM.UserId, CM.Roles, (CM.UserId=B.created_by) OR CM.SchemeAdmin, CM.SchemeUser, FALSE, CM.SchemeGuest SELECT B.Id, CM.UserId, CM.Roles, (CM.UserId=B.created_by) OR CM.SchemeAdmin, CM.SchemeUser, FALSE, CM.SchemeGuest
FROM {{.prefix}}boards AS B FROM {{.prefix}}boards AS B
INNER JOIN ChannelMembers as CM ON CM.ChannelId=B.channel_id INNER JOIN ChannelMembers as CM ON CM.ChannelId=B.channel_id;
); );
{{else}} {{else}}
{{- /* if we're in personal server or desktop, create memberships for everyone */ -}} {{- /* if we're in personal server or desktop, create memberships for everyone */ -}}
INSERT INTO {{.prefix}}board_members INSERT INTO {{.prefix}}board_members
SELECT B.id, U.id, '', B.created_by=U.id, TRUE, FALSE, FALSE SELECT B.id, U.id, '', B.created_by=U.id, TRUE, FALSE, FALSE
FROM {{.prefix}}boards AS B, {{.prefix}}users AS U FROM {{.prefix}}boards AS B, {{.prefix}}users AS U;
{{end}} {{end}}

View file

@ -3,6 +3,7 @@ package sqlstore
import ( import (
"database/sql" "database/sql"
"fmt" "fmt"
"io/ioutil"
"os" "os"
"strings" "strings"
@ -33,7 +34,12 @@ func PrepareNewTestDatabase() (dbType string, connectionString string, err error
var rootUser string var rootUser string
if dbType == model.SqliteDBType { if dbType == model.SqliteDBType {
connectionString = "file::memory:?cache=shared&_busy_timeout=5000" file, err := ioutil.TempFile("", "fbtest_*.db")
if err != nil {
return "", "", err
}
connectionString = file.Name() + "?_busy_timeout=5000"
_ = file.Close()
} else if port := strings.TrimSpace(os.Getenv("FB_STORE_TEST_DOCKER_PORT")); port != "" { } else if port := strings.TrimSpace(os.Getenv("FB_STORE_TEST_DOCKER_PORT")); port != "" {
// docker unit tests take priority over any DSN env vars // docker unit tests take priority over any DSN env vars
var template string var template string

View file

@ -117,8 +117,8 @@ Cypress.Commands.add('apiChangePassword', (userId: string, oldPassword: string,
Cypress.Commands.add('uiCreateNewBoard', (title?: string) => { Cypress.Commands.add('uiCreateNewBoard', (title?: string) => {
cy.log('**Create new empty board**') cy.log('**Create new empty board**')
cy.findByText('+ Add board').click() cy.uiCreateEmptyBoard()
cy.get('.empty-board').first().click({force: true})
cy.findByPlaceholderText('Untitled board').should('exist') cy.findByPlaceholderText('Untitled board').should('exist')
cy.wait(10) cy.wait(10)
if (title) { if (title) {

View file

@ -16,7 +16,6 @@ Cypress.Commands.add('uiCreateBoard', (item: string) => {
Cypress.Commands.add('uiCreateEmptyBoard', () => { Cypress.Commands.add('uiCreateEmptyBoard', () => {
cy.log('Create new empty board') cy.log('Create new empty board')
cy.contains('+ Add board').should('be.visible').click() cy.contains('+ Add board').should('be.visible').click().wait(500)
return cy.contains('Create empty board').click({force: true}).wait(1000) return cy.contains('Create empty board').click({force: true}).wait(1000)
}) })

View file

@ -273,17 +273,15 @@ export default function ShareBoardDialog(props: Props): JSX.Element {
<div className='user-items'> <div className='user-items'>
<TeamPermissionsRow/> <TeamPermissionsRow/>
{Object.values(members).map((member) => { {boardUsers.map((user) => {
const user = boardUsers.find((u) => u.id === member.userId) if (!members[user.id]) {
if (!user) {
return null return null
} }
return ( return (
<UserPermissionsRow <UserPermissionsRow
key={user.id} key={user.id}
user={user} user={user}
member={member} member={members[user.id]}
onDeleteBoardMember={onDeleteBoardMember} onDeleteBoardMember={onDeleteBoardMember}
onUpdateBoardMember={onUpdateBoardMember} onUpdateBoardMember={onUpdateBoardMember}
isMe={user.id === me?.id} isMe={user.id === me?.id}