1
0
mirror of https://github.com/mattermost/focalboard.git synced 2025-02-01 19:14:35 +02:00

Sidebar. WIP

This commit is contained in:
Chen-I Lim 2020-10-12 11:02:07 -07:00
parent fec32947bb
commit 316ad45020
7 changed files with 167 additions and 29 deletions

View File

@ -48,12 +48,15 @@ func handleGetBlocks(w http.ResponseWriter, r *http.Request) {
blockType := query.Get("type")
var blocks []string
if len(blockType) > 0 {
if len(blockType) > 0 && len(parentID) > 0 {
blocks = getBlocksWithParentAndType(parentID, blockType)
} else if len(blockType) > 0 {
blocks = getBlocksWithType(blockType)
} else {
blocks = getBlocksWithParent(parentID)
}
log.Printf("GetBlocks parentID: %s, %d result(s)", parentID, len(blocks))
log.Printf("GetBlocks parentID: %s, type: %s, %d result(s)", parentID, blockType, len(blocks))
response := `[` + strings.Join(blocks[:], ",") + `]`
jsonResponse(w, 200, response)
}

View File

@ -155,6 +155,32 @@ func getBlocksWithParent(parentID string) []string {
return blocksFromRows(rows)
}
func getBlocksWithType(blockType string) []string {
query := `WITH latest AS
(
SELECT * FROM
(
SELECT
*,
ROW_NUMBER() OVER (PARTITION BY id ORDER BY insert_at DESC) AS rn
FROM blocks
) a
WHERE rn = 1
)
SELECT COALESCE("json", '{}')
FROM latest
WHERE delete_at = 0 and type = $1`
rows, err := db.Query(query, blockType)
if err != nil {
log.Printf(`getBlocksWithParentAndType ERROR: %v`, err)
panic(err)
}
return blocksFromRows(rows)
}
func getSubTree(blockID string) []string {
query := `WITH latest AS
(

View File

@ -3,11 +3,10 @@ import ReactDOM from "react-dom"
import { BoardTree } from "./boardTree"
import { BoardView } from "./boardView"
import { CardTree } from "./cardTree"
import { BoardComponent } from "./components/boardComponent"
import { CardDialog } from "./components/cardDialog"
import { FilterComponent } from "./components/filterComponent"
import { PageHeader } from "./components/pageHeader"
import { TableComponent } from "./components/tableComponent"
import { WorkspaceComponent } from "./components/workspaceComponent"
import { FlashMessage } from "./flashMessage"
import { Mutator } from "./mutator"
import { OctoClient } from "./octoClient"
@ -15,6 +14,7 @@ import { OctoListener } from "./octoListener"
import { IBlock, IPageController } from "./octoTypes"
import { UndoManager } from "./undomanager"
import { Utils } from "./utils"
import { WorkspaceTree } from "./workspaceTree"
class BoardPage implements IPageController {
boardTitle: HTMLElement
@ -26,6 +26,7 @@ class BoardPage implements IPageController {
boardId: string
viewId: string
workspaceTree: WorkspaceTree
boardTree: BoardTree
view: BoardView
@ -49,6 +50,8 @@ class BoardPage implements IPageController {
this.layoutPage()
this.workspaceTree = new WorkspaceTree(this.octo)
this.boardId = queryString.get("id")
this.viewId = queryString.get("v")
@ -114,7 +117,7 @@ class BoardPage implements IPageController {
const { board, activeView } = boardTree
const mutator = new Mutator(octo)
const rootElement = Utils.getElementById("main")
const mainElement = Utils.getElementById("main")
ReactDOM.render(
<PageHeader />,
@ -126,7 +129,7 @@ class BoardPage implements IPageController {
} else {
ReactDOM.render(
<div className="page-loading">Loading...</div>,
rootElement
mainElement
)
return
}
@ -134,27 +137,10 @@ class BoardPage implements IPageController {
if (activeView) {
document.title = `OCTO - ${board.title} | ${activeView.title}`
switch (activeView.viewType) {
case "board": {
ReactDOM.render(
<BoardComponent mutator={mutator} boardTree={this.boardTree} pageController={this} />,
rootElement
)
break
}
case "table": {
ReactDOM.render(
<TableComponent mutator={mutator} boardTree={this.boardTree} pageController={this} />,
rootElement
)
break
}
default: {
Utils.assertFailure(`render() Unhandled viewType: ${activeView.viewType}`)
}
}
ReactDOM.render(
<WorkspaceComponent mutator={mutator} workspaceTree={this.workspaceTree} boardTree={this.boardTree} pageController={this} />,
mainElement
)
if (boardTree && boardTree.board && this.shownCardTree) {
ReactDOM.render(
@ -170,7 +156,7 @@ class BoardPage implements IPageController {
} else {
ReactDOM.render(
<div>Loading...</div>,
rootElement
mainElement
)
}
@ -200,8 +186,9 @@ class BoardPage implements IPageController {
}
async sync() {
const { boardTree } = this
const { workspaceTree, boardTree } = this
await workspaceTree.sync()
await boardTree.sync()
// Default to first view

View File

@ -0,0 +1,28 @@
import React from "react"
import { WorkspaceTree } from "../workspaceTree"
type Props = {
workspaceTree: WorkspaceTree
}
class Sidebar extends React.Component<Props> {
render() {
const { workspaceTree } = this.props
const { boards } = workspaceTree
return (
<div className="octo-sidebar">
{ boards.map(board => {
return (
<div>
{board.title || "(Untitled Board)"}
</div>
)
})}
</div>
)
}
}
export { Sidebar }

View File

@ -0,0 +1,51 @@
import React from "react"
import { BoardTree } from "../boardTree"
import { Mutator } from "../mutator"
import { IPageController } from "../octoTypes"
import { Utils } from "../utils"
import { WorkspaceTree } from "../workspaceTree"
import { BoardComponent } from "./boardComponent"
import { Sidebar } from "./sidebar"
import { TableComponent } from "./tableComponent"
type Props = {
mutator: Mutator,
workspaceTree: WorkspaceTree
boardTree?: BoardTree
pageController: IPageController
}
class WorkspaceComponent extends React.Component<Props> {
render() {
const element =
<div className="octo-workspace">
<Sidebar workspaceTree={this.props.workspaceTree}></Sidebar>
{this.mainComponent()}
</div>
return element
}
private mainComponent() {
const { mutator, boardTree, pageController } = this.props
const { activeView } = boardTree
switch (activeView.viewType) {
case "board": {
return <BoardComponent mutator={mutator} boardTree={boardTree} pageController={pageController} />
}
case "table": {
return <TableComponent mutator={mutator} boardTree={boardTree} pageController={pageController} />
}
default: {
Utils.assertFailure(`render() Unhandled viewType: ${activeView.viewType}`)
return <div></div>
}
}
}
}
export { WorkspaceComponent }

View File

@ -0,0 +1,23 @@
import { Board } from "./board"
import { OctoClient } from "./octoClient"
import { IBlock } from "./octoTypes"
class WorkspaceTree {
boards: Board[] = []
constructor(
private octo: OctoClient) {
}
async sync() {
const blocks = await this.octo.getBlocks(undefined, "board")
this.rebuild(blocks)
}
private rebuild(blocks: IBlock[]) {
const boardBlocks = blocks.filter(block => block.type === "board")
this.boards = boardBlocks.map(o => new Board(o))
}
}
export { WorkspaceTree }

View File

@ -60,6 +60,26 @@ hr {
display: inline-block;
}
/* Sidebar */
.octo-workspace {
display: flex;
flex-direction: row;
}
.octo-sidebar {
display: flex;
flex-direction: column;
padding: 20px;
background-color: rgb(247, 246, 243);
min-width: 230px;
}
.octo-sidebar div {
font-weight: 500;
}
/* OCTO */
.octo-frame {