mirror of
https://github.com/mattermost/focalboard.git
synced 2025-02-01 19:14:35 +02:00
Sidebar. WIP
This commit is contained in:
parent
fec32947bb
commit
316ad45020
@ -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)
|
||||
}
|
||||
|
@ -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
|
||||
(
|
||||
|
@ -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
|
||||
|
28
src/client/components/sidebar.tsx
Normal file
28
src/client/components/sidebar.tsx
Normal 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 }
|
51
src/client/components/workspaceComponent.tsx
Normal file
51
src/client/components/workspaceComponent.tsx
Normal 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 }
|
23
src/client/workspaceTree.ts
Normal file
23
src/client/workspaceTree.ts
Normal 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 }
|
@ -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 {
|
||||
|
Loading…
x
Reference in New Issue
Block a user