mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-07 01:41:39 +00:00
feat: optimize code
This commit is contained in:
@@ -120,7 +120,12 @@ class DirTool extends React.Component {
|
|||||||
if (isFileExtended) {
|
if (isFileExtended) {
|
||||||
return (
|
return (
|
||||||
<div className="dir-tool">
|
<div className="dir-tool">
|
||||||
<MetadataViewToolBar viewId={viewId} isCustomPermission={isCustomPermission} showDetail={this.showDirentDetail} closeDetail={this.props.onCloseDetail} />
|
<MetadataViewToolBar
|
||||||
|
viewId={viewId}
|
||||||
|
isCustomPermission={isCustomPermission}
|
||||||
|
showDetail={this.showDirentDetail}
|
||||||
|
closeDetail={this.props.onCloseDetail}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@@ -14,6 +14,7 @@ import { GRID_MODE, LIST_MODE, METADATA_MODE } from './constants';
|
|||||||
const propTypes = {
|
const propTypes = {
|
||||||
isSidePanelFolded: PropTypes.bool,
|
isSidePanelFolded: PropTypes.bool,
|
||||||
isTreePanelShown: PropTypes.bool.isRequired,
|
isTreePanelShown: PropTypes.bool.isRequired,
|
||||||
|
isDirentDetailShow: PropTypes.bool,
|
||||||
currentMode: PropTypes.string.isRequired,
|
currentMode: PropTypes.string.isRequired,
|
||||||
path: PropTypes.string.isRequired,
|
path: PropTypes.string.isRequired,
|
||||||
repoID: PropTypes.string.isRequired,
|
repoID: PropTypes.string.isRequired,
|
||||||
@@ -198,6 +199,7 @@ class DirColumnView extends React.Component {
|
|||||||
{currentMode === METADATA_MODE && (
|
{currentMode === METADATA_MODE && (
|
||||||
<SeafileMetadata
|
<SeafileMetadata
|
||||||
mediaUrl={mediaUrl}
|
mediaUrl={mediaUrl}
|
||||||
|
isDirentDetailShow={this.props.isDirentDetailShow}
|
||||||
repoID={this.props.repoID}
|
repoID={this.props.repoID}
|
||||||
repoInfo={this.props.currentRepoInfo}
|
repoInfo={this.props.currentRepoInfo}
|
||||||
viewID={this.props.viewId}
|
viewID={this.props.viewId}
|
||||||
|
@@ -17,6 +17,7 @@ const ViewDetails = ({ viewId, onClose }) => {
|
|||||||
if (type === VIEW_TYPE.GALLERY) return `${mediaUrl}favicons/gallery.png`;
|
if (type === VIEW_TYPE.GALLERY) return `${mediaUrl}favicons/gallery.png`;
|
||||||
if (type === VIEW_TYPE.TABLE) return `${mediaUrl}favicons/table.png`;
|
if (type === VIEW_TYPE.TABLE) return `${mediaUrl}favicons/table.png`;
|
||||||
if (type === VIEW_TYPE.FACE_RECOGNITION) return `${mediaUrl}favicons/face-recognition-view.png`;
|
if (type === VIEW_TYPE.FACE_RECOGNITION) return `${mediaUrl}favicons/face-recognition-view.png`;
|
||||||
|
if (type === VIEW_TYPE.KANBAN) return `${mediaUrl}favicons/kanban.png`;
|
||||||
return `${mediaUrl}img/file/256/file.png`;
|
return `${mediaUrl}img/file/256/file.png`;
|
||||||
}, [view]);
|
}, [view]);
|
||||||
|
|
||||||
|
@@ -100,11 +100,13 @@ const ViewToolBar = ({ viewId, isCustomPermission, showDetail, closeDetail }) =>
|
|||||||
)}
|
)}
|
||||||
{viewType === VIEW_TYPE.KANBAN && (
|
{viewType === VIEW_TYPE.KANBAN && (
|
||||||
<KanbanViewToolBar
|
<KanbanViewToolBar
|
||||||
|
isCustomPermission={isCustomPermission}
|
||||||
readOnly={readOnly}
|
readOnly={readOnly}
|
||||||
view={view}
|
view={view}
|
||||||
collaborators={collaborators}
|
collaborators={collaborators}
|
||||||
modifyFilters={modifyFilters}
|
modifyFilters={modifyFilters}
|
||||||
modifySorts={modifySorts}
|
modifySorts={modifySorts}
|
||||||
|
showDetail={showDetail}
|
||||||
closeDetail={closeDetail}
|
closeDetail={closeDetail}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
@@ -1,15 +1,18 @@
|
|||||||
import React, { useMemo } from 'react';
|
import React, { useCallback, useMemo } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { IconBtn } from '@seafile/sf-metadata-ui-component';
|
import { IconBtn } from '@seafile/sf-metadata-ui-component';
|
||||||
import { EVENT_BUS_TYPE, PRIVATE_COLUMN_KEY } from '../../../constants';
|
import { EVENT_BUS_TYPE, PRIVATE_COLUMN_KEY } from '../../../constants';
|
||||||
import { FilterSetter, SortSetter } from '../../data-process-setter';
|
import { FilterSetter, SortSetter } from '../../data-process-setter';
|
||||||
|
import { gettext } from '../../../../utils/constants';
|
||||||
|
|
||||||
const KanbanViewToolBar = ({
|
const KanbanViewToolBar = ({
|
||||||
|
isCustomPermission,
|
||||||
readOnly,
|
readOnly,
|
||||||
view,
|
view,
|
||||||
collaborators,
|
collaborators,
|
||||||
modifyFilters,
|
modifyFilters,
|
||||||
modifySorts,
|
modifySorts,
|
||||||
|
showDetail,
|
||||||
closeDetail,
|
closeDetail,
|
||||||
}) => {
|
}) => {
|
||||||
const viewType = useMemo(() => view.type, [view]);
|
const viewType = useMemo(() => view.type, [view]);
|
||||||
@@ -27,6 +30,11 @@ const KanbanViewToolBar = ({
|
|||||||
window.sfMetadataContext.eventBus.dispatch(EVENT_BUS_TYPE.TOGGLE_KANBAN_SETTINGS);
|
window.sfMetadataContext.eventBus.dispatch(EVENT_BUS_TYPE.TOGGLE_KANBAN_SETTINGS);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const toggleDetails = useCallback(() => {
|
||||||
|
window.sfMetadataContext.eventBus.dispatch(EVENT_BUS_TYPE.CLOSE_KANBAN_SETTINGS);
|
||||||
|
showDetail();
|
||||||
|
}, [showDetail]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="sf-metadata-tool-left-operations">
|
<div className="sf-metadata-tool-left-operations">
|
||||||
@@ -63,6 +71,11 @@ const KanbanViewToolBar = ({
|
|||||||
tabIndex={0}
|
tabIndex={0}
|
||||||
onClick={onToggleKanbanSetting}
|
onClick={onToggleKanbanSetting}
|
||||||
/>
|
/>
|
||||||
|
{!isCustomPermission && (
|
||||||
|
<div className="cur-view-path-btn ml-2" onClick={toggleDetails}>
|
||||||
|
<span className="sf3-font sf3-font-info" aria-label={gettext('Properties')} title={gettext('Properties')}></span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="sf-metadata-tool-right-operations"></div>
|
<div className="sf-metadata-tool-right-operations"></div>
|
||||||
</>
|
</>
|
||||||
|
@@ -60,4 +60,6 @@ export const EVENT_BUS_TYPE = {
|
|||||||
|
|
||||||
// kanban
|
// kanban
|
||||||
TOGGLE_KANBAN_SETTINGS: 'toggle_kanban_settings',
|
TOGGLE_KANBAN_SETTINGS: 'toggle_kanban_settings',
|
||||||
|
OPEN_KANBAN_SETTINGS: 'open_kanban_settings',
|
||||||
|
CLOSE_KANBAN_SETTINGS: 'close_kanban_settings',
|
||||||
};
|
};
|
||||||
|
@@ -135,9 +135,3 @@ export const GALLERY_DATE_MODE = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const UNCATEGORIZED = '_uncategorized';
|
export const UNCATEGORIZED = '_uncategorized';
|
||||||
|
|
||||||
export const FILE_TYPE = {
|
|
||||||
MARKDOWN: 'markdown',
|
|
||||||
SDOC: 'sdoc',
|
|
||||||
IMAGE: 'image',
|
|
||||||
};
|
|
||||||
|
@@ -130,6 +130,7 @@ export const MetadataViewProvider = ({
|
|||||||
isLoading,
|
isLoading,
|
||||||
metadata,
|
metadata,
|
||||||
store: storeRef.current,
|
store: storeRef.current,
|
||||||
|
isDirentDetailShow: params.isDirentDetailShow,
|
||||||
deleteFilesCallback: params.deleteFilesCallback,
|
deleteFilesCallback: params.deleteFilesCallback,
|
||||||
renameFileCallback: params.renameFileCallback,
|
renameFileCallback: params.renameFileCallback,
|
||||||
updateCurrentDirent: params.updateCurrentDirent,
|
updateCurrentDirent: params.updateCurrentDirent,
|
||||||
|
97
frontend/src/metadata/utils/open-file.js
Normal file
97
frontend/src/metadata/utils/open-file.js
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
import { getFileNameFromRecord, getParentDirFromRecord } from './cell';
|
||||||
|
import { checkIsDir } from './row';
|
||||||
|
import { Utils } from '../../utils/utils';
|
||||||
|
import { siteRoot } from '../../utils/constants';
|
||||||
|
import { EVENT_BUS_TYPE } from '../../components/common/event-bus-type';
|
||||||
|
|
||||||
|
const FILE_TYPE = {
|
||||||
|
FOLDER: 'folder',
|
||||||
|
MARKDOWN: 'markdown',
|
||||||
|
SDOC: 'sdoc',
|
||||||
|
IMAGE: 'image',
|
||||||
|
};
|
||||||
|
|
||||||
|
const _getFileType = (fileName, isDir) => {
|
||||||
|
if (isDir) return FILE_TYPE.FOLDER;
|
||||||
|
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 _getParentDir = (record) => {
|
||||||
|
const parentDir = getParentDirFromRecord(record);
|
||||||
|
if (parentDir === '/') {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
return parentDir;
|
||||||
|
};
|
||||||
|
|
||||||
|
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 _openUrl = (url) => {
|
||||||
|
window.open(url);
|
||||||
|
};
|
||||||
|
|
||||||
|
const _openMarkdown = (fileName, parentDir, eventBus) => {
|
||||||
|
eventBus && eventBus.dispatch(EVENT_BUS_TYPE.OPEN_MARKDOWN_DIALOG, parentDir, fileName);
|
||||||
|
};
|
||||||
|
|
||||||
|
const _openByNewWindow = (fileName, parentDir, fileType) => {
|
||||||
|
if (!fileType) {
|
||||||
|
const url = _generateUrl(fileName, parentDir);
|
||||||
|
_openUrl(url);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let pathname = window.location.pathname;
|
||||||
|
if (pathname.endsWith('/')) {
|
||||||
|
pathname = pathname.slice(0, -1);
|
||||||
|
}
|
||||||
|
_openUrl(window.location.origin + pathname + Utils.encodePath(Utils.joinPath(parentDir, fileName)));
|
||||||
|
};
|
||||||
|
|
||||||
|
const _openSdoc = (fileName, parentDir) => {
|
||||||
|
const url = _generateUrl(fileName, parentDir);
|
||||||
|
_openUrl(url);
|
||||||
|
};
|
||||||
|
|
||||||
|
const _openOthers = (fileName, parentDir, fileType) => {
|
||||||
|
_openByNewWindow(fileName, parentDir, fileType);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const openFile = (record, eventBus, _openImage = () => {}) => {
|
||||||
|
if (!record) return;
|
||||||
|
const fileName = getFileNameFromRecord(record);
|
||||||
|
const isDir = checkIsDir(record);
|
||||||
|
const parentDir = _getParentDir(record);
|
||||||
|
const fileType = _getFileType(fileName, isDir);
|
||||||
|
|
||||||
|
switch (fileType) {
|
||||||
|
case FILE_TYPE.MARKDOWN: {
|
||||||
|
_openMarkdown(fileName, parentDir, eventBus);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FILE_TYPE.SDOC: {
|
||||||
|
_openSdoc(fileName, parentDir);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FILE_TYPE.IMAGE: {
|
||||||
|
_openImage(record);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
_openOthers(fileName, parentDir, fileType);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
@@ -12,21 +12,32 @@
|
|||||||
user-select: none;
|
user-select: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.sf-metadata-kanban-card.selected {
|
||||||
|
border-color: #FF8000;
|
||||||
|
}
|
||||||
|
|
||||||
.sf-metadata-kanban-card:hover {
|
.sf-metadata-kanban-card:hover {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
box-shadow: 0 0 6px #0000002e;
|
box-shadow: 0 0 6px #0000002e;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sf-metadata-kanban-card.readonly {
|
|
||||||
cursor: default;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sf-metadata-kanban-card .sf-metadata-kanban-card-header {
|
.sf-metadata-kanban-card .sf-metadata-kanban-card-header {
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.sf-metadata-kanban-card .sf-metadata-kanban-card-header .sf-metadata-file-name {
|
||||||
|
text-decoration: none;
|
||||||
|
flex: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sf-metadata-kanban-card .sf-metadata-kanban-card-header .sf-metadata-file-name:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
text-decoration: underline;
|
||||||
|
text-decoration-color: #212529;
|
||||||
|
}
|
||||||
|
|
||||||
.sf-metadata-kanban-card .sf-metadata-kanban-card-body .sf-metadata-kanban-card-record:first-child {
|
.sf-metadata-kanban-card .sf-metadata-kanban-card-body .sf-metadata-kanban-card-record:first-child {
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
}
|
}
|
||||||
@@ -84,17 +95,6 @@
|
|||||||
transform: translateY(-1px);
|
transform: translateY(-1px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.sf-metadata-kanban-card .sf-metadata-ui.file-name-formatter .sf-metadata-file-name {
|
|
||||||
text-decoration: none;
|
|
||||||
flex: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sf-metadata-kanban-card .sf-metadata-ui.file-name-formatter .sf-metadata-file-name:hover {
|
|
||||||
cursor: pointer;
|
|
||||||
text-decoration: underline;
|
|
||||||
text-decoration-color: #212529;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sf-metadata-kanban-card .sf-metadata-kanban-card-record .collaborators-formatter {
|
.sf-metadata-kanban-card .sf-metadata-kanban-card-record .collaborators-formatter {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
|
@@ -1,98 +1,49 @@
|
|||||||
import React, { useCallback, useEffect, useRef } from 'react';
|
import React, { useCallback } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import classnames from 'classnames';
|
import classnames from 'classnames';
|
||||||
import Formatter from '../formatter';
|
import Formatter from '../formatter';
|
||||||
import { FILE_TYPE } from '../../../../../constants';
|
import { getCellValueByColumn, isValidCellValue } from '../../../../../utils/cell';
|
||||||
import { useMetadataView } from '../../../../../hooks/metadata-view';
|
|
||||||
import { Utils } from '../../../../../../utils/utils';
|
|
||||||
import { geRecordIdFromRecord, getCellValueByColumn, getFileNameFromRecord, getParentDirFromRecord, isValidCellValue } from '../../../../../utils/cell';
|
|
||||||
|
|
||||||
import './index.css';
|
import './index.css';
|
||||||
|
|
||||||
const Card = ({
|
const Card = ({
|
||||||
readonly,
|
isSelected,
|
||||||
displayEmptyValue,
|
displayEmptyValue,
|
||||||
displayColumnName,
|
displayColumnName,
|
||||||
record,
|
record,
|
||||||
titleColumn,
|
titleColumn,
|
||||||
displayColumns,
|
displayColumns,
|
||||||
onCloseSettings,
|
|
||||||
onOpenFile,
|
onOpenFile,
|
||||||
|
onSelectCard,
|
||||||
}) => {
|
}) => {
|
||||||
const cardRef = useRef(null);
|
|
||||||
|
|
||||||
const { updateCurrentDirent, showDirentDetail } = useMetadataView();
|
|
||||||
|
|
||||||
const titleValue = getCellValueByColumn(record, titleColumn);
|
const titleValue = getCellValueByColumn(record, titleColumn);
|
||||||
|
|
||||||
const handleClickCard = useCallback((e) => {
|
const handleClickCard = useCallback((event) => {
|
||||||
e.preventDefault();
|
event.preventDefault();
|
||||||
e.stopPropagation();
|
event.stopPropagation();
|
||||||
const name = getFileNameFromRecord(record);
|
event.nativeEvent.stopImmediatePropagation();
|
||||||
const path = getParentDirFromRecord(record);
|
onSelectCard(record);
|
||||||
updateCurrentDirent({
|
}, [record, onSelectCard]);
|
||||||
type: 'file',
|
|
||||||
name,
|
|
||||||
path,
|
|
||||||
file_tags: []
|
|
||||||
});
|
|
||||||
onCloseSettings();
|
|
||||||
showDirentDetail();
|
|
||||||
}, [record, updateCurrentDirent, showDirentDetail, onCloseSettings]);
|
|
||||||
|
|
||||||
const getFileType = useCallback((fileName) => {
|
const handleClickFilename = useCallback((event) => {
|
||||||
if (!fileName) return '';
|
event.stopPropagation();
|
||||||
const index = fileName.lastIndexOf('.');
|
event.nativeEvent.stopImmediatePropagation();
|
||||||
if (index === -1) return '';
|
onOpenFile(record);
|
||||||
const suffix = fileName.slice(index).toLowerCase();
|
}, [record, onOpenFile]);
|
||||||
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();
|
|
||||||
|
|
||||||
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 (
|
return (
|
||||||
<article
|
<article
|
||||||
ref={cardRef}
|
|
||||||
data-id={record._id}
|
data-id={record._id}
|
||||||
className={classnames('sf-metadata-kanban-card', { 'readonly': readonly })}
|
className={classnames('sf-metadata-kanban-card', { 'selected': isSelected })}
|
||||||
onClick={handleClickCard}
|
onClick={handleClickCard}
|
||||||
>
|
>
|
||||||
{titleColumn && (
|
{titleColumn && (
|
||||||
<div className="sf-metadata-kanban-card-header">
|
<div className="sf-metadata-kanban-card-header" onClick={handleClickFilename}>
|
||||||
<Formatter value={titleValue} column={titleColumn} record={record}/>
|
<Formatter value={titleValue} column={titleColumn} record={record}/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<div className="sf-metadata-kanban-card-body">
|
<div className="sf-metadata-kanban-card-body">
|
||||||
{displayColumns.map((column, index) => {
|
{displayColumns.map((column) => {
|
||||||
const value = getCellValueByColumn(record, column);
|
const value = getCellValueByColumn(record, column);
|
||||||
if (!displayEmptyValue && !isValidCellValue(value)) {
|
if (!displayEmptyValue && !isValidCellValue(value)) {
|
||||||
if (displayColumnName) {
|
if (displayColumnName) {
|
||||||
@@ -118,14 +69,14 @@ const Card = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
Card.propTypes = {
|
Card.propTypes = {
|
||||||
readonly: PropTypes.bool,
|
isSelected: PropTypes.bool,
|
||||||
displayEmptyValue: PropTypes.bool,
|
displayEmptyValue: PropTypes.bool,
|
||||||
displayColumnName: PropTypes.bool,
|
displayColumnName: PropTypes.bool,
|
||||||
record: PropTypes.object,
|
record: PropTypes.object,
|
||||||
titleColumn: PropTypes.object,
|
titleColumn: PropTypes.object,
|
||||||
displayColumns: PropTypes.array,
|
displayColumns: PropTypes.array,
|
||||||
onCloseSettings: PropTypes.func.isRequired,
|
|
||||||
onOpenFile: PropTypes.func.isRequired,
|
onOpenFile: PropTypes.func.isRequired,
|
||||||
|
onSelectCard: PropTypes.func.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Card;
|
export default Card;
|
||||||
|
@@ -6,6 +6,7 @@ import { useMetadataView } from '../../../../hooks/metadata-view';
|
|||||||
import { getRowById } from '../../../../utils/table';
|
import { getRowById } from '../../../../utils/table';
|
||||||
import Container from '../../dnd/container';
|
import Container from '../../dnd/container';
|
||||||
import Draggable from '../../dnd/draggable';
|
import Draggable from '../../dnd/draggable';
|
||||||
|
import { geRecordIdFromRecord } from '../../../../utils/cell';
|
||||||
|
|
||||||
import './index.css';
|
import './index.css';
|
||||||
|
|
||||||
@@ -19,12 +20,13 @@ const Board = ({
|
|||||||
groupByColumn,
|
groupByColumn,
|
||||||
titleColumn,
|
titleColumn,
|
||||||
displayColumns,
|
displayColumns,
|
||||||
|
selectedCard,
|
||||||
onMove,
|
onMove,
|
||||||
deleteOption,
|
deleteOption,
|
||||||
onFreezed,
|
onFreezed,
|
||||||
onUnFreezed,
|
onUnFreezed,
|
||||||
onCloseSettings,
|
|
||||||
onOpenFile,
|
onOpenFile,
|
||||||
|
onSelectCard,
|
||||||
}) => {
|
}) => {
|
||||||
const [isDraggingOver, setDraggingOver] = useState(false);
|
const [isDraggingOver, setDraggingOver] = useState(false);
|
||||||
const boardName = useMemo(() => `sf_metadata_kanban_board_${board.key}`, [board]);
|
const boardName = useMemo(() => `sf_metadata_kanban_board_${board.key}`, [board]);
|
||||||
@@ -75,17 +77,18 @@ const Board = ({
|
|||||||
{board.children.map((cardKey) => {
|
{board.children.map((cardKey) => {
|
||||||
const record = getRowById(metadata, cardKey);
|
const record = getRowById(metadata, cardKey);
|
||||||
if (!record) return null;
|
if (!record) return null;
|
||||||
|
const isSelected = selectedCard === geRecordIdFromRecord(record);
|
||||||
const CardElement = (
|
const CardElement = (
|
||||||
<Card
|
<Card
|
||||||
key={cardKey}
|
key={cardKey}
|
||||||
readonly={readonly}
|
isSelected={isSelected}
|
||||||
displayEmptyValue={displayEmptyValue}
|
displayEmptyValue={displayEmptyValue}
|
||||||
displayColumnName={displayColumnName}
|
displayColumnName={displayColumnName}
|
||||||
record={record}
|
record={record}
|
||||||
titleColumn={titleColumn}
|
titleColumn={titleColumn}
|
||||||
displayColumns={displayColumns}
|
displayColumns={displayColumns}
|
||||||
onCloseSettings={onCloseSettings}
|
|
||||||
onOpenFile={onOpenFile}
|
onOpenFile={onOpenFile}
|
||||||
|
onSelectCard={onSelectCard}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
if (readonly) return CardElement;
|
if (readonly) return CardElement;
|
||||||
@@ -110,12 +113,13 @@ Board.propTypes = {
|
|||||||
groupByColumn: PropTypes.object,
|
groupByColumn: PropTypes.object,
|
||||||
titleColumn: PropTypes.object,
|
titleColumn: PropTypes.object,
|
||||||
displayColumns: PropTypes.array,
|
displayColumns: PropTypes.array,
|
||||||
|
selectedCard: PropTypes.string,
|
||||||
onMove: PropTypes.func,
|
onMove: PropTypes.func,
|
||||||
deleteOption: PropTypes.func,
|
deleteOption: PropTypes.func,
|
||||||
onFreezed: PropTypes.func,
|
onFreezed: PropTypes.func,
|
||||||
onUnFreezed: PropTypes.func,
|
onUnFreezed: PropTypes.func,
|
||||||
onCloseSettings: PropTypes.func.isRequired,
|
|
||||||
onOpenFile: PropTypes.func.isRequired,
|
onOpenFile: PropTypes.func.isRequired,
|
||||||
|
onSelectCard: PropTypes.func.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Board;
|
export default Board;
|
||||||
|
@@ -1,29 +1,33 @@
|
|||||||
import React, { useMemo, useCallback, useState } from 'react';
|
import React, { useMemo, useCallback, useState, useRef, useEffect } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import classnames from 'classnames';
|
import classnames from 'classnames';
|
||||||
import { useMetadataView } from '../../../hooks/metadata-view';
|
import { useMetadataView } from '../../../hooks/metadata-view';
|
||||||
import { useCollaborators } from '../../../hooks';
|
import { useCollaborators } from '../../../hooks';
|
||||||
import { CellType, KANBAN_SETTINGS_KEYS, UNCATEGORIZED, FILE_TYPE } from '../../../constants';
|
import { CellType, KANBAN_SETTINGS_KEYS, UNCATEGORIZED } from '../../../constants';
|
||||||
import { COLUMN_DATA_OPERATION_TYPE } from '../../../store/operations';
|
import { COLUMN_DATA_OPERATION_TYPE } from '../../../store/operations';
|
||||||
import { gettext, siteRoot } from '../../../../utils/constants';
|
import { gettext } from '../../../../utils/constants';
|
||||||
import { checkIsPredefinedOption, getCellValueByColumn, isValidCellValue, geRecordIdFromRecord } from '../../../utils/cell';
|
import { checkIsPredefinedOption, getCellValueByColumn, isValidCellValue, geRecordIdFromRecord,
|
||||||
|
getFileNameFromRecord, getParentDirFromRecord
|
||||||
|
} from '../../../utils/cell';
|
||||||
import { getColumnOptions, getColumnOriginName } from '../../../utils/column';
|
import { getColumnOptions, getColumnOriginName } from '../../../utils/column';
|
||||||
import AddBoard from '../add-board';
|
import AddBoard from '../add-board';
|
||||||
import EmptyTip from '../../../../components/empty-tip';
|
import EmptyTip from '../../../../components/empty-tip';
|
||||||
import Board from './board';
|
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 ImagePreviewer from '../../../components/cell-formatter/image-previewer';
|
||||||
import { getRowById } from '../../../utils/table';
|
import { openFile } from '../../../utils/open-file';
|
||||||
|
import { checkIsDir } from '../../../utils/row';
|
||||||
|
|
||||||
import './index.css';
|
import './index.css';
|
||||||
|
|
||||||
const Boards = ({ modifyRecord, modifyColumnData, onCloseSettings }) => {
|
const Boards = ({ modifyRecord, modifyColumnData, onCloseSettings }) => {
|
||||||
const [haveFreezed, setHaveFreezed] = useState(false);
|
const [haveFreezed, setHaveFreezed] = useState(false);
|
||||||
const [isImagePreviewerVisible, setImagePreviewerVisible] = useState(false);
|
const [isImagePreviewerVisible, setImagePreviewerVisible] = useState(false);
|
||||||
const [record, setRecord] = useState(null);
|
const [selectedCard, setSelectedCard] = useState('');
|
||||||
|
|
||||||
const { metadata, store } = useMetadataView();
|
const currentImageRef = useRef(null);
|
||||||
|
const containerRef = useRef(null);
|
||||||
|
|
||||||
|
const { isDirentDetailShow, metadata, store, updateCurrentDirent, showDirentDetail } = useMetadataView();
|
||||||
const { collaborators } = useCollaborators();
|
const { collaborators } = useCollaborators();
|
||||||
|
|
||||||
const groupByColumn = useMemo(() => {
|
const groupByColumn = useMemo(() => {
|
||||||
@@ -170,68 +174,57 @@ const Boards = ({ modifyRecord, modifyColumnData, onCloseSettings }) => {
|
|||||||
setHaveFreezed(false);
|
setHaveFreezed(false);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const isEmpty = boards.length === 0;
|
const onOpenFile = useCallback((record) => {
|
||||||
|
openFile(record, window.sfMetadataContext.eventBus, () => {
|
||||||
const generateUrl = (fileName, parentDir) => {
|
currentImageRef.current = record;
|
||||||
const repoID = window.sfMetadataContext.getSetting('repoID');
|
setImagePreviewerVisible(true);
|
||||||
const path = Utils.encodePath(Utils.joinPath(parentDir, fileName));
|
});
|
||||||
return `${siteRoot}lib/${repoID}/file${path}`;
|
|
||||||
};
|
|
||||||
|
|
||||||
const openMarkdown = useCallback((name, parentDir) => {
|
|
||||||
window.sfMetadataContext.eventBus.dispatch(EVENT_BUS_TYPE.OPEN_MARKDOWN_DIALOG, parentDir, name);
|
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const openByNewWindow = useCallback((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 = useCallback((fileName, parentDir) => {
|
|
||||||
const url = generateUrl(fileName, parentDir);
|
|
||||||
window.open(url);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const openFile = useCallback((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);
|
|
||||||
setImagePreviewerVisible(true);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
openByNewWindow(type, fileName, parentDir);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, [openMarkdown, openSdoc, openByNewWindow, metadata]);
|
|
||||||
|
|
||||||
const closeImagePreviewer = useCallback(() => {
|
const closeImagePreviewer = useCallback(() => {
|
||||||
|
currentImageRef.current = null;
|
||||||
setImagePreviewerVisible(false);
|
setImagePreviewerVisible(false);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
const onSelectCard = useCallback((record) => {
|
||||||
|
const recordId = geRecordIdFromRecord(record);
|
||||||
|
const name = getFileNameFromRecord(record);
|
||||||
|
const path = getParentDirFromRecord(record);
|
||||||
|
const isDir = checkIsDir(record);
|
||||||
|
updateCurrentDirent({
|
||||||
|
type: isDir ? 'dir' : 'file',
|
||||||
|
mtime: '',
|
||||||
|
name,
|
||||||
|
path,
|
||||||
|
file_tags: []
|
||||||
|
});
|
||||||
|
setSelectedCard(recordId);
|
||||||
|
onCloseSettings();
|
||||||
|
showDirentDetail();
|
||||||
|
}, [onCloseSettings, showDirentDetail, updateCurrentDirent]);
|
||||||
|
|
||||||
|
const handleClickOutside = useCallback((event) => {
|
||||||
|
if (!containerRef.current.contains(event.target)) return;
|
||||||
|
setSelectedCard(null);
|
||||||
|
updateCurrentDirent();
|
||||||
|
}, [updateCurrentDirent]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!isDirentDetailShow) {
|
||||||
|
setSelectedCard(null);
|
||||||
|
}
|
||||||
|
}, [isDirentDetailShow]);
|
||||||
|
|
||||||
|
const isEmpty = boards.length === 0;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={classnames('sf-metadata-view-kanban-boards', {
|
<div
|
||||||
'sf-metadata-view-kanban-boards-text-wrap': textWrap,
|
ref={containerRef}
|
||||||
'readonly': readonly,
|
className={classnames('sf-metadata-view-kanban-boards', {
|
||||||
})}
|
'sf-metadata-view-kanban-boards-text-wrap': textWrap,
|
||||||
|
'readonly': readonly,
|
||||||
|
})}
|
||||||
|
onClick={handleClickOutside}
|
||||||
>
|
>
|
||||||
<div className="smooth-dnd-container horizontal">
|
<div className="smooth-dnd-container horizontal">
|
||||||
{isEmpty && (<EmptyTip className="tips-empty-boards" text={gettext('No categories')} />)}
|
{isEmpty && (<EmptyTip className="tips-empty-boards" text={gettext('No categories')} />)}
|
||||||
@@ -250,12 +243,13 @@ const Boards = ({ modifyRecord, modifyColumnData, onCloseSettings }) => {
|
|||||||
groupByColumn={groupByColumn}
|
groupByColumn={groupByColumn}
|
||||||
titleColumn={titleColumn}
|
titleColumn={titleColumn}
|
||||||
displayColumns={displayColumns}
|
displayColumns={displayColumns}
|
||||||
|
selectedCard={selectedCard}
|
||||||
onMove={onMove}
|
onMove={onMove}
|
||||||
deleteOption={deleteOption}
|
deleteOption={deleteOption}
|
||||||
onFreezed={onFreezed}
|
onFreezed={onFreezed}
|
||||||
onUnFreezed={onUnFreezed}
|
onUnFreezed={onUnFreezed}
|
||||||
onCloseSettings={onCloseSettings}
|
onOpenFile={onOpenFile}
|
||||||
onOpenFile={openFile}
|
onSelectCard={onSelectCard}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
@@ -263,7 +257,7 @@ const Boards = ({ modifyRecord, modifyColumnData, onCloseSettings }) => {
|
|||||||
)}
|
)}
|
||||||
{!readonly && (<AddBoard groupByColumn={groupByColumn}/>)}
|
{!readonly && (<AddBoard groupByColumn={groupByColumn}/>)}
|
||||||
</div>
|
</div>
|
||||||
{isImagePreviewerVisible && (<ImagePreviewer record={record} table={metadata} closeImagePopup={closeImagePreviewer} />)}
|
{isImagePreviewerVisible && (<ImagePreviewer record={currentImageRef.current} table={metadata} closeImagePopup={closeImagePreviewer} />)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@@ -45,8 +45,10 @@ const Kanban = () => {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const eventBus = window.sfMetadataContext.eventBus;
|
const eventBus = window.sfMetadataContext.eventBus;
|
||||||
const unsubscribeKanbanSetting = eventBus.subscribe(EVENT_BUS_TYPE.TOGGLE_KANBAN_SETTINGS, () => setShowSettings(!isShowSettings));
|
const unsubscribeKanbanSetting = eventBus.subscribe(EVENT_BUS_TYPE.TOGGLE_KANBAN_SETTINGS, () => setShowSettings(!isShowSettings));
|
||||||
|
const unsubscribeCloseKanbanSetting = eventBus.subscribe(EVENT_BUS_TYPE.CLOSE_KANBAN_SETTINGS, () => setShowSettings(false));
|
||||||
return () => {
|
return () => {
|
||||||
unsubscribeKanbanSetting();
|
unsubscribeKanbanSetting();
|
||||||
|
unsubscribeCloseKanbanSetting();
|
||||||
};
|
};
|
||||||
}, [isShowSettings]);
|
}, [isShowSettings]);
|
||||||
|
|
||||||
|
@@ -1,121 +1,28 @@
|
|||||||
import React, { useMemo } from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { UncontrolledTooltip } from 'reactstrap';
|
import { UncontrolledTooltip } from 'reactstrap';
|
||||||
import { IconBtn } from '@seafile/sf-metadata-ui-component';
|
import { IconBtn } from '@seafile/sf-metadata-ui-component';
|
||||||
import { Utils } from '../../../../../../../../utils/utils';
|
import { gettext } from '../../../../../../../../utils/constants';
|
||||||
import { gettext, siteRoot } from '../../../../../../../../utils/constants';
|
|
||||||
import { EVENT_BUS_TYPE } from '../../../../../../../..//components/common/event-bus-type';
|
|
||||||
import { EVENT_BUS_TYPE as METADATA_EVENT_BUS_TYPE, EDITOR_TYPE } from '../../../../../../../constants';
|
import { EVENT_BUS_TYPE as METADATA_EVENT_BUS_TYPE, EDITOR_TYPE } from '../../../../../../../constants';
|
||||||
import { getFileNameFromRecord, getParentDirFromRecord } from '../../../../../../../utils/cell';
|
import { openFile } from '../../../../../../../utils/open-file';
|
||||||
import { checkIsDir } from '../../../../../../../utils/row';
|
|
||||||
|
|
||||||
import './index.css';
|
import './index.css';
|
||||||
|
|
||||||
const FILE_TYPE = {
|
|
||||||
FOLDER: 'folder',
|
|
||||||
MARKDOWN: 'markdown',
|
|
||||||
SDOC: 'sdoc',
|
|
||||||
IMAGE: 'image',
|
|
||||||
};
|
|
||||||
|
|
||||||
const CellOperationBtn = ({ isDir, column, record, cellValue, ...props }) => {
|
const CellOperationBtn = ({ isDir, column, record, cellValue, ...props }) => {
|
||||||
|
|
||||||
const fileName = useMemo(() => {
|
const handelClick = (event) => {
|
||||||
const { key } = column;
|
|
||||||
return record[key];
|
|
||||||
}, [column, record]);
|
|
||||||
|
|
||||||
const fileType = useMemo(() => {
|
|
||||||
if (checkIsDir(record)) return FILE_TYPE.FOLDER;
|
|
||||||
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 '';
|
|
||||||
}, [record, fileName]);
|
|
||||||
|
|
||||||
const getParentDir = () => {
|
|
||||||
const parentDir = getParentDirFromRecord(record);
|
|
||||||
if (parentDir === '/') {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
return parentDir;
|
|
||||||
};
|
|
||||||
|
|
||||||
const generateUrl = () => {
|
|
||||||
const repoID = window.sfMetadataContext.getSetting('repoID');
|
|
||||||
const parentDir = getParentDir();
|
|
||||||
const path = Utils.encodePath(Utils.joinPath(parentDir, fileName));
|
|
||||||
return `${siteRoot}lib/${repoID}/file${path}`;
|
|
||||||
};
|
|
||||||
|
|
||||||
const openUrl = (url) => {
|
|
||||||
window.open(url);
|
|
||||||
};
|
|
||||||
|
|
||||||
const openMarkdown = () => {
|
|
||||||
const fileName = getFileNameFromRecord(record);
|
|
||||||
const parentDir = getParentDirFromRecord(record);
|
|
||||||
window.sfMetadataContext.eventBus.dispatch(EVENT_BUS_TYPE.OPEN_MARKDOWN_DIALOG, parentDir, fileName);
|
|
||||||
};
|
|
||||||
|
|
||||||
const openByNewWindow = (fileType) => {
|
|
||||||
if (!fileType) {
|
|
||||||
const url = generateUrl();
|
|
||||||
openUrl(url);
|
|
||||||
} else {
|
|
||||||
const parentDir = getParentDir();
|
|
||||||
let pathname = window.location.pathname;
|
|
||||||
if (pathname.endsWith('/')) {
|
|
||||||
pathname = pathname.slice(0, -1);
|
|
||||||
}
|
|
||||||
openUrl(window.location.origin + pathname + Utils.encodePath(Utils.joinPath(parentDir, fileName)));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const openSdoc = () => {
|
|
||||||
const url = generateUrl();
|
|
||||||
openUrl(url);
|
|
||||||
};
|
|
||||||
|
|
||||||
const openOthers = () => {
|
|
||||||
openByNewWindow(fileType);
|
|
||||||
};
|
|
||||||
|
|
||||||
const openFile = (event) => {
|
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
event.nativeEvent.stopImmediatePropagation();
|
event.nativeEvent.stopImmediatePropagation();
|
||||||
|
openFile(record, window.sfMetadataContext.eventBus, () => {
|
||||||
switch (fileType) {
|
window.sfMetadataContext.eventBus.dispatch(METADATA_EVENT_BUS_TYPE.OPEN_EDITOR, EDITOR_TYPE.PREVIEWER);
|
||||||
case FILE_TYPE.MARKDOWN: {
|
});
|
||||||
openMarkdown();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case FILE_TYPE.SDOC: {
|
|
||||||
openSdoc();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case FILE_TYPE.IMAGE: {
|
|
||||||
// render image previewer via FileNameEditor
|
|
||||||
window.sfMetadataContext.eventBus.dispatch(METADATA_EVENT_BUS_TYPE.OPEN_EDITOR, EDITOR_TYPE.PREVIEWER);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
openOthers();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!cellValue) return null;
|
if (!cellValue) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<IconBtn id={'sf-metadata-cell-open-file-btn'} className="sf-metadata-cell-operation-btn" size={20} iconName="open-file" onClick={openFile} />
|
<IconBtn id={'sf-metadata-cell-open-file-btn'} className="sf-metadata-cell-operation-btn" size={20} iconName="open-file" onClick={handelClick} />
|
||||||
<UncontrolledTooltip
|
<UncontrolledTooltip
|
||||||
hideArrow
|
hideArrow
|
||||||
target={'sf-metadata-cell-open-file-btn'}
|
target={'sf-metadata-cell-open-file-btn'}
|
||||||
|
@@ -2358,6 +2358,7 @@ class LibContentView extends React.Component {
|
|||||||
<DirColumnView
|
<DirColumnView
|
||||||
isSidePanelFolded={this.props.isSidePanelFolded}
|
isSidePanelFolded={this.props.isSidePanelFolded}
|
||||||
isTreePanelShown={this.state.isTreePanelShown}
|
isTreePanelShown={this.state.isTreePanelShown}
|
||||||
|
isDirentDetailShow={this.state.isDirentDetailShow}
|
||||||
currentMode={this.state.currentMode}
|
currentMode={this.state.currentMode}
|
||||||
path={this.state.path}
|
path={this.state.path}
|
||||||
repoID={this.props.repoID}
|
repoID={this.props.repoID}
|
||||||
|
Reference in New Issue
Block a user