diff --git a/browser/components/TagListItem.js b/browser/components/TagListItem.js index 4346ac21..6cd50c9c 100644 --- a/browser/components/TagListItem.js +++ b/browser/components/TagListItem.js @@ -9,16 +9,26 @@ import CSSModules from 'browser/lib/CSSModules' /** * @param {string} name * @param {Function} handleClickTagListItem +* @param {Function} handleClickNarrowToTag * @param {bool} isActive +* @param {bool} isRelated */ -const TagListItem = ({name, handleClickTagListItem, isActive, count}) => ( - +const TagListItem = ({name, handleClickTagListItem, handleClickNarrowToTag, isActive, isRelated, count}) => ( +
+ {isRelated + ? + :
+ } + +
) TagListItem.propTypes = { diff --git a/browser/components/TagListItem.styl b/browser/components/TagListItem.styl index 513d112a..555520b0 100644 --- a/browser/components/TagListItem.styl +++ b/browser/components/TagListItem.styl @@ -1,5 +1,9 @@ +.tagList-itemContainer + display flex + .tagList-item display flex + flex 1 width 100% height 26px background-color transparent @@ -20,9 +24,16 @@ color $ui-button-default-color background-color $ui-button-default--active-backgroundColor +.tagList-itemNarrow + composes tagList-item + flex none + width 20px + padding 0 4px + .tagList-item-active background-color $ui-button-default--active-backgroundColor display flex + flex 1 width 100% height 26px padding 0 @@ -36,10 +47,16 @@ background-color alpha($ui-button-default--active-backgroundColor, 60%) transition 0.2s +.tagList-itemNarrow-active + composes tagList-item-active + flex none + width 20px + padding 0 4px + .tagList-item-name display block flex 1 - padding 0 15px + padding 0 8px 0 4px height 26px line-height 26px border-width 0 0 0 2px diff --git a/browser/main/NoteList/index.js b/browser/main/NoteList/index.js index dedad209..e8c09f65 100644 --- a/browser/main/NoteList/index.js +++ b/browser/main/NoteList/index.js @@ -343,11 +343,10 @@ class NoteList extends React.Component { } if (location.pathname.match(/\/tags/)) { + const listOfTags = params.tagname.split(' ') return data.noteMap.map(note => { return note - }).filter(note => { - return note.tags.includes(params.tagname) - }) + }).filter(note => listOfTags.every(tag => note.tags.includes(tag))) } return this.getContextNotes() diff --git a/browser/main/SideNav/index.js b/browser/main/SideNav/index.js index f8a65013..6b53478e 100644 --- a/browser/main/SideNav/index.js +++ b/browser/main/SideNav/index.js @@ -145,20 +145,27 @@ class SideNav extends React.Component { tagListComponent () { const { data, location, config } = this.props + const relatedTags = this.getRelatedTags(this.getActiveTags(location.pathname), data.noteMap) let tagList = _.sortBy(data.tagNoteMap.map( - (tag, name) => ({name, size: tag.size})), - ['name'] - ) + (tag, name) => ({ name, size: tag.size, related: relatedTags.has(name) }) + ), ['name']) if (config.sortTagsBy === 'COUNTER') { tagList = _.sortBy(tagList, item => (0 - item.size)) } + if (config.ui.showOnlyRelatedTags && (relatedTags.size > 0)) { + tagList = tagList.filter( + tag => tag.related + ) + } return ( tagList.map(tag => { return ( @@ -167,10 +174,30 @@ class SideNav extends React.Component { ) } + getRelatedTags (activeTags, noteMap) { + if (activeTags.length === 0) { + return new Set() + } + const relatedNotes = noteMap.map( + note => ({key: note.key, tags: note.tags}) + ).filter( + note => activeTags.every(tag => note.tags.includes(tag)) + ) + let relatedTags = new Set() + relatedNotes.forEach(note => note.tags.map(tag => relatedTags.add(tag))) + return relatedTags + } + getTagActive (path, tag) { + return this.getActiveTags(path).includes(tag) + } + + getActiveTags (path) { const pathSegments = path.split('/') - const pathTag = pathSegments[pathSegments.length - 1] - return pathTag === tag + const tags = pathSegments[pathSegments.length - 1] + return (tags === 'alltags') + ? [] + : tags.split(' ') } handleClickTagListItem (name) { @@ -192,6 +219,19 @@ class SideNav extends React.Component { }) } + handleClickNarrowToTag (tag) { + const { router } = this.context + const { location } = this.props + let listOfTags = this.getActiveTags(location.pathname) + const indexOfTag = listOfTags.indexOf(tag) + if (indexOfTag > -1) { + listOfTags.splice(indexOfTag, 1) + } else { + listOfTags.push(tag) + } + router.push(`/tags/${listOfTags.join(' ')}`) + } + emptyTrash (entries) { const { dispatch } = this.props const deletionPromises = entries.map((note) => { diff --git a/browser/main/modals/PreferencesModal/UiTab.js b/browser/main/modals/PreferencesModal/UiTab.js index 9c74255d..21338731 100644 --- a/browser/main/modals/PreferencesModal/UiTab.js +++ b/browser/main/modals/PreferencesModal/UiTab.js @@ -66,6 +66,7 @@ class UiTab extends React.Component { language: this.refs.uiLanguage.value, showCopyNotification: this.refs.showCopyNotification.checked, confirmDeletion: this.refs.confirmDeletion.checked, + showOnlyRelatedTags: this.refs.showOnlyRelatedTags.checked, disableDirectWrite: this.refs.uiD2w != null ? this.refs.uiD2w.checked : false @@ -210,6 +211,16 @@ class UiTab extends React.Component { {i18n.__('Show a confirmation dialog when deleting notes')}
+
+ +
{ global.process.platform === 'win32' ?
diff --git a/tests/components/__snapshots__/TagListItem.snapshot.test.js.snap b/tests/components/__snapshots__/TagListItem.snapshot.test.js.snap index 0805edcd..0521ca0e 100644 --- a/tests/components/__snapshots__/TagListItem.snapshot.test.js.snap +++ b/tests/components/__snapshots__/TagListItem.snapshot.test.js.snap @@ -1,19 +1,26 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`TagListItem renders correctly 1`] = ` - + +
`;