diff --git a/src/client/archiver.ts b/src/client/archiver.ts index 6185de606..c2db067de 100644 --- a/src/client/archiver.ts +++ b/src/client/archiver.ts @@ -1,5 +1,5 @@ import { BoardTree } from "./boardTree" -import { Mutator } from "./mutator" +import mutator from "./mutator" import { IBlock } from "./octoTypes" import { Utils } from "./utils" @@ -21,7 +21,7 @@ class Archiver { this.exportArchive(archive) } - static async exportFullArchive(mutator: Mutator) { + static async exportFullArchive() { const blocks = await mutator.exportFullArchive() const archive: Archive = { version: 1, @@ -50,7 +50,7 @@ class Archiver { // TODO: Remove or reuse link } - static importFullArchive(mutator: Mutator, onImported?: () => void): void { + static importFullArchive(onImported?: () => void): void { const input = document.createElement("input") input.type = "file" input.accept = ".octo" diff --git a/src/client/boardTree.ts b/src/client/boardTree.ts index 285bb2440..47fedc1bd 100644 --- a/src/client/boardTree.ts +++ b/src/client/boardTree.ts @@ -2,7 +2,7 @@ import { Board, IPropertyOption, IPropertyTemplate } from "./board" import { BoardView } from "./boardView" import { Card } from "./card" import { CardFilter } from "./cardFilter" -import { OctoClient } from "./octoClient" +import octoClient from "./octoClient" import { IBlock } from "./octoTypes" import { Utils } from "./utils" @@ -24,13 +24,11 @@ class BoardTree { return [this.board, ...this.views, ...this.allCards] } - constructor( - private octo: OctoClient, - private boardId: string) { + constructor(private boardId: string) { } async sync() { - const blocks = await this.octo.getSubtree(this.boardId) + const blocks = await octoClient.getSubtree(this.boardId) this.rebuild(blocks) } diff --git a/src/client/cardTree.ts b/src/client/cardTree.ts index 819d522b3..92d8b0f12 100644 --- a/src/client/cardTree.ts +++ b/src/client/cardTree.ts @@ -1,5 +1,5 @@ import { Card } from "./card" -import { OctoClient } from "./octoClient" +import octoClient from "./octoClient" import { IBlock } from "./octoTypes" class CardTree { @@ -8,13 +8,11 @@ class CardTree { contents: IBlock[] isSynched: boolean - constructor( - private octo: OctoClient, - private cardId: string) { + constructor(private cardId: string) { } async sync() { - const blocks = await this.octo.getSubtree(this.cardId) + const blocks = await octoClient.getSubtree(this.cardId) this.rebuild(blocks) } diff --git a/src/client/components/boardCard.tsx b/src/client/components/boardCard.tsx index 39ca5fb96..4a0177d31 100644 --- a/src/client/components/boardCard.tsx +++ b/src/client/components/boardCard.tsx @@ -3,12 +3,11 @@ import { Block } from "../block" import { IPropertyTemplate } from "../board" import { Card } from "../card" import { Menu } from "../menu" -import { Mutator } from "../mutator" +import mutator from "../mutator" import { OctoUtils } from "../octoUtils" import { Utils } from "../utils" type BoardCardProps = { - mutator: Mutator card: Card visiblePropertyTemplates: IPropertyTemplate[] onClick?: (e: React.MouseEvent) => void @@ -58,7 +57,7 @@ class BoardCard extends React.Component { } private showOptionsMenu(e: React.MouseEvent) { - const { mutator, card } = this.props + const { card } = this.props e.stopPropagation() diff --git a/src/client/components/boardComponent.tsx b/src/client/components/boardComponent.tsx index af0966b5a..f0a2f731b 100644 --- a/src/client/components/boardComponent.tsx +++ b/src/client/components/boardComponent.tsx @@ -11,7 +11,7 @@ import Menu from "../widgets/menu" import { Constants } from "../constants" import { randomEmojiList } from "../emojiList" import { Menu as OldMenu } from "../menu" -import { Mutator } from "../mutator" +import mutator from "../mutator" import { OctoUtils } from "../octoUtils" import { Utils } from "../utils" import { BoardCard } from "./boardCard" @@ -20,7 +20,6 @@ import Button from "./button" import { Editable } from "./editable" type Props = { - mutator: Mutator, boardTree?: BoardTree showView: (id: string) => void showCard: (card: Card) => void @@ -29,8 +28,8 @@ type Props = { } type State = { - isHoverOnCover: boolean isSearching: boolean + isHoverOnCover: boolean } class BoardComponent extends React.Component { @@ -50,7 +49,7 @@ class BoardComponent extends React.Component { } render() { - const { mutator, boardTree, showView } = this.props + const { boardTree, showView } = this.props if (!boardTree || !boardTree.board) { return ( @@ -109,7 +108,6 @@ class BoardComponent extends React.Component { @@ -120,7 +118,7 @@ class BoardComponent extends React.Component { Group by {boardTree.groupByProperty?.name}
{ this.filterClicked(e) }}>Filter
-
{ OctoUtils.showSortMenu(e, mutator, boardTree) }}>Sort
+
{ OctoUtils.showSortMenu(e, boardTree) }}>Sort
{this.state.isSearching ? { { this.onDropToColumn(undefined) }}> {boardTree.emptyGroupCards.map(card => { { this.onDropToColumn(group.option) }} key={group.option.value}> {group.cards.map(card => { } async addCard(groupByValue?: string) { - const { mutator, boardTree } = this.props + const { boardTree } = this.props const { activeView, board } = boardTree const card = new Card() @@ -252,7 +248,7 @@ class BoardComponent extends React.Component { } async propertyNameChanged(option: IPropertyOption, text: string) { - const { mutator, boardTree } = this.props + const { boardTree } = this.props await mutator.changePropertyOptionValue(boardTree, boardTree.groupByProperty, option, text) } @@ -290,7 +286,7 @@ class BoardComponent extends React.Component { } private async testAddCards(count: number) { - const { mutator, boardTree } = this.props + const { boardTree } = this.props const { board, activeView } = boardTree const startCount = boardTree?.cards?.length @@ -313,7 +309,7 @@ class BoardComponent extends React.Component { } private async propertiesClicked(e: React.MouseEvent) { - const { mutator, boardTree } = this.props + const { boardTree } = this.props const { activeView } = boardTree const selectProperties = boardTree.board.cardProperties @@ -339,7 +335,7 @@ class BoardComponent extends React.Component { } private async groupByClicked(e: React.MouseEvent) { - const { mutator, boardTree } = this.props + const { boardTree } = this.props const selectProperties = boardTree.board.cardProperties.filter(o => o.type === "select") OldMenu.shared.options = selectProperties.map((o) => { return { id: o.id, name: o.name } }) @@ -354,7 +350,7 @@ class BoardComponent extends React.Component { async addGroupClicked() { console.log(`onAddGroupClicked`) - const { mutator, boardTree } = this.props + const { boardTree } = this.props const option: IPropertyOption = { value: "New group", @@ -366,7 +362,7 @@ class BoardComponent extends React.Component { } async onDropToColumn(option: IPropertyOption) { - const { mutator, boardTree } = this.props + const { boardTree } = this.props const { draggedCard, draggedHeaderOption } = this const propertyValue = option ? option.value : undefined diff --git a/src/client/components/cardDialog.tsx b/src/client/components/cardDialog.tsx index e664c55c9..81d42415e 100644 --- a/src/client/components/cardDialog.tsx +++ b/src/client/components/cardDialog.tsx @@ -4,7 +4,7 @@ import { BlockIcons } from "../blockIcons" import { BoardTree } from "../boardTree" import { CardTree } from "../cardTree" import { Menu, MenuOption } from "../menu" -import { Mutator } from "../mutator" +import mutator from "../mutator" import { IBlock } from "../octoTypes" import { OctoUtils } from "../octoUtils" import { PropertyMenu } from "../propertyMenu" @@ -16,7 +16,6 @@ import { MarkdownEditor } from "./markdownEditor" type Props = { boardTree: BoardTree cardTree: CardTree - mutator: Mutator onClose: () => void } @@ -51,7 +50,7 @@ class CardDialog extends React.Component { } render() { - const { boardTree, cardTree, mutator } = this.props + const { boardTree, cardTree } = this.props const { board } = boardTree const { card, comments } = cardTree @@ -203,7 +202,7 @@ class CardDialog extends React.Component { } menu.showAtElement(e.target as HTMLElement) }}>{propertyTemplate.name} - {OctoUtils.propertyValueEditableElement(mutator, card, propertyTemplate)} + {OctoUtils.propertyValueEditableElement(card, propertyTemplate)} ) })} @@ -332,7 +331,7 @@ class CardDialog extends React.Component { } async sendComment(text: string) { - const { mutator, cardTree } = this.props + const { cardTree } = this.props const { card } = cardTree Utils.assertValue(card) @@ -342,7 +341,7 @@ class CardDialog extends React.Component { } private showContentBlockMenu(e: React.MouseEvent, block: IBlock) { - const { mutator, cardTree } = this.props + const { cardTree } = this.props const { card } = cardTree const index = cardTree.contents.indexOf(block) @@ -409,7 +408,7 @@ class CardDialog extends React.Component { } private iconClicked(e: React.MouseEvent) { - const { mutator, cardTree } = this.props + const { cardTree } = this.props const { card } = cardTree Menu.shared.options = [ diff --git a/src/client/components/filterComponent.tsx b/src/client/components/filterComponent.tsx index 9047b736e..0642b5392 100644 --- a/src/client/components/filterComponent.tsx +++ b/src/client/components/filterComponent.tsx @@ -3,11 +3,10 @@ import { BoardTree } from "../boardTree" import { FilterClause, FilterCondition } from "../filterClause" import { FilterGroup } from "../filterGroup" import { Menu } from "../menu" -import { Mutator } from "../mutator" +import mutator from "../mutator" import { Utils } from "../utils" type Props = { - mutator: Mutator boardTree: BoardTree pageX: number pageY: number @@ -67,7 +66,7 @@ class FilterComponent extends React.Component { } private propertyClicked(e: React.MouseEvent, filter: FilterClause) { - const { mutator, boardTree } = this.props + const { boardTree } = this.props const { board, activeView: view } = boardTree const filterIndex = view.filter.filters.indexOf(filter) @@ -90,7 +89,7 @@ class FilterComponent extends React.Component { } private conditionClicked(e: React.MouseEvent, filter: FilterClause) { - const { mutator, boardTree } = this.props + const { boardTree } = this.props const { activeView: view } = boardTree const filterIndex = view.filter.filters.indexOf(filter) @@ -115,7 +114,7 @@ class FilterComponent extends React.Component { } private valuesClicked(e: React.MouseEvent, filter: FilterClause) { - const { mutator, boardTree } = this.props + const { boardTree } = this.props const { board, activeView: view } = boardTree const template = board.cardProperties.find(o => o.id === filter.propertyId) @@ -143,7 +142,7 @@ class FilterComponent extends React.Component { } private deleteClicked(filter: FilterClause) { - const { mutator, boardTree } = this.props + const { boardTree } = this.props const { activeView: view } = boardTree const filterGroup = new FilterGroup(view.filter) @@ -153,7 +152,7 @@ class FilterComponent extends React.Component { } private addFilterClicked() { - const { mutator, boardTree } = this.props + const { boardTree } = this.props const { board, activeView: view } = boardTree const filters = view.filter?.filters.filter(o => !FilterGroup.isAnInstanceOf(o)) as FilterClause[] || [] diff --git a/src/client/components/sidebar.tsx b/src/client/components/sidebar.tsx index adace5a11..d7b989ea5 100644 --- a/src/client/components/sidebar.tsx +++ b/src/client/components/sidebar.tsx @@ -3,12 +3,11 @@ import { Archiver } from "../archiver" import { Board } from "../board" import { BoardTree } from "../boardTree" import { Menu, MenuOption } from "../menu" -import { Mutator } from "../mutator" +import mutator from "../mutator" import { IPageController } from "../octoTypes" import { WorkspaceTree } from "../workspaceTree" type Props = { - mutator: Mutator showBoard: (id: string) => void workspaceTree: WorkspaceTree, boardTree?: BoardTree @@ -51,7 +50,7 @@ class Sidebar extends React.Component { } private showOptions(e: React.MouseEvent, board: Board) { - const { mutator, showBoard, workspaceTree } = this.props + const { showBoard, workspaceTree } = this.props const { boards } = workspaceTree const options: MenuOption[] = [] @@ -79,8 +78,6 @@ class Sidebar extends React.Component { } private settingsClicked(e: React.MouseEvent) { - const { mutator } = this.props - Menu.shared.options = [ { id: "import", name: "Import Archive" }, { id: "export", name: "Export Archive" }, @@ -88,13 +85,13 @@ class Sidebar extends React.Component { Menu.shared.onMenuClicked = (optionId: string, type?: string) => { switch (optionId) { case "import": { - Archiver.importFullArchive(mutator, () => { + Archiver.importFullArchive(() => { this.forceUpdate() }) break } case "export": { - Archiver.exportFullArchive(mutator) + Archiver.exportFullArchive() break } } @@ -112,7 +109,7 @@ class Sidebar extends React.Component { } async addBoardClicked() { - const { mutator, boardTree, showBoard } = this.props + const { boardTree, showBoard } = this.props const oldBoardId = boardTree?.board?.id const board = new Board() diff --git a/src/client/components/tableComponent.tsx b/src/client/components/tableComponent.tsx index 93084987f..6a3d906e2 100644 --- a/src/client/components/tableComponent.tsx +++ b/src/client/components/tableComponent.tsx @@ -10,7 +10,7 @@ import MenuWrapper from "../widgets/menuWrapper" import Menu from "../widgets/menu" import { CsvExporter } from "../csvExporter" import { Menu as OldMenu } from "../menu" -import { Mutator } from "../mutator" +import mutator from "../mutator" import { OctoUtils } from "../octoUtils" import { Utils } from "../utils" import Button from "./button" @@ -18,7 +18,6 @@ import { Editable } from "./editable" import { TableRow } from "./tableRow" type Props = { - mutator: Mutator, boardTree?: BoardTree showView: (id: string) => void showCard: (card: Card) => void @@ -50,7 +49,7 @@ class TableComponent extends React.Component { } render() { - const { mutator, boardTree, showView } = this.props + const { boardTree, showView } = this.props if (!boardTree || !boardTree.board) { return ( @@ -107,7 +106,6 @@ class TableComponent extends React.Component { @@ -115,7 +113,7 @@ class TableComponent extends React.Component {
{ this.propertiesClicked(e) }}>Properties
{ this.filterClicked(e) }}>Filter
-
{ OctoUtils.showSortMenu(e, mutator, boardTree) }}>Sort
+
{ OctoUtils.showSortMenu(e, boardTree) }}>Sort
{this.state.isSearching ? { const tableRow = { } private async propertiesClicked(e: React.MouseEvent) { - const { mutator, boardTree } = this.props + const { boardTree } = this.props const { activeView } = boardTree const selectProperties = boardTree.board.cardProperties @@ -274,7 +271,7 @@ class TableComponent extends React.Component { } private async headerClicked(e: React.MouseEvent, templateId: string) { - const { mutator, boardTree } = this.props + const { boardTree } = this.props const { board } = boardTree const { activeView } = boardTree @@ -361,7 +358,7 @@ class TableComponent extends React.Component { } async addCard(show: boolean = false) { - const { mutator, boardTree } = this.props + const { boardTree } = this.props const card = new Card() card.parentId = boardTree.board.id @@ -383,7 +380,7 @@ class TableComponent extends React.Component { const { draggedHeaderTemplate } = this if (!draggedHeaderTemplate) { return } - const { mutator, boardTree } = this.props + const { boardTree } = this.props const { board } = boardTree Utils.assertValue(mutator) diff --git a/src/client/components/tableRow.tsx b/src/client/components/tableRow.tsx index 3625fef47..67d055a73 100644 --- a/src/client/components/tableRow.tsx +++ b/src/client/components/tableRow.tsx @@ -1,12 +1,11 @@ import React from "react" import { BoardTree } from "../boardTree" import { Card } from "../card" -import { Mutator } from "../mutator" +import mutator from "../mutator" import { OctoUtils } from "../octoUtils" import { Editable } from "./editable" type Props = { - mutator: Mutator boardTree: BoardTree card: Card focusOnMount: boolean @@ -27,7 +26,7 @@ class TableRow extends React.Component { } render() { - const { mutator, boardTree, card, showCard, onKeyDown } = this.props + const { boardTree, card, showCard, onKeyDown } = this.props const { board, activeView } = boardTree const openButonRef = React.createRef() @@ -57,7 +56,7 @@ class TableRow extends React.Component { .filter(template => activeView.visiblePropertyIds.includes(template.id)) .map(template => { return
- {OctoUtils.propertyValueEditableElement(mutator, card, template)} + {OctoUtils.propertyValueEditableElement(card, template)}
})} diff --git a/src/client/components/viewMenu.tsx b/src/client/components/viewMenu.tsx index 08c1af2ee..620a0f5b6 100644 --- a/src/client/components/viewMenu.tsx +++ b/src/client/components/viewMenu.tsx @@ -2,12 +2,11 @@ import React from "react" import { Board } from "../board" import { BoardTree } from "../boardTree" import { BoardView } from "../boardView" -import { Mutator } from "../mutator" +import mutator from "../mutator" import { Utils } from "../utils" import Menu from "../widgets/menu" type Props = { - mutator: Mutator, boardTree?: BoardTree board: Board, showView: (id: string) => void @@ -15,7 +14,7 @@ type Props = { export default class ViewMenu extends React.Component { handleDeleteView = async (id: string) => { - const { board, boardTree, mutator, showView } = this.props + const { board, boardTree, showView } = this.props Utils.log(`deleteView`) const view = boardTree.activeView const nextView = boardTree.views.find(o => o !== view) @@ -31,7 +30,7 @@ export default class ViewMenu extends React.Component { } handleAddViewBoard = async (id: string) => { - const { board, boardTree, mutator, showView } = this.props + const { board, boardTree, showView } = this.props Utils.log(`addview-board`) const view = new BoardView() view.title = "Board View" @@ -48,7 +47,7 @@ export default class ViewMenu extends React.Component { } handleAddViewTable = async (id: string) => { - const { board, boardTree, mutator, showView } = this.props + const { board, boardTree, showView } = this.props Utils.log(`addview-table`) const view = new BoardView() diff --git a/src/client/components/workspaceComponent.tsx b/src/client/components/workspaceComponent.tsx index e7c37a30f..dd7042939 100644 --- a/src/client/components/workspaceComponent.tsx +++ b/src/client/components/workspaceComponent.tsx @@ -1,7 +1,6 @@ import React from "react" import { BoardTree } from "../boardTree" import { Card } from "../card" -import { Mutator } from "../mutator" import { Utils } from "../utils" import { WorkspaceTree } from "../workspaceTree" import { BoardComponent } from "./boardComponent" @@ -9,7 +8,6 @@ import { Sidebar } from "./sidebar" import { TableComponent } from "./tableComponent" type Props = { - mutator: Mutator, workspaceTree: WorkspaceTree boardTree?: BoardTree showBoard: (id: string) => void @@ -21,12 +19,12 @@ type Props = { class WorkspaceComponent extends React.Component { render() { - const { mutator, boardTree, workspaceTree, showBoard } = this.props + const { boardTree, workspaceTree, showBoard } = this.props Utils.assert(workspaceTree) const element =
- + {this.mainComponent()}
@@ -34,7 +32,7 @@ class WorkspaceComponent extends React.Component { } private mainComponent() { - const { mutator, boardTree, showCard, showFilter, setSearchText, showView } = this.props + const { boardTree, showCard, showFilter, setSearchText, showView } = this.props const { activeView } = boardTree || {} if (!activeView) { @@ -43,11 +41,11 @@ class WorkspaceComponent extends React.Component { switch (activeView?.viewType) { case "board": { - return + return } case "table": { - return + return } default: { diff --git a/src/client/mutator.ts b/src/client/mutator.ts index 918134935..a52ce423c 100644 --- a/src/client/mutator.ts +++ b/src/client/mutator.ts @@ -4,9 +4,9 @@ import { BoardTree } from "./boardTree" import { BoardView, ISortOption } from "./boardView" import { Card } from "./card" import { FilterGroup } from "./filterGroup" -import { OctoClient } from "./octoClient" +import octoClient from "./octoClient" import { IBlock } from "./octoTypes" -import { UndoManager } from "./undomanager" +import undoManager from "./undomanager" import { Utils } from "./utils" // @@ -14,37 +14,33 @@ import { Utils } from "./utils" // It also ensures that the Undo-manager is called for each action // class Mutator { - constructor(private octo: OctoClient, private undoManager = UndoManager.shared) { + constructor() { } async insertBlock(block: IBlock, description: string = "add", afterRedo?: () => Promise, beforeUndo?: () => Promise) { - const { octo, undoManager } = this - await undoManager.perform( async () => { - await octo.insertBlock(block) + await octoClient.insertBlock(block) await afterRedo?.() }, async () => { await beforeUndo?.() - await octo.deleteBlock(block.id) + await octoClient.deleteBlock(block.id) }, description ) } async insertBlocks(blocks: IBlock[], description: string = "add", afterRedo?: () => Promise, beforeUndo?: () => Promise) { - const { octo, undoManager } = this - await undoManager.perform( async () => { - await octo.insertBlocks(blocks) + await octoClient.insertBlocks(blocks) await afterRedo?.() }, async () => { await beforeUndo?.() for (const block of blocks) { - await octo.deleteBlock(block.id) + await octoClient.deleteBlock(block.id) } }, description @@ -52,8 +48,6 @@ class Mutator { } async deleteBlock(block: IBlock, description?: string, beforeRedo?: () => Promise, afterUndo?: () => Promise) { - const { octo, undoManager } = this - if (!description) { description = `delete ${block.type}` } @@ -61,10 +55,10 @@ class Mutator { await undoManager.perform( async () => { await beforeRedo?.() - await octo.deleteBlock(block.id) + await octoClient.deleteBlock(block.id) }, async () => { - await octo.insertBlock(block) + await octoClient.insertBlock(block) await afterUndo?.() }, description @@ -72,51 +66,45 @@ class Mutator { } async changeTitle(block: IBlock, title: string, description: string = "change title") { - const { octo, undoManager } = this - const oldValue = block.title await undoManager.perform( async () => { block.title = title - await octo.updateBlock(block) + await octoClient.updateBlock(block) }, async () => { block.title = oldValue - await octo.updateBlock(block) + await octoClient.updateBlock(block) }, description ) } async changeIcon(block: Card | Board, icon: string, description: string = "change icon") { - const { octo, undoManager } = this - const oldValue = block.icon await undoManager.perform( async () => { block.icon = icon - await octo.updateBlock(block) + await octoClient.updateBlock(block) }, async () => { block.icon = oldValue - await octo.updateBlock(block) + await octoClient.updateBlock(block) }, description ) } async changeOrder(block: IBlock, order: number, description: string = "change order") { - const { octo, undoManager } = this - const oldValue = block.order await undoManager.perform( async () => { block.order = order - await octo.updateBlock(block) + await octoClient.updateBlock(block) }, async () => { block.order = oldValue - await octo.updateBlock(block) + await octoClient.updateBlock(block) }, description ) @@ -125,7 +113,6 @@ class Mutator { // Property Templates async insertPropertyTemplate(boardTree: BoardTree, index: number = -1, template?: IPropertyTemplate) { - const { octo, undoManager } = this const { board, activeView } = boardTree if (index < 0) { index = board.cardProperties.length } @@ -156,17 +143,16 @@ class Mutator { await undoManager.perform( async () => { - await octo.updateBlocks(changedBlocks) + await octoClient.updateBlocks(changedBlocks) }, async () => { - await octo.updateBlocks(oldBlocks) + await octoClient.updateBlocks(oldBlocks) }, description ) } async duplicatePropertyTemplate(boardTree: BoardTree, propertyId: string) { - const { octo, undoManager } = this const { board, activeView } = boardTree const oldBlocks: IBlock[] = [new Board(board)] @@ -194,10 +180,10 @@ class Mutator { await undoManager.perform( async () => { - await octo.updateBlocks(changedBlocks) + await octoClient.updateBlocks(changedBlocks) }, async () => { - await octo.updateBlocks(oldBlocks) + await octoClient.updateBlocks(oldBlocks) }, description ) @@ -206,8 +192,6 @@ class Mutator { } async changePropertyTemplateOrder(board: Board, template: IPropertyTemplate, destIndex: number) { - const { octo, undoManager } = this - const templates = board.cardProperties const oldValue = templates const newValue = templates.slice() @@ -219,18 +203,17 @@ class Mutator { await undoManager.perform( async () => { board.cardProperties = newValue - await octo.updateBlock(board) + await octoClient.updateBlock(board) }, async () => { board.cardProperties = oldValue - await octo.updateBlock(board) + await octoClient.updateBlock(board) }, "reorder properties" ) } async deleteProperty(boardTree: BoardTree, propertyId: string) { - const { octo, undoManager } = this const { board, views, cards } = boardTree const oldBlocks: IBlock[] = [new Board(board)] @@ -255,18 +238,16 @@ class Mutator { await undoManager.perform( async () => { - await octo.updateBlocks(changedBlocks) + await octoClient.updateBlocks(changedBlocks) }, async () => { - await octo.updateBlocks(oldBlocks) + await octoClient.updateBlocks(oldBlocks) }, "delete property" ) } async renameProperty(board: Board, propertyId: string, name: string) { - const { octo, undoManager } = this - const oldBlocks: IBlock[] = [new Board(board)] const changedBlocks: IBlock[] = [board] @@ -277,10 +258,10 @@ class Mutator { await undoManager.perform( async () => { - await octo.updateBlocks(changedBlocks) + await octoClient.updateBlocks(changedBlocks) }, async () => { - await octo.updateBlocks(oldBlocks) + await octoClient.updateBlocks(oldBlocks) }, "rename property" ) @@ -289,7 +270,6 @@ class Mutator { // Properties async insertPropertyOption(boardTree: BoardTree, template: IPropertyTemplate, option: IPropertyOption, description: string = "add option") { - const { octo, undoManager } = this const { board } = boardTree Utils.assert(board.cardProperties.includes(template)) @@ -301,19 +281,18 @@ class Mutator { await undoManager.perform( async () => { template.options = newValue - await octo.updateBlock(board) + await octoClient.updateBlock(board) }, async () => { // TODO: Also remove property on cards template.options = oldValue - await octo.updateBlock(board) + await octoClient.updateBlock(board) }, description ) } async deletePropertyOption(boardTree: BoardTree, template: IPropertyTemplate, option: IPropertyOption) { - const { octo, undoManager } = this const { board } = boardTree const oldValue = template.options.slice() @@ -324,19 +303,17 @@ class Mutator { await undoManager.perform( async () => { template.options = newValue - await octo.updateBlock(board) + await octoClient.updateBlock(board) }, async () => { template.options = oldValue - await octo.updateBlock(board) + await octoClient.updateBlock(board) }, "delete option" ) } async changePropertyOptionOrder(board: Board, template: IPropertyTemplate, option: IPropertyOption, destIndex: number) { - const { octo, undoManager } = this - const oldValue = template.options const newValue = template.options.slice() @@ -347,18 +324,17 @@ class Mutator { await undoManager.perform( async () => { template.options = newValue - await octo.updateBlock(board) + await octoClient.updateBlock(board) }, async () => { template.options = oldValue - await octo.updateBlock(board) + await octoClient.updateBlock(board) }, "reorder options" ) } async changePropertyOptionValue(boardTree: BoardTree, propertyTemplate: IPropertyTemplate, option: IPropertyOption, value: string) { - const { octo, undoManager } = this const { board, cards } = boardTree const oldValue = option.value @@ -379,10 +355,10 @@ class Mutator { await undoManager.perform( async () => { - await octo.updateBlocks(changedBlocks) + await octoClient.updateBlocks(changedBlocks) }, async () => { - await octo.updateBlocks(oldBlocks) + await octoClient.updateBlocks(oldBlocks) }, "rename option" ) @@ -391,52 +367,46 @@ class Mutator { } async changePropertyOptionColor(board: Board, option: IPropertyOption, color: string) { - const { octo, undoManager } = this - const oldValue = option.color undoManager.perform( async () => { option.color = color - await octo.updateBlock(board) + await octoClient.updateBlock(board) }, async () => { option.color = oldValue - await octo.updateBlock(board) + await octoClient.updateBlock(board) }, "change option color" ) } async changePropertyValue(card: Card, propertyId: string, value?: string, description: string = "change property") { - const { octo, undoManager } = this - const oldValue = card.properties[propertyId] await undoManager.perform( async () => { card.properties[propertyId] = value - await octo.updateBlock(card) + await octoClient.updateBlock(card) }, async () => { card.properties[propertyId] = oldValue - await octo.updateBlock(card) + await octoClient.updateBlock(card) }, description ) } async changePropertyType(board: Board, propertyTemplate: IPropertyTemplate, type: PropertyType) { - const { octo, undoManager } = this - const oldValue = propertyTemplate.type await undoManager.perform( async () => { propertyTemplate.type = type - await octo.updateBlock(board) + await octoClient.updateBlock(board) }, async () => { propertyTemplate.type = oldValue - await octo.updateBlock(board) + await octoClient.updateBlock(board) }, "change property type" ) @@ -445,72 +415,64 @@ class Mutator { // Views async changeViewSortOptions(view: BoardView, sortOptions: ISortOption[]) { - const { octo, undoManager } = this - const oldValue = view.sortOptions await undoManager.perform( async () => { view.sortOptions = sortOptions - await octo.updateBlock(view) + await octoClient.updateBlock(view) }, async () => { view.sortOptions = oldValue - await octo.updateBlock(view) + await octoClient.updateBlock(view) }, "sort" ) } async changeViewFilter(view: BoardView, filter?: FilterGroup) { - const { octo, undoManager } = this - const oldValue = view.filter await undoManager.perform( async () => { view.filter = filter - await octo.updateBlock(view) + await octoClient.updateBlock(view) }, async () => { view.filter = oldValue - await octo.updateBlock(view) + await octoClient.updateBlock(view) }, "filter" ) } async changeViewVisibleProperties(view: BoardView, visiblePropertyIds: string[]) { - const { octo, undoManager } = this - const oldValue = view.visiblePropertyIds await undoManager.perform( async () => { view.visiblePropertyIds = visiblePropertyIds - await octo.updateBlock(view) + await octoClient.updateBlock(view) }, async () => { view.visiblePropertyIds = oldValue - await octo.updateBlock(view) + await octoClient.updateBlock(view) }, "hide / show property" ) } async changeViewGroupById(view: BoardView, groupById: string) { - const { octo, undoManager } = this - const oldValue = view.groupById await undoManager.perform( async () => { view.groupById = groupById - await octo.updateBlock(view) + await octoClient.updateBlock(view) }, async () => { view.groupById = oldValue - await octo.updateBlock(view) + await octoClient.updateBlock(view) }, "group by" ) @@ -518,18 +480,16 @@ class Mutator { // Not a mutator, but convenient to put here since Mutator wraps OctoClient async exportFullArchive() { - return this.octo.exportFullArchive() + return octoClient.exportFullArchive() } // Not a mutator, but convenient to put here since Mutator wraps OctoClient async importFullArchive(blocks: IBlock[]) { - return this.octo.importFullArchive(blocks) + return octoClient.importFullArchive(blocks) } async createImageBlock(parentId: string, file: File, order = 1000): Promise { - const { octo, undoManager } = this - - const url = await octo.uploadFile(file) + const url = await octoClient.uploadFile(file) if (!url) { return undefined } @@ -539,16 +499,35 @@ class Mutator { await undoManager.perform( async () => { - await octo.insertBlock(block) + await octoClient.insertBlock(block) }, async () => { - await octo.deleteBlock(block.id) + await octoClient.deleteBlock(block.id) }, "group by" ) return block } + + async undo() { + await undoManager.undo() + } + + undoDescription(): string | undefined { + return undoManager.undoDescription + } + + async redo() { + await undoManager.redo() + } + + redoDescription(): string | undefined { + return undoManager.redoDescription + } } -export { Mutator } +const mutator = new Mutator() +export default mutator + +export { mutator } diff --git a/src/client/octoClient.ts b/src/client/octoClient.ts index 1c804bce9..0801446b2 100644 --- a/src/client/octoClient.ts +++ b/src/client/octoClient.ts @@ -152,4 +152,6 @@ class OctoClient { } } -export { OctoClient } +const client = new OctoClient() + +export default client diff --git a/src/client/octoUtils.tsx b/src/client/octoUtils.tsx index 5072c4665..b97f47bab 100644 --- a/src/client/octoUtils.tsx +++ b/src/client/octoUtils.tsx @@ -5,7 +5,7 @@ import { ISortOption } from "./boardView" import { Card } from "./card" import { Editable } from "./components/editable" import { Menu } from "./menu" -import { Mutator } from "./mutator" +import mutator from "./mutator" import { IBlock } from "./octoTypes" import { Utils } from "./utils" @@ -27,14 +27,14 @@ class OctoUtils { } static propertyValueReadonlyElement(card: Card, propertyTemplate: IPropertyTemplate, emptyDisplayValue: string = "Empty"): JSX.Element { - return this.propertyValueElement(undefined, card, propertyTemplate, emptyDisplayValue) + return this.propertyValueElement(true, card, propertyTemplate, emptyDisplayValue) } - static propertyValueEditableElement(mutator: Mutator, card: Card, propertyTemplate: IPropertyTemplate, emptyDisplayValue?: string): JSX.Element { - return this.propertyValueElement(mutator, card, propertyTemplate, emptyDisplayValue) + static propertyValueEditableElement(card: Card, propertyTemplate: IPropertyTemplate, emptyDisplayValue?: string): JSX.Element { + return this.propertyValueElement(false, card, propertyTemplate, emptyDisplayValue) } - private static propertyValueElement(mutator: Mutator | undefined, card: Card, propertyTemplate: IPropertyTemplate, emptyDisplayValue: string = "Empty"): JSX.Element { + private static propertyValueElement(readOnly: boolean, card: Card, propertyTemplate: IPropertyTemplate, emptyDisplayValue: string = "Empty"): JSX.Element { const propertyValue = card.properties[propertyTemplate.id] const displayValue = OctoUtils.propertyDisplayValue(card, propertyValue, propertyTemplate) const finalDisplayValue = displayValue || emptyDisplayValue @@ -69,18 +69,18 @@ class OctoUtils { key={propertyTemplate.id} className={`${className} ${propertyColorCssClassName}`} tabIndex={0} - onClick={mutator ? (e) => { showMenu(e.target as HTMLElement) } : undefined} - onKeyDown={mutator ? (e) => { + onClick={!readOnly ? (e) => { showMenu(e.target as HTMLElement) } : undefined} + onKeyDown={!readOnly ? (e) => { if (e.keyCode === 13) { showMenu(e.target as HTMLElement) } } : undefined} - onFocus={mutator ? () => { Menu.shared.hide() } : undefined} + onFocus={!readOnly ? () => { Menu.shared.hide() } : undefined} > {finalDisplayValue} } else if (propertyTemplate.type === "text" || propertyTemplate.type === "number") { - if (mutator) { + if (!readOnly) { element = 0 ? sortOptions[0] : undefined diff --git a/src/client/pages/boardPage.tsx b/src/client/pages/boardPage.tsx index cd35e991b..ff02e350e 100644 --- a/src/client/pages/boardPage.tsx +++ b/src/client/pages/boardPage.tsx @@ -8,10 +8,9 @@ import { CardDialog } from "../components/cardDialog" import { FilterComponent } from "../components/filterComponent" import { WorkspaceComponent } from "../components/workspaceComponent" import { FlashMessage } from "../flashMessage" -import { Mutator } from "../mutator" -import { OctoClient } from "../octoClient" +import mutator from "../mutator" +import octoClient from "../octoClient" import { OctoListener } from "../octoListener" -import { UndoManager } from "../undomanager" import { Utils } from "../utils" import { WorkspaceTree } from "../workspaceTree" @@ -33,7 +32,6 @@ export default class BoardPage extends React.Component { updateTitleTimeout: number updatePropertyLabelTimeout: number - private octo = new OctoClient() private boardListener = new OctoListener() private cardListener = new OctoListener() @@ -46,7 +44,7 @@ export default class BoardPage extends React.Component { this.state = { boardId, viewId, - workspaceTree: new WorkspaceTree(this.octo), + workspaceTree: new WorkspaceTree(), } Utils.log(`BoardPage. boardId: ${boardId}`) @@ -73,8 +71,8 @@ export default class BoardPage extends React.Component { 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() + const description = mutator.undoDescription() + await mutator.undo() if (description) { FlashMessage.show(`Undo ${description}`) } else { @@ -82,8 +80,8 @@ export default class BoardPage extends React.Component { } } 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() + const description = mutator.redoDescription() + await mutator.redo() if (description) { FlashMessage.show(`Redo ${description}`) } else { @@ -108,12 +106,11 @@ export default class BoardPage extends React.Component { 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 && shownCardTree) { ReactDOM.render( - { this.showCard(undefined) }}>, + { this.showCard(undefined) }}>, Utils.getElementById("overlay") ) } else { @@ -137,7 +134,6 @@ export default class BoardPage extends React.Component { ReactDOM.render( { return (
{ this.showView(id) }} @@ -187,7 +182,7 @@ export default class BoardPage extends React.Component { await workspaceTree.sync() if (boardId) { - const boardTree = new BoardTree(this.octo, boardId) + const boardTree = new BoardTree(boardId) await boardTree.sync() // Default to first view @@ -214,7 +209,7 @@ export default class BoardPage extends React.Component { this.cardListener.close() if (card) { - const cardTree = new CardTree(this.octo, card.id) + const cardTree = new CardTree(card.id) await cardTree.sync() this.setState({...this.state, shownCardTree: cardTree}) diff --git a/src/client/pages/homePage.tsx b/src/client/pages/homePage.tsx index 05fed1d02..b1177d822 100644 --- a/src/client/pages/homePage.tsx +++ b/src/client/pages/homePage.tsx @@ -2,10 +2,9 @@ import React from 'react' import { Archiver } from "../archiver" import { Board } from "../board" import Button from '../components/button' -import { Mutator } from "../mutator" -import { OctoClient } from "../octoClient" +import mutator from '../mutator' +import octoClient from "../octoClient" import { IBlock } from "../octoTypes" -import { UndoManager } from "../undomanager" import { Utils } from "../utils" type Props = {} @@ -27,29 +26,23 @@ export default class HomePage extends React.Component { } loadBoards = async () => { - const octo = new OctoClient() - const boards = await octo.getBlocks(null, "board") + const boards = await octoClient.getBlocks(null, "board") this.setState({ boards }) } importClicked = async () => { - const octo = new OctoClient() - const mutator = new Mutator(octo, UndoManager.shared) - Archiver.importFullArchive(mutator, () => { + Archiver.importFullArchive(() => { this.loadBoards() }) } exportClicked = async () => { - const octo = new OctoClient() - const mutator = new Mutator(octo, UndoManager.shared) - Archiver.exportFullArchive(mutator) + Archiver.exportFullArchive() } addClicked = async () => { - const octo = new OctoClient() const board = new Board() - await octo.insertBlock(board) + await octoClient.insertBlock(board) } render(): React.ReactNode { diff --git a/src/client/undomanager.ts b/src/client/undomanager.ts index db750b38d..070939022 100644 --- a/src/client/undomanager.ts +++ b/src/client/undomanager.ts @@ -9,8 +9,6 @@ interface UndoCommand { // General-purpose undo manager // class UndoManager { - static shared = new UndoManager() - onStateDidChange?: () => void private commands: UndoCommand[] = [] @@ -164,4 +162,5 @@ class UndoManager { } } -export { UndoManager } +const undoManager = new UndoManager() +export default undoManager diff --git a/src/client/workspaceTree.ts b/src/client/workspaceTree.ts index c86fdb6d0..cc7d221c0 100644 --- a/src/client/workspaceTree.ts +++ b/src/client/workspaceTree.ts @@ -1,16 +1,12 @@ import { Board } from "./board" -import { OctoClient } from "./octoClient" +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") + const blocks = await octoClient.getBlocks(undefined, "board") this.rebuild(blocks) }