diff --git a/webapp/src/blocks/boardView.ts b/webapp/src/blocks/boardView.ts index 789fb55b9..e42847b3e 100644 --- a/webapp/src/blocks/boardView.ts +++ b/webapp/src/blocks/boardView.ts @@ -10,7 +10,7 @@ type ISortOption = { propertyId: '__title' | string, reversed: boolean } interface BoardView extends IBlock { readonly viewType: IViewType - readonly groupById: string + readonly groupById?: string readonly sortOptions: readonly ISortOption[] readonly visiblePropertyIds: readonly string[] readonly visibleOptionIds: readonly string[] @@ -20,7 +20,7 @@ interface BoardView extends IBlock { readonly columnWidths: Readonly> } -class MutableBoardView extends MutableBlock { +class MutableBoardView extends MutableBlock implements BoardView { get viewType(): IViewType { return this.fields.viewType } diff --git a/webapp/src/pages/boardPage.tsx b/webapp/src/pages/boardPage.tsx index ba8be87b4..c0616fc30 100644 --- a/webapp/src/pages/boardPage.tsx +++ b/webapp/src/pages/boardPage.tsx @@ -11,6 +11,7 @@ import {OctoListener} from '../octoListener' import {Utils} from '../utils' import {MutableWorkspaceTree, WorkspaceTree} from '../viewModel/workspaceTree' import {IBlock} from '../blocks/block' +import { isReturnStatement } from 'typescript' type Props = { setLanguage: (lang: string) => void @@ -24,18 +25,13 @@ type State = { } export default class BoardPage extends React.Component { - view: BoardView - - updateTitleTimeout: number - updatePropertyLabelTimeout: number - private workspaceListener = new OctoListener() constructor(props: Props) { super(props) const queryString = new URLSearchParams(window.location.search) - const boardId = queryString.get('id') - const viewId = queryString.get('v') + const boardId = queryString.get('id') || '' + const viewId = queryString.get('v') || '' this.state = { boardId, @@ -180,7 +176,7 @@ export default class BoardPage extends React.Component { this.setState({ boardTree, boardId, - viewId: boardTree.activeView.id, + viewId: boardTree.activeView!.id, }) Utils.log(`sync complete: ${boardTree.board.id} (${boardTree.board.title})`) } @@ -220,7 +216,7 @@ export default class BoardPage extends React.Component { } showView(viewId: string, boardId: string = this.state.boardId): void { - if (this.state.boardId === boardId) { + if (this.state.boardTree && this.state.boardId === boardId) { const newBoardTree = this.state.boardTree.mutableCopy() newBoardTree.setActiveView(viewId) this.setState({boardTree: newBoardTree, viewId}) @@ -233,6 +229,11 @@ export default class BoardPage extends React.Component { } setSearchText(text?: string): void { + if (!this.state.boardTree) { + Utils.assertFailure('setSearchText: boardTree') + return + } + const newBoardTree = this.state.boardTree.mutableCopy() newBoardTree.setSearchText(text) this.setState({boardTree: newBoardTree}) diff --git a/webapp/src/viewModel/boardTree.ts b/webapp/src/viewModel/boardTree.ts index 4e05a4a43..1fe0493ca 100644 --- a/webapp/src/viewModel/boardTree.ts +++ b/webapp/src/viewModel/boardTree.ts @@ -146,10 +146,10 @@ class MutableBoardTree implements BoardTree { this.cards = this.sortCards(this.cards) as MutableCard[] Utils.assert(this.cards !== undefined) - if (this.activeView.groupById) { + if (this.activeView?.groupById) { this.setGroupByProperty(this.activeView.groupById) } else { - Utils.assert(this.activeView.viewType !== 'board') + Utils.assert(this.activeView?.viewType !== 'board') } Utils.assert(this.cards !== undefined) @@ -186,6 +186,10 @@ class MutableBoardTree implements BoardTree { private groupCards() { const {activeView, groupByProperty} = this + if (!activeView || !groupByProperty) { + Utils.assertFailure('groupCards') + return + } const unassignedOptionIds = groupByProperty.options. filter((o) => !activeView.visibleOptionIds.includes(o.id) && !activeView.hiddenOptionIds.includes(o.id)). @@ -221,7 +225,7 @@ class MutableBoardTree implements BoardTree { // Empty group const emptyGroupCards = this.cards.filter((o) => { const optionId = o.properties[groupByProperty.id] - return !optionId || !this.groupByProperty.options.find((option) => option.id === optionId) + return !optionId || !groupByProperty.options.find((option) => option.id === optionId) }) const group: Group = { option: {id: '', value: `No ${groupByProperty.name}`, color: ''}, @@ -264,9 +268,7 @@ class MutableBoardTree implements BoardTree { return cardA.createAt - cardB.createAt } - private manualOrder(cardA: Card, cardB: Card) { - const {activeView} = this - + private manualOrder(activeView: BoardView, cardA: Card, cardB: Card) { const indexA = activeView.cardOrder.indexOf(cardA.id) const indexB = activeView.cardOrder.indexOf(cardB.id) @@ -280,17 +282,17 @@ class MutableBoardTree implements BoardTree { } private sortCards(cards: Card[]): Card[] { - if (!this.activeView) { + const {board, activeView} = this + if (!activeView) { Utils.assertFailure() return cards } - const {board} = this - const {sortOptions} = this.activeView + const {sortOptions} = activeView let sortedCards: Card[] = [] if (sortOptions.length < 1) { Utils.log('Manual sort') - sortedCards = cards.sort((a, b) => this.manualOrder(a, b)) + sortedCards = cards.sort((a, b) => this.manualOrder(activeView, a, b)) } else { sortOptions.forEach((sortOption) => { if (sortOption.propertyId === Constants.titleColumnId) { diff --git a/webapp/src/viewModel/cardTree.ts b/webapp/src/viewModel/cardTree.ts index 5ddafd20c..43eaf77dc 100644 --- a/webapp/src/viewModel/cardTree.ts +++ b/webapp/src/viewModel/cardTree.ts @@ -5,7 +5,6 @@ import {IOrderedBlock} from '../blocks/orderedBlock' import octoClient from '../octoClient' import {IBlock, MutableBlock} from '../blocks/block' import {OctoUtils} from '../octoUtils' -import {Utils} from '../utils' interface CardTree { readonly card: Card @@ -17,7 +16,7 @@ interface CardTree { } class MutableCardTree implements CardTree { - card: MutableCard + card!: MutableCard comments: IBlock[] = [] contents: IOrderedBlock[] = []