1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-09-08 02:10:24 +00:00

open file

This commit is contained in:
zhouwenxuan
2024-11-14 14:18:25 +08:00
committed by 杨国璇
parent 0b30d895f3
commit 160dc2b447
5 changed files with 128 additions and 17 deletions

View File

@@ -135,3 +135,9 @@ export const GALLERY_DATE_MODE = {
};
export const UNCATEGORIZED = '_uncategorized';
export const FILE_TYPE = {
MARKDOWN: 'markdown',
SDOC: 'sdoc',
IMAGE: 'image',
};

View File

@@ -9,6 +9,7 @@
display: flex;
flex-direction: column;
overflow: hidden;
user-select: none;
}
.sf-metadata-kanban-card:hover {
@@ -16,6 +17,10 @@
box-shadow: 0 0 6px #0000002e;
}
.sf-metadata-kanban-card.readonly {
cursor: default;
}
.sf-metadata-kanban-card .sf-metadata-kanban-card-header {
font-weight: 500;
width: 100%;
@@ -34,10 +39,6 @@
margin-bottom: 0;
}
.sf-metadata-kanban-card .sf-metadata-kanban-card-record .file-name-formatter-wrapper {
width: fit-content;
}
.sf-metadata-kanban-card .sf-metadata-kanban-card-record .sf-metadata-kanban-card-record-name {
margin-bottom: 4px;
color: #666;
@@ -76,7 +77,7 @@
}
.sf-metadata-kanban-card .sf-metadata-special-file-name-formatter:not(.sf-metadata-image-file-formatter) {
margin-left: -2px;
transform: translateX(-2px)
}
.sf-metadata-kanban-card .file-name-formatter .sf-metadata-file-icon {
@@ -89,6 +90,7 @@
}
.sf-metadata-kanban-card .sf-metadata-ui.file-name-formatter .sf-metadata-file-name:hover {
cursor: pointer;
text-decoration: underline;
text-decoration-color: #212529;
}

View File

