Skip to content

Commit

Permalink
optimize code
Browse files Browse the repository at this point in the history
  • Loading branch information
zhouwenxuan authored and zhouwenxuan committed Dec 13, 2024
1 parent e385ec6 commit 7b2750e
Show file tree
Hide file tree
Showing 11 changed files with 164 additions and 305 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
display: block;
opacity: 1;
box-shadow: 0 0 5px #ccc;
position: fixed;
position: absolute;
}
Original file line number Diff line number Diff line change
@@ -1,50 +1,18 @@
import React, { useState, useRef, useEffect, useCallback, useMemo } from 'react';
import React, { useState, useRef, useEffect, useCallback } from 'react';
import PropTypes from 'prop-types';
import { gettext } from '../../../../utils/constants';
import './index.css';

const OPERATION = {
DOWNLOAD: 'download',
DELETE: 'delete',
};

const ContextMenu = ({ getContentRect, getContainerRect, onDownload, onDelete }) => {
const ContextMenu = ({ options, getContainerRect, getContentRect, onOptionClick, validTargets }) => {
const menuRef = useRef(null);
const [visible, setVisible] = useState(false);
const [position, setPosition] = useState({ top: 0, left: 0 });

const options = useMemo(() => {
if (!visible) return [];
return [
{ value: OPERATION.DOWNLOAD, label: gettext('Download') },
{ value: OPERATION.DELETE, label: gettext('Delete') }
];
}, [visible]);

const handleHide = useCallback((event) => {
if (menuRef.current && !menuRef.current.contains(event.target)) {
setVisible(false);
}
}, [menuRef]);

const handleOptionClick = useCallback((event, option) => {
event.stopPropagation();
switch (option.value) {
case OPERATION.DOWNLOAD: {
onDownload && onDownload();
break;
}
case OPERATION.DELETE: {
onDelete && onDelete();
break;
}
default: {
break;
}
}
setVisible(false);
}, [onDownload, onDelete]);

const getMenuPosition = useCallback((x = 0, y = 0) => {
let menuStyles = {
top: y,
Expand Down Expand Up @@ -77,7 +45,7 @@ const ContextMenu = ({ getContentRect, getContainerRect, onDownload, onDelete })
event.preventDefault();
if (menuRef.current && menuRef.current.contains(event.target)) return;

if (event.target.tagName.toLowerCase() !== 'img') {
if (validTargets && !validTargets.some(target => event.target.closest(target))) {
return;
}

Expand All @@ -92,8 +60,7 @@ const ContextMenu = ({ getContentRect, getContainerRect, onDownload, onDelete })
return () => {
document.removeEventListener('contextmenu', handleShow);
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
}, [getMenuPosition, validTargets]);

useEffect(() => {
if (visible) {
Expand All @@ -120,7 +87,11 @@ const ContextMenu = ({ getContentRect, getContainerRect, onDownload, onDelete })
<button
key={index}
className='dropdown-item sf-metadata-contextmenu-item'
onClick={(event) => handleOptionClick(event, option)}
onClick={(event) => {
event.stopPropagation();
onOptionClick(option);
setVisible(false);
}}
>
{option.label}
</button>
Expand All @@ -130,10 +101,14 @@ const ContextMenu = ({ getContentRect, getContainerRect, onDownload, onDelete })
};

ContextMenu.propTypes = {
getContentRect: PropTypes.func.isRequired,
options: PropTypes.arrayOf(PropTypes.shape({
value: PropTypes.string.isRequired,
label: PropTypes.string.isRequired,
})).isRequired,
getContainerRect: PropTypes.func.isRequired,
onDownload: PropTypes.func,
onDelete: PropTypes.func,
getContentRect: PropTypes.func.isRequired,
onOptionClick: PropTypes.func.isRequired,
validTargets: PropTypes.array,
};

export default ContextMenu;
27 changes: 27 additions & 0 deletions frontend/src/metadata/utils/row/core.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import { siteRoot } from '../../../utils/constants';
import URLDecorator from '../../../utils/url-decorator';

Check warning on line 2 in frontend/src/metadata/utils/row/core.js

View workflow job for this annotation

GitHub Actions / build

'URLDecorator' is defined but never used
import { Utils } from '../../../utils/utils';
import { PRIVATE_COLUMN_KEY } from '../../constants';
import { getFileNameFromRecord, getParentDirFromRecord } from '../cell';
import { getTableById } from '../table';

/**
Expand Down Expand Up @@ -35,6 +39,29 @@ export const checkIsDir = (record) => {
return isDir;
};

export const openInNewTab = (record) => {
const repoID = window.sfMetadataStore.repoId;
const isDir = checkIsDir(record);
const parentDir = getParentDirFromRecord(record);
const name = getFileNameFromRecord(record);
const url = isDir
? window.location.origin + window.location.pathname + Utils.encodePath(Utils.joinPath(parentDir, name))
: `${siteRoot}lib/${repoID}/file${Utils.encodePath(Utils.joinPath(parentDir, name))}`;

window.open(url, '_blank');
};

export const openParentFolder = (record) => {
let parentDir = getParentDirFromRecord(record);

if (window.location.pathname.endsWith('/')) {
parentDir = parentDir.slice(1);
}

const url = window.location.origin + window.location.pathname + Utils.encodePath(parentDir);
window.open(url, '_blank');
};

export {
isTableRows,
updateTableRowsWithRowsData,
Expand Down
42 changes: 36 additions & 6 deletions frontend/src/metadata/views/gallery/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,17 @@ import metadataAPI from '../../api';
import URLDecorator from '../../../utils/url-decorator';
import toaster from '../../../components/toast';
import Content from './content';
import ContextMenu from './context-menu';
import ImageDialog from '../../../components/dialog/image-dialog';
import ZipDownloadDialog from '../../../components/dialog/zip-download-dialog';
import ModalPortal from '../../../components/modal-portal';
import { useMetadataView } from '../../hooks/metadata-view';
import { Utils } from '../../../utils/utils';
import { getDateDisplayString, getFileNameFromRecord, getParentDirFromRecord } from '../../utils/cell';
import { siteRoot, fileServerRoot, useGoFileserver, thumbnailSizeForGrid, thumbnailSizeForOriginal } from '../../../utils/constants';
import { siteRoot, fileServerRoot, useGoFileserver, thumbnailSizeForGrid, thumbnailSizeForOriginal, gettext } from '../../../utils/constants';
import { EVENT_BUS_TYPE, PRIVATE_COLUMN_KEY, GALLERY_DATE_MODE, DATE_TAG_HEIGHT, GALLERY_IMAGE_GAP } from '../../constants';
import { getRowById } from '../../utils/table';
import { getEventClassName } from '../../utils/common';
import ContextMenu from '../../components/context-menu';

import './index.css';

Expand Down Expand Up @@ -340,6 +340,35 @@ const Main = ({ isLoadingMore, metadata, onDelete, onLoadMore }) => {
}
}, [handleImageSelection, updateSelectedImage]);

const options = useMemo(() => {
return [
{ value: 'download', label: gettext('Download') },
{ value: 'delete', label: gettext('Delete') }
];
}, []);

const handleOptionClick = useCallback(option => {
switch (option.value) {
case 'download':
handleDownload();
break;
case 'delete':
handleDelete();
break;
default:
break;
}
}, [handleDownload, handleDelete]);

const getContainerRect = useCallback(() => {
return containerRef.current.getBoundingClientRect();
}, []);

const getContentRect = useCallback(() => {
const { clientWidth, clientHeight } = containerRef.current;
return { right: clientWidth, bottom: clientHeight };
}, []);

return (
<>
<div
Expand Down Expand Up @@ -372,10 +401,11 @@ const Main = ({ isLoadingMore, metadata, onDelete, onLoadMore }) => {
)}
</div>
<ContextMenu
getContentRect={() => containerRef.current.getBoundingClientRect()}
getContainerRect={() => containerRef.current.getBoundingClientRect()}
onDownload={handleDownload}
onDelete={handleDelete}
options={options}
onOptionClick={handleOptionClick}
getContainerRect={getContainerRect}
getContentRect={getContentRect}
validTargets={['.metadata-gallery-image-item', '.metadata-gallery-grid-image']}
/>
{isImagePopupOpen && (
<ModalPortal>
Expand Down
6 changes: 3 additions & 3 deletions frontend/src/metadata/views/kanban/boards/board/card/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const Card = ({
displayColumns,
onOpenFile,
onSelectCard,
onRightClick,
onContextMenu,
}) => {
const titleValue = getCellValueByColumn(record, titleColumn);

Expand All @@ -42,7 +42,7 @@ const Card = ({
data-id={record._id}
className={classnames('sf-metadata-kanban-card', { 'selected': isSelected })}
onClick={handleClickCard}
onContextMenu={onRightClick}
onContextMenu={onContextMenu}
>
{titleColumn && (
<div className="sf-metadata-kanban-card-header" onClick={handleClickFilename}>
Expand Down Expand Up @@ -84,7 +84,7 @@ Card.propTypes = {
displayColumns: PropTypes.array,
onOpenFile: PropTypes.func.isRequired,
onSelectCard: PropTypes.func.isRequired,
onRightClick: PropTypes.func.isRequired,
onContextMenu: PropTypes.func.isRequired,
};

export default Card;
6 changes: 3 additions & 3 deletions frontend/src/metadata/views/kanban/boards/board/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ const Board = ({
onOpenFile,
onSelectCard,
updateDragging,
onRightClick,
onContextMenu,
}) => {
const [isDraggingOver, setDraggingOver] = useState(false);
const boardName = useMemo(() => `sf_metadata_kanban_board_${board.key}`, [board]);
Expand Down Expand Up @@ -94,7 +94,7 @@ const Board = ({
displayColumns={displayColumns}
onOpenFile={onOpenFile}
onSelectCard={onSelectCard}
onRightClick={(e) => onRightClick(e, recordId)}
onContextMenu={(e) => onContextMenu(e, recordId)}
/>
);
if (readonly) return CardElement;
Expand Down Expand Up @@ -127,7 +127,7 @@ Board.propTypes = {
onOpenFile: PropTypes.func.isRequired,
onSelectCard: PropTypes.func.isRequired,
updateDragging: PropTypes.func.isRequired,
onRightClick: PropTypes.func,
onContextMenu: PropTypes.func,
};

export default Board;
Loading

0 comments on commit 7b2750e

Please sign in to comment.