Skip to content

Commit

Permalink
Workspace Switcher - include channels with no workspaces and boards (#…
Browse files Browse the repository at this point in the history
…1158)

* API WIP

* WIP

* Finished changes

* Fixed colors:

* Don't enforce charset adn collation in migration, pick from database DSN

* Added MySQL query

* Updated mocks

* Added tests

* Lint fixes

* Fixed typo and removed unsed style

* Checked in a snapshot

* Updated snapshot

* Updated Cypress test

* Updated Cypress test

* Updated Cypress test

* Fixed review comments

* Fixed tests

* Added default collation for MySQL

* Added documentation for ensuring correct database collation

* Updated migrations

* Fixed a bug with collation

* Fixed lint errors

* Used correct collation

* debugging

* Updating css

* Minor UI changes

* USe inbuilt default collation

* Used only charset for mysql

* Fixed linter issue:

* Added migration for matching collation

* Reverted local config changes

* Reverted local config changes

* Handled the case of personal server running on MySQL

* WIP

* Now running collation matching migration onlyt for plugins

* Minor optimization

* Multiple review fixes

* Added group by clause to primary query

* Supported for subpacth

* Displayed all channels in workspace switcher

* Included channels without a Focalbaord workspaces in worksapce switcher as well

Co-authored-by: Asaad Mahmood <asaadmahmood@users.noreply.github.com>
Co-authored-by: Jesús Espino <jespinog@gmail.com>
  • Loading branch information
3 people committed Sep 15, 2021
1 parent 32985d0 commit e58c77d
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 17 deletions.
26 changes: 16 additions & 10 deletions server/services/store/sqlstore/workspaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,24 +155,30 @@ func (s *SQLStore) GetWorkspaceCount() (int64, error) {
func (s *SQLStore) GetUserWorkspaces(userID string) ([]model.UserWorkspace, error) {
var query sq.SelectBuilder

query = s.getQueryBuilder().
Select("Channels.ID", "Channels.DisplayName", "COUNT(focalboard_blocks.id)").
From("focalboard_blocks").
Join("ChannelMembers ON focalboard_blocks.workspace_id = ChannelMembers.ChannelId").
Join("Channels ON ChannelMembers.ChannelId = Channels.Id").
Where(sq.Eq{"ChannelMembers.UserId": userID}).
Where(sq.Eq{"focalboard_blocks.type": "board"}).
GroupBy("Channels.Id", "Channels.DisplayName")
var nonTemplateFilter string

switch s.dbType {
case mysqlDBType:
query = query.Where(sq.Like{"focalboard_blocks.fields": "%\"isTemplate\":false%"})
nonTemplateFilter = "focalboard_blocks.fields LIKE %\"isTemplate\":false%"
case postgresDBType:
query = query.Where("focalboard_blocks.fields ->> 'isTemplate' = 'false'")
nonTemplateFilter = "focalboard_blocks.fields ->> 'isTemplate' = 'false'"
default:
return nil, fmt.Errorf("GetUserWorkspaces - %w", errUnsupportedDatabaseError)
}

query = s.getQueryBuilder().
Select("Channels.ID", "Channels.DisplayName", "COUNT(focalboard_blocks.id)").
From("ChannelMembers").
// select channels without a corresponding workspace
LeftJoin(
"focalboard_blocks ON focalboard_blocks.workspace_id = ChannelMembers.ChannelId AND "+
"focalboard_blocks.type = 'board' AND "+
nonTemplateFilter,
).
Join("Channels ON ChannelMembers.ChannelId = Channels.Id").
Where(sq.Eq{"ChannelMembers.UserId": userID}).
GroupBy("Channels.Id", "Channels.DisplayName")

rows, err := query.Query()
if err != nil {
s.logger.Error("ERROR GetUserWorkspaces", mlog.Err(err))
Expand Down
27 changes: 20 additions & 7 deletions webapp/src/components/workspaceSwitcher/workspaceOptions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,26 @@ type Props = {
const WorkspaceOptions = (props: Props): JSX.Element => {
const intl = useIntl()
const userWorkspaces = useAppSelector<UserWorkspace[]>(getUserWorkspaceList)
const options = userWorkspaces.filter((workspace) => workspace.id !== props.activeWorkspaceId).map((workspace) => {
return {
label: workspace.title,
value: workspace.id,
boardCount: workspace.boardCount,
}
})
const options = userWorkspaces.
filter((workspace) => workspace.id !== props.activeWorkspaceId).
map((workspace) => {
return {
label: workspace.title,
value: workspace.id,
boardCount: workspace.boardCount,
}
}).
sort((a, b) => {
// This will arrange into two groups -
// on the top we'll have workspaces with boards
// and below that we'll have onces with no boards,
// and each group will be sorted alphabetically within itself.
if ((a.boardCount === 0 && b.boardCount === 0) || (a.boardCount !== 0 && b.boardCount !== 0)) {
return a.label.localeCompare(b.label)
}

return b.boardCount - a.boardCount
})

return (
<Select
Expand Down

0 comments on commit e58c77d

Please sign in to comment.