mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-16 17:46:45 +00:00
feat(editor): Add drag n drop support for folders (#14549)
This commit is contained in:
committed by
GitHub
parent
86de2db4f3
commit
57444d3a16
@@ -6,6 +6,7 @@ import { ProjectTypes } from '@/types/projects.types';
|
||||
import type { UserAction } from '@n8n/design-system/types';
|
||||
import { type PathItem } from '@n8n/design-system/components/N8nBreadcrumbs/Breadcrumbs.vue';
|
||||
import { computed } from 'vue';
|
||||
import { useFoldersStore } from '@/stores/folders.store';
|
||||
|
||||
type Props = {
|
||||
actions: UserAction[];
|
||||
@@ -13,18 +14,24 @@ type Props = {
|
||||
visibleItems: FolderPathItem[];
|
||||
hiddenItems: FolderPathItem[];
|
||||
};
|
||||
hiddenItemsTrigger?: 'hover' | 'click';
|
||||
};
|
||||
|
||||
defineProps<Props>();
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
hiddenItemsTrigger: 'click',
|
||||
});
|
||||
|
||||
const emit = defineEmits<{
|
||||
itemSelected: [item: PathItem];
|
||||
action: [action: string];
|
||||
itemDrop: [item: PathItem];
|
||||
projectDrop: [id: string, name: string];
|
||||
}>();
|
||||
|
||||
const i18n = useI18n();
|
||||
|
||||
const projectsStore = useProjectsStore();
|
||||
const foldersStore = useFoldersStore();
|
||||
|
||||
const currentProject = computed(() => projectsStore.currentProject);
|
||||
|
||||
@@ -35,6 +42,10 @@ const projectName = computed(() => {
|
||||
return currentProject.value?.name;
|
||||
});
|
||||
|
||||
const isDragging = computed(() => {
|
||||
return foldersStore.draggedElement !== null;
|
||||
});
|
||||
|
||||
const onItemSelect = (item: PathItem) => {
|
||||
emit('itemSelected', item);
|
||||
};
|
||||
@@ -42,20 +53,61 @@ const onItemSelect = (item: PathItem) => {
|
||||
const onAction = (action: string) => {
|
||||
emit('action', action);
|
||||
};
|
||||
|
||||
const onProjectMouseUp = () => {
|
||||
if (!isDragging.value || !currentProject.value?.name) {
|
||||
return;
|
||||
}
|
||||
emit('projectDrop', currentProject.value.id, currentProject.value.name);
|
||||
};
|
||||
|
||||
const onProjectHover = () => {
|
||||
if (!isDragging.value || !currentProject.value?.name) {
|
||||
return;
|
||||
}
|
||||
foldersStore.activeDropTarget = {
|
||||
type: 'project',
|
||||
id: currentProject.value?.id,
|
||||
name: currentProject.value?.name,
|
||||
};
|
||||
};
|
||||
|
||||
const onItemHover = (item: PathItem) => {
|
||||
if (!isDragging.value) {
|
||||
return;
|
||||
}
|
||||
foldersStore.activeDropTarget = {
|
||||
type: 'folder',
|
||||
id: item.id,
|
||||
name: item.label,
|
||||
};
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
<div :class="$style.container">
|
||||
<div
|
||||
:class="{ [$style.container]: true, [$style['dragging']]: isDragging }"
|
||||
data-test-id="folder-breadcrumbs"
|
||||
>
|
||||
<n8n-breadcrumbs
|
||||
v-if="breadcrumbs.visibleItems"
|
||||
v-model:drag-active="isDragging"
|
||||
:items="breadcrumbs.visibleItems"
|
||||
:highlight-last-item="false"
|
||||
:path-truncated="breadcrumbs.visibleItems[0].parentFolder"
|
||||
:hidden-items="breadcrumbs.hiddenItems"
|
||||
:hidden-items-trigger="props.hiddenItemsTrigger"
|
||||
data-test-id="folder-list-breadcrumbs"
|
||||
@item-selected="onItemSelect"
|
||||
@item-hover="onItemHover"
|
||||
@item-drop="emit('itemDrop', $event)"
|
||||
>
|
||||
<template v-if="currentProject" #prepend>
|
||||
<div :class="$style['home-project']" data-test-id="home-project">
|
||||
<div
|
||||
:class="{ [$style['home-project']]: true, [$style.dragging]: isDragging }"
|
||||
data-test-id="home-project"
|
||||
@mouseenter="onProjectHover"
|
||||
@mouseup="isDragging ? onProjectMouseUp() : null"
|
||||
>
|
||||
<n8n-link :to="`/projects/${currentProject.id}`">
|
||||
<N8nText size="medium" color="text-base">{{ projectName }}</N8nText>
|
||||
</n8n-link>
|
||||
@@ -88,6 +140,18 @@ const onAction = (action: string) => {
|
||||
.home-project {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: var(--spacing-4xs);
|
||||
border: var(--border-width-base) var(--border-style-base) transparent;
|
||||
|
||||
&.dragging:hover {
|
||||
border: var(--border-width-base) var(--border-style-base) var(--color-secondary);
|
||||
border-radius: var(--border-radius-base);
|
||||
background-color: var(--color-callout-secondary-background);
|
||||
* {
|
||||
cursor: grabbing;
|
||||
color: var(--color-text-base);
|
||||
}
|
||||
}
|
||||
|
||||
&:hover * {
|
||||
color: var(--color-text-dark);
|
||||
|
||||
Reference in New Issue
Block a user