Skip to content

Commit

Permalink
Merge branch 'main' into weblate-focalboard-webapp
Browse files Browse the repository at this point in the history
  • Loading branch information
mattermod authored Jul 29, 2022
2 parents 164dcd2 + 2fd2285 commit eb249c6
Show file tree
Hide file tree
Showing 46 changed files with 1,176 additions and 269 deletions.
25 changes: 24 additions & 1 deletion .github/workflows/lint-server.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ on:
branches: [ main, release-** ]
workflow_dispatch:

env:
BRANCH_NAME: ${{ github.head_ref || github.ref_name }}
USE_LOCAL_MATTERMOST-SERVER_REPO: true

jobs:
golangci:
name: plugin
Expand All @@ -16,7 +20,26 @@ jobs:
with:
go-version: 1.18.1
- uses: actions/checkout@v3
with:
path: "focalboard"
- id: "mattermostServer"
uses: actions/checkout@v3
continue-on-error: true
with:
repository: "mattermost/mattermost-server"
fetch-depth: "20"
path: "mattermost-server"
ref: ${{ env.BRANCH_NAME }}
- uses: actions/checkout@v3
if: steps.mattermostServer.outcome == 'failure'
with:
repository: "mattermost/mattermost-server"
fetch-depth: "20"
path: "mattermost-server"
ref : "master"
- name: set up golangci-lint
run: curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.46.2
- name: lint
run: make server-lint
run: |
cd focalboard
make server-lint
14 changes: 11 additions & 3 deletions mattermost-plugin/build/gowork/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,17 +42,25 @@ func main() {
}

