Show workspace title in sidebar
This commit is contained in:
parent
83ca65a7e6
commit
7be7bed916
8 changed files with 40 additions and 12 deletions
|
@ -35,6 +35,7 @@ const (
|
||||||
|
|
||||||
type WorkspaceAuthenticator interface {
|
type WorkspaceAuthenticator interface {
|
||||||
DoesUserHaveWorkspaceAccess(session *model.Session, workspaceID string) bool
|
DoesUserHaveWorkspaceAccess(session *model.Session, workspaceID string) bool
|
||||||
|
GetWorkspace(session *model.Session, workspaceID string) *model.Workspace
|
||||||
}
|
}
|
||||||
|
|
||||||
type API struct {
|
type API struct {
|
||||||
|
@ -902,8 +903,11 @@ func (a *API) handleGetWorkspace(w http.ResponseWriter, r *http.Request) {
|
||||||
errorResponse(w, http.StatusUnauthorized, "", nil)
|
errorResponse(w, http.StatusUnauthorized, "", nil)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
workspace = &model.Workspace{
|
|
||||||
ID: workspaceID,
|
workspace = a.WorkspaceAuthenticator.GetWorkspace(session, workspaceID)
|
||||||
|
if workspace == nil {
|
||||||
|
errorResponse(w, http.StatusUnauthorized, "", nil)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
workspace, err = a.app().GetRootWorkspace()
|
workspace, err = a.app().GetRootWorkspace()
|
||||||
|
|
|
@ -8,6 +8,7 @@ import (
|
||||||
type MattermostAuth interface {
|
type MattermostAuth interface {
|
||||||
RegisterRoutes(*mux.Router)
|
RegisterRoutes(*mux.Router)
|
||||||
DoesUserHaveWorkspaceAccess(session *model.Session, workspaceID string) bool
|
DoesUserHaveWorkspaceAccess(session *model.Session, workspaceID string) bool
|
||||||
|
GetWorkspace(session *model.Session, workspaceID string) *model.Workspace
|
||||||
}
|
}
|
||||||
|
|
||||||
type MattermostAuthParameters struct {
|
type MattermostAuthParameters struct {
|
||||||
|
|
|
@ -7,6 +7,10 @@ type Workspace struct {
|
||||||
// required: true
|
// required: true
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
|
|
||||||
|
// Title of the workspace
|
||||||
|
// required: false
|
||||||
|
Title string `json:"title"`
|
||||||
|
|
||||||
// Token required to register new users
|
// Token required to register new users
|
||||||
// required: true
|
// required: true
|
||||||
SignupToken string `json:"signupToken"`
|
SignupToken string `json:"signupToken"`
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
// See LICENSE.txt for license information.
|
// See LICENSE.txt for license information.
|
||||||
interface IWorkspace {
|
interface IWorkspace {
|
||||||
readonly id: string,
|
readonly id: string,
|
||||||
|
readonly title: string,
|
||||||
readonly signupToken: string,
|
readonly signupToken: string,
|
||||||
readonly settings: Readonly<Record<string, any>>
|
readonly settings: Readonly<Record<string, any>>
|
||||||
readonly modifiedBy?: string,
|
readonly modifiedBy?: string,
|
||||||
|
|
|
@ -39,6 +39,11 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.WorkspaceTitle {
|
||||||
|
padding: 0 16px;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
.octo-sidebar-list {
|
.octo-sidebar-list {
|
||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||||
// See LICENSE.txt for license information.
|
// 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 {loadTheme} from '../../theme'
|
||||||
import {WorkspaceTree} from '../../viewModel/workspaceTree'
|
import {WorkspaceTree} from '../../viewModel/workspaceTree'
|
||||||
import IconButton from '../../widgets/buttons/iconButton'
|
import IconButton from '../../widgets/buttons/iconButton'
|
||||||
|
@ -9,13 +10,14 @@ import HamburgerIcon from '../../widgets/icons/hamburger'
|
||||||
import HideSidebarIcon from '../../widgets/icons/hideSidebar'
|
import HideSidebarIcon from '../../widgets/icons/hideSidebar'
|
||||||
import ShowSidebarIcon from '../../widgets/icons/showSidebar'
|
import ShowSidebarIcon from '../../widgets/icons/showSidebar'
|
||||||
|
|
||||||
import SidebarSettingsMenu from './sidebarSettingsMenu'
|
import './sidebar.scss'
|
||||||
import SidebarAddBoardMenu from './sidebarAddBoardMenu'
|
import SidebarAddBoardMenu from './sidebarAddBoardMenu'
|
||||||
import SidebarBoardItem from './sidebarBoardItem'
|
import SidebarBoardItem from './sidebarBoardItem'
|
||||||
|
import SidebarSettingsMenu from './sidebarSettingsMenu'
|
||||||
import SidebarUserMenu from './sidebarUserMenu'
|
import SidebarUserMenu from './sidebarUserMenu'
|
||||||
import './sidebar.scss'
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
|
workspace?: IWorkspace
|
||||||
showBoard: (id?: string) => void
|
showBoard: (id?: string) => void
|
||||||
showView: (id: string, boardId?: string) => void
|
showView: (id: string, boardId?: string) => void
|
||||||
workspaceTree: WorkspaceTree,
|
workspaceTree: WorkspaceTree,
|
||||||
|
@ -35,7 +37,7 @@ const Sidebar = React.memo((props: Props) => {
|
||||||
}
|
}
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
const {workspaceTree} = props
|
const {workspace, workspaceTree} = props
|
||||||
if (!workspaceTree) {
|
if (!workspaceTree) {
|
||||||
return <div/>
|
return <div/>
|
||||||
}
|
}
|
||||||
|
@ -76,6 +78,11 @@ const Sidebar = React.memo((props: Props) => {
|
||||||
icon={<HideSidebarIcon/>}
|
icon={<HideSidebarIcon/>}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
{workspace && workspace.id !== '0' &&
|
||||||
|
<div className='WorkspaceTitle'>
|
||||||
|
{workspace.title}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
<div className='octo-sidebar-list'>
|
<div className='octo-sidebar-list'>
|
||||||
{
|
{
|
||||||
boards.map((board) => {
|
boards.map((board) => {
|
||||||
|
|
|
@ -3,15 +3,17 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import {FormattedMessage} from 'react-intl'
|
import {FormattedMessage} from 'react-intl'
|
||||||
|
|
||||||
|
import {IWorkspace} from '../blocks/workspace'
|
||||||
import {Utils} from '../utils'
|
import {Utils} from '../utils'
|
||||||
import {BoardTree} from '../viewModel/boardTree'
|
import {BoardTree} from '../viewModel/boardTree'
|
||||||
import {WorkspaceTree} from '../viewModel/workspaceTree'
|
import {WorkspaceTree} from '../viewModel/workspaceTree'
|
||||||
|
|
||||||
import Sidebar from './sidebar/sidebar'
|
|
||||||
import CenterPanel from './centerPanel'
|
import CenterPanel from './centerPanel'
|
||||||
|
import Sidebar from './sidebar/sidebar'
|
||||||
import './workspace.scss'
|
import './workspace.scss'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
|
workspace?: IWorkspace
|
||||||
workspaceTree: WorkspaceTree
|
workspaceTree: WorkspaceTree
|
||||||
boardTree?: BoardTree
|
boardTree?: BoardTree
|
||||||
showBoard: (id?: string) => void
|
showBoard: (id?: string) => void
|
||||||
|
@ -22,7 +24,7 @@ type Props = {
|
||||||
}
|
}
|
||||||
|
|
||||||
const Workspace = React.memo((props: 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 || {}
|
const {activeView} = boardTree || {}
|
||||||
|
|
||||||
Utils.assert(workspaceTree || !props.readonly)
|
Utils.assert(workspaceTree || !props.readonly)
|
||||||
|
@ -31,6 +33,7 @@ const Workspace = React.memo((props: Props) => {
|
||||||
<div className='Workspace'>
|
<div className='Workspace'>
|
||||||
{!props.readonly &&
|
{!props.readonly &&
|
||||||
<Sidebar
|
<Sidebar
|
||||||
|
workspace={workspace}
|
||||||
showBoard={showBoard}
|
showBoard={showBoard}
|
||||||
showView={showView}
|
showView={showView}
|
||||||
workspaceTree={workspaceTree}
|
workspaceTree={workspaceTree}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import React from 'react'
|
||||||
import {injectIntl, IntlShape} from 'react-intl'
|
import {injectIntl, IntlShape} from 'react-intl'
|
||||||
|
|
||||||
import {IBlock} from '../blocks/block'
|
import {IBlock} from '../blocks/block'
|
||||||
|
import {IWorkspace} from '../blocks/workspace'
|
||||||
import {sendFlashMessage} from '../components/flashMessages'
|
import {sendFlashMessage} from '../components/flashMessages'
|
||||||
import Workspace from '../components/workspace'
|
import Workspace from '../components/workspace'
|
||||||
import mutator from '../mutator'
|
import mutator from '../mutator'
|
||||||
|
@ -24,6 +25,7 @@ type Props = {
|
||||||
type State = {
|
type State = {
|
||||||
boardId: string
|
boardId: string
|
||||||
viewId: string
|
viewId: string
|
||||||
|
workspace?: IWorkspace,
|
||||||
workspaceTree: WorkspaceTree
|
workspaceTree: WorkspaceTree
|
||||||
boardTree?: BoardTree
|
boardTree?: BoardTree
|
||||||
syncFailed?: boolean
|
syncFailed?: boolean
|
||||||
|
@ -143,7 +145,7 @@ class BoardPage extends React.Component<Props, State> {
|
||||||
|
|
||||||
render(): JSX.Element {
|
render(): JSX.Element {
|
||||||
const {intl} = this.props
|
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}`)
|
Utils.log(`BoardPage.render (workspace ${this.props.workspaceId}) ${this.state.boardTree?.board?.title}`)
|
||||||
|
|
||||||
|
@ -164,6 +166,7 @@ class BoardPage extends React.Component<Props, State> {
|
||||||
return (
|
return (
|
||||||
<div className='BoardPage'>
|
<div className='BoardPage'>
|
||||||
<Workspace
|
<Workspace
|
||||||
|
workspace={workspace}
|
||||||
workspaceTree={workspaceTree}
|
workspaceTree={workspaceTree}
|
||||||
boardTree={this.state.boardTree}
|
boardTree={this.state.boardTree}
|
||||||
showView={(id, boardId) => {
|
showView={(id, boardId) => {
|
||||||
|
@ -202,10 +205,10 @@ class BoardPage extends React.Component<Props, State> {
|
||||||
private async sync(boardId: string = this.state.boardId, viewId: string | undefined = this.state.viewId) {
|
private async sync(boardId: string = this.state.boardId, viewId: string | undefined = this.state.viewId) {
|
||||||
Utils.log(`sync start: ${boardId}`)
|
Utils.log(`sync start: ${boardId}`)
|
||||||
|
|
||||||
|
let workspace: IWorkspace | undefined
|
||||||
if (!this.props.readonly) {
|
if (!this.props.readonly) {
|
||||||
// Require workspace for editing, not for sharing (readonly)
|
// Require workspace for editing, not for sharing (readonly)
|
||||||
|
workspace = await octoClient.getWorkspace()
|
||||||
const workspace = await octoClient.getWorkspace()
|
|
||||||
if (!workspace) {
|
if (!workspace) {
|
||||||
location.href = '/error?id=no_workspace'
|
location.href = '/error?id=no_workspace'
|
||||||
}
|
}
|
||||||
|
@ -213,7 +216,7 @@ class BoardPage extends React.Component<Props, State> {
|
||||||
|
|
||||||
const workspaceTree = await MutableWorkspaceTree.sync()
|
const workspaceTree = await MutableWorkspaceTree.sync()
|
||||||
const boardIds = [...workspaceTree.boards.map((o) => o.id), ...workspaceTree.boardTemplates.map((o) => o.id)]
|
const boardIds = [...workspaceTree.boards.map((o) => o.id), ...workspaceTree.boardTemplates.map((o) => o.id)]
|
||||||
this.setState({workspaceTree})
|
this.setState({workspace, workspaceTree})
|
||||||
|
|
||||||
let boardIdsToListen: string[]
|
let boardIdsToListen: string[]
|
||||||
if (boardIds.length > 0) {
|
if (boardIds.length > 0) {
|
||||||
|
|
Loading…
Reference in a new issue