Fixes bug where images don't show up in templates and boards created from templates (#2224)
* Base fix for bug causing images to not appear in templates created from boards * Added some docs * Fixed lint error * Update server/app/blocks.go Co-authored-by: Doug Lauder <wiggin77@warpmail.net> * used a better method name Co-authored-by: Doug Lauder <wiggin77@warpmail.net>
This commit is contained in:
parent
46801d72cb
commit
21ba0e00ce
4 changed files with 46 additions and 4 deletions
|
@ -440,6 +440,16 @@ func (a *API) handlePostBlocks(w http.ResponseWriter, r *http.Request) {
|
|||
ctx := r.Context()
|
||||
session := ctx.Value(sessionContextKey).(*model.Session)
|
||||
|
||||
// this query param exists only when creating
|
||||
// template from board
|
||||
sourceBoardID := r.URL.Query().Get("sourceBoardID")
|
||||
if sourceBoardID != "" {
|
||||
if updateFileIDsErr := a.app.CopyCardFiles(sourceBoardID, blocks); updateFileIDsErr != nil {
|
||||
a.errorResponse(w, r.URL.Path, http.StatusInternalServerError, "", updateFileIDsErr)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
newBlocks, err := a.app.InsertBlocks(*container, blocks, session.UserID, true)
|
||||
if err != nil {
|
||||
a.errorResponse(w, r.URL.Path, http.StatusInternalServerError, "", err)
|
||||
|
|
|
@ -133,6 +133,36 @@ func (a *App) InsertBlocks(c store.Container, blocks []model.Block, modifiedByID
|
|||
return blocks, nil
|
||||
}
|
||||
|
||||
func (a *App) CopyCardFiles(sourceBoardID string, blocks []model.Block) error {
|
||||
// Images attached in cards have a path comprising the card's board ID.
|
||||
// When we create a template from this board, we need to copy the files
|
||||
// with the new board ID in path.
|
||||
// Not doing so causing images in templates (and boards created from this
|
||||
// template) to fail to load.
|
||||
|
||||
for i := range blocks {
|
||||
block := blocks[i]
|
||||
|
||||
fileName, ok := block.Fields["fileId"]
|
||||
if block.Type == model.TypeImage && ok {
|
||||
sourceFilePath := filepath.Join(block.WorkspaceID, sourceBoardID, fileName.(string))
|
||||
destinationFilePath := filepath.Join(block.WorkspaceID, block.RootID, fileName.(string))
|
||||
if err := a.filesBackend.CopyFile(sourceFilePath, destinationFilePath); err != nil {
|
||||
a.logger.Error(
|
||||
"CopyCardFiles failed to copy file",
|
||||
mlog.String("sourceFilePath", sourceFilePath),
|
||||
mlog.String("destinationFilePath", destinationFilePath),
|
||||
mlog.Err(err),
|
||||
)
|
||||
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *App) GetSubTree(c store.Container, blockID string, levels int) ([]model.Block, error) {
|
||||
// Only 2 or 3 levels are supported for now
|
||||
if levels >= 3 {
|
||||
|
|
|
@ -132,10 +132,10 @@ class Mutator {
|
|||
}
|
||||
|
||||
//eslint-disable-next-line no-shadow
|
||||
async insertBlocks(blocks: Block[], description = 'add', afterRedo?: (blocks: Block[]) => Promise<void>, beforeUndo?: () => Promise<void>) {
|
||||
async insertBlocks(blocks: Block[], description = 'add', afterRedo?: (blocks: Block[]) => Promise<void>, beforeUndo?: () => Promise<void>, sourceBoardID?: string) {
|
||||
return undoManager.perform(
|
||||
async () => {
|
||||
const res = await octoClient.insertBlocks(blocks)
|
||||
const res = await octoClient.insertBlocks(blocks, sourceBoardID)
|
||||
const newBlocks = (await res.json()) as Block[]
|
||||
updateAllBlocks(newBlocks)
|
||||
await afterRedo?.(newBlocks)
|
||||
|
@ -793,6 +793,7 @@ class Mutator {
|
|||
await afterRedo?.(board?.id || '')
|
||||
},
|
||||
beforeUndo,
|
||||
boardId,
|
||||
)
|
||||
const board = createdBlocks.find((b: Block) => b.type === 'board')
|
||||
return [createdBlocks, board.id]
|
||||
|
|
|
@ -315,13 +315,14 @@ class OctoClient {
|
|||
return this.insertBlocks([block])
|
||||
}
|
||||
|
||||
async insertBlocks(blocks: Block[]): Promise<Response> {
|
||||
async insertBlocks(blocks: Block[], sourceBoardID?: string): Promise<Response> {
|
||||
Utils.log(`insertBlocks: ${blocks.length} blocks(s)`)
|
||||
blocks.forEach((block) => {
|
||||
Utils.log(`\t ${block.type}, ${block.id}, ${block.title?.substr(0, 50) || ''}`)
|
||||
})
|
||||
const body = JSON.stringify(blocks)
|
||||
return fetch(this.getBaseURL() + this.workspacePath() + '/blocks', {
|
||||
const url = this.getBaseURL() + this.workspacePath() + '/blocks' + (sourceBoardID ? `?sourceBoardID=${encodeURIComponent(sourceBoardID)}` : '')
|
||||
return fetch(url, {
|
||||
method: 'POST',
|
||||
headers: this.headers(),
|
||||
body,
|
||||
|
|
Loading…
Reference in a new issue