mirror of
https://github.com/we-promise/sure.git
synced 2026-04-07 14:31:25 +00:00
feat: Display dashboard as a 2-columns grid on big screens (#1000)
* feat: display 2 columns grid in dashboard for wide screens * fix: update sortable controller to consider X/Y coordinates * fix: lint issues + missing variable init
This commit is contained in:
@@ -12,6 +12,7 @@ export default class extends Controller {
|
||||
this.draggedElement = null;
|
||||
this.placeholder = null;
|
||||
this.touchStartY = 0;
|
||||
this.currentTouchX = 0;
|
||||
this.currentTouchY = 0;
|
||||
this.isTouching = false;
|
||||
this.keyboardGrabbedElement = null;
|
||||
@@ -37,7 +38,7 @@ export default class extends Controller {
|
||||
event.preventDefault();
|
||||
event.dataTransfer.dropEffect = "move";
|
||||
|
||||
const afterElement = this.getDragAfterElement(event.clientY);
|
||||
const afterElement = this.getDragAfterElement(event.clientX, event.clientY);
|
||||
const container = this.element;
|
||||
|
||||
this.clearPlaceholders();
|
||||
@@ -53,7 +54,7 @@ export default class extends Controller {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
const afterElement = this.getDragAfterElement(event.clientY);
|
||||
const afterElement = this.getDragAfterElement(event.clientX, event.clientY);
|
||||
const container = this.element;
|
||||
|
||||
if (afterElement == null) {
|
||||
@@ -81,7 +82,9 @@ export default class extends Controller {
|
||||
if (section.getAttribute("draggable") === "false") return;
|
||||
|
||||
this.pendingSection = section;
|
||||
this.touchStartX = event.touches[0].clientX;
|
||||
this.touchStartY = event.touches[0].clientY;
|
||||
this.currentTouchX = this.touchStartX;
|
||||
this.currentTouchY = this.touchStartY;
|
||||
this.holdActivated = false;
|
||||
|
||||
@@ -110,9 +113,10 @@ export default class extends Controller {
|
||||
if (!this.holdActivated || !this.isTouching || !this.draggedElement) return;
|
||||
|
||||
event.preventDefault();
|
||||
this.currentTouchX = event.touches[0].clientX;
|
||||
this.currentTouchY = event.touches[0].clientY;
|
||||
|
||||
const afterElement = this.getDragAfterElement(this.currentTouchY);
|
||||
const afterElement = this.getDragAfterElement(this.currentTouchX, this.currentTouchY);
|
||||
this.clearPlaceholders();
|
||||
|
||||
if (afterElement == null) {
|
||||
@@ -130,7 +134,7 @@ export default class extends Controller {
|
||||
return;
|
||||
}
|
||||
|
||||
const afterElement = this.getDragAfterElement(this.currentTouchY);
|
||||
const afterElement = this.getDragAfterElement(this.currentTouchX, this.currentTouchY);
|
||||
const container = this.element;
|
||||
|
||||
if (afterElement == null) {
|
||||
@@ -240,23 +244,32 @@ export default class extends Controller {
|
||||
}
|
||||
}
|
||||
|
||||
getDragAfterElement(y) {
|
||||
const draggableElements = [
|
||||
...this.sectionTargets.filter((section) => section !== this.draggedElement),
|
||||
];
|
||||
getDragAfterElement(pointerX, pointerY) {
|
||||
const draggableElements = this.sectionTargets.filter(
|
||||
(section) => section !== this.draggedElement,
|
||||
);
|
||||
|
||||
return draggableElements.reduce(
|
||||
(closest, child) => {
|
||||
const box = child.getBoundingClientRect();
|
||||
const offset = y - box.top - box.height / 2;
|
||||
if (draggableElements.length === 0) return null;
|
||||
|
||||
if (offset < 0 && offset > closest.offset) {
|
||||
return { offset: offset, element: child };
|
||||
}
|
||||
return closest;
|
||||
},
|
||||
{ offset: Number.NEGATIVE_INFINITY },
|
||||
).element;
|
||||
let closest = null;
|
||||
let minDistance = Number.POSITIVE_INFINITY;
|
||||
|
||||
draggableElements.forEach((child) => {
|
||||
const rect = child.getBoundingClientRect();
|
||||
const centerX = rect.left + rect.width / 2;
|
||||
const centerY = rect.top + rect.height / 2;
|
||||
|
||||
const dx = pointerX - centerX;
|
||||
const dy = pointerY - centerY;
|
||||
const distance = Math.sqrt(dx * dx + dy * dy);
|
||||
|
||||
if (distance < minDistance) {
|
||||
minDistance = distance;
|
||||
closest = child;
|
||||
}
|
||||
});
|
||||
|
||||
return closest;
|
||||
}
|
||||
|
||||
showPlaceholder(element, position) {
|
||||
|
||||
@@ -126,7 +126,7 @@ end %>
|
||||
<% end %>
|
||||
|
||||
<%# SHARED - Main content %>
|
||||
<%= tag.main class: class_names("grow overflow-y-auto px-3 lg:px-10 w-full mx-auto max-w-5xl"), data: { app_layout_target: "content", viewport_target: "content" } do %>
|
||||
<%= tag.main class: class_names("grow overflow-y-auto px-3 lg:px-10 w-full mx-auto"), data: { app_layout_target: "content", viewport_target: "content" } do %>
|
||||
<% unless intro_mode %>
|
||||
<div class="hidden lg:flex gap-2 items-center justify-between mb-6 sticky top-0 z-10 -mx-3 lg:-mx-10 px-3 lg:px-10 py-4 bg-surface border-b border-tertiary">
|
||||
<div class="flex items-center gap-2">
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<div class="w-full space-y-6 pb-6 lg:pb-12" data-controller="dashboard-sortable" data-action="dragover->dashboard-sortable#dragOver drop->dashboard-sortable#drop" role="list" aria-label="Dashboard sections">
|
||||
<div class="grid grid-cols-1 2xl:grid-cols-2 gap-6 pb-6 lg:pb-12" data-controller="dashboard-sortable" data-action="dragover->dashboard-sortable#dragOver drop->dashboard-sortable#drop" role="list" aria-label="Dashboard sections">
|
||||
<% if Current.family.accounts.any? %>
|
||||
<% @dashboard_sections.each do |section| %>
|
||||
<% next unless section[:visible] %>
|
||||
|
||||
Reference in New Issue
Block a user