77 <Fragment >
88 <NcAppNavigationItem
99 :name =" t('notes', 'All notes')"
10- :class =" { active: selectedCategory === null }"
10+ :class =" {
11+ active: selectedCategory === null,
12+ 'drop-over': dragOverAllNotes,
13+ }"
1114 @click.prevent.stop =" onSelectCategory(null)"
15+ @dragover.native =" onAllNotesDragOver($event)"
16+ @dragleave.native =" onAllNotesDragLeave($event)"
17+ @drop.native =" onAllNotesDrop($event)"
1218 >
1319 <template #icon >
1420 <HistoryIcon :size =" 20" />
2632 :key =" category.name"
2733 :name =" categoryTitle(category.name)"
2834 :icon =" category.name === '' ? 'icon-emptyfolder' : 'icon-files'"
29- :class =" { active: category.name === selectedCategory }"
35+ :class =" {
36+ active: category.name === selectedCategory,
37+ 'drop-over': category.name === dragOverCategory,
38+ }"
3039 @click.prevent.stop =" onSelectCategory(category.name)"
40+ @dragover.native =" onCategoryDragOver(category.name, $event)"
41+ @dragleave.native =" onCategoryDragLeave(category.name, $event)"
42+ @drop.native =" onCategoryDrop(category.name, $event)"
3143 >
3244 <template #icon >
3345 <FolderOutlineIcon v-if =" category.name === ''" :size =" 20" />
@@ -52,7 +64,7 @@ import FolderIcon from 'vue-material-design-icons/Folder.vue'
5264import FolderOutlineIcon from ' vue-material-design-icons/FolderOutline.vue'
5365import HistoryIcon from ' vue-material-design-icons/History.vue'
5466
55- import { getCategories } from ' ../NotesService.js'
67+ import { getCategories , setCategory } from ' ../NotesService.js'
5668import { categoryLabel } from ' ../Util.js'
5769import store from ' ../store.js'
5870
@@ -69,6 +81,13 @@ export default {
6981 HistoryIcon,
7082 },
7183
84+ data () {
85+ return {
86+ dragOverCategory: null ,
87+ dragOverAllNotes: false ,
88+ }
89+ },
90+
7291 computed: {
7392 numNotes () {
7493 return store .getters .numNotes ()
@@ -88,6 +107,118 @@ export default {
88107 return categoryLabel (category)
89108 },
90109
110+ getDraggedNoteId (event ) {
111+ const dt = event ? .dataTransfer
112+ if (! dt) {
113+ return null
114+ }
115+
116+ let raw = ' '
117+ try {
118+ raw = dt .getData (' application/x-nextcloud-notes-note-id' )
119+ } catch {
120+ // Some browsers only allow specific mime types.
121+ }
122+ if (! raw) {
123+ raw = dt .getData (' text/plain' ) || dt .getData (' text/uri-list' ) || dt .getData (' text/x-moz-url' ) || ' '
124+ }
125+
126+ const match = / \/ note\/ (\d + )(?:[/?#\s ] | $ )/ .exec (raw) || / ^ \s * (\d + )\s * $ / .exec (raw)
127+ const noteId = match ? Number .parseInt (match[1 ], 10 ) : Number .NaN
128+ if (! Number .isFinite (noteId)) {
129+ return null
130+ }
131+ const note = store .getters .getNote (noteId)
132+ if (! note || note .readonly ) {
133+ return null
134+ }
135+
136+ return noteId
137+ },
138+
139+ onCategoryDragOver (category , event ) {
140+ event .preventDefault ()
141+ if (event .dataTransfer ) {
142+ event .dataTransfer .dropEffect = ' move'
143+ }
144+ this .dragOverAllNotes = false
145+ this .dragOverCategory = category
146+ },
147+
148+ onAllNotesDragOver (event ) {
149+ event .preventDefault ()
150+ if (event .dataTransfer ) {
151+ event .dataTransfer .dropEffect = ' move'
152+ }
153+ this .dragOverCategory = null
154+ this .dragOverAllNotes = true
155+ },
156+
157+ onAllNotesDragLeave (event ) {
158+ if (! this .dragOverAllNotes ) {
159+ return
160+ }
161+
162+ const currentTarget = event .currentTarget
163+ const relatedTarget = event .relatedTarget
164+ if (currentTarget && relatedTarget && currentTarget .contains (relatedTarget)) {
165+ return
166+ }
167+
168+ this .dragOverAllNotes = false
169+ },
170+
171+ onCategoryDragLeave (category , event ) {
172+ if (this .dragOverCategory !== category) {
173+ return
174+ }
175+
176+ const currentTarget = event .currentTarget
177+ const relatedTarget = event .relatedTarget
178+ if (currentTarget && relatedTarget && currentTarget .contains (relatedTarget)) {
179+ return
180+ }
181+
182+ this .dragOverCategory = null
183+ },
184+
185+ async onAllNotesDrop (event ) {
186+ event .preventDefault ()
187+ event .stopPropagation ()
188+
189+ this .dragOverAllNotes = false
190+ const noteId = this .getDraggedNoteId (event )
191+ if (noteId === null ) {
192+ return
193+ }
194+
195+ const note = store .getters .getNote (noteId)
196+ if (! note || note .category === ' ' ) {
197+ return
198+ }
199+
200+ await setCategory (noteId, ' ' )
201+ },
202+
203+ async onCategoryDrop (category , event ) {
204+ event .preventDefault ()
205+ event .stopPropagation ()
206+
207+ const noteId = this .getDraggedNoteId (event )
208+ this .dragOverCategory = null
209+ this .dragOverAllNotes = false
210+ if (noteId === null ) {
211+ return
212+ }
213+
214+ const note = store .getters .getNote (noteId)
215+ if (! note || note .category === category) {
216+ return
217+ }
218+
219+ await setCategory (noteId, category)
220+ },
221+
91222 onSelectCategory (category ) {
92223 store .commit (' setSelectedCategory' , category)
93224 },
@@ -98,4 +229,10 @@ export default {
98229.app - navigation- entry- wrapper .active : deep (.app - navigation - entry ) {
99230 background- color: var (-- color- primary- element- light) ! important;
100231}
232+
233+ .app - navigation- entry- wrapper .drop - over: deep (.app - navigation - entry ) {
234+ background- color: var (-- color- primary- element- light) ! important;
235+ outline: 2px dashed var (-- color- primary- element);
236+ outline- offset: - 2px ;
237+ }
101238< / style>
0 commit comments