Add global templates to redux store (#731)
* Add global templates to redux store * Removing unused import * Remove unnecesary reducer * Fixing eslint
This commit is contained in:
parent
e988812ccb
commit
ee94e17f16
6 changed files with 49 additions and 66 deletions
2
mattermost-plugin/server/manifest.go
generated
2
mattermost-plugin/server/manifest.go
generated
|
@ -20,7 +20,7 @@ const manifestStr = `
|
|||
"release_notes_url": "https://github.com/mattermost/focalboard/releases",
|
||||
"icon_path": "assets/starter-template-icon.svg",
|
||||
"version": "0.8.0",
|
||||
"min_server_version": "5.36.0",
|
||||
"min_server_version": "5.37.0",
|
||||
"server": {
|
||||
"executables": {
|
||||
"linux-amd64": "server/dist/plugin-linux-amd64",
|
||||
|
|
|
@ -50,7 +50,7 @@ const BoardTemplateMenuItem = React.memo((props: Props) => {
|
|||
key={boardTemplate.id}
|
||||
id={boardTemplate.id}
|
||||
name={displayName}
|
||||
icon={<div className='Icon'>{boardTemplate.icon}</div>}
|
||||
icon={<div className='Icon'>{boardTemplate.fields.icon}</div>}
|
||||
onClick={() => {
|
||||
addBoardFromTemplate(intl, props.showBoard, boardTemplate.id, activeBoardId, isGlobal)
|
||||
}}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
import React, {useState, useEffect, useCallback} from 'react'
|
||||
import React, {useEffect, useCallback} from 'react'
|
||||
import {FormattedMessage, useIntl, IntlShape} from 'react-intl'
|
||||
import {generatePath, useHistory, useRouteMatch} from 'react-router-dom'
|
||||
|
||||
|
@ -8,12 +8,13 @@ import {MutableBoard} from '../../blocks/board'
|
|||
import {MutableBoardView} from '../../blocks/boardView'
|
||||
import mutator from '../../mutator'
|
||||
import octoClient from '../../octoClient'
|
||||
import {GlobalTemplateTree, MutableGlobalTemplateTree} from '../../viewModel/globalTemplateTree'
|
||||
import {WorkspaceTree} from '../../viewModel/workspaceTree'
|
||||
import AddIcon from '../../widgets/icons/add'
|
||||
import BoardIcon from '../../widgets/icons/board'
|
||||
import Menu from '../../widgets/menu'
|
||||
import MenuWrapper from '../../widgets/menuWrapper'
|
||||
import {useAppDispatch, useAppSelector} from '../../store/hooks'
|
||||
import {getGlobalTemplates, fetchGlobalTemplates} from '../../store/globalTemplates'
|
||||
|
||||
import BoardTemplateMenuItem from './boardTemplateMenuItem'
|
||||
|
||||
|
@ -68,7 +69,8 @@ const addBoardTemplateClicked = async (showBoard: (id: string) => void, activeBo
|
|||
}
|
||||
|
||||
const SidebarAddBoardMenu = (props: Props): JSX.Element => {
|
||||
const [globalTemplateTree, setGlobalTemplateTree] = useState<GlobalTemplateTree|null>(null)
|
||||
const globalTemplates = useAppSelector<MutableBoard[]>(getGlobalTemplates)
|
||||
const dispatch = useAppDispatch()
|
||||
const history = useHistory()
|
||||
const match = useRouteMatch()
|
||||
|
||||
|
@ -78,13 +80,10 @@ const SidebarAddBoardMenu = (props: Props): JSX.Element => {
|
|||
}, [match, history])
|
||||
|
||||
useEffect(() => {
|
||||
if (octoClient.workspaceId !== '0' && !globalTemplateTree) {
|
||||
const syncFunc = async () => {
|
||||
setGlobalTemplateTree(await MutableGlobalTemplateTree.sync())
|
||||
}
|
||||
syncFunc()
|
||||
if (octoClient.workspaceId !== '0' && globalTemplates.length === 0) {
|
||||
dispatch(fetchGlobalTemplates())
|
||||
}
|
||||
}, [])
|
||||
}, [octoClient.workspaceId])
|
||||
|
||||
const {workspaceTree} = props
|
||||
const intl = useIntl()
|
||||
|
@ -126,7 +125,7 @@ const SidebarAddBoardMenu = (props: Props): JSX.Element => {
|
|||
/>
|
||||
))}
|
||||
|
||||
{globalTemplateTree && globalTemplateTree.boardTemplates.map((boardTemplate) => (
|
||||
{globalTemplates.map((boardTemplate: MutableBoard) => (
|
||||
<BoardTemplateMenuItem
|
||||
key={boardTemplate.id}
|
||||
boardTemplate={boardTemplate}
|
||||
|
|
36
webapp/src/store/globalTemplates.ts
Normal file
36
webapp/src/store/globalTemplates.ts
Normal file
|
@ -0,0 +1,36 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {createSlice, createAsyncThunk} from '@reduxjs/toolkit'
|
||||
|
||||
import {default as client, OctoClient} from '../octoClient'
|
||||
import {MutableBoard} from '../blocks/board'
|
||||
|
||||
import {RootState} from './index'
|
||||
|
||||
export const fetchGlobalTemplates = createAsyncThunk(
|
||||
'globalTemplates/fetch',
|
||||
async () => {
|
||||
const rootClient = new OctoClient(client.serverUrl, '0')
|
||||
const rawBlocks = await rootClient.getBlocksWithType('board')
|
||||
const allBoards = rawBlocks as MutableBoard[]
|
||||
return allBoards.filter((block) => block.fields.isTemplate).sort((a, b) => a.title.localeCompare(b.title)) as MutableBoard[]
|
||||
},
|
||||
)
|
||||
|
||||
const globalTemplatesSlice = createSlice({
|
||||
name: 'globalTemplates',
|
||||
initialState: {value: []} as {value: MutableBoard[]},
|
||||
reducers: {},
|
||||
extraReducers: (builder) => {
|
||||
builder.addCase(fetchGlobalTemplates.fulfilled, (state, action) => {
|
||||
state.value = action.payload || []
|
||||
})
|
||||
},
|
||||
})
|
||||
|
||||
export const {reducer} = globalTemplatesSlice
|
||||
|
||||
export function getGlobalTemplates(state: RootState): MutableBoard[] {
|
||||
return state.globalTemplates.value
|
||||
}
|
|
@ -7,6 +7,7 @@ import {reducer as currentUserReducer} from './currentUser'
|
|||
import {reducer as currentWorkspaceReducer} from './currentWorkspace'
|
||||
import {reducer as currentWorkspaceUsersReducer} from './currentWorkspaceUsers'
|
||||
import {reducer as languageReducer} from './language'
|
||||
import {reducer as globalTemplatesReducer} from './globalTemplates'
|
||||
|
||||
const store = configureStore({
|
||||
reducer: {
|
||||
|
@ -14,6 +15,7 @@ const store = configureStore({
|
|||
currentWorkspace: currentWorkspaceReducer,
|
||||
currentWorkspaceUsers: currentWorkspaceUsersReducer,
|
||||
language: languageReducer,
|
||||
globalTemplates: globalTemplatesReducer,
|
||||
},
|
||||
})
|
||||
|
||||
|
|
|
@ -1,54 +0,0 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
import {IBlock} from '../blocks/block'
|
||||
import {Board} from '../blocks/board'
|
||||
import octoClient, {OctoClient} from '../octoClient'
|
||||
import {OctoUtils} from '../octoUtils'
|
||||
|
||||
interface GlobalTemplateTree {
|
||||
readonly boardTemplates: readonly Board[]
|
||||
readonly allBlocks: readonly IBlock[]
|
||||
}
|
||||
|
||||
class MutableGlobalTemplateTree implements GlobalTemplateTree {
|
||||
boardTemplates: Board[] = []
|
||||
get allBlocks(): IBlock[] {
|
||||
return [...this.boardTemplates]
|
||||
}
|
||||
|
||||
// Factory methods
|
||||
|
||||
static async sync(): Promise<GlobalTemplateTree> {
|
||||
const rootClient = new OctoClient(octoClient.serverUrl, '0')
|
||||
const rawBlocks = await rootClient.getBlocksWithType('board')
|
||||
|
||||
return this.buildTree(rawBlocks)
|
||||
}
|
||||
|
||||
static incrementalUpdate(originalTree: GlobalTemplateTree, updatedBlocks: IBlock[]): GlobalTemplateTree {
|
||||
const relevantBlocks = updatedBlocks.filter((block) => block.deleteAt !== 0 || block.type === 'board' || block.type === 'view')
|
||||
if (relevantBlocks.length < 1) {
|
||||
// No change
|
||||
return originalTree
|
||||
}
|
||||
const rawBlocks = OctoUtils.mergeBlocks(originalTree.allBlocks, relevantBlocks)
|
||||
return this.buildTree(rawBlocks)
|
||||
}
|
||||
|
||||
private static buildTree(sourceBlocks: readonly IBlock[]): MutableGlobalTemplateTree {
|
||||
const blocks = OctoUtils.hydrateBlocks(sourceBlocks)
|
||||
|
||||
const workspaceTree = new MutableGlobalTemplateTree()
|
||||
const allBoards = blocks.filter((block) => block.type === 'board') as Board[]
|
||||
workspaceTree.boardTemplates = allBoards.filter((block) => block.isTemplate).
|
||||
sort((a, b) => a.title.localeCompare(b.title)) as Board[]
|
||||
|
||||
return workspaceTree
|
||||
}
|
||||
|
||||
// private mutableCopy(): MutableWorkspaceTree {
|
||||
// return MutableWorkspaceTree.buildTree(this.allBlocks)!
|
||||
// }
|
||||
}
|
||||
|
||||
export {MutableGlobalTemplateTree, GlobalTemplateTree}
|
Loading…
Reference in a new issue