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;