Merge pull request #13 from mattermost/sidebar-menu-migration
Sidebar menus migrated to the new menus system
This commit is contained in:
commit
3192271e7b
4 changed files with 35 additions and 62 deletions
|
@ -2,9 +2,9 @@ import React from "react"
|
||||||
import { Archiver } from "../archiver"
|
import { Archiver } from "../archiver"
|
||||||
import { Board } from "../board"
|
import { Board } from "../board"
|
||||||
import { BoardTree } from "../boardTree"
|
import { BoardTree } from "../boardTree"
|
||||||
import { Menu, MenuOption } from "../menu"
|
import Menu from '../widgets/menu'
|
||||||
|
import MenuWrapper from '../widgets/menuWrapper'
|
||||||
import mutator from "../mutator"
|
import mutator from "../mutator"
|
||||||
import { IPageController } from "../octoTypes"
|
|
||||||
import { WorkspaceTree } from "../workspaceTree"
|
import { WorkspaceTree } from "../workspaceTree"
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
|
@ -32,7 +32,19 @@ class Sidebar extends React.Component<Props> {
|
||||||
<div key={board.id} className="octo-sidebar-item octo-hover-container">
|
<div key={board.id} className="octo-sidebar-item octo-hover-container">
|
||||||
<div className="octo-sidebar-title" onClick={() => { this.boardClicked(board) }}>{board.icon ? `${board.icon} ${displayTitle}` : displayTitle}</div>
|
<div className="octo-sidebar-title" onClick={() => { this.boardClicked(board) }}>{board.icon ? `${board.icon} ${displayTitle}` : displayTitle}</div>
|
||||||
<div className="octo-spacer"></div>
|
<div className="octo-spacer"></div>
|
||||||
<div className="octo-button square octo-hover-item" onClick={(e) => { this.showOptions(e, board) }}><div className="imageOptions" /></div>
|
<MenuWrapper>
|
||||||
|
<div className="octo-button square octo-hover-item"><div className="imageOptions" /></div>
|
||||||
|
<Menu>
|
||||||
|
<Menu.Text id="delete" name="Delete board" onClick={async () => {
|
||||||
|
const nextBoardId = boards.length > 1 ? boards.find(o => o.id !== board.id).id : undefined
|
||||||
|
mutator.deleteBlock(
|
||||||
|
board,
|
||||||
|
"delete block",
|
||||||
|
async () => { nextBoardId && this.props.showBoard(nextBoardId!) },
|
||||||
|
async () => { this.props.showBoard(board.id) },
|
||||||
|
)}} />
|
||||||
|
</Menu>
|
||||||
|
</MenuWrapper>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
@ -44,66 +56,17 @@ class Sidebar extends React.Component<Props> {
|
||||||
|
|
||||||
<div className="octo-spacer"></div>
|
<div className="octo-spacer"></div>
|
||||||
|
|
||||||
<div className="octo-button" onClick={(e) => { this.settingsClicked(e) }}>Settings</div>
|
<MenuWrapper>
|
||||||
|
<div className="octo-button">Settings</div>
|
||||||
|
<Menu position="top">
|
||||||
|
<Menu.Text id="import" name="Import Archive" onClick={async () => Archiver.importFullArchive(() => { this.forceUpdate() })} />
|
||||||
|
<Menu.Text id="export" name="Export Archive" onClick={async () => Archiver.exportFullArchive()} />
|
||||||
|
</Menu>
|
||||||
|
</MenuWrapper>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private showOptions(e: React.MouseEvent, board: Board) {
|
|
||||||
const { showBoard, workspaceTree } = this.props
|
|
||||||
const { boards } = workspaceTree
|
|
||||||
|
|
||||||
const options: MenuOption[] = []
|
|
||||||
|
|
||||||
const nextBoardId = boards.length > 1 ? boards.find(o => o.id !== board.id).id : undefined
|
|
||||||
if (nextBoardId) {
|
|
||||||
options.push({ id: "delete", name: "Delete board" })
|
|
||||||
}
|
|
||||||
|
|
||||||
Menu.shared.options = options
|
|
||||||
Menu.shared.onMenuClicked = (optionId: string, type?: string) => {
|
|
||||||
switch (optionId) {
|
|
||||||
case "delete": {
|
|
||||||
mutator.deleteBlock(
|
|
||||||
board,
|
|
||||||
"delete block",
|
|
||||||
async () => { showBoard(nextBoardId!) },
|
|
||||||
async () => { showBoard(board.id) },
|
|
||||||
)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Menu.shared.showAtElement(e.target as HTMLElement)
|
|
||||||
}
|
|
||||||
|
|
||||||
private settingsClicked(e: React.MouseEvent) {
|
|
||||||
Menu.shared.options = [
|
|
||||||
{ id: "import", name: "Import Archive" },
|
|
||||||
{ id: "export", name: "Export Archive" },
|
|
||||||
]
|
|
||||||
Menu.shared.onMenuClicked = (optionId: string, type?: string) => {
|
|
||||||
switch (optionId) {
|
|
||||||
case "import": {
|
|
||||||
Archiver.importFullArchive(() => {
|
|
||||||
this.forceUpdate()
|
|
||||||
})
|
|
||||||
break
|
|
||||||
}
|
|
||||||
case "export": {
|
|
||||||
Archiver.exportFullArchive()
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// HACKHACK: Show menu above (TODO: refactor menu code to do this automatically)
|
|
||||||
const element = e.target as HTMLElement
|
|
||||||
const bodyRect = document.body.getBoundingClientRect()
|
|
||||||
const rect = element.getBoundingClientRect()
|
|
||||||
Menu.shared.showAt(rect.left - bodyRect.left + 20, rect.top - bodyRect.top - 30 * Menu.shared.options.length)
|
|
||||||
}
|
|
||||||
|
|
||||||
private boardClicked(board: Board) {
|
private boardClicked(board: Board) {
|
||||||
this.props.showBoard(board.id)
|
this.props.showBoard(board.id)
|
||||||
}
|
}
|
||||||
|
|
|
@ -117,6 +117,7 @@ class TextOption extends React.Component<TextOptionProps> {
|
||||||
|
|
||||||
type MenuProps = {
|
type MenuProps = {
|
||||||
children: React.ReactNode
|
children: React.ReactNode
|
||||||
|
position?: 'top'|'bottom'
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class Menu extends React.Component<MenuProps> {
|
export default class Menu extends React.Component<MenuProps> {
|
||||||
|
@ -127,10 +128,11 @@ export default class Menu extends React.Component<MenuProps> {
|
||||||
static Text = TextOption
|
static Text = TextOption
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
const {position, children} = this.props
|
||||||
return (
|
return (
|
||||||
<div className="Menu menu noselect">
|
<div className={"Menu menu noselect " + (position ? position : "bottom")}>
|
||||||
<div className="menu-options">
|
<div className="menu-options">
|
||||||
{this.props.children}
|
{children}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
|
@ -82,7 +82,7 @@ export default class MenuWrapper extends React.PureComponent<Props, State> {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={'MenuWrapper'}
|
className={'MenuWrapper menu-wrapper'}
|
||||||
onClick={this.toggle}
|
onClick={this.toggle}
|
||||||
ref={this.node}
|
ref={this.node}
|
||||||
>
|
>
|
||||||
|
|
|
@ -329,6 +329,14 @@ hr {
|
||||||
background-color: #ffffff;
|
background-color: #ffffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.menu.top {
|
||||||
|
bottom: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-wrapper {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
.menu-options {
|
.menu-options {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
Loading…
Reference in a new issue