Skip to content

Commit

Permalink
feat(document): allow moving of a document per drag & drop
Browse files Browse the repository at this point in the history
  • Loading branch information
anehx committed Dec 6, 2023
1 parent dfa9c2f commit 41663c2
Show file tree
Hide file tree
Showing 11 changed files with 165 additions and 18 deletions.
9 changes: 8 additions & 1 deletion addon/components/category-nav/category.hbs
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
<li class="category-nav__category" ...attributes>
<li
class="category-nav__category {{if this.isDragOver "category-nav__category--dragover"}}"
...attributes
{{on "dragenter" this.onDragEnter}}
{{on "dragleave" this.onDragLeave}}
{{on "dragover" this.onDragOver}}
{{on "drop" (perform this.onDrop)}}
>
<div
class="uk-link-reset {{if this.isActive "active"}}"
tabindex="0"
Expand Down
80 changes: 79 additions & 1 deletion addon/components/category-nav/category.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,19 @@ import { action } from "@ember/object";
import { inject as service } from "@ember/service";
import Component from "@glimmer/component";
import { tracked } from "@glimmer/tracking";
import { dropTask } from "ember-concurrency";

export default class CategoryNavCategoryComponent extends Component {
@service notification;
@service documents;
@service router;
@service store;
@service intl;

dragCounter = 0;

@tracked collapseChildren = false;
@tracked isDragOver = false;

get isActive() {
if (!this.args.category.id) {
Expand All @@ -27,7 +34,7 @@ export default class CategoryNavCategoryComponent extends Component {
}

get expandChildren() {
return this.isOpen && !this.collapseChildren;
return this.isDragOver || (this.isOpen && !this.collapseChildren);
}

get controllerInstance() {
Expand All @@ -52,4 +59,75 @@ export default class CategoryNavCategoryComponent extends Component {
},
});
}

@action onDragEnter() {
if (!this.args.category.id) return;

this.dragCounter++;
this.isDragOver = true;
}

@action onDragLeave() {
if (!this.args.category.id) return;

this.dragCounter--;
this.isDragOver = this.dragCounter > 0;
}

@action onDragOver(event) {
if (!this.args.category.id) return;

event.preventDefault();
event.stopPropagation();
}

@dropTask
*onDrop(event) {
event.preventDefault();

if (!this.args.category.id) return;

const documentIds = event.dataTransfer.getData("text").split(",");

try {
yield Promise.all(
documentIds.map(async (id) => {
const document = this.store.peekRecord("document", id);

if (document.category.id === this.args.category.id) {
return;
}

document.category = this.args.category;

await document.save();
}),
);

this.notification.success(
this.intl.t("alexandria.success.move-document", {
count: documentIds.length,
}),
);

this.router.transitionTo(this.router.currentRouteName, {
queryParams: {
category: this.args.category.id,
search: undefined,
document: documentIds.join(","),
tags: [],
marks: [],
},
});
} catch (e) {
this.notification.danger(
this.intl.t("alexandria.errors.move-document", {
count: documentIds.length,
}),
);
} finally {
this.dragCounter = 0;
this.isDragOver = false;
}
}
}
2 changes: 2 additions & 0 deletions addon/components/document-grid.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@
data-test-document
@document={{document}}
@isSelected={{includes document.id (map-by "id" @selectedDocuments)}}
draggable="true"
{{on "click" (fn @onClickDocument document)}}
{{on "dblclick" (fn @onDoubleClickDocument document)}}
{{on "dragstart" (fn @onDragStart document)}}
/>
</div>
{{else}}
Expand Down
2 changes: 2 additions & 0 deletions addon/components/document-list-item.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
data-test-document-list-item
data-test-document-list-item-id={{@document.id}}
tabindex="0"
draggable="true"
{{on "click" (fn @onClickDocument @document)}}
{{on "dblclick" (fn @onDoubleClickDocument @document)}}
{{on "dragstart" (fn @onDragStart @document)}}
>
<td class="uk-preserve-width">
<FaIcon
Expand Down
1 change: 1 addition & 0 deletions addon/components/document-list.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@
@isSelected={{includes document.id (map-by "id" @selectedDocuments)}}
@onClickDocument={{@onClickDocument}}
@onDoubleClickDocument={{@onDoubleClickDocument}}
@onDragStart={{@onDragStart}}
/>
{{/each}}
</tbody>
Expand Down
9 changes: 9 additions & 0 deletions addon/components/document-view.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
@selectedDocuments={{this.documents.selectedDocuments}}
@onClickDocument={{this.handleDocumentSelection}}
@onDoubleClickDocument={{this.openDocument}}
@onDragStart={{this.dragDocument}}
/>
{{else}}
<DocumentGrid
Expand All @@ -66,6 +67,7 @@
@fetchedDocuments={{this.fetchedDocuments}}
@onClickDocument={{this.handleDocumentSelection}}
@onDoubleClickDocument={{this.openDocument}}
@onDragStart={{this.dragDocument}}
/>
{{/if}}
</div>
Expand All @@ -87,4 +89,11 @@
</div>
</div>
<DocumentsSidePanel @selectedDocuments={{this.documents.selectedDocuments}} />
</div>

