diff --git a/server/api/api.go b/server/api/api.go index b24748ae7..fd04b409f 100644 --- a/server/api/api.go +++ b/server/api/api.go @@ -35,6 +35,7 @@ const ( type WorkspaceAuthenticator interface { DoesUserHaveWorkspaceAccess(session *model.Session, workspaceID string) bool + GetWorkspace(session *model.Session, workspaceID string) *model.Workspace } type API struct { @@ -902,8 +903,11 @@ func (a *API) handleGetWorkspace(w http.ResponseWriter, r *http.Request) { errorResponse(w, http.StatusUnauthorized, "", nil) return } - workspace = &model.Workspace{ - ID: workspaceID, + + workspace = a.WorkspaceAuthenticator.GetWorkspace(session, workspaceID) + if workspace == nil { + errorResponse(w, http.StatusUnauthorized, "", nil) + return } } else { workspace, err = a.app().GetRootWorkspace() diff --git a/server/einterfaces/einterfaces.go b/server/einterfaces/einterfaces.go index 9c45fcbc0..385db9835 100644 --- a/server/einterfaces/einterfaces.go +++ b/server/einterfaces/einterfaces.go @@ -8,6 +8,7 @@ import ( type MattermostAuth interface { RegisterRoutes(*mux.Router) DoesUserHaveWorkspaceAccess(session *model.Session, workspaceID string) bool + GetWorkspace(session *model.Session, workspaceID string) *model.Workspace } type MattermostAuthParameters struct { diff --git a/server/model/workspace.go b/server/model/workspace.go index a43537da3..f302fcd61 100644 --- a/server/model/workspace.go +++ b/server/model/workspace.go @@ -7,6 +7,10 @@ type Workspace struct { // required: true ID string `json:"id"` + // Title of the workspace + // required: false + Title string `json:"title"` + // Token required to register new users // required: true SignupToken string `json:"signupToken"` diff --git a/webapp/src/blocks/workspace.ts b/webapp/src/blocks/workspace.ts index 478d86f9e..3a7112f81 100644 --- a/webapp/src/blocks/workspace.ts +++ b/webapp/src/blocks/workspace.ts @@ -2,6 +2,7 @@ // See LICENSE.txt for license information. interface IWorkspace { readonly id: string, + readonly title: string, readonly signupToken: string, readonly settings: Readonly> readonly modifiedBy?: string, diff --git a/webapp/src/components/sidebar/sidebar.scss b/webapp/src/components/sidebar/sidebar.scss index 2d55b0435..d81576f78 100644 --- a/webapp/src/components/sidebar/sidebar.scss +++ b/webapp/src/components/sidebar/sidebar.scss @@ -39,6 +39,11 @@ } } + .WorkspaceTitle { + padding: 0 16px; + font-weight: 600; + } + .octo-sidebar-list { flex: 1 1 auto; overflow-y: auto; diff --git a/webapp/src/components/sidebar/sidebar.tsx b/webapp/src/components/sidebar/sidebar.tsx index 09c1ed05e..5ef6cc0f5 100644 --- a/webapp/src/components/sidebar/sidebar.tsx +++ b/webapp/src/components/sidebar/sidebar.tsx @@ -1,7 +1,8 @@ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. -import React, {useState, useEffect} from 'react' +import React, {useEffect, useState} from 'react' +import {IWorkspace} from '../../blocks/workspace' import {loadTheme} from '../../theme' import {WorkspaceTree} from '../../viewModel/workspaceTree' import IconButton from '../../widgets/buttons/iconButton' @@ -9,13 +10,14 @@ import HamburgerIcon from '../../widgets/icons/hamburger' import HideSidebarIcon from '../../widgets/icons/hideSidebar' import ShowSidebarIcon from '../../widgets/icons/showSidebar' -import SidebarSettingsMenu from './sidebarSettingsMenu' +import './sidebar.scss' import SidebarAddBoardMenu from './sidebarAddBoardMenu' import SidebarBoardItem from './sidebarBoardItem' +import SidebarSettingsMenu from './sidebarSettingsMenu' import SidebarUserMenu from './sidebarUserMenu' -import './sidebar.scss' type Props = { + workspace?: IWorkspace showBoard: (id?: string) => void showView: (id: string, boardId?: string) => void workspaceTree: WorkspaceTree, @@ -35,7 +37,7 @@ const Sidebar = React.memo((props: Props) => { } }, []) - const {workspaceTree} = props + const {workspace, workspaceTree} = props if (!workspaceTree) { return
} @@ -76,6 +78,11 @@ const Sidebar = React.memo((props: Props) => { icon={} />
+ {workspace && workspace.id !== '0' && +
+ {workspace.title} +
+ }
{ boards.map((board) => { diff --git a/webapp/src/components/workspace.tsx b/webapp/src/components/workspace.tsx index 9cbe782de..4d2281601 100644 --- a/webapp/src/components/workspace.tsx +++ b/webapp/src/components/workspace.tsx @@ -3,15 +3,17 @@ import React from 'react' import {FormattedMessage} from 'react-intl' +import {IWorkspace} from '../blocks/workspace' import {Utils} from '../utils' import {BoardTree} from '../viewModel/boardTree' import {WorkspaceTree} from '../viewModel/workspaceTree' -import Sidebar from './sidebar/sidebar' import CenterPanel from './centerPanel' +import Sidebar from './sidebar/sidebar' import './workspace.scss' type Props = { + workspace?: IWorkspace workspaceTree: WorkspaceTree boardTree?: BoardTree showBoard: (id?: string) => void @@ -22,7 +24,7 @@ type Props = { } const Workspace = React.memo((props: Props) => { - const {boardTree, setSearchText, workspaceTree, showBoard, showView, setLanguage} = props + const {workspace, boardTree, setSearchText, workspaceTree, showBoard, showView, setLanguage} = props const {activeView} = boardTree || {} Utils.assert(workspaceTree || !props.readonly) @@ -31,6 +33,7 @@ const Workspace = React.memo((props: Props) => {
{!props.readonly && { render(): JSX.Element { const {intl} = this.props - const {workspaceTree} = this.state + const {workspace, workspaceTree} = this.state Utils.log(`BoardPage.render (workspace ${this.props.workspaceId}) ${this.state.boardTree?.board?.title}`) @@ -164,6 +166,7 @@ class BoardPage extends React.Component { return (
{ @@ -202,10 +205,10 @@ class BoardPage extends React.Component { private async sync(boardId: string = this.state.boardId, viewId: string | undefined = this.state.viewId) { Utils.log(`sync start: ${boardId}`) + let workspace: IWorkspace | undefined if (!this.props.readonly) { // Require workspace for editing, not for sharing (readonly) - - const workspace = await octoClient.getWorkspace() + workspace = await octoClient.getWorkspace() if (!workspace) { location.href = '/error?id=no_workspace' } @@ -213,7 +216,7 @@ class BoardPage extends React.Component { const workspaceTree = await MutableWorkspaceTree.sync() const boardIds = [...workspaceTree.boards.map((o) => o.id), ...workspaceTree.boardTemplates.map((o) => o.id)] - this.setState({workspaceTree}) + this.setState({workspace, workspaceTree}) let boardIdsToListen: string[] if (boardIds.length > 0) {