func makeGoWork(ci bool) string {
repos := []string{
"mattermost-server",
"enterprise",
}

var b strings.Builder

b.WriteString("go 1.18\n\n")
b.WriteString("use ./mattermost-plugin\n")
b.WriteString("use ./server\n")

for repoIdx := range repos {
if isEnvVarTrue(fmt.Sprintf("USE_LOCAL_%s_REPO", strings.ToUpper(repos[repoIdx])), true) {
b.WriteString(fmt.Sprintf("use ../%s\n", repos[repoIdx]))
}
}

if ci {
b.WriteString("use ./linux\n")
} else {
b.WriteString("use ../mattermost-server\n")
b.WriteString("use ../enterprise\n")
}

return b.String()
Expand Down
4 changes: 2 additions & 2 deletions mattermost-plugin/product/api_adapter.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ type serviceAPIAdapter struct {
func newServiceAPIAdapter(api *boardsProduct) *serviceAPIAdapter {
return &serviceAPIAdapter{
api: api,
ctx: &request.Context{},
ctx: request.EmptyContext(api.logger),
}
}

Expand Down Expand Up @@ -94,7 +94,7 @@ func (a *serviceAPIAdapter) GetUserByEmail(email string) (*mm_model.User, error)
}

func (a *serviceAPIAdapter) UpdateUser(user *mm_model.User) (*mm_model.User, error) {
user, appErr := a.api.userService.UpdateUser(user, true)
user, appErr := a.api.userService.UpdateUser(a.ctx, user, true)
return user, normalizeAppErr(appErr)
}

Expand Down
1 change: 1 addition & 0 deletions mattermost-plugin/server/boards/notifications.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ func createDelivery(servicesAPI model.ServicesAPI, serverRoot string) (*pluginde
Username: botUsername,
DisplayName: botDisplayname,
Description: botDescription,
OwnerId: model.SystemUserID,
}
botID, err := servicesAPI.EnsureBot(bot)
if err != nil {
Expand Down
30 changes: 6 additions & 24 deletions mattermost-plugin/webapp/src/components/boardSelector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,21 @@ import {useWebsockets} from '../../../../webapp/src/hooks/websockets'
import octoClient from '../../../../webapp/src/octoClient'
import mutator from '../../../../webapp/src/mutator'
import {getCurrentTeamId, getAllTeams, Team} from '../../../../webapp/src/store/teams'
import {createBoard, BoardsAndBlocks, Board} from '../../../../webapp/src/blocks/board'
import {createBoardView} from '../../../../webapp/src/blocks/boardView'
import {createBoard, Board} from '../../../../webapp/src/blocks/board'
import {useAppSelector, useAppDispatch} from '../../../../webapp/src/store/hooks'
import {EmptySearch, EmptyResults} from '../../../../webapp/src/components/searchDialog/searchDialog'
import ConfirmationDialog from '../../../../webapp/src/components/confirmationDialogBox'
import Dialog from '../../../../webapp/src/components/dialog'
import SearchIcon from '../../../../webapp/src/widgets/icons/search'
import Button from '../../../../webapp/src/widgets/buttons/button'
import {getCurrentLinkToChannel, setLinkToChannel} from '../../../../webapp/src/store/boards'
import TelemetryClient, {TelemetryCategory, TelemetryActions} from '../../../../webapp/src/telemetry/telemetryClient'
import {WSClient} from '../../../../webapp/src/wsclient'
import {SuiteWindow} from '../../../../webapp/src/types/index'

import BoardSelectorItem from './boardSelectorItem'

const windowAny = (window as SuiteWindow)

import './boardSelector.scss'

const BoardSelector = () => {
Expand Down Expand Up @@ -107,27 +108,8 @@ const BoardSelector = () => {
}

const newLinkedBoard = async (): Promise<void> => {
const board = {...createBoard(), teamId, channelId: currentChannel}

const view = createBoardView()
view.fields.viewType = 'board'
view.parentId = board.id
view.boardId = board.id
view.title = intl.formatMessage({id: 'View.NewBoardTitle', defaultMessage: 'Board view'})

await mutator.createBoardsAndBlocks(
{boards: [board], blocks: [view]},
'add linked board',
async (bab: BoardsAndBlocks): Promise<void> => {
const windowAny: any = window
const newBoard = bab.boards[0]
// TODO: Maybe create a new event for create linked board
TelemetryClient.trackEvent(TelemetryCategory, TelemetryActions.CreateBoard, {board: newBoard?.id})
windowAny.WebappUtils.browserHistory.push(`/boards/team/${teamId}/${newBoard.id}`)
dispatch(setLinkToChannel(''))
},
async () => {return},
)
window.open(`${windowAny.frontendBaseURL}/team/${teamId}/new/${currentChannel}`, '_blank', 'noopener')
dispatch(setLinkToChannel(''))
}

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,12 @@ import OptionsIcon from '../../../../webapp/src/widgets/icons/options'
import DeleteIcon from '../../../../webapp/src/widgets/icons/delete'
import Menu from '../../../../webapp/src/widgets/menu'
import MenuWrapper from '../../../../webapp/src/widgets/menuWrapper'
import {SuiteWindow} from '../../../../webapp/src/types/index'

import './rhsChannelBoardItem.scss'

const windowAny = (window as SuiteWindow)

type Props = {
board: Board
}
Expand All @@ -30,8 +33,7 @@ const RHSChannelBoardItem = (props: Props) => {
}

const handleBoardClicked = (boardID: string) => {
const windowAny: any = window
windowAny.WebappUtils.browserHistory.push(`/boards/team/${team.id}/${boardID}`)
window.open(`${windowAny.frontendBaseURL}/team/${team.id}/${boardID}`, '_blank', 'noopener')
}

const onUnlinkBoard = async (board: Board) => {
Expand Down
3 changes: 2 additions & 1 deletion mattermost-plugin/webapp/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -284,8 +284,9 @@ export default class Plugin {

const goToFocalboardTemplate = () => {
const currentTeam = mmStore.getState().entities.teams.currentTeamId
const currentChannel = mmStore.getState().entities.channels.currentChannelId
TelemetryClient.trackEvent(TelemetryCategory, TelemetryActions.ClickChannelIntro, {teamID: currentTeam})
window.open(`${windowAny.frontendBaseURL}/team/${currentTeam}`, '_blank', 'noopener')
window.open(`${windowAny.frontendBaseURL}/team/${currentTeam}/new/${currentChannel}`, '_blank', 'noopener')
}

if (registry.registerChannelIntroButtonAction) {
Expand Down
2 changes: 1 addition & 1 deletion server/app/boards.go
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,7 @@ func (a *App) AddMemberToBoard(member *model.BoardMember) (*model.BoardMember, e
return nil, err
}

if existingMembership != nil {
if existingMembership != nil && !existingMembership.Synthetic {
return existingMembership, nil
}

Expand Down
107 changes: 107 additions & 0 deletions server/app/boards_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
package app

import (
"testing"

"github.com/mattermost/focalboard/server/model"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
)

func TestAddMemberToBoard(t *testing.T) {
th, tearDown := SetupTestHelper(t)
defer tearDown()

t.Run("base case", func(t *testing.T) {
const boardID = "board_id_1"
const userID = "user_id_1"

boardMember := &model.BoardMember{
BoardID: boardID,
UserID: userID,
SchemeEditor: true,
}

th.Store.EXPECT().GetBoard(boardID).Return(&model.Board{
TeamID: "team_id_1",
}, nil)

th.Store.EXPECT().GetMemberForBoard(boardID, userID).Return(nil, nil)

th.Store.EXPECT().SaveMember(mock.MatchedBy(func(i interface{}) bool {
p := i.(*model.BoardMember)
return p.BoardID == boardID && p.UserID == userID
})).Return(&model.BoardMember{
BoardID: boardID,
}, nil)

// for WS change broadcast
th.Store.EXPECT().GetMembersForBoard(boardID).Return([]*model.BoardMember{}, nil)

addedBoardMember, err := th.App.AddMemberToBoard(boardMember)
require.NoError(t, err)
require.Equal(t, boardID, addedBoardMember.BoardID)
})

t.Run("return existing non-synthetic membership if any", func(t *testing.T) {
const boardID = "board_id_1"
const userID = "user_id_1"

boardMember := &model.BoardMember{
BoardID: boardID,
UserID: userID,
SchemeEditor: true,
}

th.Store.EXPECT().GetBoard(boardID).Return(&model.Board{
TeamID: "team_id_1",
}, nil)

th.Store.EXPECT().GetMemberForBoard(boardID, userID).Return(&model.BoardMember{
UserID: userID,
BoardID: boardID,
Synthetic: false,
}, nil)

addedBoardMember, err := th.App.AddMemberToBoard(boardMember)
require.NoError(t, err)
require.Equal(t, boardID, addedBoardMember.BoardID)
})

t.Run("should convert synthetic membership into natural membership", func(t *testing.T) {
const boardID = "board_id_1"
const userID = "user_id_1"

boardMember := &model.BoardMember{
BoardID: boardID,
UserID: userID,
SchemeEditor: true,
}

th.Store.EXPECT().GetBoard(boardID).Return(&model.Board{
TeamID: "team_id_1",
}, nil)

th.Store.EXPECT().GetMemberForBoard(boardID, userID).Return(&model.BoardMember{
UserID: userID,
BoardID: boardID,
Synthetic: true,
}, nil)

th.Store.EXPECT().SaveMember(mock.MatchedBy(func(i interface{}) bool {
p := i.(*model.BoardMember)
return p.BoardID == boardID && p.UserID == userID
})).Return(&model.BoardMember{
UserID: userID,
BoardID: boardID,
Synthetic: false,
}, nil)

// for WS change broadcast
th.Store.EXPECT().GetMembersForBoard(boardID).Return([]*model.BoardMember{}, nil)

addedBoardMember, err := th.App.AddMemberToBoard(boardMember)
require.NoError(t, err)
require.Equal(t, boardID, addedBoardMember.BoardID)
})
}
Original file line number Diff line number Diff line change
Expand Up @@ -669,8 +669,16 @@ func (s *MattermostAuthLayer) GetMemberForBoard(boardID, userID string) (*model.
if b.ChannelID != "" {
_, err := s.servicesAPI.GetChannelMember(b.ChannelID, userID)
if err != nil {
var appErr *mmModel.AppError
if errors.As(err, &appErr) && appErr.StatusCode == http.StatusNotFound {
// Plugin API returns error if channel member doesn't exist.
// We're fine if it doesn't exist, so its not an error for us.
return nil, nil
}

return nil, err
}

return &model.BoardMember{
BoardID: boardID,
UserID: userID,
Expand Down
Loading

0 comments on commit eb249c6

Please sign in to comment.