u
This commit is contained in:
194
src/components/vfs/VfsEditorPanel.jsx
Normal file
194
src/components/vfs/VfsEditorPanel.jsx
Normal file
@@ -0,0 +1,194 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
import Box from '@mui/material/Box';
|
||||
import Typography from '@mui/material/Typography';
|
||||
import IconButton from '@mui/material/IconButton';
|
||||
import Tooltip from '@mui/material/Tooltip';
|
||||
import FolderOpenRoundedIcon from '@mui/icons-material/FolderOpenRounded';
|
||||
import CloseRoundedIcon from '@mui/icons-material/CloseRounded';
|
||||
|
||||
import vfsAutomat from '../../automats/vfsAutomat';
|
||||
import VfsFileExplorer from './VfsFileExplorer';
|
||||
import VfsTextEditor from './VfsTextEditor';
|
||||
import VfsFilePreview from './VfsFilePreview';
|
||||
import VfsNewFileDialog from './VfsNewFileDialog';
|
||||
|
||||
export default class VfsEditorPanel extends PureComponent {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
const s = vfsAutomat.state;
|
||||
this.state = {
|
||||
files: s.files,
|
||||
loadingFiles: s.loadingFiles,
|
||||
loadError: s.loadError,
|
||||
selectedFileName: s.selectedFileName,
|
||||
selectedFile: s.selectedFile,
|
||||
fileContent: s.fileContent,
|
||||
originalContent: s.originalContent,
|
||||
isDirty: s.isDirty,
|
||||
loadingContent: s.loadingContent,
|
||||
isSaving: s.isSaving,
|
||||
saveError: s.saveError,
|
||||
isUploading: s.isUploading,
|
||||
searchQuery: s.searchQuery,
|
||||
newFileDialogOpen: s.newFileDialogOpen,
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.unsub = vfsAutomat.subscribe(this, (state) => ({
|
||||
files: state.files,
|
||||
loadingFiles: state.loadingFiles,
|
||||
loadError: state.loadError,
|
||||
selectedFileName: state.selectedFileName,
|
||||
selectedFile: state.selectedFile,
|
||||
fileContent: state.fileContent,
|
||||
originalContent: state.originalContent,
|
||||
isDirty: state.isDirty,
|
||||
loadingContent: state.loadingContent,
|
||||
isSaving: state.isSaving,
|
||||
saveError: state.saveError,
|
||||
isUploading: state.isUploading,
|
||||
searchQuery: state.searchQuery,
|
||||
newFileDialogOpen: state.newFileDialogOpen,
|
||||
}));
|
||||
|
||||
if (this.state.files.length === 0 && !this.state.loadingFiles) {
|
||||
void vfsAutomat.actions.loadFiles();
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this.unsub?.();
|
||||
}
|
||||
|
||||
handleMentionInChat = (file) => {
|
||||
if (!file) return;
|
||||
if (this.props.onInsertToChat) {
|
||||
const isImg = file.isImage;
|
||||
const tag = isImg
|
||||
? ``
|
||||
: `[${file.name}](${file.name})`;
|
||||
this.props.onInsertToChat(tag);
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const {
|
||||
files,
|
||||
loadingFiles,
|
||||
selectedFileName,
|
||||
selectedFile,
|
||||
fileContent,
|
||||
originalContent,
|
||||
isDirty,
|
||||
loadingContent,
|
||||
isSaving,
|
||||
saveError,
|
||||
searchQuery,
|
||||
newFileDialogOpen,
|
||||
} = this.state;
|
||||
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
height: '100%',
|
||||
width: '100%',
|
||||
overflow: 'hidden',
|
||||
bgcolor: 'background.paper',
|
||||
borderRight: 1,
|
||||
borderColor: 'divider',
|
||||
}}
|
||||
>
|
||||
{selectedFileName && selectedFile?.isText ? (
|
||||
/* Single Column Mode: Text Editor */
|
||||
<VfsTextEditor
|
||||
fileName={selectedFileName}
|
||||
file={selectedFile}
|
||||
content={fileContent}
|
||||
originalContent={originalContent}
|
||||
isDirty={isDirty}
|
||||
isSaving={isSaving}
|
||||
saveError={saveError}
|
||||
loadingContent={loadingContent}
|
||||
onChange={(c) => vfsAutomat.actions.updateContent(c)}
|
||||
onSave={() => vfsAutomat.actions.saveCurrentFile()}
|
||||
onClose={() => vfsAutomat.actions.selectFile(null)}
|
||||
onDownload={() => vfsAutomat.actions.downloadFile(selectedFileName)}
|
||||
onMentionInChat={() => this.handleMentionInChat(selectedFile)}
|
||||
/>
|
||||
) : selectedFileName && !selectedFile?.isText ? (
|
||||
/* Single Column Mode: Preview (Image, PDF, Binary) */
|
||||
<VfsFilePreview
|
||||
fileName={selectedFileName}
|
||||
file={selectedFile}
|
||||
onClose={() => vfsAutomat.actions.selectFile(null)}
|
||||
onDownload={() => vfsAutomat.actions.downloadFile(selectedFileName)}
|
||||
onMentionInChat={() => this.handleMentionInChat(selectedFile)}
|
||||
/>
|
||||
) : (
|
||||
/* Single Column Mode: File Explorer */
|
||||
<>
|
||||
<Box
|
||||
sx={{
|
||||
p: 1.5,
|
||||
px: 2,
|
||||
borderBottom: 1,
|
||||
borderColor: 'divider',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
bgcolor: 'background.paper',
|
||||
minHeight: 52,
|
||||
flexShrink: 0,
|
||||
}}
|
||||
>
|
||||
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
|
||||
<FolderOpenRoundedIcon color="primary" sx={{ fontSize: 22 }} />
|
||||
<Typography variant="subtitle1" fontWeight={700}>
|
||||
VFS Dateisystem
|
||||
</Typography>
|
||||
</Box>
|
||||
|
||||
<Tooltip title="VFS-Dateisystem schließen">
|
||||
<IconButton
|
||||
size="small"
|
||||
onClick={() => vfsAutomat.actions.closeVfs()}
|
||||
aria-label="VFS schließen"
|
||||
>
|
||||
<CloseRoundedIcon fontSize="small" />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
</Box>
|
||||
|
||||
<Box sx={{ flexGrow: 1, minHeight: 0, overflow: 'hidden' }}>
|
||||
<VfsFileExplorer
|
||||
files={files}
|
||||
loading={loadingFiles}
|
||||
selectedFileName={selectedFileName}
|
||||
searchQuery={searchQuery}
|
||||
onSelectFile={(name) => vfsAutomat.actions.selectFile(name)}
|
||||
onRefresh={() => vfsAutomat.actions.loadFiles()}
|
||||
onOpenNewDialog={() => vfsAutomat.actions.setNewFileDialogOpen(true)}
|
||||
onSearchChange={(q) => vfsAutomat.actions.setSearchQuery(q)}
|
||||
onDownload={(name) => vfsAutomat.actions.downloadFile(name)}
|
||||
onDelete={(name) => vfsAutomat.actions.deleteFile(name)}
|
||||
onUpload={(filesToUpload) => vfsAutomat.actions.uploadFiles(filesToUpload)}
|
||||
onMentionInChat={this.handleMentionInChat}
|
||||
/>
|
||||
</Box>
|
||||
</>
|
||||
)}
|
||||
|
||||
{/* New File Dialog */}
|
||||
<VfsNewFileDialog
|
||||
open={newFileDialogOpen}
|
||||
onClose={() => vfsAutomat.actions.setNewFileDialogOpen(false)}
|
||||
onCreate={(name) => vfsAutomat.actions.createFile(name)}
|
||||
isCreating={isSaving}
|
||||
/>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user