Mailspring/internal_packages/account-sidebar/lib/sidebar-item.coffee
Annie 7e3aab2256 refactor(folders): Make folders disappear when deleted rather than graying out until confirmed
Summary:
When testing we thought that Deleting a folder turns it grey but keeps it in the folder list; trying again throws this error.
It turns out, that the folder was actually going to be deleted if left alone long enough, however, since it sat there grey for a while
we would attempt to delete it again which would throw an error. To get around this, we removed the isDeleted grey state and
unpersisted the folder right when delete is clicked then persisted the folder if there was an API error.

fix(folders): Add new and extend destroy category task specs

Test Plan: I tested locally, tweaked destroy category task specs and added minor new specs

Reviewers: bengotow, juan

Reviewed By: juan

Subscribers: bengotow, juan

Differential Revision: https://phab.nylas.com/D3131
2016-07-28 12:10:54 -07:00

162 lines
5.5 KiB
CoffeeScript

_ = require 'underscore'
_str = require 'underscore.string'
{WorkspaceStore,
MailboxPerspective,
FocusedPerspectiveStore,
SyncbackCategoryTask,
DestroyCategoryTask,
CategoryStore,
Actions,
Utils,
RegExpUtils} = require 'nylas-exports'
{OutlineViewItem} = require 'nylas-component-kit'
SidebarActions = require './sidebar-actions'
idForCategories = (categories) ->
_.pluck(categories, 'id').join('-')
countForItem = (perspective) ->
unreadCountEnabled = NylasEnv.config.get('core.workspace.showUnreadForAllCategories')
if perspective.isInbox() or unreadCountEnabled
return perspective.unreadCount()
return 0
isItemSelected = (perspective) ->
(WorkspaceStore.rootSheet() in [WorkspaceStore.Sheet.Threads, WorkspaceStore.Sheet.Drafts] and
FocusedPerspectiveStore.current().isEqual(perspective))
isItemCollapsed = (id) ->
if NylasEnv.savedState.sidebarKeysCollapsed[id] isnt undefined
NylasEnv.savedState.sidebarKeysCollapsed[id]
else
true
toggleItemCollapsed = (item) ->
return unless item.children.length > 0
SidebarActions.setKeyCollapsed(item.id, not isItemCollapsed(item.id))
onDeleteItem = (item) ->
# TODO Delete multiple categories at once
return if item.deleted is true
category = item.perspective.category()
return unless category
Actions.queueTask(new DestroyCategoryTask({category}))
onEditItem = (item, value) ->
return unless value
return if item.deleted is true
category = item.perspective.category()
return unless category
re = RegExpUtils.subcategorySplitRegex()
match = re.exec(category.displayName)
lastMatch = match
while match
lastMatch = match
match = re.exec(category.displayName)
if lastMatch
newDisplayName = category.displayName.slice(0, lastMatch.index + 1) + value
else
newDisplayName = value
if newDisplayName is category.displayName
return
Actions.queueTask(new SyncbackCategoryTask({category, displayName: newDisplayName}))
class SidebarItem
@forPerspective: (id, perspective, opts = {}) ->
counterStyle = OutlineViewItem.CounterStyles.Alt if perspective.isInbox()
return _.extend({
id: id
name: perspective.name
contextMenuLabel: perspective.name
count: countForItem(perspective)
iconName: perspective.iconName
children: []
perspective: perspective
selected: isItemSelected(perspective)
collapsed: isItemCollapsed(id) ? true
counterStyle: counterStyle
dataTransferType: 'nylas-threads-data'
onDelete: if opts.deletable then onDeleteItem else undefined
onEdited: if opts.editable then onEditItem else undefined
onCollapseToggled: toggleItemCollapsed
onDrop: (item, event) ->
jsonString = event.dataTransfer.getData(item.dataTransferType)
data = Utils.jsonParse(jsonString)
return unless data
item.perspective.receiveThreads(data.threadIds)
shouldAcceptDrop: (item, event) ->
target = item.perspective
current = FocusedPerspectiveStore.current()
jsonString = event.dataTransfer.getData(item.dataTransferType)
data = Utils.jsonParse(jsonString)
return false unless data
return false unless target
return false if target.isEqual(current)
return false unless target.canReceiveThreadsFromAccountIds(data.accountIds)
return item.dataTransferType in event.dataTransfer.types
onSelect: (item) ->
Actions.focusMailboxPerspective(item.perspective)
}, opts)
@forCategories: (categories = [], opts = {}) ->
id = idForCategories(categories)
contextMenuLabel = _str.capitalize(categories[0]?.displayType())
perspective = MailboxPerspective.forCategories(categories)
opts.deletable ?= true
opts.editable ?= true
opts.contextMenuLabel = contextMenuLabel
@forPerspective(id, perspective, opts)
@forSnoozed: (accountIds, opts = {}) ->
# TODO This constant should be available elsewhere
constants = require('../../thread-snooze/lib/snooze-constants')
displayName = constants.SNOOZE_CATEGORY_NAME
id = displayName
id += "-#{opts.name}" if opts.name
opts.name = "Snoozed" unless opts.name
opts.iconName= 'snooze.png'
categories = accountIds.map (accId) =>
_.findWhere CategoryStore.categories(accId), {displayName}
categories = _.compact(categories)
perspective = MailboxPerspective.forCategories(categories)
perspective.name = id unless perspective.name
@forPerspective(id, perspective, opts)
@forStarred: (accountIds, opts = {}) ->
perspective = MailboxPerspective.forStarred(accountIds)
id = 'Starred'
id += "-#{opts.name}" if opts.name
@forPerspective(id, perspective, opts)
@forUnread: (accountIds, opts = {}) ->
categories = accountIds.map (accId) =>
CategoryStore.getStandardCategory(accId, 'inbox')
# NOTE: It's possible for an account to not yet have an `inbox`
# category. Since the `SidebarStore` triggers on `AccountStore`
# changes, it'll trigger the exact moment an account is added to the
# config. However, the API has not yet come back with the list of
# `categories` for that account.
categories = _.compact(categories)
perspective = MailboxPerspective.forUnread(categories)
id = 'Unread'
id += "-#{opts.name}" if opts.name
@forPerspective(id, perspective, opts)
@forDrafts: (accountIds, opts = {}) ->
perspective = MailboxPerspective.forDrafts(accountIds)
id = "Drafts-#{opts.name}"
@forPerspective(id, perspective, opts)
module.exports = SidebarItem