<div
class="drag-info uk-background-default uk-box-shadow-medium uk-border-rounded uk-width-auto"
{{did-insert this.registerDragInfo}}
>
{{t "alexandria.move-document" count=this.documents.selectedDocuments.length}}
</div>
26 changes: 24 additions & 2 deletions addon/components/document-view.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ export default class DocumentViewComponent extends Component {
@tracked sort = "title";
@tracked sortDirection = "";

dragElement = null;

constructor(parent, args) {
super(parent, args);
/* Adds a key down event listener to enable Ctrl+A document selection of all docs
Expand Down Expand Up @@ -81,7 +83,7 @@ export default class DocumentViewComponent extends Component {
}

// Drag'n'Drop document upload
@action onDragEnter() {
@action onDragEnter(event) {
this.dragCounter++;
this.isDragOver = true;
}
Expand All @@ -97,7 +99,9 @@ export default class DocumentViewComponent extends Component {
}

onDrop = dropTask(async (event) => {
if (!this.args.filters.category) {
if (!this.args.filters.category || !event.dataTransfer.files.length) {
this.dragCounter = 0;
this.isDragOver = false;
return;
}

Expand Down Expand Up @@ -125,6 +129,7 @@ export default class DocumentViewComponent extends Component {
);
}

this.dragCounter = 0;
this.isDragOver = false;
});

Expand Down Expand Up @@ -195,4 +200,21 @@ export default class DocumentViewComponent extends Component {
);
open(file.downloadUrl);
}

@action registerDragInfo(element) {
this.dragInfo = element;
}

@action dragDocument(document, event) {
if (!this.documents.selectedDocuments.includes(document)) {
this.handleDocumentSelection(document, event);
}

event.dataTransfer.clearData();
event.dataTransfer.setData(
"text/plain",
this.documents.selectedDocuments.map((d) => d.id).join(","),
);
event.dataTransfer.setDragImage(this.dragInfo, -20, 0);
}
}
9 changes: 9 additions & 0 deletions app/styles/components/_drop.scss
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,12 @@
}
}
}

.drag-info {
padding: $padding-small-padding/3 $padding-small-padding;
border-color: $global-primary-background;
position: fixed;
top: 0;
right: 0;
transform: translate(100%, -100%);
}
39 changes: 25 additions & 14 deletions app/styles/components/category-nav/_category.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,34 @@
background: $background-default-background;
}

.uk-nav .category-nav__category > div {
transition-property: background, box-shadow, color;
transition-duration: $animation-duration;
padding: 10px 0 10px $global-margin;
cursor: pointer;
.uk-nav .category-nav__category {
&--dragover {
outline: 1px solid $alert-primary-color;
outline-offset: -1px;

&.active {
@include active;
> div {
background-color: rgba($alert-primary-color, 0.25) !important;
}
}

&:hover {
@include active;
@extend .uk-box-shadow-small;
}
> div {
transition-property: background, box-shadow, color;
transition-duration: $animation-duration;
padding: 10px 0 10px $global-margin;
cursor: pointer;

&.active {
@include active;
}

&:hover {
@include active;
@extend .uk-box-shadow-small;
}

.skeleton-text {
height: 15px;
width: 70%;
.skeleton-text {
height: 15px;
width: 70%;
}
}
}
3 changes: 3 additions & 0 deletions translations/de.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ alexandria:
delete: "Löschen"
upload-file: "Datei hochladen"
download: "Download"
move-document: "{count} {count, plural, one {Dokument} other {Dokumente}} verschieben"

errors:
save-file: "Beim Herunterladen der Datei ist ein Fehler aufgetreten. Bitte versuchen Sie es erneut."
Expand All @@ -18,6 +19,7 @@ alexandria:
} ist ein Fehler aufgetreten.
update: "Änderungen konnten nicht gespeichert werden. Versuchen Sie es erneut."
no-permission: "Sie haben keine Berechtigung, diese Aktion auszuführen."
move-document: "Beim Verschieben {count, plural, one {des Dokumentes} other {der Dokumente}} ist ein Fehler aufgetreten"

success:
delete-document: "Das Dokument wurde erfolgreich gelöscht."
Expand All @@ -27,6 +29,7 @@ alexandria:
other {Die Dokumente wurden}
} erfolgreich hochgeladen.
update: "Änderungen wurden gespeichert."
move-document: "{count, plural, one {Das Dokument wurde} other {Die Dokumente wurden}} erfolgreich verschoben"

category-nav:
all-files: "Alle Dokumente"
Expand Down
3 changes: 3 additions & 0 deletions translations/en.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ alexandria:
delete: "Delete"
upload-file: "Upload file"
download: "Download"
move-document: "Move {count} {count, plural, one {document} other {documents}}"

errors:
save-file: "While downloading the document, an error occured. Please try again."
Expand All @@ -18,6 +19,7 @@ alexandria:
}, an error occured.
update: "Your changes chould'nt be saved. Please try again."
no-permission: "You don't have permission to perform this action."
move-document: "While moving the {count, plural, one {document} other {documents}}, an error occured. Please try again."

success:
delete-document: "Document deleted successfully"
Expand All @@ -27,6 +29,7 @@ alexandria:
other {documents were}
} uploaded successfully.
update: "Changes saved."
move-document: "{count, plural, one {Document} other {Documents}} moved successfully"

category-nav:
all-files: "All documents"
Expand Down

0 comments on commit 41663c2

Please sign in to comment.