1
0
mirror of https://github.com/BoostIo/Boostnote synced 2025-12-13 17:56:25 +00:00

When storage or folder is removed, Detail components should render without error (#3168)

* optimize: when storage or folder is removed, Detail components should render without error, fix #2876

* optimize: Handle some scenarios where storage is not found, should not break the renderer

* optimize: NoteList should work without error when storage is not found
This commit is contained in:
hikerpig
2020-04-06 17:02:52 +08:00
committed by GitHub
parent 0d797ce8a8
commit 6ee92588b1
7 changed files with 69 additions and 24 deletions

View File

@@ -156,7 +156,12 @@ class MarkdownSplitEditor extends React.Component {
linesHighlighted, linesHighlighted,
RTL RTL
} = this.props } = this.props
const storage = findStorage(storageKey) let storage
try {
storage = findStorage(storageKey)
} catch (e) {
return <div />
}
let editorFontSize = parseInt(config.editor.fontSize, 10) let editorFontSize = parseInt(config.editor.fontSize, 10)
if (!(editorFontSize > 0 && editorFontSize < 101)) editorFontSize = 14 if (!(editorFontSize > 0 && editorFontSize < 101)) editorFontSize = 14
let editorIndentSize = parseInt(config.editor.indentSize, 10) let editorIndentSize = parseInt(config.editor.indentSize, 10)

View File

@@ -294,7 +294,7 @@ class FolderSelect extends React.Component {
{optionList} {optionList}
</div> </div>
</div> </div>
) : ( ) : currentOption ? (
<div styleName='idle' style={{ color: currentOption.folder.color }}> <div styleName='idle' style={{ color: currentOption.folder.color }}>
<div styleName='idle-label'> <div styleName='idle-label'>
<i className='fa fa-folder' /> <i className='fa fa-folder' />
@@ -303,7 +303,7 @@ class FolderSelect extends React.Component {
</span> </span>
</div> </div>
</div> </div>
)} ) : null}
</div> </div>
) )
} }

View File

