Improve UI + UX of the "move nodes" feature

This commit is contained in:
brufdev
2025-03-08 19:22:07 +00:00
parent 47334193b9
commit ebfefb83b6
4 changed files with 80 additions and 54 deletions
+1
View File
@@ -67,6 +67,7 @@ final class TreeView extends Component
new UpdateVaultNode()->handle($source, ['parent_id' => $parentId]);
$this->dispatch('file-refresh', node: $source);
$this->dispatch('toast', message: __('Node moved'), type: 'success');
}
public function placeholder(): string
@@ -11,6 +11,10 @@
Alpine.data('treeView', () => ({
moveNodeId: null,
moving() {
return this.moveNodeId !== null;
},
moveNode(nodeId) {
this.moveNodeId = nodeId;
},
@@ -1,6 +1,10 @@
@aware(['node'])
<div class="relative flex items-center w-full">
<div class="relative flex items-center w-full"
x-data="{ hovered: false }"
@mouseenter="hovered = true"
@mouseleave="hovered = false"
>
<x-menu class="flex flex-grow">
<a href="" class="flex items-center w-full" title="{{ $node->name }}" x-ref="button"
@click.prevent="accordionOpen = !accordionOpen"
@@ -61,8 +65,10 @@
</x-menu.items>
</x-menu>
<a href="" class="flex items-center hover:text-primary-300 dark:hover:text-primary-600"
x-show="moveNodeId && showDropZone(['{{ str_replace(".", "','", $node->path) }}'])"
<a href="" class="flex items-center text-primary-400 dark:text-primary-500 hover:text-primary-300 dark:hover:text-primary-600"
x-show="moving() && hovered && showDropZone(['{{ str_replace(".", "','", $node->path) }}'])"
x-transition:enter.duration.300ms
x-transition:leave.duration.150ms
@click.prevent="dropNode({{ $node->id }})"
>
<x-icons.arrowDownOnSquare class="w-5 h-5" />
@@ -1,57 +1,72 @@
<div class="flex flex-grow px-4">
<x-treeView>
<div class="sticky top-0 z-[5] flex justify-between py-4 bg-light-base-50 dark:bg-base-900">
<h3>{{ $vault->name }}</h3>
<div class="flex items-center" x-show="!moveNodeId">
<x-menu>
<x-menu.button>
<x-icons.bars3 class="w-5 h-5" />
</x-menu.button>
<x-menu.items>
<x-menu.close>
<x-menu.item @click="$wire.dispatchTo('modals.add-node', 'open-modal')">
<x-icons.documentPlus class="w-4 h-4" />
{{ __('New note') }}
</x-menu.item>
<x-menu.item @click="$wire.dispatchTo('modals.add-node', 'open-modal', { isFile: false })">
<x-icons.folderPlus class="w-4 h-4" />
{{ __('New folder') }}
</x-menu.item>
<x-menu.item @click="$wire.dispatchTo('modals.import-file', 'open-modal')">
<x-icons.arrowUpTray class="w-4 h-4" />
{{ __('Import file') }}
</x-menu.item>
<x-modal>
<x-modal.open>
<x-menu.item>
<x-icons.pencilSquare class="w-4 h-4" />
{{ __('Edit vault') }}
</x-menu.item>
</x-modal.open>
<x-modal.panel title="{{ __('Edit vault') }}">
<x-form wire:submit="editVault" class="flex flex-col gap-6">
<x-form.input name="vaultForm.name" label="{{ __('Name') }}"
type="text" required autofocus />
<div class="flex justify-end">
<x-form.submit label="{{ __('Edit') }}" target="edit" />
</div>
</x-form>
</x-modal.panel>
</x-modal>
</x-menu.close>
</x-menu.items>
</x-menu>
</div>
<a href="" class="flex items-center hover:text-primary-300 dark:hover:text-primary-600" x-show="moveNodeId"
@click.prevent="dropNode(0)"
<div class="sticky top-0 z-[5] flex flex-col gap-2 py-4 bg-light-base-50 dark:bg-base-900">
<div class="flex justify-center py-1 rounded-sm bg-primary-400 dark:bg-primary-500 text-light-base-50"
x-show="moving()" x-transition
>{{ __('Drop item') }}</div>
<div class="flex justify-between w-full"
x-data="{ hovered: false }"
@mouseenter="hovered = true"
@mouseleave="hovered = false"
>
<x-icons.arrowDownOnSquare class="w-5 h-5" />
</a>
<h3>{{ $vault->name }}</h3>
<div class="flex items-center" x-show="!moving()"
x-transition:enter.duration.300ms
x-transition:leave.duration.150ms
>
<x-menu>
<x-menu.button>
<x-icons.bars3 class="w-5 h-5" />
</x-menu.button>
<x-menu.items>
<x-menu.close>
<x-menu.item @click="$wire.dispatchTo('modals.add-node', 'open-modal')">
<x-icons.documentPlus class="w-4 h-4" />
{{ __('New note') }}
</x-menu.item>
<x-menu.item @click="$wire.dispatchTo('modals.add-node', 'open-modal', { isFile: false })">
<x-icons.folderPlus class="w-4 h-4" />
{{ __('New folder') }}
</x-menu.item>
<x-menu.item @click="$wire.dispatchTo('modals.import-file', 'open-modal')">
<x-icons.arrowUpTray class="w-4 h-4" />
{{ __('Import file') }}
</x-menu.item>
<x-modal>
<x-modal.open>
<x-menu.item>
<x-icons.pencilSquare class="w-4 h-4" />
{{ __('Edit vault') }}
</x-menu.item>
</x-modal.open>
<x-modal.panel title="{{ __('Edit vault') }}">
<x-form wire:submit="editVault" class="flex flex-col gap-6">
<x-form.input name="vaultForm.name" label="{{ __('Name') }}"
type="text" required autofocus />
<div class="flex justify-end">
<x-form.submit label="{{ __('Edit') }}" target="edit" />
</div>
</x-form>
</x-modal.panel>
</x-modal>
</x-menu.close>
</x-menu.items>
</x-menu>
</div>
<a href="" class="flex items-center text-primary-400 dark:text-primary-500 hover:text-primary-300 dark:hover:text-primary-600"
x-show="moving() && hovered"
x-transition:enter.duration.300ms
x-transition:leave.duration.150ms
@click.prevent="dropNode(0)"
>
<x-icons.arrowDownOnSquare class="w-5 h-5" />
</a>
</div>
</div>
<div>