Compare commits
2 Commits
d08ca24c87
...
3dfbc64913
| Author | SHA1 | Date | |
|---|---|---|---|
| 3dfbc64913 | |||
| 73c539ba4a |
Binary file not shown.
@@ -71,10 +71,12 @@ class UiSmokeGoldenTest(unittest.TestCase):
|
|||||||
self.assertIn('id="context-menu"', body)
|
self.assertIn('id="context-menu"', body)
|
||||||
self.assertIn('id="context-menu-scope"', body)
|
self.assertIn('id="context-menu-scope"', body)
|
||||||
self.assertIn('id="context-menu-target"', body)
|
self.assertIn('id="context-menu-target"', body)
|
||||||
|
self.assertIn('id="context-menu-open-btn"', body)
|
||||||
self.assertIn('id="context-menu-rename-btn"', body)
|
self.assertIn('id="context-menu-rename-btn"', body)
|
||||||
self.assertIn('id="context-menu-copy-btn"', body)
|
self.assertIn('id="context-menu-copy-btn"', body)
|
||||||
self.assertIn('id="context-menu-move-btn"', body)
|
self.assertIn('id="context-menu-move-btn"', body)
|
||||||
self.assertIn('id="context-menu-delete-btn"', body)
|
self.assertIn('id="context-menu-delete-btn"', body)
|
||||||
|
self.assertIn('id="context-menu-properties-btn"', body)
|
||||||
self.assertIn('id="settings-btn"', body)
|
self.assertIn('id="settings-btn"', body)
|
||||||
self.assertIn('id="rename-btn"', body)
|
self.assertIn('id="rename-btn"', body)
|
||||||
self.assertIn('id="view-btn"', body)
|
self.assertIn('id="view-btn"', body)
|
||||||
@@ -211,24 +213,37 @@ class UiSmokeGoldenTest(unittest.TestCase):
|
|||||||
self.assertIn('function openContextMenu(pane, entry, event)', app_js)
|
self.assertIn('function openContextMenu(pane, entry, event)', app_js)
|
||||||
self.assertIn('function closeContextMenu()', app_js)
|
self.assertIn('function closeContextMenu()', app_js)
|
||||||
self.assertIn('function applyContextMenuSelection()', app_js)
|
self.assertIn('function applyContextMenuSelection()', app_js)
|
||||||
|
self.assertIn('function startContextMenuOpen()', app_js)
|
||||||
self.assertIn('function startContextMenuRename()', app_js)
|
self.assertIn('function startContextMenuRename()', app_js)
|
||||||
self.assertIn('function startContextMenuCopy()', app_js)
|
self.assertIn('function startContextMenuCopy()', app_js)
|
||||||
self.assertIn('function startContextMenuMove()', app_js)
|
self.assertIn('function startContextMenuMove()', app_js)
|
||||||
self.assertIn('function startContextMenuDelete()', app_js)
|
self.assertIn('function startContextMenuDelete()', app_js)
|
||||||
|
self.assertIn('function startContextMenuProperties()', app_js)
|
||||||
self.assertIn('selectedPathsSet.has(entry.path)', app_js)
|
self.assertIn('selectedPathsSet.has(entry.path)', app_js)
|
||||||
self.assertIn('entry.isParent', app_js)
|
self.assertIn('entry.isParent', app_js)
|
||||||
self.assertIn('row.oncontextmenu = (event) => {', app_js)
|
self.assertIn('row.oncontextmenu = (event) => {', app_js)
|
||||||
self.assertIn('event.target.closest("li[data-row-index]")', app_js)
|
self.assertIn('event.target.closest("li[data-row-index]")', app_js)
|
||||||
self.assertIn('if (!row) {', app_js)
|
self.assertIn('if (!row) {', app_js)
|
||||||
self.assertIn('closeContextMenu();', app_js)
|
self.assertIn('closeContextMenu();', app_js)
|
||||||
|
self.assertIn('elements.openButton.classList.toggle("hidden", isMulti);', app_js)
|
||||||
|
self.assertIn('elements.openButton.disabled = isMulti || items.length !== 1;', app_js)
|
||||||
self.assertIn('elements.renameButton.classList.toggle("hidden", isMulti);', app_js)
|
self.assertIn('elements.renameButton.classList.toggle("hidden", isMulti);', app_js)
|
||||||
self.assertIn('elements.copyButton.classList.remove("hidden");', app_js)
|
self.assertIn('elements.copyButton.classList.remove("hidden");', app_js)
|
||||||
self.assertIn('elements.copyButton.disabled = items.length === 0;', app_js)
|
self.assertIn('elements.copyButton.disabled = items.length === 0;', app_js)
|
||||||
self.assertIn('elements.moveButton.classList.remove("hidden");', app_js)
|
self.assertIn('elements.moveButton.classList.remove("hidden");', app_js)
|
||||||
|
self.assertIn('elements.propertiesButton.classList.remove("hidden");', app_js)
|
||||||
|
self.assertIn('elements.propertiesButton.disabled = items.length === 0;', app_js)
|
||||||
|
self.assertIn('openCurrentDirectory();', app_js)
|
||||||
self.assertIn('openRenamePopup();', app_js)
|
self.assertIn('openRenamePopup();', app_js)
|
||||||
self.assertIn('startCopySelected();', app_js)
|
self.assertIn('startCopySelected();', app_js)
|
||||||
self.assertIn('openF6Flow();', app_js)
|
self.assertIn('openF6Flow();', app_js)
|
||||||
self.assertIn('deleteSelected();', app_js)
|
self.assertIn('deleteSelected();', app_js)
|
||||||
|
self.assertIn('openInfo();', app_js)
|
||||||
|
self.assertIn('elements.title.textContent = "Properties";', app_js)
|
||||||
|
self.assertIn('if (selectedItems.length > 1) {', app_js)
|
||||||
|
self.assertIn('renderInfoField("Selected items", selectedItems.length);', app_js)
|
||||||
|
self.assertIn('renderInfoField("Files", fileCount);', app_js)
|
||||||
|
self.assertIn('renderInfoField("Directories", directoryCount);', app_js)
|
||||||
self.assertIn('document.getElementById("copy-btn").disabled = !hasSelection;', app_js)
|
self.assertIn('document.getElementById("copy-btn").disabled = !hasSelection;', app_js)
|
||||||
self.assertNotIn('Only files are supported for copy', app_js)
|
self.assertNotIn('Only files are supported for copy', app_js)
|
||||||
self.assertIn('document.getElementById("upload-menu-toggle").onclick = (event) => {', app_js)
|
self.assertIn('document.getElementById("upload-menu-toggle").onclick = (event) => {', app_js)
|
||||||
|
|||||||
+51
-5
@@ -326,10 +326,12 @@ function contextMenuElements() {
|
|||||||
menu: document.getElementById("context-menu"),
|
menu: document.getElementById("context-menu"),
|
||||||
scope: document.getElementById("context-menu-scope"),
|
scope: document.getElementById("context-menu-scope"),
|
||||||
target: document.getElementById("context-menu-target"),
|
target: document.getElementById("context-menu-target"),
|
||||||
|
openButton: document.getElementById("context-menu-open-btn"),
|
||||||
renameButton: document.getElementById("context-menu-rename-btn"),
|
renameButton: document.getElementById("context-menu-rename-btn"),
|
||||||
copyButton: document.getElementById("context-menu-copy-btn"),
|
copyButton: document.getElementById("context-menu-copy-btn"),
|
||||||
moveButton: document.getElementById("context-menu-move-btn"),
|
moveButton: document.getElementById("context-menu-move-btn"),
|
||||||
deleteButton: document.getElementById("context-menu-delete-btn"),
|
deleteButton: document.getElementById("context-menu-delete-btn"),
|
||||||
|
propertiesButton: document.getElementById("context-menu-properties-btn"),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -370,11 +372,15 @@ function openContextMenu(pane, entry, event) {
|
|||||||
const isMulti = items.length > 1;
|
const isMulti = items.length > 1;
|
||||||
elements.scope.textContent = isMulti ? "Multi-selection" : "Single item";
|
elements.scope.textContent = isMulti ? "Multi-selection" : "Single item";
|
||||||
elements.target.textContent = isMulti ? `${items.length} selected items` : entry.name;
|
elements.target.textContent = isMulti ? `${items.length} selected items` : entry.name;
|
||||||
|
elements.openButton.classList.toggle("hidden", isMulti);
|
||||||
|
elements.openButton.disabled = isMulti || items.length !== 1;
|
||||||
elements.renameButton.classList.toggle("hidden", isMulti);
|
elements.renameButton.classList.toggle("hidden", isMulti);
|
||||||
elements.copyButton.classList.remove("hidden");
|
elements.copyButton.classList.remove("hidden");
|
||||||
elements.copyButton.disabled = items.length === 0;
|
elements.copyButton.disabled = items.length === 0;
|
||||||
elements.moveButton.classList.remove("hidden");
|
elements.moveButton.classList.remove("hidden");
|
||||||
elements.deleteButton.classList.remove("hidden");
|
elements.deleteButton.classList.remove("hidden");
|
||||||
|
elements.propertiesButton.classList.remove("hidden");
|
||||||
|
elements.propertiesButton.disabled = items.length === 0;
|
||||||
|
|
||||||
const menuWidth = 220;
|
const menuWidth = 220;
|
||||||
const menuHeight = 120;
|
const menuHeight = 120;
|
||||||
@@ -445,6 +451,30 @@ function startContextMenuCopy() {
|
|||||||
startCopySelected();
|
startCopySelected();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function startContextMenuOpen() {
|
||||||
|
if (contextMenuElements().openButton?.disabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!applyContextMenuSelection()) {
|
||||||
|
closeContextMenu();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
closeContextMenu();
|
||||||
|
openCurrentDirectory();
|
||||||
|
}
|
||||||
|
|
||||||
|
function startContextMenuProperties() {
|
||||||
|
if (contextMenuElements().propertiesButton?.disabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!applyContextMenuSelection()) {
|
||||||
|
closeContextMenu();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
closeContextMenu();
|
||||||
|
openInfo();
|
||||||
|
}
|
||||||
|
|
||||||
function settingsElements() {
|
function settingsElements() {
|
||||||
return {
|
return {
|
||||||
overlay: document.getElementById("settings-modal"),
|
overlay: document.getElementById("settings-modal"),
|
||||||
@@ -482,6 +512,7 @@ function searchElements() {
|
|||||||
function infoElements() {
|
function infoElements() {
|
||||||
return {
|
return {
|
||||||
overlay: document.getElementById("info-modal"),
|
overlay: document.getElementById("info-modal"),
|
||||||
|
title: document.getElementById("info-title"),
|
||||||
closeButton: document.getElementById("info-close-btn"),
|
closeButton: document.getElementById("info-close-btn"),
|
||||||
error: document.getElementById("info-error"),
|
error: document.getElementById("info-error"),
|
||||||
grid: document.getElementById("info-grid"),
|
grid: document.getElementById("info-grid"),
|
||||||
@@ -2926,14 +2957,23 @@ function renderInfoField(label, value) {
|
|||||||
|
|
||||||
async function openInfo() {
|
async function openInfo() {
|
||||||
const selectedItems = activePaneState().selectedItems;
|
const selectedItems = activePaneState().selectedItems;
|
||||||
if (selectedItems.length !== 1) {
|
if (selectedItems.length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const elements = infoElements();
|
||||||
|
elements.overlay.classList.remove("hidden");
|
||||||
|
elements.title.textContent = "Properties";
|
||||||
|
elements.error.textContent = "";
|
||||||
|
elements.grid.innerHTML = "";
|
||||||
|
if (selectedItems.length > 1) {
|
||||||
|
const fileCount = selectedItems.filter((item) => item.kind === "file").length;
|
||||||
|
const directoryCount = selectedItems.filter((item) => item.kind === "directory").length;
|
||||||
|
renderInfoField("Selected items", selectedItems.length);
|
||||||
|
renderInfoField("Files", fileCount);
|
||||||
|
renderInfoField("Directories", directoryCount);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const selected = selectedItems[0];
|
const selected = selectedItems[0];
|
||||||
const elements = infoElements();
|
|
||||||
elements.overlay.classList.remove("hidden");
|
|
||||||
elements.error.textContent = "";
|
|
||||||
elements.grid.innerHTML = "";
|
|
||||||
try {
|
try {
|
||||||
const data = await apiRequest("GET", `/api/files/info?${new URLSearchParams({ path: selected.path }).toString()}`);
|
const data = await apiRequest("GET", `/api/files/info?${new URLSearchParams({ path: selected.path }).toString()}`);
|
||||||
renderInfoField("Name", data.name);
|
renderInfoField("Name", data.name);
|
||||||
@@ -3763,6 +3803,9 @@ function setupEvents() {
|
|||||||
if (contextMenu.renameButton) {
|
if (contextMenu.renameButton) {
|
||||||
contextMenu.renameButton.onclick = startContextMenuRename;
|
contextMenu.renameButton.onclick = startContextMenuRename;
|
||||||
}
|
}
|
||||||
|
if (contextMenu.openButton) {
|
||||||
|
contextMenu.openButton.onclick = startContextMenuOpen;
|
||||||
|
}
|
||||||
if (contextMenu.copyButton) {
|
if (contextMenu.copyButton) {
|
||||||
contextMenu.copyButton.onclick = startContextMenuCopy;
|
contextMenu.copyButton.onclick = startContextMenuCopy;
|
||||||
}
|
}
|
||||||
@@ -3772,6 +3815,9 @@ function setupEvents() {
|
|||||||
if (contextMenu.deleteButton) {
|
if (contextMenu.deleteButton) {
|
||||||
contextMenu.deleteButton.onclick = startContextMenuDelete;
|
contextMenu.deleteButton.onclick = startContextMenuDelete;
|
||||||
}
|
}
|
||||||
|
if (contextMenu.propertiesButton) {
|
||||||
|
contextMenu.propertiesButton.onclick = startContextMenuProperties;
|
||||||
|
}
|
||||||
document.addEventListener("click", (event) => {
|
document.addEventListener("click", (event) => {
|
||||||
const elements = uploadElements();
|
const elements = uploadElements();
|
||||||
if (!elements.menu || elements.menu.contains(event.target)) {
|
if (!elements.menu || elements.menu.contains(event.target)) {
|
||||||
|
|||||||
@@ -122,10 +122,12 @@
|
|||||||
<div id="context-menu-scope" class="context-menu-scope"></div>
|
<div id="context-menu-scope" class="context-menu-scope"></div>
|
||||||
<div id="context-menu-target" class="context-menu-target"></div>
|
<div id="context-menu-target" class="context-menu-target"></div>
|
||||||
<div class="context-menu-separator"></div>
|
<div class="context-menu-separator"></div>
|
||||||
|
<button id="context-menu-open-btn" type="button" role="menuitem">Open</button>
|
||||||
<button id="context-menu-rename-btn" type="button" role="menuitem">Rename</button>
|
<button id="context-menu-rename-btn" type="button" role="menuitem">Rename</button>
|
||||||
<button id="context-menu-copy-btn" type="button" role="menuitem">Copy</button>
|
<button id="context-menu-copy-btn" type="button" role="menuitem">Copy</button>
|
||||||
<button id="context-menu-move-btn" type="button" role="menuitem">Move</button>
|
<button id="context-menu-move-btn" type="button" role="menuitem">Move</button>
|
||||||
<button id="context-menu-delete-btn" type="button" role="menuitem">Delete</button>
|
<button id="context-menu-delete-btn" type="button" role="menuitem">Delete</button>
|
||||||
|
<button id="context-menu-properties-btn" type="button" role="menuitem">Properties</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="settings-modal" class="popup-overlay hidden" role="dialog" aria-modal="true" aria-labelledby="settings-title">
|
<div id="settings-modal" class="popup-overlay hidden" role="dialog" aria-modal="true" aria-labelledby="settings-title">
|
||||||
|
|||||||
Reference in New Issue
Block a user