Skip to content

Commit 0f64c52

Browse files
committed
refactor(files-tree): added shared service and drop zone
1 parent b2b366d commit 0f64c52

7 files changed

Lines changed: 188 additions & 193 deletions

File tree

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<div
2+
class="drop-zone-container flex flex-1"
3+
(dragenter)="onDragEnter($event)"
4+
(dragleave)="onDragLeave($event)"
5+
(dragover)="onDragOver($event)"
6+
(drop)="onDrop($event)"
7+
>
8+
@if (enabled()) {
9+
<div class="drop-zone" [class.active]="isDragOver()">
10+
@if (isDragOver()) {
11+
<div class="flex flex-column gap-2 align-items-center pointer-events-none">
12+
<i class="fa-solid fa-cloud-arrow-up text-5xl"></i>
13+
<p class="drop-text text-xl">{{ 'files.dropText' | translate }}</p>
14+
</div>
15+
}
16+
</div>
17+
}
18+
19+
<ng-content></ng-content>
20+
</div>
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
.drop-zone-container {
2+
position: relative;
3+
}
4+
5+
.drop-zone {
6+
position: absolute;
7+
top: 0;
8+
left: 0;
9+
width: 100%;
10+
height: 100%;
11+
z-index: 1000;
12+
display: flex;
13+
align-items: center;
14+
justify-content: center;
15+
color: var(--white);
16+
transition:
17+
background 0.3s ease,
18+
backdrop-filter 0.3s ease;
19+
pointer-events: none;
20+
background: transparent;
21+
22+
&.active {
23+
backdrop-filter: blur(0.3rem);
24+
background: rgba(132, 174, 210, 0.5);
25+
pointer-events: all;
26+
}
27+
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import { TranslatePipe } from '@ngx-translate/core';
2+
3+
import { ChangeDetectionStrategy, Component, input, output, signal } from '@angular/core';
4+
5+
@Component({
6+
selector: 'osf-files-drop-zone',
7+
imports: [TranslatePipe],
8+
templateUrl: './files-drop-zone.component.html',
9+
styleUrl: './files-drop-zone.component.scss',
10+
changeDetection: ChangeDetectionStrategy.OnPush,
11+
})
12+
export class FilesDropZoneComponent {
13+
enabled = input<boolean>(true);
14+
filesDropped = output<File[]>();
15+
isDragOver = signal(false);
16+
17+
private dragDepth = 0;
18+
19+
onDragEnter(event: DragEvent): void {
20+
if (!this.enabled()) {
21+
return;
22+
}
23+
24+
if (event.dataTransfer?.types?.includes('Files')) {
25+
this.dragDepth += 1;
26+
this.isDragOver.set(true);
27+
}
28+
}
29+
30+
onDragOver(event: DragEvent): void {
31+
if (!this.enabled()) {
32+
return;
33+
}
34+
35+
event.preventDefault();
36+
event.stopPropagation();
37+
if (event.dataTransfer) {
38+
event.dataTransfer.dropEffect = 'copy';
39+
}
40+
this.isDragOver.set(true);
41+
}
42+
43+
onDragLeave(event: Event): void {
44+
if (!this.enabled()) {
45+
return;
46+
}
47+
48+
event.preventDefault();
49+
event.stopPropagation();
50+
this.dragDepth = Math.max(0, this.dragDepth - 1);
51+
if (this.dragDepth === 0) {
52+
this.isDragOver.set(false);
53+
}
54+
}
55+
56+
onDrop(event: DragEvent): void {
57+
event.preventDefault();
58+
event.stopPropagation();
59+
this.dragDepth = 0;
60+
this.isDragOver.set(false);
61+
62+
if (!this.enabled()) {
63+
return;
64+
}
65+
66+
const files = event.dataTransfer?.files;
67+
if (!files || files.length === 0) {
68+
return;
69+
}
70+
71+
this.filesDropped.emit(Array.from(files));
72+
}
73+
}

src/app/shared/components/files-tree/files-tree.component.html

Lines changed: 8 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,8 @@
1-
<div #dropZoneContainer class="drop-zone-container flex flex-1">
2-
@if (!hasViewOnly() && supportUpload()) {
3-
<div
4-
class="drop-zone"
5-
[class.active]="isDragOver()"
6-
(dragleave)="onDragLeave($event)"
7-
(dragover)="onDragOver($event)"
8-
(drop)="onDrop($event)"
9-
>
10-
@if (isDragOver()) {
11-
<div class="flex flex-column gap-2 align-items-center pointer-events-none">
12-
<i class="fa-solid fa-cloud-arrow-up text-5xl"></i>
13-
<p class="drop-text text-xl">{{ 'files.dropText' | translate }}</p>
14-
</div>
15-
}
16-
</div>
17-
}
18-
1+
<osf-files-drop-zone
2+
class="flex flex-1"
3+
[enabled]="!hasViewOnly() && supportUpload()"
4+
(filesDropped)="onDropFiles($event)"
5+
>
196
@if (isLoading() && !isLoadingMore()) {
207
<div class="flex flex-1">
218
<osf-loading-spinner></osf-loading-spinner>
@@ -30,7 +17,6 @@
3017
[lazy]="true"
3118
[loading]="isLoadingMore()"
3219
[selectionMode]="selectionMode()"
33-
[selection]="selectedNodes()"
3420
[scrollHeight]="scrollHeight()"
3521
[value]="nodes()"
3622
[virtualScroll]="true"
@@ -84,8 +70,8 @@
8470
{{ file.dateModified | date: 'MMM d, y hh:mm a' }}
8571
</div>
8672

87-
@if (isSomeFileActionAllowed && !selectedFiles().length) {
88-
<div class="relative ml-auto">
73+
@if (canShowMenu()) {
74+
<div class="ml-auto">
8975
<osf-file-menu
9076
(action)="onFileMenuAction($event, file)"
9177
[isFolder]="file.kind === 'folder'"
@@ -115,4 +101,4 @@ <h3 class="font-normal mb-4 text-no-transform">{{ 'files.emptyState' | translate
115101
</div>
116102
</div>
117103
}
118-
</div>
104+
</osf-files-drop-zone>

src/app/shared/components/files-tree/files-tree.component.scss

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -62,27 +62,3 @@
6262
padding: 0;
6363
}
6464
}
65-
66-
.drop-zone {
67-
position: absolute;
68-
top: 0;
69-
left: 0;
70-
width: 100%;
71-
height: 100%;
72-
z-index: 1000;
73-
display: flex;
74-
align-items: center;
75-
justify-content: center;
76-
color: var(--white);
77-
transition:
78-
background 0.3s ease,
79-
backdrop-filter 0.3s ease;
80-
pointer-events: none;
81-
background: transparent;
82-
83-
&.active {
84-
backdrop-filter: blur(0.3rem);
85-
background: rgba(132, 174, 210, 0.5);
86-
pointer-events: all;
87-
}
88-
}

0 commit comments

Comments
 (0)