mirror of
https://github.com/mattermost/focalboard.git
synced 2025-06-03 22:27:30 +02:00
npm run fix and replaced tabs with spaces
This commit is contained in:
parent
262f3c043d
commit
a8a274ff0f
@ -1,6 +1,7 @@
|
|||||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||||
// See LICENSE.txt for license information.
|
// See LICENSE.txt for license information.
|
||||||
import {IBlock} from '../blocks/block'
|
import {IBlock} from '../blocks/block'
|
||||||
|
|
||||||
import {MutableBlock} from './block'
|
import {MutableBlock} from './block'
|
||||||
|
|
||||||
type PropertyType = 'text' | 'number' | 'select' | 'multiSelect' | 'date' | 'person' | 'file' | 'checkbox' | 'url' | 'email' | 'phone' | 'createdTime' | 'createdBy' | 'updatedTime' | 'updatedBy'
|
type PropertyType = 'text' | 'number' | 'select' | 'multiSelect' | 'date' | 'person' | 'file' | 'checkbox' | 'url' | 'email' | 'phone' | 'createdTime' | 'createdBy' | 'updatedTime' | 'updatedBy'
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||||
// See LICENSE.txt for license information.
|
// See LICENSE.txt for license information.
|
||||||
import {IBlock} from '../blocks/block'
|
import {IBlock} from '../blocks/block'
|
||||||
|
|
||||||
import {MutableBlock} from './block'
|
import {MutableBlock} from './block'
|
||||||
|
|
||||||
interface CommentBlock extends IBlock {
|
type CommentBlock = IBlock
|
||||||
}
|
|
||||||
|
|
||||||
class MutableCommentBlock extends MutableBlock {
|
class MutableCommentBlock extends MutableBlock {
|
||||||
constructor(block: any = {}) {
|
constructor(block: any = {}) {
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
import { IBlock } from "../blocks/block"
|
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||||
import { MutableBlock } from "./block"
|
// See LICENSE.txt for license information.
|
||||||
|
import {IBlock} from '../blocks/block'
|
||||||
|
|
||||||
|
import {MutableBlock} from './block'
|
||||||
|
|
||||||
interface IOrderedBlock extends IBlock {
|
interface IOrderedBlock extends IBlock {
|
||||||
readonly order: number
|
readonly order: number
|
||||||
|
@ -2,9 +2,7 @@
|
|||||||
// See LICENSE.txt for license information.
|
// See LICENSE.txt for license information.
|
||||||
import {IOrderedBlock, MutableOrderedBlock} from './orderedBlock'
|
import {IOrderedBlock, MutableOrderedBlock} from './orderedBlock'
|
||||||
|
|
||||||
interface TextBlock extends IOrderedBlock {
|
type TextBlock = IOrderedBlock
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
class MutableTextBlock extends MutableOrderedBlock {
|
class MutableTextBlock extends MutableOrderedBlock {
|
||||||
constructor(block: any = {}) {
|
constructor(block: any = {}) {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||||
// See LICENSE.txt for license information.
|
// See LICENSE.txt for license information.
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
|
|
||||||
import {MutableBlock} from '../blocks/block'
|
import {MutableBlock} from '../blocks/block'
|
||||||
|
|
||||||
import {IPropertyTemplate} from '../blocks/board'
|
import {IPropertyTemplate} from '../blocks/board'
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||||
// See LICENSE.txt for license information.
|
// See LICENSE.txt for license information.
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
|
|
||||||
import {BlockIcons} from '../blockIcons'
|
import {BlockIcons} from '../blockIcons'
|
||||||
import {MutableCommentBlock} from '../blocks/commentBlock'
|
import {MutableCommentBlock} from '../blocks/commentBlock'
|
||||||
import {IOrderedBlock} from '../blocks/orderedBlock'
|
import {IOrderedBlock} from '../blocks/orderedBlock'
|
||||||
@ -14,12 +15,11 @@ import { IBlock } from '../blocks/block'
|
|||||||
import {OctoUtils} from '../octoUtils'
|
import {OctoUtils} from '../octoUtils'
|
||||||
import {PropertyMenu} from '../propertyMenu'
|
import {PropertyMenu} from '../propertyMenu'
|
||||||
import {Utils} from '../utils'
|
import {Utils} from '../utils'
|
||||||
|
|
||||||
import Button from './button'
|
import Button from './button'
|
||||||
import {Editable} from './editable'
|
import {Editable} from './editable'
|
||||||
import {MarkdownEditor} from './markdownEditor'
|
import {MarkdownEditor} from './markdownEditor'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
boardTree: BoardTree
|
boardTree: BoardTree
|
||||||
cardId: string
|
cardId: string
|
||||||
@ -98,7 +98,9 @@ export default class CardDetail extends React.Component<Props, State> {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<MarkdownEditor
|
<MarkdownEditor
|
||||||
text={cardText} placeholderText='Edit text...' onChanged={(text) => {
|
text={cardText}
|
||||||
|
placeholderText='Edit text...'
|
||||||
|
onChanged={(text) => {
|
||||||
Utils.log(`change text ${block.id}, ${text}`)
|
Utils.log(`change text ${block.id}, ${text}`)
|
||||||
mutator.changeTitle(block, text, 'edit card text')
|
mutator.changeTitle(block, text, 'edit card text')
|
||||||
}}
|
}}
|
||||||
@ -123,7 +125,7 @@ export default class CardDetail extends React.Component<Props, State> {
|
|||||||
<img
|
<img
|
||||||
src={url}
|
src={url}
|
||||||
alt={block.title}
|
alt={block.title}
|
||||||
></img>
|
/>
|
||||||
</div>)
|
</div>)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ class Editable extends React.Component<Props, State> {
|
|||||||
this._text = props.text || ''
|
this._text = props.text || ''
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidUpdate(prevPros: Props, prevState: State) {
|
componentDidUpdate() {
|
||||||
this._text = this.props.text || ''
|
this._text = this.props.text || ''
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||||
// See LICENSE.txt for license information.
|
// See LICENSE.txt for license information.
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
|
|
||||||
import {Archiver} from '../archiver'
|
import {Archiver} from '../archiver'
|
||||||
import {Board, MutableBoard} from '../blocks/board'
|
import {Board, MutableBoard} from '../blocks/board'
|
||||||
import {BoardTree} from '../viewModel/boardTree'
|
import {BoardTree} from '../viewModel/boardTree'
|
||||||
@ -10,7 +11,6 @@ import MenuWrapper from '../widgets/menuWrapper'
|
|||||||
import {WorkspaceTree} from '../viewModel/workspaceTree'
|
import {WorkspaceTree} from '../viewModel/workspaceTree'
|
||||||
import {BoardView} from '../blocks/boardView'
|
import {BoardView} from '../blocks/boardView'
|
||||||
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
showBoard: (id: string) => void
|
showBoard: (id: string) => void
|
||||||
showView: (id: string, boardId?: string) => void
|
showView: (id: string, boardId?: string) => void
|
||||||
@ -32,11 +32,16 @@ class Sidebar extends React.Component<Props> {
|
|||||||
{
|
{
|
||||||
boards.map((board) => {
|
boards.map((board) => {
|
||||||
const displayTitle = board.title || '(Untitled Board)'
|
const displayTitle = board.title || '(Untitled Board)'
|
||||||
const boardViews = views.filter(view => view.parentId === board.id)
|
const boardViews = views.filter((view) => view.parentId === board.id)
|
||||||
return (
|
return (
|
||||||
<div key={board.id}>
|
<div key={board.id}>
|
||||||
<div className='octo-sidebar-item octo-hover-container'>
|
<div className='octo-sidebar-item octo-hover-container'>
|
||||||
<div className='octo-sidebar-title' onClick={() => { this.boardClicked(board) }}>
|
<div
|
||||||
|
className='octo-sidebar-title'
|
||||||
|
onClick={() => {
|
||||||
|
this.boardClicked(board)
|
||||||
|
}}
|
||||||
|
>
|
||||||
{board.icon ? `${board.icon} ${displayTitle}` : displayTitle}
|
{board.icon ? `${board.icon} ${displayTitle}` : displayTitle}
|
||||||
</div>
|
</div>
|
||||||
<div className='octo-spacer'/>
|
<div className='octo-spacer'/>
|
||||||
@ -63,12 +68,20 @@ class Sidebar extends React.Component<Props> {
|
|||||||
</Menu>
|
</Menu>
|
||||||
</MenuWrapper>
|
</MenuWrapper>
|
||||||
</div>
|
</div>
|
||||||
{boardViews.map(view => {
|
{boardViews.map((view) => {
|
||||||
return <div key={view.id} className='octo-sidebar-item subitem octo-hover-container'>
|
return (<div
|
||||||
<div className='octo-sidebar-title' onClick={() => { this.viewClicked(board, view) }}>
|
key={view.id}
|
||||||
|
className='octo-sidebar-item subitem octo-hover-container'
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className='octo-sidebar-title'
|
||||||
|
onClick={() => {
|
||||||
|
this.viewClicked(board, view)
|
||||||
|
}}
|
||||||
|
>
|
||||||
{view.title || '(Untitled View)'}
|
{view.title || '(Untitled View)'}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>)
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
@ -97,7 +97,7 @@ class Mutator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async changeIcon(block: Card | Board, icon: string, description = 'change icon') {
|
async changeIcon(block: Card | Board, icon: string, description = 'change icon') {
|
||||||
var newBlock: IBlock
|
let newBlock: IBlock
|
||||||
switch (block.type) {
|
switch (block.type) {
|
||||||
case 'card': {
|
case 'card': {
|
||||||
const card = new MutableCard(block)
|
const card = new MutableCard(block)
|
||||||
@ -265,7 +265,7 @@ class Mutator {
|
|||||||
Utils.assert(board.cardProperties.includes(template))
|
Utils.assert(board.cardProperties.includes(template))
|
||||||
|
|
||||||
const newBoard = new MutableBoard(board)
|
const newBoard = new MutableBoard(board)
|
||||||
const newTemplate = newBoard.cardProperties.find(o => o.id === template.id)
|
const newTemplate = newBoard.cardProperties.find((o) => o.id === template.id)
|
||||||
newTemplate.options.push(option)
|
newTemplate.options.push(option)
|
||||||
|
|
||||||
await this.updateBlock(newBoard, board, description)
|
await this.updateBlock(newBoard, board, description)
|
||||||
@ -275,8 +275,8 @@ class Mutator {
|
|||||||
const {board} = boardTree
|
const {board} = boardTree
|
||||||
|
|
||||||
const newBoard = new MutableBoard(board)
|
const newBoard = new MutableBoard(board)
|
||||||
const newTemplate = newBoard.cardProperties.find(o => o.id === template.id)
|
const newTemplate = newBoard.cardProperties.find((o) => o.id === template.id)
|
||||||
newTemplate.options = newTemplate.options.filter(o => o.value !== option.value)
|
newTemplate.options = newTemplate.options.filter((o) => o.value !== option.value)
|
||||||
|
|
||||||
await this.updateBlock(newBoard, board, 'delete option')
|
await this.updateBlock(newBoard, board, 'delete option')
|
||||||
}
|
}
|
||||||
@ -286,7 +286,7 @@ class Mutator {
|
|||||||
Utils.log(`srcIndex: ${srcIndex}, destIndex: ${destIndex}`)
|
Utils.log(`srcIndex: ${srcIndex}, destIndex: ${destIndex}`)
|
||||||
|
|
||||||
const newBoard = new MutableBoard(board)
|
const newBoard = new MutableBoard(board)
|
||||||
const newTemplate = newBoard.cardProperties.find(o => o.id === template.id)
|
const newTemplate = newBoard.cardProperties.find((o) => o.id === template.id)
|
||||||
newTemplate.options.splice(destIndex, 0, newTemplate.options.splice(srcIndex, 1)[0])
|
newTemplate.options.splice(destIndex, 0, newTemplate.options.splice(srcIndex, 1)[0])
|
||||||
|
|
||||||
await this.updateBlock(newBoard, board, 'reorder options')
|
await this.updateBlock(newBoard, board, 'reorder options')
|
||||||
@ -299,8 +299,8 @@ class Mutator {
|
|||||||
const oldBlocks: IBlock[] = [board]
|
const oldBlocks: IBlock[] = [board]
|
||||||
|
|
||||||
const newBoard = new MutableBoard(board)
|
const newBoard = new MutableBoard(board)
|
||||||
const newTemplate = newBoard.cardProperties.find(o => o.id === propertyTemplate.id)
|
const newTemplate = newBoard.cardProperties.find((o) => o.id === propertyTemplate.id)
|
||||||
const newOption = newTemplate.options.find(o => o.value === oldValue)
|
const newOption = newTemplate.options.find((o) => o.value === oldValue)
|
||||||
newOption.value = value
|
newOption.value = value
|
||||||
const changedBlocks: IBlock[] = [newBoard]
|
const changedBlocks: IBlock[] = [newBoard]
|
||||||
|
|
||||||
@ -323,8 +323,8 @@ class Mutator {
|
|||||||
|
|
||||||
async changePropertyOptionColor(board: Board, template: IPropertyTemplate, option: IPropertyOption, color: string) {
|
async changePropertyOptionColor(board: Board, template: IPropertyTemplate, option: IPropertyOption, color: string) {
|
||||||
const newBoard = new MutableBoard(board)
|
const newBoard = new MutableBoard(board)
|
||||||
const newTemplate = newBoard.cardProperties.find(o => o.id === template.id)
|
const newTemplate = newBoard.cardProperties.find((o) => o.id === template.id)
|
||||||
const newOption = newTemplate.options.find(o => o.value === option.value)
|
const newOption = newTemplate.options.find((o) => o.value === option.value)
|
||||||
newOption.color = color
|
newOption.color = color
|
||||||
await this.updateBlock(newBoard, board, 'change option color')
|
await this.updateBlock(newBoard, board, 'change option color')
|
||||||
}
|
}
|
||||||
@ -337,7 +337,7 @@ class Mutator {
|
|||||||
|
|
||||||
async changePropertyType(board: Board, propertyTemplate: IPropertyTemplate, type: PropertyType) {
|
async changePropertyType(board: Board, propertyTemplate: IPropertyTemplate, type: PropertyType) {
|
||||||
const newBoard = new MutableBoard(board)
|
const newBoard = new MutableBoard(board)
|
||||||
const newTemplate = newBoard.cardProperties.find(o => o.id === propertyTemplate.id)
|
const newTemplate = newBoard.cardProperties.find((o) => o.id === propertyTemplate.id)
|
||||||
newTemplate.type = type
|
newTemplate.type = type
|
||||||
await this.updateBlock(newBoard, board, 'change property type')
|
await this.updateBlock(newBoard, board, 'change property type')
|
||||||
}
|
}
|
||||||
@ -356,7 +356,7 @@ class Mutator {
|
|||||||
await this.updateBlock(newView, view, 'filter')
|
await this.updateBlock(newView, view, 'filter')
|
||||||
}
|
}
|
||||||
|
|
||||||
async changeViewVisibleProperties(view: BoardView, visiblePropertyIds: string[], description: string = 'show / hide property') {
|
async changeViewVisibleProperties(view: BoardView, visiblePropertyIds: string[], description = 'show / hide property') {
|
||||||
const newView = new MutableBoardView(view)
|
const newView = new MutableBoardView(view)
|
||||||
newView.visiblePropertyIds = visiblePropertyIds
|
newView.visiblePropertyIds = visiblePropertyIds
|
||||||
await this.updateBlock(newView, view, description)
|
await this.updateBlock(newView, view, description)
|
||||||
|
@ -49,7 +49,7 @@ class OctoListener {
|
|||||||
this.ws = ws
|
this.ws = ws
|
||||||
|
|
||||||
ws.onopen = () => {
|
ws.onopen = () => {
|
||||||
Utils.log(`OctoListener webSocket opened.`)
|
Utils.log('OctoListener webSocket opened.')
|
||||||
this.addBlocks(blockIds)
|
this.addBlocks(blockIds)
|
||||||
this.isInitialized = true
|
this.isInitialized = true
|
||||||
}
|
}
|
||||||
@ -73,7 +73,7 @@ class OctoListener {
|
|||||||
ws.onmessage = (e) => {
|
ws.onmessage = (e) => {
|
||||||
Utils.log(`OctoListener websocket onmessage. data: ${e.data}`)
|
Utils.log(`OctoListener websocket onmessage. data: ${e.data}`)
|
||||||
if (ws !== this.ws) {
|
if (ws !== this.ws) {
|
||||||
Utils.log(`Ignoring closed ws`)
|
Utils.log('Ignoring closed ws')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,13 +115,13 @@ class OctoListener {
|
|||||||
|
|
||||||
addBlocks(blockIds: string[]): void {
|
addBlocks(blockIds: string[]): void {
|
||||||
if (!this.isOpen) {
|
if (!this.isOpen) {
|
||||||
Utils.assertFailure(`OctoListener.addBlocks: ws is not open`)
|
Utils.assertFailure('OctoListener.addBlocks: ws is not open')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const command: WSCommand = {
|
const command: WSCommand = {
|
||||||
action: 'ADD',
|
action: 'ADD',
|
||||||
blockIds
|
blockIds,
|
||||||
}
|
}
|
||||||
|
|
||||||
this.ws.send(JSON.stringify(command))
|
this.ws.send(JSON.stringify(command))
|
||||||
@ -130,13 +130,13 @@ class OctoListener {
|
|||||||
|
|
||||||
removeBlocks(blockIds: string[]): void {
|
removeBlocks(blockIds: string[]): void {
|
||||||
if (!this.isOpen) {
|
if (!this.isOpen) {
|
||||||
Utils.assertFailure(`OctoListener.removeBlocks: ws is not open`)
|
Utils.assertFailure('OctoListener.removeBlocks: ws is not open')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const command: WSCommand = {
|
const command: WSCommand = {
|
||||||
action: 'REMOVE',
|
action: 'REMOVE',
|
||||||
blockIds
|
blockIds,
|
||||||
}
|
}
|
||||||
|
|
||||||
this.ws.send(JSON.stringify(command))
|
this.ws.send(JSON.stringify(command))
|
||||||
|
@ -168,7 +168,7 @@ export default class BoardPage extends React.Component<Props, State> {
|
|||||||
Utils.log(`sync start: ${boardId}`)
|
Utils.log(`sync start: ${boardId}`)
|
||||||
|
|
||||||
await workspaceTree.sync()
|
await workspaceTree.sync()
|
||||||
const boardIds = workspaceTree.boards.map(o => o.id)
|
const boardIds = workspaceTree.boards.map((o) => o.id)
|
||||||
this.workspaceListener.open(boardIds, async (blockId) => {
|
this.workspaceListener.open(boardIds, async (blockId) => {
|
||||||
Utils.log(`workspaceListener.onChanged: ${blockId}`)
|
Utils.log(`workspaceListener.onChanged: ${blockId}`)
|
||||||
this.sync()
|
this.sync()
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||||
// See LICENSE.txt for license information.
|
// See LICENSE.txt for license information.
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
|
|
||||||
import {Archiver} from '../archiver'
|
import {Archiver} from '../archiver'
|
||||||
import {MutableBoard} from '../blocks/board'
|
import {MutableBoard} from '../blocks/board'
|
||||||
import Button from '../components/button'
|
import Button from '../components/button'
|
||||||
@ -8,7 +9,6 @@ import octoClient from '../octoClient'
|
|||||||
import {IBlock} from '../blocks/block'
|
import {IBlock} from '../blocks/block'
|
||||||
import {Utils} from '../utils'
|
import {Utils} from '../utils'
|
||||||
|
|
||||||
|
|
||||||
type Props = {}
|
type Props = {}
|
||||||
|
|
||||||
type State = {
|
type State = {
|
||||||
|
@ -50,9 +50,9 @@ class MutableBoardTree implements BoardTree {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private rebuild(blocks: IBlock[]) {
|
private rebuild(blocks: IBlock[]) {
|
||||||
this.board = blocks.find(block => block.type === "board") as Board
|
this.board = blocks.find((block) => block.type === 'board') as Board
|
||||||
this.views = blocks.filter(block => block.type === "view") as MutableBoardView[]
|
this.views = blocks.filter((block) => block.type === 'view') as MutableBoardView[]
|
||||||
this.allCards = blocks.filter(block => block.type === "card") as Card[]
|
this.allCards = blocks.filter((block) => block.type === 'card') as Card[]
|
||||||
this.cards = []
|
this.cards = []
|
||||||
|
|
||||||
this.ensureMinimumSchema()
|
this.ensureMinimumSchema()
|
||||||
@ -64,14 +64,14 @@ class MutableBoardTree implements BoardTree {
|
|||||||
let didChange = false
|
let didChange = false
|
||||||
|
|
||||||
// At least one select property
|
// At least one select property
|
||||||
const selectProperties = board.cardProperties.find(o => o.type === "select")
|
const selectProperties = board.cardProperties.find((o) => o.type === 'select')
|
||||||
if (!selectProperties) {
|
if (!selectProperties) {
|
||||||
const newBoard = new MutableBoard(board)
|
const newBoard = new MutableBoard(board)
|
||||||
const property: IPropertyTemplate = {
|
const property: IPropertyTemplate = {
|
||||||
id: Utils.createGuid(),
|
id: Utils.createGuid(),
|
||||||
name: "Status",
|
name: 'Status',
|
||||||
type: "select",
|
type: 'select',
|
||||||
options: []
|
options: [],
|
||||||
}
|
}
|
||||||
newBoard.cardProperties.push(property)
|
newBoard.cardProperties.push(property)
|
||||||
this.board = newBoard
|
this.board = newBoard
|
||||||
@ -82,7 +82,7 @@ class MutableBoardTree implements BoardTree {
|
|||||||
if (this.views.length < 1) {
|
if (this.views.length < 1) {
|
||||||
const view = new MutableBoardView()
|
const view = new MutableBoardView()
|
||||||
view.parentId = board.id
|
view.parentId = board.id
|
||||||
view.groupById = board.cardProperties.find(o => o.type === "select")?.id
|
view.groupById = board.cardProperties.find((o) => o.type === 'select')?.id
|
||||||
this.views.push(view)
|
this.views.push(view)
|
||||||
didChange = true
|
didChange = true
|
||||||
}
|
}
|
||||||
@ -91,15 +91,15 @@ class MutableBoardTree implements BoardTree {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setActiveView(viewId: string) {
|
setActiveView(viewId: string) {
|
||||||
this.activeView = this.views.find(o => o.id === viewId)
|
this.activeView = this.views.find((o) => o.id === viewId)
|
||||||
if (!this.activeView) {
|
if (!this.activeView) {
|
||||||
Utils.logError(`Cannot find BoardView: ${viewId}`)
|
Utils.logError(`Cannot find BoardView: ${viewId}`)
|
||||||
this.activeView = this.views[0]
|
this.activeView = this.views[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fix missing group by (e.g. for new views)
|
// Fix missing group by (e.g. for new views)
|
||||||
if (this.activeView.viewType === "board" && !this.activeView.groupById) {
|
if (this.activeView.viewType === 'board' && !this.activeView.groupById) {
|
||||||
this.activeView.groupById = this.board.cardProperties.find(o => o.type === "select")?.id
|
this.activeView.groupById = this.board.cardProperties.find((o) => o.type === 'select')?.id
|
||||||
}
|
}
|
||||||
this.applyFilterSortAndGroup()
|
this.applyFilterSortAndGroup()
|
||||||
}
|
}
|
||||||
@ -126,7 +126,7 @@ class MutableBoardTree implements BoardTree {
|
|||||||
if (this.activeView.groupById) {
|
if (this.activeView.groupById) {
|
||||||
this.setGroupByProperty(this.activeView.groupById)
|
this.setGroupByProperty(this.activeView.groupById)
|
||||||
} else {
|
} else {
|
||||||
Utils.assert(this.activeView.viewType !== "board")
|
Utils.assert(this.activeView.viewType !== 'board')
|
||||||
}
|
}
|
||||||
|
|
||||||
Utils.assert(this.cards !== undefined)
|
Utils.assert(this.cards !== undefined)
|
||||||
@ -134,21 +134,26 @@ class MutableBoardTree implements BoardTree {
|
|||||||
|
|
||||||
private searchFilterCards(cards: Card[]): Card[] {
|
private searchFilterCards(cards: Card[]): Card[] {
|
||||||
const searchText = this.searchText?.toLocaleLowerCase()
|
const searchText = this.searchText?.toLocaleLowerCase()
|
||||||
if (!searchText) { return cards.slice() }
|
if (!searchText) {
|
||||||
|
return cards.slice()
|
||||||
|
}
|
||||||
|
|
||||||
return cards.filter(card => {
|
return cards.filter((card) => {
|
||||||
if (card.title?.toLocaleLowerCase().indexOf(searchText) !== -1) { return true }
|
if (card.title?.toLocaleLowerCase().indexOf(searchText) !== -1) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
private setGroupByProperty(propertyId: string) {
|
private setGroupByProperty(propertyId: string) {
|
||||||
const {board} = this
|
const {board} = this
|
||||||
|
|
||||||
let property = board.cardProperties.find(o => o.id === propertyId)
|
let property = board.cardProperties.find((o) => o.id === propertyId)
|
||||||
|
|
||||||
// TODO: Handle multi-select
|
// TODO: Handle multi-select
|
||||||
if (!property || property.type !== "select") {
|
if (!property || property.type !== 'select') {
|
||||||
Utils.logError(`this.view.groupById card property not found: ${propertyId}`)
|
Utils.logError(`this.view.groupById card property not found: ${propertyId}`)
|
||||||
property = board.cardProperties.find(o => o.type === "select")
|
property = board.cardProperties.find((o) => o.type === 'select')
|
||||||
Utils.assertValue(property)
|
Utils.assertValue(property)
|
||||||
}
|
}
|
||||||
this.groupByProperty = property
|
this.groupByProperty = property
|
||||||
@ -161,22 +166,22 @@ class MutableBoardTree implements BoardTree {
|
|||||||
|
|
||||||
const groupByPropertyId = this.groupByProperty.id
|
const groupByPropertyId = this.groupByProperty.id
|
||||||
|
|
||||||
this.emptyGroupCards = this.cards.filter(o => {
|
this.emptyGroupCards = this.cards.filter((o) => {
|
||||||
const propertyValue = o.properties[groupByPropertyId]
|
const propertyValue = o.properties[groupByPropertyId]
|
||||||
return !propertyValue || !this.groupByProperty.options.find(option => option.value === propertyValue)
|
return !propertyValue || !this.groupByProperty.options.find((option) => option.value === propertyValue)
|
||||||
})
|
})
|
||||||
|
|
||||||
const propertyOptions = this.groupByProperty.options || []
|
const propertyOptions = this.groupByProperty.options || []
|
||||||
for (const option of propertyOptions) {
|
for (const option of propertyOptions) {
|
||||||
const cards = this.cards
|
const cards = this.cards.
|
||||||
.filter(o => {
|
filter((o) => {
|
||||||
const propertyValue = o.properties[groupByPropertyId]
|
const propertyValue = o.properties[groupByPropertyId]
|
||||||
return propertyValue && propertyValue === option.value
|
return propertyValue && propertyValue === option.value
|
||||||
})
|
})
|
||||||
|
|
||||||
const group: Group = {
|
const group: Group = {
|
||||||
option,
|
option,
|
||||||
cards
|
cards,
|
||||||
}
|
}
|
||||||
|
|
||||||
this.groups.push(group)
|
this.groups.push(group)
|
||||||
@ -186,50 +191,68 @@ class MutableBoardTree implements BoardTree {
|
|||||||
private filterCards(cards: Card[]): Card[] {
|
private filterCards(cards: Card[]): Card[] {
|
||||||
const {board} = this
|
const {board} = this
|
||||||
const filterGroup = this.activeView?.filter
|
const filterGroup = this.activeView?.filter
|
||||||
if (!filterGroup) { return cards.slice() }
|
if (!filterGroup) {
|
||||||
|
return cards.slice()
|
||||||
|
}
|
||||||
|
|
||||||
return CardFilter.applyFilterGroup(filterGroup, board.cardProperties, cards)
|
return CardFilter.applyFilterGroup(filterGroup, board.cardProperties, cards)
|
||||||
}
|
}
|
||||||
|
|
||||||
private sortCards(cards: Card[]): Card[] {
|
private sortCards(cards: Card[]): Card[] {
|
||||||
if (!this.activeView) { Utils.assertFailure(); return cards }
|
if (!this.activeView) {
|
||||||
|
Utils.assertFailure(); return cards
|
||||||
|
}
|
||||||
const {board} = this
|
const {board} = this
|
||||||
const {sortOptions} = this.activeView
|
const {sortOptions} = this.activeView
|
||||||
let sortedCards: Card[] = []
|
let sortedCards: Card[] = []
|
||||||
|
|
||||||
if (sortOptions.length < 1) {
|
if (sortOptions.length < 1) {
|
||||||
Utils.log(`Default sort`)
|
Utils.log('Default sort')
|
||||||
sortedCards = cards.sort((a, b) => {
|
sortedCards = cards.sort((a, b) => {
|
||||||
const aValue = a.title || ""
|
const aValue = a.title || ''
|
||||||
const bValue = b.title || ""
|
const bValue = b.title || ''
|
||||||
|
|
||||||
// Always put empty values at the bottom
|
// Always put empty values at the bottom
|
||||||
if (aValue && !bValue) { return -1 }
|
if (aValue && !bValue) {
|
||||||
if (bValue && !aValue) { return 1 }
|
return -1
|
||||||
if (!aValue && !bValue) { return a.createAt - b.createAt }
|
}
|
||||||
|
if (bValue && !aValue) {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
if (!aValue && !bValue) {
|
||||||
|
return a.createAt - b.createAt
|
||||||
|
}
|
||||||
|
|
||||||
return a.createAt - b.createAt
|
return a.createAt - b.createAt
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
sortOptions.forEach(sortOption => {
|
sortOptions.forEach((sortOption) => {
|
||||||
if (sortOption.propertyId === "__name") {
|
if (sortOption.propertyId === '__name') {
|
||||||
Utils.log(`Sort by name`)
|
Utils.log('Sort by name')
|
||||||
sortedCards = cards.sort((a, b) => {
|
sortedCards = cards.sort((a, b) => {
|
||||||
const aValue = a.title || ""
|
const aValue = a.title || ''
|
||||||
const bValue = b.title || ""
|
const bValue = b.title || ''
|
||||||
|
|
||||||
// Always put empty values at the bottom, newest last
|
// Always put empty values at the bottom, newest last
|
||||||
if (aValue && !bValue) { return -1 }
|
if (aValue && !bValue) {
|
||||||
if (bValue && !aValue) { return 1 }
|
return -1
|
||||||
if (!aValue && !bValue) { return a.createAt - b.createAt }
|
}
|
||||||
|
if (bValue && !aValue) {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
if (!aValue && !bValue) {
|
||||||
|
return a.createAt - b.createAt
|
||||||
|
}
|
||||||
|
|
||||||
let result = aValue.localeCompare(bValue)
|
let result = aValue.localeCompare(bValue)
|
||||||
if (sortOption.reversed) { result = -result }
|
if (sortOption.reversed) {
|
||||||
|
result = -result
|
||||||
|
}
|
||||||
return result
|
return result
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
const sortPropertyId = sortOption.propertyId
|
const sortPropertyId = sortOption.propertyId
|
||||||
const template = board.cardProperties.find(o => o.id === sortPropertyId)
|
const template = board.cardProperties.find((o) => o.id === sortPropertyId)
|
||||||
if (!template) {
|
if (!template) {
|
||||||
Utils.logError(`Missing template for property id: ${sortPropertyId}`)
|
Utils.logError(`Missing template for property id: ${sortPropertyId}`)
|
||||||
return cards.slice()
|
return cards.slice()
|
||||||
@ -237,47 +260,73 @@ class MutableBoardTree implements BoardTree {
|
|||||||
Utils.log(`Sort by ${template?.name}`)
|
Utils.log(`Sort by ${template?.name}`)
|
||||||
sortedCards = cards.sort((a, b) => {
|
sortedCards = cards.sort((a, b) => {
|
||||||
// Always put cards with no titles at the bottom
|
// Always put cards with no titles at the bottom
|
||||||
if (a.title && !b.title) { return -1 }
|
if (a.title && !b.title) {
|
||||||
if (b.title && !a.title) { return 1 }
|
return -1
|
||||||
if (!a.title && !b.title) { return a.createAt - b.createAt }
|
}
|
||||||
|
if (b.title && !a.title) {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
if (!a.title && !b.title) {
|
||||||
|
return a.createAt - b.createAt
|
||||||
|
}
|
||||||
|
|
||||||
const aValue = a.properties[sortPropertyId] || ""
|
const aValue = a.properties[sortPropertyId] || ''
|
||||||
const bValue = b.properties[sortPropertyId] || ""
|
const bValue = b.properties[sortPropertyId] || ''
|
||||||
let result = 0
|
let result = 0
|
||||||
if (template.type === "select") {
|
if (template.type === 'select') {
|
||||||
// Always put empty values at the bottom
|
// Always put empty values at the bottom
|
||||||
if (aValue && !bValue) { return -1 }
|
if (aValue && !bValue) {
|
||||||
if (bValue && !aValue) { return 1 }
|
return -1
|
||||||
if (!aValue && !bValue) { return a.createAt - b.createAt }
|
}
|
||||||
|
if (bValue && !aValue) {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
if (!aValue && !bValue) {
|
||||||
|
return a.createAt - b.createAt
|
||||||
|
}
|
||||||
|
|
||||||
// Sort by the option order (not alphabetically by value)
|
// Sort by the option order (not alphabetically by value)
|
||||||
const aOrder = template.options.findIndex(o => o.value === aValue)
|
const aOrder = template.options.findIndex((o) => o.value === aValue)
|
||||||
const bOrder = template.options.findIndex(o => o.value === bValue)
|
const bOrder = template.options.findIndex((o) => o.value === bValue)
|
||||||
|
|
||||||
result = aOrder - bOrder
|
result = aOrder - bOrder
|
||||||
} else if (template.type === "number" || template.type === "date") {
|
} else if (template.type === 'number' || template.type === 'date') {
|
||||||
// Always put empty values at the bottom
|
// Always put empty values at the bottom
|
||||||
if (aValue && !bValue) { return -1 }
|
if (aValue && !bValue) {
|
||||||
if (bValue && !aValue) { return 1 }
|
return -1
|
||||||
if (!aValue && !bValue) { return a.createAt - b.createAt }
|
}
|
||||||
|
if (bValue && !aValue) {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
if (!aValue && !bValue) {
|
||||||
|
return a.createAt - b.createAt
|
||||||
|
}
|
||||||
|
|
||||||
result = Number(aValue) - Number(bValue)
|
result = Number(aValue) - Number(bValue)
|
||||||
} else if (template.type === "createdTime") {
|
} else if (template.type === 'createdTime') {
|
||||||
result = a.createAt - b.createAt
|
result = a.createAt - b.createAt
|
||||||
} else if (template.type === "updatedTime") {
|
} else if (template.type === 'updatedTime') {
|
||||||
result = a.updateAt - b.updateAt
|
result = a.updateAt - b.updateAt
|
||||||
} else {
|
} else {
|
||||||
// Text-based sort
|
// Text-based sort
|
||||||
|
|
||||||
// Always put empty values at the bottom
|
// Always put empty values at the bottom
|
||||||
if (aValue && !bValue) { return -1 }
|
if (aValue && !bValue) {
|
||||||
if (bValue && !aValue) { return 1 }
|
return -1
|
||||||
if (!aValue && !bValue) { return a.createAt - b.createAt }
|
}
|
||||||
|
if (bValue && !aValue) {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
if (!aValue && !bValue) {
|
||||||
|
return a.createAt - b.createAt
|
||||||
|
}
|
||||||
|
|
||||||
result = aValue.localeCompare(bValue)
|
result = aValue.localeCompare(bValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sortOption.reversed) { result = -result }
|
if (sortOption.reversed) {
|
||||||
|
result = -result
|
||||||
|
}
|
||||||
return result
|
return result
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -26,13 +26,13 @@ class MutableCardTree implements CardTree {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private rebuild(blocks: IBlock[]) {
|
private rebuild(blocks: IBlock[]) {
|
||||||
this.card = blocks.find(o => o.id === this.cardId) as Card
|
this.card = blocks.find((o) => o.id === this.cardId) as Card
|
||||||
|
|
||||||
this.comments = blocks
|
this.comments = blocks.
|
||||||
.filter(block => block.type === "comment")
|
filter((block) => block.type === 'comment').
|
||||||
.sort((a, b) => a.createAt - b.createAt)
|
sort((a, b) => a.createAt - b.createAt)
|
||||||
|
|
||||||
const contentBlocks = blocks.filter(block => block.type === "text" || block.type === "image") as IOrderedBlock[]
|
const contentBlocks = blocks.filter((block) => block.type === 'text' || block.type === 'image') as IOrderedBlock[]
|
||||||
this.contents = contentBlocks.sort((a, b) => a.order - b.order)
|
this.contents = contentBlocks.sort((a, b) => a.order - b.order)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,17 +16,17 @@ class MutableWorkspaceTree {
|
|||||||
views: BoardView[] = []
|
views: BoardView[] = []
|
||||||
|
|
||||||
async sync() {
|
async sync() {
|
||||||
const boards = await octoClient.getBlocksWithType("board")
|
const boards = await octoClient.getBlocksWithType('board')
|
||||||
const views = await octoClient.getBlocksWithType("view")
|
const views = await octoClient.getBlocksWithType('view')
|
||||||
this.rebuild(
|
this.rebuild(
|
||||||
OctoUtils.hydrateBlocks(boards),
|
OctoUtils.hydrateBlocks(boards),
|
||||||
OctoUtils.hydrateBlocks(views)
|
OctoUtils.hydrateBlocks(views),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private rebuild(boards: IBlock[], views: IBlock[]) {
|
private rebuild(boards: IBlock[], views: IBlock[]) {
|
||||||
this.boards = boards.filter(block => block.type === "board") as Board[]
|
this.boards = boards.filter((block) => block.type === 'board') as Board[]
|
||||||
this.views = views.filter(block => block.type === "view") as BoardView[]
|
this.views = views.filter((block) => block.type === 'view') as BoardView[]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user