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:
Harshil Sharma 2022-02-02 22:42:59 +05:30 committed by GitHub
parent 46801d72cb
commit 21ba0e00ce
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 46 additions and 4 deletions

View file

@ -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)

View file

@ -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 {

View file

@ -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]

View file

@ -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,