From 8167c2ddb38108485cff24be03b659e451ed8135 Mon Sep 17 00:00:00 2001 From: Jelle van der Waa Date: Thu, 1 Feb 2024 14:23:35 +0100 Subject: [PATCH] Move ContextMenu to the CardBody The ContextMenu has nothing to do with the main app, it appears in the `CardBody` or better said DirectoryView. This allows us to later to consolidate the event listeners and if the ContextMenu should be shown to the NavigatorCardBody instead of the app itself. Note: later rename CardBody to DirectoryView. --- src/app.jsx | 100 ++--------------------- src/navigator-card-body.jsx | 153 +++++++++++++++++++++++++++++++++--- 2 files changed, 147 insertions(+), 106 deletions(-) diff --git a/src/app.jsx b/src/app.jsx index 49c3bb58e..360f3e79e 100644 --- a/src/app.jsx +++ b/src/app.jsx @@ -19,36 +19,27 @@ import cockpit from "cockpit"; import { superuser } from "superuser"; -import { useDialogs } from "dialogs.jsx"; import React, { useEffect, useState } from "react"; import { Card, - MenuItem, MenuList, Page, PageSection, Sidebar, SidebarPanel, SidebarContent, - Divider, AlertGroup, Alert, AlertActionCloseButton + AlertGroup, Alert, AlertActionCloseButton } from "@patternfly/react-core"; import { ExclamationCircleIcon } from "@patternfly/react-icons"; import { EmptyStatePanel } from "cockpit-components-empty-state.jsx"; -import { ContextMenu } from "./navigatorContextMenu.jsx"; import { NavigatorBreadcrumbs } from "./navigatorBreadcrumbs.jsx"; import { NavigatorCardBody } from "./navigator-card-body.jsx"; -import { - copyItem, createDirectory, createLink, deleteItem, editPermissions, pasteItem, renameItem -} from "./fileActions.jsx"; import { SidebarPanelDetails } from "./sidebar.jsx"; import { NavigatorCardHeader } from "./header.jsx"; import { usePageLocation } from "hooks.js"; import { fsinfo } from "./fsinfo"; -const _ = cockpit.gettext; - superuser.reload_page_on_change(); export const Application = () => { const { options } = usePageLocation(); - const Dialogs = useDialogs(); const [loading, setLoading] = useState(true); const [loadingFiles, setLoadingFiles] = useState(true); const [errorMessage, setErrorMessage] = useState(); @@ -120,87 +111,9 @@ export const Application = () => { ? files.filter(file => !file.name.startsWith(".")) : files; - const _createDirectory = () => createDirectory(Dialogs, currentDir, selectedContext || selected); - const _createLink = () => createLink(Dialogs, currentDir, files, selectedContext); - const _copyItem = () => { - copyItem(setClipboard, selected.length > 1 - ? selected.map(s => currentDir + s.name) - : [currentDir + selectedContext.name]); - }; - const _pasteItem = (targetPath, asSymlink) => pasteItem(clipboard, targetPath.join("/") + "/", asSymlink, addAlert); - const _renameItem = () => renameItem(Dialogs, { selected: selectedContext, path, setHistory, setHistoryIndex }); - const _editPermissions = () => editPermissions(Dialogs, { selected: selectedContext || rootInfo, path }); - const _deleteItem = () => { - deleteItem( - Dialogs, - { - selected, - itemPath: currentDir + selectedContext.name, - setHistory, - setHistoryIndex, - path: currentDir, - setSelected - } - ); - }; - const addAlert = (title, variant, key) => setAlerts(prevAlerts => [...prevAlerts, { title, variant, key }]); const removeAlert = (key) => setAlerts(prevAlerts => [...prevAlerts.filter(alert => alert.key !== key)]); - const contextMenuItems = ( - - { - (!selectedContext - ? [ - // eslint-disable-next-line max-len - { title: _("Paste"), onClick: () => _pasteItem(path, false), isDisabled: clipboard === undefined }, - { - title: _("Paste as symlink"), - onClick: () => _pasteItem(path, true), - isDisabled: clipboard === undefined - }, - { type: "divider" }, - { title: _("Create directory"), onClick: _createDirectory }, - { title: _("Create link"), onClick: _createLink }, - { type: "divider" }, - { title: _("Edit permissions"), onClick: _editPermissions } - ] - : selected.length > 1 && selected.includes(selectedContext) - // eslint-disable-next-line max-len - ? [{ title: _("Copy"), onClick: _copyItem }, { title: _("Delete"), onClick: _deleteItem, className: "pf-m-danger" }] - : [ - { title: _("Copy"), onClick: _copyItem }, - ...(selectedContext.type === "dir") - ? [ - { - title: _("Paste into directory"), - onClick: () => _pasteItem([...path, selectedContext.name], false), - isDisabled: clipboard === undefined - } - ] - : [], - { type: "divider" }, - { title: _("Edit permissions"), onClick: _editPermissions }, - { title: _("Rename"), onClick: _renameItem }, - { type: "divider" }, - { title: _("Create link"), onClick: _createLink }, - { type: "divider" }, - { title: cockpit.format(_("Delete")), onClick: _deleteItem, className: "pf-m-danger" }, - ]) - .map((item, i) => item.type !== "divider" - ? ( - -
{item.title}
-
- ) - : ) - } -
- ); - return ( { currentDir={currentDir} isGrid={isGrid} sortBy={sortBy} selected={selected} setSelected={setSelected} + selectedContext={selectedContext} setSelectedContext={setSelectedContext} setHistory={setHistory} setHistoryIndex={setHistoryIndex} historyIndex={historyIndex} loadingFiles={loadingFiles} + clipboard={clipboard} + setClipboard={setClipboard} + addAlert={addAlert} + rootInfo={rootInfo} + allFiles={files} /> - {!loadingFiles && - } {alerts.map(alert => ( { @@ -75,7 +82,91 @@ const compare = (sortBy) => { } }; +// eslint-disable-next-line max-len +const ContextMenuItems = ({ path, currentDir, selected, selectedContext, setSelected, setHistory, setHistoryIndex, addAlert, rootInfo, clipboard, setClipboard, files }) => { + const Dialogs = useDialogs(); + + const _createDirectory = () => createDirectory(Dialogs, currentDir, selectedContext || selected); + const _createLink = () => createLink(Dialogs, currentDir, files, selectedContext); + const _copyItem = () => { + copyItem(setClipboard, selected.length > 1 + ? selected.map(s => currentDir + s.name) + : [currentDir + selectedContext.name]); + }; + const _pasteItem = (targetPath, asSymlink) => pasteItem(clipboard, targetPath.join("/") + "/", asSymlink, addAlert); + const _renameItem = () => renameItem(Dialogs, { selected: selectedContext, path, setHistory, setHistoryIndex }); + const _editPermissions = () => editPermissions(Dialogs, { selected: selectedContext || rootInfo, path }); + const _deleteItem = () => { + deleteItem( + Dialogs, + { + selected, + itemPath: currentDir + selectedContext.name, + setHistory, + setHistoryIndex, + path: currentDir, + setSelected + } + ); + }; + + return ( + + { + (!selectedContext + ? [ + // eslint-disable-next-line max-len + { title: _("Paste"), onClick: () => _pasteItem(path, false), isDisabled: clipboard === undefined }, + { + title: _("Paste as symlink"), + onClick: () => _pasteItem(path, true), + isDisabled: clipboard === undefined + }, + { type: "divider" }, + { title: _("Create directory"), onClick: _createDirectory }, + { title: _("Create link"), onClick: _createLink }, + { type: "divider" }, + { title: _("Edit permissions"), onClick: _editPermissions } + ] + : selected.length > 1 && selected.includes(selectedContext) + // eslint-disable-next-line max-len + ? [{ title: _("Copy"), onClick: _copyItem }, { title: _("Delete"), onClick: _deleteItem, className: "pf-m-danger" }] + : [ + { title: _("Copy"), onClick: _copyItem }, + ...(selectedContext.type === "dir") + ? [ + { + title: _("Paste into directory"), + onClick: () => _pasteItem([...path, selectedContext.name], false), + isDisabled: clipboard === undefined + } + ] + : [], + { type: "divider" }, + { title: _("Edit permissions"), onClick: _editPermissions }, + { title: _("Rename"), onClick: _renameItem }, + { type: "divider" }, + { title: _("Create link"), onClick: _createLink }, + { type: "divider" }, + { title: cockpit.format(_("Delete")), onClick: _deleteItem, className: "pf-m-danger" }, + ]) + .map((item, i) => item.type !== "divider" + ? ( + +
{item.title}
+
+ ) + : ) + } +
+ ); +}; + export const NavigatorCardBody = ({ + currentDir, currentFilter, files, historyIndex, @@ -87,7 +178,13 @@ export const NavigatorCardBody = ({ setSelected, setSelectedContext, sortBy, - loadingFiles + loadingFiles, + clipboard, + setClipboard, + addAlert, + allFiles, + selectedContext, + rootInfo, }) => { const [boxPerRow, setBoxPerRow] = useState(0); const Dialogs = useDialogs(); @@ -280,23 +377,53 @@ export const NavigatorCardBody = ({ ); + + const contextMenu = ( + + } + setSelectedContext={setSelectedContext} + /> + ); + if (isGrid) { return ( - - - {sortedFiles.map(file => )} - - + <> + {contextMenu} + + + {sortedFiles.map(file => )} + + + ); } else { return ( - ({ columns: [{ title: }] }))} - /> + <> + {contextMenu} + ({ columns: [{ title: }] }))} + /> + ); } };