99 <NcAppNavigation :class =" {loading: loading.notes, 'icon-error': error}" >
1010 <NcAppNavigationNew
1111 v-show =" !loading.notes && !error"
12- :text =" t('notes', 'New note')"
13- @click =" onNewNote"
12+ :text =" t('notes', 'New category')"
13+ @click =" onNewCategory"
14+ @dragover.native =" onNewCategoryDragOver"
15+ @drop.native =" onNewCategoryDrop"
1416 >
15- <PlusIcon slot =" icon" :size =" 20" />
17+ <FolderPlusIcon slot =" icon" :size =" 20" />
1618 </NcAppNavigationNew >
1719
1820 <template #list >
19- <CategoriesList v-show =" !loading.notes"
20- v-if =" numNotes"
21- />
21+ <CategoriesList v-show =" !loading.notes" />
2222 </template >
2323
2424 <template #footer >
@@ -54,16 +54,17 @@ import NcContent from '@nextcloud/vue/components/NcContent'
5454import { loadState } from ' @nextcloud/initial-state'
5555import { showSuccess , TOAST_UNDO_TIMEOUT , TOAST_PERMANENT_TIMEOUT } from ' @nextcloud/dialogs'
5656import ' @nextcloud/dialogs/style.css'
57+ import { emit } from ' @nextcloud/event-bus'
5758
58- import PlusIcon from ' vue-material-design-icons/Plus.vue'
5959import CogIcon from ' vue-material-design-icons/CogOutline.vue'
60+ import FolderPlusIcon from ' vue-material-design-icons/FolderPlus.vue'
6061
6162import AppSettings from ' ./components/AppSettings.vue'
6263import CategoriesList from ' ./components/CategoriesList.vue'
6364import EditorHint from ' ./components/Modal/EditorHint.vue'
6465
6566import { config } from ' ./config.js'
66- import { fetchNotes , noteExists , createNote , undoDeleteNote } from ' ./NotesService.js'
67+ import { fetchNotes , noteExists , undoDeleteNote } from ' ./NotesService.js'
6768import store from ' ./store.js'
6869
6970export default {
@@ -79,7 +80,7 @@ export default {
7980 NcAppNavigationNew,
8081 NcAppNavigationItem,
8182 NcContent,
82- PlusIcon ,
83+ FolderPlusIcon ,
8384 },
8485
8586 data () {
@@ -89,7 +90,6 @@ export default {
8990 },
9091 loading: {
9192 notes: true ,
92- create: false ,
9393 },
9494 error: false ,
9595 undoNotification: null ,
@@ -227,20 +227,89 @@ export default {
227227 this .settingsVisible = true
228228 },
229229
230- onNewNote () {
231- if (this .loading .create ) {
230+ onNewCategory () {
231+ emit (' notes:category:new' )
232+ },
233+
234+ onNewCategoryDragOver (event ) {
235+ if (! this .isNoteDrag (event )) {
232236 return
233237 }
234- this .loading .create = true
235- createNote (store .getters .getSelectedCategory ())
236- .then (note => {
237- this .routeToNote (note .id , { new: null })
238- })
239- .catch (() => {
240- })
241- .finally (() => {
242- this .loading .create = false
243- })
238+ event .preventDefault ()
239+ if (event .dataTransfer ) {
240+ event .dataTransfer .dropEffect = ' move'
241+ }
242+ },
243+
244+ onNewCategoryDrop (event ) {
245+ const noteId = this .getDraggedNoteId (event )
246+ if (noteId === null ) {
247+ return
248+ }
249+ event .preventDefault ()
250+ event .stopPropagation ()
251+ emit (' notes:category:new' , { noteId })
252+ },
253+
254+ getDraggedNoteId (event ) {
255+ const dt = event ? .dataTransfer
256+ if (! dt) {
257+ return null
258+ }
259+
260+ const types = Array .from (dt .types ?? [])
261+ const hasCustom = types .includes (' application/x-nextcloud-notes-note-id' )
262+ const hasUri = types .includes (' text/uri-list' )
263+ if (! hasCustom && hasUri) {
264+ return null
265+ }
266+
267+ let raw = ' '
268+ if (hasCustom) {
269+ try {
270+ raw = dt .getData (' application/x-nextcloud-notes-note-id' )
271+ } catch {
272+ // Some browsers only allow specific mime types.
273+ }
274+ }
275+ if (! raw) {
276+ try {
277+ raw = dt .getData (' text/plain' )
278+ } catch {
279+ raw = ' '
280+ }
281+ }
282+
283+ const match = / ^ \s * (\d + )\s * $ / .exec (raw)
284+ const parsedId = match ? Number .parseInt (match[1 ], 10 ) : Number .NaN
285+ if (! Number .isFinite (parsedId)) {
286+ return null
287+ }
288+ const note = store .getters .getNote (parsedId)
289+ if (! note || note .readonly ) {
290+ return null
291+ }
292+
293+ return parsedId
294+ },
295+
296+ isNoteDrag (event ) {
297+ const dt = event ? .dataTransfer
298+ if (! dt) {
299+ return false
300+ }
301+ const types = Array .from (dt .types ?? [])
302+ if (types .includes (' application/x-nextcloud-notes-note-id' )) {
303+ return true
304+ }
305+ if (types .includes (' text/uri-list' )) {
306+ return false
307+ }
308+ try {
309+ return / ^ \s * \d + \s * $ / .test (dt .getData (' text/plain' ))
310+ } catch {
311+ return false
312+ }
244313 },
245314
246315 onNoteDeleted (note ) {
@@ -325,4 +394,19 @@ export default {
325394 padding- inline- start: 3px ;
326395 margin: 0 3px ;
327396}
397+
398+ : deep (.app - navigation__body ) {
399+ overflow: hidden ! important;
400+ flex: 0 0 auto;
401+ }
402+
403+ : deep (.app - navigation__content ) {
404+ min- height: 0 ;
405+ }
406+
407+ : deep (.app - navigation__list ) {
408+ flex: 1 1 auto;
409+ min- height: 0 ;
410+ height: auto ! important;
411+ }
328412< / style>
0 commit comments