33 :title =" title"
44 :active =" isSelected"
55 :to =" { name: 'note', params: { noteId: note.id.toString() } }"
6+ @update:menuOpen =" onMenuChange"
67 @click =" onNoteSelected(note.id)"
78 >
89 <template #subtitle >
2930 <NcActionButton :icon =" actionFavoriteIcon" @click =" onToggleFavorite" >
3031 {{ actionFavoriteText }}
3132 </NcActionButton >
32- <NcActionButton @click =" onToggleSidebar" >
33- <SidebarIcon slot =" icon" :size =" 20" />
34- {{ t('notes', 'Details') }}
33+
34+ <NcActionButton v-if =" !showCategorySelect" @click =" showCategorySelect = true" >
35+ <template #icon >
36+ <FolderIcon :size =" 20" />
37+ </template >
38+ {{ categoryTitle }}
3539 </NcActionButton >
36- <NcActionButton v-if =" !note.readonly" :icon =" actionDeleteIcon" @click =" onDeleteNote" >
37- {{ t('notes', 'Delete note') }}
40+ <NcActionInput
41+ v-else
42+ :value =" note.category"
43+ type =" multiselect"
44+ label =" label"
45+ track-by =" id"
46+ :multiple =" false"
47+ :options =" categories"
48+ :disabled =" loading.category"
49+ :taggable =" true"
50+ @input =" onCategoryChange"
51+ @search-change =" onCategoryChange"
52+ >
53+ <template #icon >
54+ <FolderIcon :size =" 20" />
55+ </template >
56+ {{ t('notes', 'Change category') }}
57+ </NcActionInput >
58+
59+ <NcActionButton v-if =" !renaming" @click =" startRenaming" >
60+ <PencilIcon slot =" icon" :size =" 20" />
61+ {{ t('notes', 'Rename') }}
3862 </NcActionButton >
63+ <NcActionInput v-else
64+ v-model.trim =" newTitle"
65+ :disabled =" !renaming"
66+ :placeholder =" t('notes', 'Rename note')"
67+ :show-trailing-button =" true"
68+ @input =" onInputChange($event)"
69+ @submit =" onRename"
70+ >
71+ <PencilIcon slot =" icon" :size =" 20" />
72+ </NcActionInput >
73+
3974 <NcActionSeparator />
40- <NcActionButton icon =" icon-files-dark" @click =" onCategorySelected" >
41- {{ actionCategoryText }}
75+
76+ <NcActionButton v-if =" !note.readonly" :icon =" actionDeleteIcon" @click =" onDeleteNote" >
77+ {{ t('notes', 'Delete note') }}
4278 </NcActionButton >
4379 </template >
4480 </NcListItem >
4581</template >
4682
4783<script >
48- import { NcListItem , NcActionButton } from ' @nextcloud/vue'
84+ import { NcListItem , NcActionButton , NcActionSeparator , NcActionInput } from ' @nextcloud/vue'
4985import AlertOctagonIcon from ' vue-material-design-icons/AlertOctagon.vue'
5086import FileDocumentOutlineIcon from ' vue-material-design-icons/FileDocumentOutline.vue'
87+ import FolderIcon from ' vue-material-design-icons/Folder.vue'
88+ import PencilIcon from ' vue-material-design-icons/Pencil.vue'
5189import StarIcon from ' vue-material-design-icons/Star.vue'
52- import SidebarIcon from ' vue-material-design-icons/PageLayoutSidebarRight.vue'
5390import { categoryLabel , routeIsNewNote } from ' ../Util.js'
5491import { showError } from ' @nextcloud/dialogs'
55- import store from ' ../store.js'
56- import { setFavorite , setTitle , fetchNote , deleteNote } from ' ../NotesService.js'
92+ import { setFavorite , setTitle , fetchNote , deleteNote , setCategory } from ' ../NotesService.js'
5793
5894export default {
5995 name: ' NoteItem' ,
6096
6197 components: {
6298 AlertOctagonIcon,
6399 FileDocumentOutlineIcon,
100+ FolderIcon,
64101 NcActionButton,
65102 NcListItem,
66- SidebarIcon,
67103 StarIcon,
104+ NcActionSeparator,
105+ NcActionInput,
106+ PencilIcon,
68107 },
69108
70109 props: {
@@ -78,7 +117,11 @@ export default {
78117 return {
79118 loading: {
80119 note: false ,
120+ category: false ,
81121 },
122+ newTitle: ' ' ,
123+ renaming: false ,
124+ showCategorySelect: false ,
82125 }
83126 },
84127
@@ -111,9 +154,24 @@ export default {
111154 actionDeleteIcon () {
112155 return ' icon-delete' + (this .loading .delete ? ' loading' : ' ' )
113156 },
157+ categories () {
158+ return [
159+ {
160+ id: ' ' ,
161+ label: categoryLabel (' ' ),
162+ },
163+ ... this .$store .getters .getCategories (0 , false ).map ((category ) => ({
164+ id: category,
165+ label: categoryLabel (category),
166+ })),
167+ ]
168+ },
114169 },
115-
116170 methods: {
171+ onMenuChange (state ) {
172+ this .actionsOpen = state
173+ this .showCategorySelect = false
174+ },
117175 onNoteSelected (noteId ) {
118176 this .$emit (' note-selected' , noteId)
119177 },
@@ -131,24 +189,49 @@ export default {
131189 this .actionsOpen = false
132190 this .$emit (' category-selected' , this .note .category )
133191 },
134- onToggleSidebar () {
135- this .actionsOpen = false
136- store .commit (' setSidebarOpen' , ! store .state .app .sidebarOpen )
192+ startRenaming () {
193+ this .renaming = true
194+ this .newTitle = this .note .title
195+ this .$emit (' start-renaming' , this .note .id )
196+ },
197+ onInputChange (event ) {
198+ this .newTitle = event .target .value .toString ()
137199 },
138- onRename (newTitle ) {
200+ async onCategoryChange (result ) {
201+ this .showCategorySelect = false
202+ const category = result? .id ?? result? .label ?? null
203+ if (category !== null && this .note .category !== category) {
204+ this .loading .category = true
205+ await setCategory (this .note .id , category)
206+ this .loading .category = false
207+ }
208+ },
209+ async onRename () {
210+ const newTitle = this .newTitle .toString ()
211+ if (! newTitle) {
212+ return
213+ }
139214 this .loading .note = true
140215 setTitle (this .note .id , newTitle)
141- .catch (() => {
216+ .then (() => {
217+ this .newTitle = ' '
218+ })
219+ .catch ((e ) => {
220+ console .error (' Failed to rename note' , e)
221+ showError (this .t (' notes' , ' Error while renaming note.' ))
142222 })
143223 .finally (() => {
144224 this .loading .note = false
145225 })
226+
146227 if (routeIsNewNote (this .$route )) {
147228 this .$router .replace ({
148229 name: ' note' ,
149230 params: { noteId: this .note .id .toString () },
150231 })
151232 }
233+ this .renaming = false
234+
152235 },
153236 async onDeleteNote () {
154237 this .loading .delete = true
0 commit comments