Merge branch 'dev'
This commit is contained in:
commit
9533a71b42
|
|
@ -264,9 +264,17 @@ function autoResolveSpace(token: string, username: string): void {
|
|||
|
||||
// Detect current space
|
||||
const currentSpace = _getCurrentSpace();
|
||||
if (currentSpace !== "demo") return; // Already on a non-demo space
|
||||
|
||||
// Provision personal space and redirect
|
||||
if (currentSpace !== "demo") {
|
||||
// User followed a link to a specific space (e.g., orgname.rspace.online).
|
||||
// Provision their personal space silently, then reload to apply the
|
||||
// authenticated session (clears access gates, reconnects CRDT sync, etc.).
|
||||
autoProvisionSpace(token);
|
||||
window.location.reload();
|
||||
return;
|
||||
}
|
||||
|
||||
// On demo/landing — provision personal space and redirect there
|
||||
fetch("/api/spaces/auto-provision", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
|
|
|
|||
|
|
@ -6685,31 +6685,53 @@
|
|||
function showBulkDeleteConfirm(count) {
|
||||
if (bulkDeleteOverlay) return; // prevent stacking from key repeat
|
||||
const overlay = document.createElement("div");
|
||||
overlay.style.cssText = "position:fixed;inset:0;background:rgba(0,0,0,0.6);z-index:10000;display:flex;align-items:center;justify-content:center";
|
||||
overlay.style.cssText = "position:fixed;inset:0;background:rgba(0,0,0,0.6);z-index:100002;display:flex;align-items:center;justify-content:center;touch-action:manipulation";
|
||||
const dialog = document.createElement("div");
|
||||
dialog.style.cssText = "background:var(--rs-bg-surface,#1e1b4b);border:1px solid var(--rs-border,#334155);border-radius:12px;padding:1.5rem 2rem;max-width:380px;text-align:center;color:var(--rs-text-primary,#e2e8f0);font-family:system-ui,sans-serif";
|
||||
dialog.style.cssText = "background:var(--rs-bg-surface,#1e1b4b);border:1px solid var(--rs-border,#334155);border-radius:12px;padding:1.5rem 2rem;max-width:380px;text-align:center;color:var(--rs-text-primary,#e2e8f0);font-family:system-ui,sans-serif;user-select:none";
|
||||
const btnBase = "padding:0.5rem 1.25rem;border-radius:8px;cursor:pointer;font-size:0.875rem;touch-action:manipulation;user-select:none;-webkit-tap-highlight-color:transparent;transition:filter 0.1s";
|
||||
dialog.innerHTML = `
|
||||
<h3 style="margin:0 0 0.5rem;font-size:1.125rem">Delete ${count} elements?</h3>
|
||||
<p style="color:var(--rs-text-secondary,#94a3b8);font-size:0.875rem;margin:0 0 1.25rem;line-height:1.5">You are about to delete a large number of elements. This action cannot be easily undone.</p>
|
||||
<div style="display:flex;gap:0.75rem;justify-content:center">
|
||||
<button id="bulk-delete-cancel" style="padding:0.5rem 1.25rem;border-radius:8px;border:1px solid var(--rs-border,#334155);background:transparent;color:var(--rs-text-primary,#e2e8f0);cursor:pointer;font-size:0.875rem">Cancel</button>
|
||||
<button id="bulk-delete-confirm" style="padding:0.5rem 1.25rem;border-radius:8px;border:1px solid #dc2626;background:#dc2626;color:#fff;cursor:pointer;font-size:0.875rem;font-weight:600">DELETE</button>
|
||||
<button id="bulk-delete-cancel" style="${btnBase};border:1px solid var(--rs-border,#334155);background:transparent;color:var(--rs-text-primary,#e2e8f0)">Cancel</button>
|
||||
<button id="bulk-delete-confirm" style="${btnBase};border:1px solid #dc2626;background:#dc2626;color:#fff;font-weight:600">DELETE</button>
|
||||
</div>`;
|
||||
overlay.appendChild(dialog);
|
||||
document.body.appendChild(overlay);
|
||||
bulkDeleteOverlay = overlay;
|
||||
|
||||
overlay.addEventListener("click", (e) => { if (e.target === overlay) dismissBulkDelete(); });
|
||||
dialog.querySelector("#bulk-delete-cancel").addEventListener("click", dismissBulkDelete);
|
||||
dialog.querySelector("#bulk-delete-confirm").addEventListener("click", () => {
|
||||
const cancelBtn = dialog.querySelector("#bulk-delete-cancel");
|
||||
const confirmBtn = dialog.querySelector("#bulk-delete-confirm");
|
||||
|
||||
// Use pointerdown for instant response (no 300ms click delay on touch)
|
||||
overlay.addEventListener("pointerdown", (e) => {
|
||||
if (e.target === overlay) { e.stopPropagation(); dismissBulkDelete(); }
|
||||
});
|
||||
cancelBtn.addEventListener("pointerdown", (e) => {
|
||||
e.stopPropagation();
|
||||
dismissBulkDelete();
|
||||
});
|
||||
confirmBtn.addEventListener("pointerdown", (e) => {
|
||||
e.stopPropagation();
|
||||
dismissBulkDelete();
|
||||
doDeleteSelected();
|
||||
});
|
||||
|
||||
// Visual feedback on hover/active
|
||||
[cancelBtn, confirmBtn].forEach(btn => {
|
||||
btn.addEventListener("pointerenter", () => { btn.style.filter = "brightness(1.2)"; });
|
||||
btn.addEventListener("pointerleave", () => { btn.style.filter = ""; });
|
||||
btn.addEventListener("pointerdown", () => { btn.style.filter = "brightness(0.85)"; });
|
||||
});
|
||||
|
||||
// Escape key closes dialog
|
||||
const escHandler = (e) => {
|
||||
if (e.key === "Escape") { dismissBulkDelete(); document.removeEventListener("keydown", escHandler); }
|
||||
};
|
||||
document.addEventListener("keydown", escHandler);
|
||||
|
||||
// Focus the confirm button so Enter also works
|
||||
confirmBtn.focus();
|
||||
}
|
||||
|
||||
// ── Canvas pointer interaction: pan-first + hold-to-select ──
|
||||
|
|
|
|||
Loading…
Reference in New Issue