@@ -1,10 +1,11 @@
import React, { useCallback } from 'react';
import React, { useCallback, useEffect, useRef } from 'react';
import PropTypes from 'prop-types';
import classnames from 'classnames';
import { getCellValueByColumn, isValidCellValue } from '../../../../../utils/cell';
import Formatter from '../formatter';
import { PRIVATE_COLUMN_KEY } from '../../../../../constants';
import { FILE_TYPE } from '../../../../../constants';
import { useMetadataView } from '../../../../../hooks/metadata-view';
import { Utils } from '../../../../../../utils/utils';
import { geRecordIdFromRecord, getCellValueByColumn, getFileNameFromRecord, getParentDirFromRecord, isValidCellValue } from '../../../../../utils/cell';
import './index.css';
@@ -16,7 +17,10 @@ const Card = ({
titleColumn,
displayColumns,
onCloseSettings,
onOpenFile,
}) => {
const cardRef = useRef(null);
const { updateCurrentDirent, showDirentDetail } = useMetadataView();
const titleValue = getCellValueByColumn(record, titleColumn);
@@ -24,8 +28,8 @@ const Card = ({
const handleClick = useCallback((e) => {
e.preventDefault();
e.stopPropagation();
const name = record[PRIVATE_COLUMN_KEY.FILE_NAME];
const path = record[PRIVATE_COLUMN_KEY.PARENT_DIR];
const name = getFileNameFromRecord(record);
const path = getParentDirFromRecord(record);
updateCurrentDirent({
type: 'file',
name,
@@ -36,14 +40,48 @@ const Card = ({
showDirentDetail();
}, [record, updateCurrentDirent, showDirentDetail, onCloseSettings]);
const getFileType = useCallback((fileName) => {
if (!fileName) return '';
const index = fileName.lastIndexOf('.');
if (index === -1) return '';
const suffix = fileName.slice(index).toLowerCase();
if (suffix.indexOf(' ') > -1) return '';
if (Utils.imageCheck(fileName)) return FILE_TYPE.IMAGE;
if (Utils.isMarkdownFile(fileName)) return FILE_TYPE.MARKDOWN;
if (Utils.isSdocFile(fileName)) return FILE_TYPE.SDOC;
return '';
}, []);
const handleClickFilename = useCallback((e) => {
e.preventDefault();
e.stopPropagation();
console.log('click filename');
}, []);
const fileName = getFileNameFromRecord(record);
const fileType = getFileType(fileName);
const parentDir = getParentDirFromRecord(record);
const recordId = geRecordIdFromRecord(record);
onOpenFile(fileType, fileName, parentDir, recordId);
}, [record, getFileType, onOpenFile]);
useEffect(() => {
const cardElement = cardRef.current;
if (!cardElement) return;
const filenameElement = cardElement.querySelector('.file-name-formatter .sf-metadata-file-name');
if (filenameElement) {
filenameElement.addEventListener('click', handleClickFilename);
}
return () => {
if (filenameElement) {
filenameElement.removeEventListener('click', handleClickFilename);
}
};
}, [handleClickFilename]);
return (
<article
ref={cardRef}
data-id={record._id}
className={classnames('sf-metadata-kanban-card', { 'readonly': readonly })}
onClick={handleClick}
@@ -70,9 +108,7 @@ const Card = ({
return (
<div className="sf-metadata-kanban-card-record" key={column.key}>
{displayColumnName && (<div className="sf-metadata-kanban-card-record-name">{column.name}</div>)}
<div className='file-name-formatter-wrapper' onClick={handleClickFilename}>
<Formatter value={value} column={column} record={record}/>
</div>
<Formatter value={value} column={column} record={record}/>
</div>
);
})}
@@ -89,6 +125,7 @@ Card.propTypes = {
titleColumn: PropTypes.object,
displayColumns: PropTypes.array,
onCloseSettings: PropTypes.func.isRequired,
onOpenFile: PropTypes.func.isRequired,
};
export default Card;

View File

@@ -24,6 +24,7 @@ const Board = ({
onFreezed,
onUnFreezed,
onCloseSettings,
onOpenFile,
}) => {
const [isDraggingOver, setDraggingOver] = useState(false);
const boardName = useMemo(() => `sf_metadata_kanban_board_${board.key}`, [board]);
@@ -84,6 +85,7 @@ const Board = ({
titleColumn={titleColumn}
displayColumns={displayColumns}
onCloseSettings={onCloseSettings}
onOpenFile={onOpenFile}
/>
);
if (readonly) return CardElement;
@@ -113,6 +115,7 @@ Board.propTypes = {
onFreezed: PropTypes.func,
onUnFreezed: PropTypes.func,
onCloseSettings: PropTypes.func.isRequired,
onOpenFile: PropTypes.func.isRequired,
};
export default Board;

View File

@@ -3,19 +3,25 @@ import PropTypes from 'prop-types';
import classnames from 'classnames';
import { useMetadataView } from '../../../hooks/metadata-view';
import { useCollaborators } from '../../../hooks';
import { CellType, KANBAN_SETTINGS_KEYS, UNCATEGORIZED } from '../../../constants';
import { CellType, KANBAN_SETTINGS_KEYS, UNCATEGORIZED, FILE_TYPE } from '../../../constants';
import { COLUMN_DATA_OPERATION_TYPE } from '../../../store/operations';
import { gettext } from '../../../../utils/constants';
import { gettext, siteRoot } from '../../../../utils/constants';
import { checkIsPredefinedOption, getCellValueByColumn, isValidCellValue, geRecordIdFromRecord } from '../../../utils/cell';
import { getColumnOptions, getColumnOriginName } from '../../../utils/column';
import AddBoard from '../add-board';
import EmptyTip from '../../../../components/empty-tip';
import Board from './board';
import { Utils } from '../../../../utils/utils';
import { EVENT_BUS_TYPE } from '../../../../components/common/event-bus-type';
import ImagePreviewer from '../../../components/cell-formatter/image-previewer';
import './index.css';
import { getRowById } from '../../../utils/table';
const Boards = ({ modifyRecord, modifyColumnData, onCloseSettings }) => {
const [haveFreezed, setHaveFreezed] = useState(false);
const [isShowImagePreviewer, setIsShowImagePreviewer] = useState(false);
const [record, setRecord] = useState(null);
const { metadata, store } = useMetadataView();
const { collaborators } = useCollaborators();
@@ -166,6 +172,61 @@ const Boards = ({ modifyRecord, modifyColumnData, onCloseSettings }) => {
const isEmpty = boards.length === 0;
const generateUrl = (fileName, parentDir) => {
const repoID = window.sfMetadataContext.getSetting('repoID');
const path = Utils.encodePath(Utils.joinPath(parentDir, fileName));
return `${siteRoot}lib/${repoID}/file${path}`;
};
const openMarkdown = (name, parentDir) => {
window.sfMetadataContext.eventBus.dispatch(EVENT_BUS_TYPE.OPEN_MARKDOWN_DIALOG, parentDir, name);
};
const openByNewWindow = (fileType, fileName, parentDir) => {
if (!fileType) {
const url = generateUrl(fileName, parentDir);
window.open(url);
} else {
let pathname = window.location.pathname;
if (pathname.endsWith('/')) {
pathname = pathname.slice(0, -1);
}
window.open(window.location.origin + pathname + Utils.encodePath(Utils.joinPath(parentDir, fileName)));
}
};
const openSdoc = (fileName, parentDir) => {
const url = generateUrl(fileName, parentDir);
window.open(url);
};
const openFile = (type, fileName, parentDir, recordId = null) => {
switch (type) {
case FILE_TYPE.MARKDOWN: {
openMarkdown(fileName, parentDir);
break;
}
case FILE_TYPE.SDOC: {
openSdoc(fileName, parentDir);
break;
}
case FILE_TYPE.IMAGE: {
const record = getRowById(metadata, recordId);
setRecord(record);
setIsShowImagePreviewer(true);
break;
}
default: {
openByNewWindow(type, fileName, parentDir);
break;
}
}
};
const closeImagePreviewer = () => {
setIsShowImagePreviewer(false);
};
return (
<div className={classnames('sf-metadata-view-kanban-boards', {
'sf-metadata-view-kanban-boards-text-wrap': textWrap,
@@ -194,6 +255,7 @@ const Boards = ({ modifyRecord, modifyColumnData, onCloseSettings }) => {
onFreezed={onFreezed}
onUnFreezed={onUnFreezed}
onCloseSettings={onCloseSettings}
onOpenFile={openFile}
/>
);
})}
@@ -201,6 +263,7 @@ const Boards = ({ modifyRecord, modifyColumnData, onCloseSettings }) => {
)}
{!readonly && (<AddBoard groupByColumn={groupByColumn}/>)}
</div>
{isShowImagePreviewer && (<ImagePreviewer record={record} table={metadata} closeImagePopup={closeImagePreviewer} />)}
</div>
);
};