diff --git a/app/assets/javascripts/app.ts b/app/assets/javascripts/app.ts index 8adffd559..eead8b4e8 100644 --- a/app/assets/javascripts/app.ts +++ b/app/assets/javascripts/app.ts @@ -64,6 +64,7 @@ import { MultipleSelectedNotesDirective } from './components/MultipleSelectedNot import { NotesContextMenuDirective } from './components/NotesContextMenu'; import { NotesOptionsPanelDirective } from './components/NotesOptionsPanel'; import { IconDirective } from './components/Icon'; +import { NoteTagsDirective } from './components/NoteTags'; function reloadHiddenFirefoxTab(): boolean { /** @@ -157,7 +158,8 @@ const startApplication: StartApplication = async function startApplication( .directive('multipleSelectedNotesPanel', MultipleSelectedNotesDirective) .directive('notesContextMenu', NotesContextMenuDirective) .directive('notesOptionsPanel', NotesOptionsPanelDirective) - .directive('icon', IconDirective); + .directive('icon', IconDirective) + .directive('noteTags', NoteTagsDirective); // Filters angular.module('app').filter('trusted', ['$sce', trusted]); diff --git a/app/assets/javascripts/components/NoteTags.tsx b/app/assets/javascripts/components/NoteTags.tsx new file mode 100644 index 000000000..8b78e0ff6 --- /dev/null +++ b/app/assets/javascripts/components/NoteTags.tsx @@ -0,0 +1,23 @@ +import { AppState } from "@/ui_models/app_state"; +import { observer } from "mobx-react-lite"; +import { toDirective } from "./utils"; +import { Icon } from "./Icon"; + +type Props = { + appState: AppState; +} + +const NoteTags = observer(({ appState }: Props) => { + return ( +
+ {appState.notes.activeNoteTags.map(tag => ( + + + {tag.title} + + ))} +
+ ); +}); + +export const NoteTagsDirective = toDirective(NoteTags); \ No newline at end of file diff --git a/app/assets/javascripts/ui_models/app_state/notes_state.ts b/app/assets/javascripts/ui_models/app_state/notes_state.ts index 6688e4e97..d8dcccb02 100644 --- a/app/assets/javascripts/ui_models/app_state/notes_state.ts +++ b/app/assets/javascripts/ui_models/app_state/notes_state.ts @@ -29,6 +29,7 @@ export class NotesState { }; contextMenuMaxHeight: number | 'auto' = 'auto'; showProtectedWarning = false; + activeNoteTags: SNTag[] = []; constructor( private application: WebApplication, @@ -40,6 +41,7 @@ export class NotesState { contextMenuOpen: observable, contextMenuPosition: observable, showProtectedWarning: observable, + activeNoteTags: observable, selectedNotesCount: computed, trashedNotesCount: computed, @@ -164,6 +166,11 @@ export class NotesState { } else { this.activeEditor.setNote(note); } + + runInAction(() => { + this.activeNoteTags = this.application.getAppState().getNoteTags(note); + }); + await this.onActiveEditorChanged(); if (note.waitingForKey) { diff --git a/app/assets/javascripts/views/editor/editor-view.pug b/app/assets/javascripts/views/editor/editor-view.pug index f5ef81437..dabb895c3 100644 --- a/app/assets/javascripts/views/editor/editor-view.pug +++ b/app/assets/javascripts/views/editor/editor-view.pug @@ -30,7 +30,7 @@ div.flex-grow( ng-class="{'locked' : self.noteLocked}" ) - .title + .title.overflow-auto input#note-title-editor.input( ng-blur='self.onTitleBlur()', ng-change='self.onTitleChange()', @@ -48,16 +48,20 @@ ng-style="self.notesLocked && {'pointer-events' : 'none'}", application='self.application' ) - input.tags-input( - ng-blur='self.onTagsInputBlur()', - ng-disabled='self.noteLocked', - ng-if='!self.state.tagsComponent', - ng-keyup='$event.keyCode == 13 && $event.target.blur();', - ng-model='self.editorValues.tagsInputValue', - placeholder='#tags', - spellcheck='false', - type='text' + div.flex + note-tags( + app-state='self.appState' ) + input.tags-input( + ng-blur='self.onTagsInputBlur()', + ng-disabled='self.noteLocked', + ng-if='!self.state.tagsComponent', + ng-keyup='$event.keyCode == 13 && $event.target.blur();', + ng-model='self.editorValues.tagsInputValue', + placeholder='#tags', + spellcheck='false', + type='text' + ) div.flex.items-center #save-status .message( diff --git a/app/assets/stylesheets/_editor.scss b/app/assets/stylesheets/_editor.scss index 45ad2a88c..ca4d681af 100644 --- a/app/assets/stylesheets/_editor.scss +++ b/app/assets/stylesheets/_editor.scss @@ -106,7 +106,6 @@ $heading-height: 75px; .tags-input { background-color: transparent; color: var(--sn-stylekit-foreground-color); - width: 100%; border: none; &:focus { diff --git a/app/assets/stylesheets/_sn.scss b/app/assets/stylesheets/_sn.scss index 9a4f00026..d4d8cd236 100644 --- a/app/assets/stylesheets/_sn.scss +++ b/app/assets/stylesheets/_sn.scss @@ -53,6 +53,14 @@ margin-bottom: 0.5rem; } +.mr-1 { + margin-right: 0.25rem; +} + +.p-1 { + padding: 0.25rem; +} + .py-1\.5 { padding-top: 0.375rem; padding-bottom: 0.375rem; @@ -167,10 +175,18 @@ overflow-y: scroll; } +.overflow-auto { + overflow: auto; +} + .items-start { align-items: flex-start; } +.p-2 { + padding: 0.5rem; +} + /** * A button that is just an icon. Separated from .sn-button because there * is almost no style overlap. @@ -205,6 +221,11 @@ @extend .fill-current; } +.sn-icon.small { + @extend .h-3\.5; + @extend .w-3\.5; +} + .sn-dropdown { @extend .bg-default; @extend .min-w-80;