@@ -479,10 +479,16 @@ class MarkdownNoteDetail extends React.Component {
}) })
}) })
}) })
const currentOption = options.filter(
const currentOption = _.find(
options,
option => option =>
option.storage.key === storageKey && option.folder.key === folderKey option.storage.key === storageKey && option.folder.key === folderKey
)[0] )
// currentOption may be undefined
const storageName = _.get(currentOption, 'storage.name') || ''
const folderName = _.get(currentOption, 'folder.name') || ''
const trashTopBar = ( const trashTopBar = (
<div styleName='info'> <div styleName='info'>
@@ -495,8 +501,8 @@ class MarkdownNoteDetail extends React.Component {
/> />
<InfoButton onClick={e => this.handleInfoButtonClick(e)} /> <InfoButton onClick={e => this.handleInfoButtonClick(e)} />
<InfoPanelTrashed <InfoPanelTrashed
storageName={currentOption.storage.name} storageName={storageName}
folderName={currentOption.folder.name} folderName={folderName}
updatedAt={formatDate(note.updatedAt)} updatedAt={formatDate(note.updatedAt)}
createdAt={formatDate(note.createdAt)} createdAt={formatDate(note.createdAt)}
exportAsHtml={this.exportAsHtml} exportAsHtml={this.exportAsHtml}
@@ -579,8 +585,8 @@ class MarkdownNoteDetail extends React.Component {
<InfoButton onClick={e => this.handleInfoButtonClick(e)} /> <InfoButton onClick={e => this.handleInfoButtonClick(e)} />
<InfoPanel <InfoPanel
storageName={currentOption.storage.name} storageName={storageName}
folderName={currentOption.folder.name} folderName={folderName}
noteLink={`[${note.title}](:note:${ noteLink={`[${note.title}](:note:${
queryString.parse(location.search).key queryString.parse(location.search).key
})`} })`}

View File

@@ -885,10 +885,16 @@ class SnippetNoteDetail extends React.Component {
}) })
}) })
}) })
const currentOption = options.filter(
const currentOption = _.find(
options,
option => option =>
option.storage.key === storageKey && option.folder.key === folderKey option.storage.key === storageKey && option.folder.key === folderKey
)[0] )
// currentOption may be undefined
const storageName = _.get(currentOption, 'storage.name') || ''
const folderName = _.get(currentOption, 'folder.name') || ''
const trashTopBar = ( const trashTopBar = (
<div styleName='info'> <div styleName='info'>
@@ -901,8 +907,8 @@ class SnippetNoteDetail extends React.Component {
/> />
<InfoButton onClick={e => this.handleInfoButtonClick(e)} /> <InfoButton onClick={e => this.handleInfoButtonClick(e)} />
<InfoPanelTrashed <InfoPanelTrashed
storageName={currentOption.storage.name} storageName={storageName}
folderName={currentOption.folder.name} folderName={folderName}
updatedAt={formatDate(note.updatedAt)} updatedAt={formatDate(note.updatedAt)}
createdAt={formatDate(note.createdAt)} createdAt={formatDate(note.createdAt)}
exportAsMd={this.showWarning} exportAsMd={this.showWarning}
@@ -951,8 +957,8 @@ class SnippetNoteDetail extends React.Component {
<InfoButton onClick={e => this.handleInfoButtonClick(e)} /> <InfoButton onClick={e => this.handleInfoButtonClick(e)} />
<InfoPanel <InfoPanel
storageName={currentOption.storage.name} storageName={storageName}
folderName={currentOption.folder.name} folderName={folderName}
noteLink={`[${note.title}](:note:${ noteLink={`[${note.title}](:note:${
queryString.parse(location.search).key queryString.parse(location.search).key
})`} })`}

View File

@@ -1107,10 +1107,10 @@ class NoteList extends React.Component {
getNoteFolder(note) { getNoteFolder(note) {
// note.folder = folder key // note.folder = folder key
return _.find( const storage = this.getNoteStorage(note)
this.getNoteStorage(note).folders, return storage
({ key }) => key === note.folder ? _.find(storage.folders, ({ key }) => key === note.folder)
) : []
} }
getViewType() { getViewType() {
@@ -1145,9 +1145,14 @@ class NoteList extends React.Component {
? this.getNotes().sort(sortFunc) ? this.getNotes().sort(sortFunc)
: this.sortByPin(this.getNotes().sort(sortFunc)) : this.sortByPin(this.getNotes().sort(sortFunc))
this.notes = notes = sortedNotes.filter(note => { this.notes = notes = sortedNotes.filter(note => {
if (
// has matching storage
!!this.getNoteStorage(note) &&
// this is for the trash box // this is for the trash box
if (note.isTrashed !== true || location.pathname === '/trashed') (note.isTrashed !== true || location.pathname === '/trashed')
) {
return true return true
}
}) })
if (sortDir === 'DESCENDING') this.notes.reverse() if (sortDir === 'DESCENDING') this.notes.reverse()
@@ -1193,6 +1198,8 @@ class NoteList extends React.Component {
sortBy === 'CREATED_AT' ? note.createdAt : note.updatedAt sortBy === 'CREATED_AT' ? note.createdAt : note.updatedAt
).fromNow('D') ).fromNow('D')
const storage = this.getNoteStorage(note)
if (isDefault) { if (isDefault) {
return ( return (
<NoteItem <NoteItem
@@ -1205,7 +1212,7 @@ class NoteList extends React.Component {
handleDragStart={this.handleDragStart.bind(this)} handleDragStart={this.handleDragStart.bind(this)}
pathname={location.pathname} pathname={location.pathname}
folderName={this.getNoteFolder(note).name} folderName={this.getNoteFolder(note).name}
storageName={this.getNoteStorage(note).name} storageName={storage.name}
viewType={viewType} viewType={viewType}
showTagsAlphabetically={config.ui.showTagsAlphabetically} showTagsAlphabetically={config.ui.showTagsAlphabetically}
coloredTags={config.coloredTags} coloredTags={config.coloredTags}
@@ -1223,7 +1230,7 @@ class NoteList extends React.Component {
handleDragStart={this.handleDragStart.bind(this)} handleDragStart={this.handleDragStart.bind(this)}
pathname={location.pathname} pathname={location.pathname}
folderName={this.getNoteFolder(note).name} folderName={this.getNoteFolder(note).name}
storageName={this.getNoteStorage(note).name} storageName={storage.name}
viewType={viewType} viewType={viewType}
/> />
) )

View File

@@ -835,7 +835,15 @@ function getAttachmentsPathAndStatus(markdownContent, storageKey, noteKey) {
if (storageKey == null || noteKey == null || markdownContent == null) { if (storageKey == null || noteKey == null || markdownContent == null) {
return null return null
} }
const targetStorage = findStorage.findStorage(storageKey) let targetStorage = null
try {
targetStorage = findStorage.findStorage(storageKey)
} catch (error) {
console.warn(`No stroage found for: ${storageKey}`)
}
if (!targetStorage) {
return null
}
const attachmentFolder = path.join( const attachmentFolder = path.join(
targetStorage.path, targetStorage.path,
DESTINATION_FOLDER, DESTINATION_FOLDER,

View File

@@ -912,6 +912,19 @@ it('should test that getAttachmentsPathAndStatus return null if noteKey, storage
expect(result).toBeNull() expect(result).toBeNull()
}) })
it('should test that getAttachmentsPathAndStatus return null if no storage found', function() {
const noteKey = 'test'
const storageKey = 'not_exist'
const markdownContent = ''
const result = systemUnderTest.getAttachmentsPathAndStatus(
markdownContent,
storageKey,
noteKey
)
expect(result).toBeNull()
})
it('should test that getAttachmentsPathAndStatus return the correct path and status for attachments', async function() { it('should test that getAttachmentsPathAndStatus return the correct path and status for attachments', async function() {
const dummyStorage = { path: 'dummyStoragePath' } const dummyStorage = { path: 'dummyStoragePath' }
const noteKey = 'noteKey' const noteKey = 'noteKey'