@@ -42,11 +43,11 @@ class WorkspaceComponent extends React.Component
{
switch (activeView?.viewType) {
case "board": {
- return
+ return
}
case "table": {
- return
+ return
}
default: {
diff --git a/src/client/pages/boardPage.tsx b/src/client/pages/boardPage.tsx
index 20ece3b9f..ad4ee5f03 100644
--- a/src/client/pages/boardPage.tsx
+++ b/src/client/pages/boardPage.tsx
@@ -5,13 +5,12 @@ import { BoardView } from "../boardView"
import { CardTree } from "../cardTree"
import { CardDialog } from "../components/cardDialog"
import { FilterComponent } from "../components/filterComponent"
-import { PageHeader } from "../components/pageHeader"
import { WorkspaceComponent } from "../components/workspaceComponent"
import { FlashMessage } from "../flashMessage"
import { Mutator } from "../mutator"
import { OctoClient } from "../octoClient"
import { OctoListener } from "../octoListener"
-import { IBlock, IPageController } from "../octoTypes"
+import { IBlock } from "../octoTypes"
import { UndoManager } from "../undomanager"
import { Utils } from "../utils"
import { WorkspaceTree } from "../workspaceTree"
@@ -20,109 +19,111 @@ type Props = {
}
type State = {
- boardId: string
- viewId: string
- workspaceTree: WorkspaceTree
- boardTree?: BoardTree
+ boardId: string
+ viewId: string
+ workspaceTree: WorkspaceTree
+ boardTree?: BoardTree
+ shownCardTree?: CardTree
}
export default class BoardPage extends React.Component {
- workspaceTree: WorkspaceTree
- boardTree?: BoardTree
view: BoardView
updateTitleTimeout: number
updatePropertyLabelTimeout: number
- shownCardTree: CardTree
-
private filterAnchorElement?: HTMLElement
private octo = new OctoClient()
private boardListener = new OctoListener()
private cardListener = new OctoListener()
constructor(props: Props) {
- super(props)
+ super(props)
const queryString = new URLSearchParams(window.location.search)
const boardId = queryString.get("id")
const viewId = queryString.get("v")
- this.state = {
- boardId,
- viewId,
- workspaceTree: new WorkspaceTree(this.octo),
- }
-
- console.log(`BoardPage. boardId: ${boardId}`)
- }
-
- componentDidUpdate(prevProps: Props, prevState: State) {
- const board = this.state.boardTree.board;
- const prevBoard = prevState.boardTree.board;
-
- const activeView = this.state.boardTree.activeView;
- const prevActiveView = prevState.boardTree.activeView;
-
- if (board.icon !== prevBoard.icon) {
- Utils.setFavicon(board.icon)
- }
- if (board.title !== prevBoard.title || activeView.title !== prevActiveView.title) {
- document.title = `OCTO - ${board.title} | ${activeView.title}`
+ this.state = {
+ boardId,
+ viewId,
+ workspaceTree: new WorkspaceTree(this.octo),
}
- }
- undoRedoHandler = async (e: KeyboardEvent) => {
- if (e.target !== document) { return }
+ Utils.log(`BoardPage. boardId: ${boardId}`)
+ }
- if (e.keyCode === 90 && !e.shiftKey && (e.ctrlKey || e.metaKey) && !e.altKey) { // Cmd+Z
- Utils.log(`Undo`)
- const description = UndoManager.shared.undoDescription
- await UndoManager.shared.undo()
- if (description) {
- FlashMessage.show(`Undo ${description}`)
- } else {
- FlashMessage.show(`Undo`)
- }
- } else if (e.keyCode === 90 && e.shiftKey && (e.ctrlKey || e.metaKey) && !e.altKey) { // Shift+Cmd+Z
- Utils.log(`Redo`)
- const description = UndoManager.shared.redoDescription
- await UndoManager.shared.redo()
- if (description) {
- FlashMessage.show(`Redo ${description}`)
- } else {
- FlashMessage.show(`Redo`)
- }
- }
- }
+ componentDidUpdate(prevProps: Props, prevState: State) {
+ Utils.log(`componentDidUpdate`)
+ const board = this.state.boardTree?.board
+ const prevBoard = prevState.boardTree?.board
- componentDidMount() {
+ const activeView = this.state.boardTree?.activeView
+ const prevActiveView = prevState.boardTree?.activeView
+
+ if (board?.icon !== prevBoard?.icon) {
+ Utils.setFavicon(board?.icon)
+ }
+ if (board?.title !== prevBoard?.title || activeView?.title !== prevActiveView?.title) {
+ document.title = `OCTO - ${board?.title} | ${activeView?.title}`
+ }
+ }
+
+ undoRedoHandler = async (e: KeyboardEvent) => {
+ if (e.target !== document.body) { return }
+
+ if (e.keyCode === 90 && !e.shiftKey && (e.ctrlKey || e.metaKey) && !e.altKey) { // Cmd+Z
+ Utils.log(`Undo`)
+ const description = UndoManager.shared.undoDescription
+ await UndoManager.shared.undo()
+ if (description) {
+ FlashMessage.show(`Undo ${description}`)
+ } else {
+ FlashMessage.show(`Undo`)
+ }
+ } else if (e.keyCode === 90 && e.shiftKey && (e.ctrlKey || e.metaKey) && !e.altKey) { // Shift+Cmd+Z
+ Utils.log(`Redo`)
+ const description = UndoManager.shared.redoDescription
+ await UndoManager.shared.redo()
+ if (description) {
+ FlashMessage.show(`Redo ${description}`)
+ } else {
+ FlashMessage.show(`Redo`)
+ }
+ }
+ }
+
+ componentDidMount() {
document.addEventListener("keydown", this.undoRedoHandler)
if (this.state.boardId) {
this.attachToBoard(this.state.boardId, this.state.viewId)
- } else {
- this.sync()
- }
+ } else {
+ this.sync()
+ }
}
- componentWillUnmount() {
+ componentWillUnmount() {
document.removeEventListener("keydown", this.undoRedoHandler)
- }
+ }
render() {
+ const { workspaceTree, shownCardTree } = this.state
const { board, activeView } = this.state.boardTree || {}
const mutator = new Mutator(this.octo)
- // TODO Move all this into the root portal component when that is merged
- if (this.state.boardTree && this.state.boardTree.board && this.shownCardTree) {
+ // TODO Move all this into the root portal component when that is merged
+ if (this.state.boardTree && this.state.boardTree.board && shownCardTree) {
ReactDOM.render(
- { this.showCard(undefined) }}>,
+ { this.showCard(undefined) }}>,
Utils.getElementById("overlay")
)
} else {
- ReactDOM.render(
- ,
- Utils.getElementById("overlay")
- )
+ const overlay = document.getElementById("overlay")
+ if (overlay) {
+ ReactDOM.render(
+ ,
+ overlay
+ )
+ }
}
if (this.filterAnchorElement) {
@@ -146,50 +147,64 @@ export default class BoardPage extends React.Component {
Utils.getElementById("modal")
)
} else {
- ReactDOM.render(, Utils.getElementById("modal"))
+ const modal = document.getElementById("modal")
+ if (modal) {
+ ReactDOM.render(, modal)
+ }
}
- return (
-
- ,
-
- );
+ Utils.log(`BoardPage.render ${this.state.boardTree?.board?.title}`)
+ return (
+
+ { this.showView(id) }}
+ showCard={(card) => { this.showCard(card) }}
+ showBoard={(id) => { this.showBoard(id) }}
+ showFilter={(el) => { this.showFilter(el) }}
+ setSearchText={(text) => { this.setSearchText(text) }} />
+
+ )
}
- private attachToBoard(boardId: string, viewId?: string) {
- const boardTree = new BoardTree(this.octo, boardId)
- this.setState({
- boardId,
- viewId,
- boardTree,
- })
+ private async attachToBoard(boardId: string, viewId?: string) {
+ Utils.log(`attachToBoard: ${boardId}`)
this.boardListener.open(boardId, (blockId: string) => {
console.log(`octoListener.onChanged: ${blockId}`)
- this.sync()
+ this.sync(boardId)
})
- this.sync()
+ this.sync(boardId, viewId)
}
- async sync() {
- const { viewId, workspaceTree, boardTree } = this.state
+ async sync(boardId: string = this.state.boardId, viewId: string | undefined = this.state.viewId) {
+ const { workspaceTree } = this.state
+ Utils.log(`sync start: ${boardId}`)
await workspaceTree.sync()
- if (boardTree) {
+
+ if (boardId) {
+ const boardTree = new BoardTree(this.octo, boardId)
await boardTree.sync()
// Default to first view
if (!viewId) {
- this.setState({viewId: boardTree.views[0].id})
+ viewId = boardTree.views[0].id
}
- boardTree.setActiveView(this.state.viewId)
+ boardTree.setActiveView(viewId)
// TODO: Handle error (viewId not found)
- this.setState({
- viewId: boardTree.activeView.id
- })
- console.log(`sync complete... title: ${boardTree.board.title}`)
+ this.setState({
+ ...this.state,
+ boardTree,
+ viewId: boardTree.activeView.id
+ })
+ Utils.log(`sync complete: ${boardTree.board.id} (${boardTree.board.title})`)
+ } else {
+ this.forceUpdate()
}
}
@@ -201,20 +216,22 @@ export default class BoardPage extends React.Component {
if (card) {
const cardTree = new CardTree(this.octo, card.id)
await cardTree.sync()
- this.shownCardTree = cardTree
+ this.setState({...this.state, shownCardTree: cardTree})
this.cardListener = new OctoListener()
this.cardListener.open(card.id, async () => {
await cardTree.sync()
- this.render()
+ this.forceUpdate()
})
} else {
- this.shownCardTree = undefined
+ this.setState({...this.state, shownCardTree: undefined})
}
}
showBoard(boardId: string) {
- if (this.boardTree?.board?.id === boardId) { return }
+ const { boardTree } = this.state
+
+ if (boardTree?.board?.id === boardId) { return }
const newUrl = window.location.protocol + "//" + window.location.host + window.location.pathname + `?id=${encodeURIComponent(boardId)}`
window.history.pushState({ path: newUrl }, "", newUrl)
@@ -224,7 +241,7 @@ export default class BoardPage extends React.Component {
showView(viewId: string) {
this.state.boardTree.setActiveView(viewId)
- this.setState({viewId, boardTree: this.state.boardTree})
+ this.setState({ viewId, boardTree: this.state.boardTree })
const newUrl = window.location.protocol + "//" + window.location.host + window.location.pathname + `?id=${encodeURIComponent(this.state.boardId)}&v=${encodeURIComponent(viewId)}`
window.history.pushState({ path: newUrl }, "", newUrl)
}
@@ -234,6 +251,6 @@ export default class BoardPage extends React.Component {
}
setSearchText(text?: string) {
- this.boardTree.setSearchText(text)
+ this.state.boardTree?.setSearchText(text)
}
}
diff --git a/src/static/main.css b/src/static/main.css
index 512da8390..893d8b8ec 100644
--- a/src/static/main.css
+++ b/src/static/main.css
@@ -73,7 +73,9 @@ hr {
overflow: auto;
}
-#octo-tasks-app > #main {
+#octo-tasks-app #frame,
+#octo-tasks-app #main,
+#octo-tasks-app .BoardPage {
flex: 1 1 auto;
display: flex;
flex-direction: column;