Skip to content

Commit

Permalink
Merge pull request #39 from Strexas/MDE/PKFE-22
Browse files Browse the repository at this point in the history
MDE/PKFE-22
  • Loading branch information
mantvydasdeltuva authored Aug 21, 2024
2 parents 731943d + b7a385b commit 05ef057
Show file tree
Hide file tree
Showing 10 changed files with 224 additions and 21 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { EditorToolbar } from '@/features/editor/components/editorView';
import { useWorkspaceContext } from '@/features/editor/hooks';
import { axios, socket } from '@/lib';
import { Endpoints, FileTypes } from '@/types';
import { Endpoints } from '@/types';
import { getUUID } from '@/utils';
import { DataGrid, GridColDef, GridRowsProp, useGridApiRef } from '@mui/x-data-grid';
import Papa from 'papaparse';
Expand Down Expand Up @@ -40,7 +40,11 @@ export const EditorView: React.FC = () => {

useEffect(() => {
const getWorkspaceFile = async () => {
if (Workspace.fileType === FileTypes.FOLDER) return;
if (!Workspace.fileId) {
setRows([]);
setColumns([]);
return;
}

setIsLoading(true);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,8 @@ export const FileTreeItem = React.forwardRef(function CustomTreeItem(
const Workspace = useWorkspaceContext();

const handleClick = (newId: string, newLabel: string, newType: FileTypes) => {
if (newType === FileTypes.FOLDER) return;

Workspace.update(newId, newLabel, newType);
};

Expand Down
3 changes: 0 additions & 3 deletions app/front-end/src/features/editor/components/filebar.tsx

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { List } from '@mui/material';

export interface FilebarGroupProps {
children: React.ReactNode;
}

/**
* `FilebarGroup` is a functional component that arranges its children in a horizontal list layout.
*
* @description This component is designed to group its child components in a horizontal row using Material-UI's `List` component.
* It applies styles to ensure that the child elements are displayed in a flexible, row-wise layout that allows horizontal scrolling.
*
* @component
*
* @example
* // Example usage of the FilebarGroup component
* <FilebarGroup>
* <FilebarItem />
* <FilebarItem />
* </FilebarGroup>
*
* @param {FilebarGroupProps} props - The props object for the FilebarGroup component.
* @param {React.ReactNode} props.children - The child elements to be displayed inside the FilebarGroup.
*
* @returns {JSX.Element} The `List` component containing the grouped child elements.
*/
export const FilebarGroup: React.FC<FilebarGroupProps> = ({ children }) => {
return (
<List sx={{ display: 'flex', flexDirection: 'row', height: '100%', p: '0', overflowX: 'auto' }}>{children}</List>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import { useWorkspaceContext } from '@/features/editor/hooks';
import { FileTypes } from '@/types';
import { Close as CloseIcon } from '@mui/icons-material';
import { Box, IconButton, Typography, useTheme } from '@mui/material';

export interface FilebarGroupItemProps {
fileId: string;
fileLabel: string;
fileType: FileTypes;
}

/**
* `FilebarGroupItem` is a functional component that represents an individual item in the file bar group.
*
* @description This component displays the label of a file or folder within the file bar, allowing the user to select it and switch
* to its corresponding workspace. It also includes a close button to remove the item from the workspace.
*
* @component
*
* @example
* // Example usage of the FilebarGroupItem component
* <FilebarGroupItem fileId="1" fileLabel="Document.txt" fileType={FileTypes.TXT} />
*
* @param {FilebarGroupItemProps} props - The props object for the FilebarGroupItem component.
* @param {string} props.fileId - The unique identifier of the file or folder.
* @param {string} props.fileLabel - The label (name) of the file or folder to be displayed.
* @param {FileTypes} props.fileType - The type of the file (e.g., txt, csv, folder).
*
* @returns {JSX.Element} A `Box` component representing an item in the file bar with a clickable label and a close button.
*/
export const FilebarGroupItem: React.FC<FilebarGroupItemProps> = ({ fileId, fileLabel, fileType }) => {
const Theme = useTheme();
const Workspace = useWorkspaceContext();

return (
<Box
id={fileId}
sx={{
height: '100%',
pl: '1rem',
pr: '0.5rem',
bgcolor: Workspace.fileId === fileId ? Theme.palette.background.default : Theme.palette.action.selected,
borderRadius: '0rem 0rem 0.625rem 0.625rem',
':hover': {
backgroundColor: Theme.palette.background.paper,
},
cursor: 'pointer',
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
gap: '0.5rem',
}}
onClick={() => {
// Update the workspace to the selected file
Workspace.update(fileId, fileLabel, fileType);
}}
>
<Typography
sx={{
fontSize: 12,
fontWeight: 'bold',
textTransform: 'none',
maxWidth: '10rem',
overflow: 'hidden',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
}}
>
{fileLabel}
</Typography>
<IconButton
size='small'
onClick={(event) => {
event.stopPropagation();
}}
onMouseDown={(event) => {
event.stopPropagation();
// Remove the file from the workspace
Workspace.remove(fileId);
}}
>
<CloseIcon sx={{ fontSize: 12, color: Theme.palette.text.primary }} />
</IconButton>
</Box>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { FilebarGroup, FilebarGroupItem } from '@/features/editor/components/filebarView';
import { useWorkspaceContext } from '@/features/editor/hooks';

/**
* `FilebarView` is a functional component that renders a group of file items currently open in the workspace.
*
* @description This component utilizes the `FilebarGroup` and `FilebarGroupItem` components to display the files
* that have been recently opened in the workspace. It maps over the `fileHistory` from the workspace context to generate
* individual `FilebarGroupItem` components for each file.
*
* @component
*
* @example
* // Example usage of the FilebarView component
* <FilebarView />
*
* @returns {JSX.Element} A `FilebarGroup` component containing a list of `FilebarGroupItem` components.
*/
export const FilebarView: React.FC = () => {
const Workspace = useWorkspaceContext();

return (
<FilebarGroup>
{Workspace.fileHistory.map((item, index) => (
<FilebarGroupItem key={index} {...item} />
))}
</FilebarGroup>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export { FilebarGroup } from './filebarGroup';
export type { FilebarGroupProps } from './filebarGroup';
export { FilebarGroupItem } from './filebarGroupItem';
export type { FilebarGroupItemProps } from './filebarGroupItem';
export { FilebarView } from './filebarView';
2 changes: 1 addition & 1 deletion app/front-end/src/features/editor/components/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export { Console } from './console';
export { EditorView } from './editorView';
export { Filebar } from './filebar';
export { FilebarView } from './filebarView';
export { FileTreeView } from './fileTreeView/fileTreeView';
export { ToolbarView } from './toolbarView';
19 changes: 10 additions & 9 deletions app/front-end/src/features/editor/index.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { Console, EditorView, Filebar, FileTreeView, ToolbarView } from '@/features/editor/components';
import { Console, EditorView, FilebarView, FileTreeView, ToolbarView } from '@/features/editor/components';
import { WorkspaceContextProvider } from '@/features/editor/stores';
import { Box, useTheme } from '@mui/material';

/**
* Editor component sets up the main layout for the editor application, integrating various UI components within a responsive
* `Editor` component sets up the main layout for the editor application, integrating various UI components within a responsive
* flexbox layout.
*
* @description This component uses Material-UI's `Box` component to create a flexible layout for the editor interface. It
* integrates multiple sub-components, including `FileTreeView`, `Toolbar`, `EditorView`, `Filebar`, and `Console`, each
* integrates multiple sub-components, including `FileTreeView`, `Toolbar`, `EditorView`, `FilebarView`, and `Console`, each
* occupying a specific region of the layout. The component also provides a context for workspace management using
* `WorkspaceContextProvider`.
*
Expand All @@ -16,10 +16,11 @@ import { Box, useTheme } from '@mui/material';
* - A main content area on the right (`80%` width) that includes:
* - A `ToolbarView` at the top (`15%` height).
* - An `EditorView` below the toolbar (`60%` height).
* - A `Filebar` at the bottom (`5%` height).
* - A `Console` component at the bottom (`20%` height) with rounded bottom corners.
* - A `FilebarView` above the console (`3%` height).
* - A `Console` component at the bottom (`22%` height) with rounded bottom corners.
*
* The layout is styled using the current theme's colors and responsive design principles.
* The layout is styled using the current theme's colors and responsive design principles. The theme controls the background
* colors, border-radius, and other styling aspects, making the layout adapt to light and dark modes seamlessly.
*
* @component
*
Expand Down Expand Up @@ -77,18 +78,18 @@ export const Editor = () => {
<Box
sx={{
width: '100%',
height: '5%',
height: '3%',
display: 'flex',
flexDirection: 'row',
bgcolor: Theme.palette.action.selected,
}}
>
<Filebar />
<FilebarView />
</Box>
<Box
sx={{
width: '100%',
height: '20%',
height: '22%',
display: 'flex',
flexDirection: 'column',
bgcolor: Theme.palette.background.paper,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { FilebarGroupItemProps } from '@/features/editor/components/filebarView';
import { FileTypes } from '@/types';
import React, { createContext, useState } from 'react';

Expand All @@ -6,32 +7,37 @@ export interface WorkspaceContextProps {
fileLabel: string;
fileType: FileTypes;
update: (newId: string, newLabel: string, newType: FileTypes) => void;
fileHistory: FilebarGroupItemProps[];
remove: (fileId: string) => void;
}

export const WorkspaceContext = createContext<WorkspaceContextProps>({
fileId: '',
fileLabel: '',
fileType: FileTypes.FOLDER,
update: () => {},
fileHistory: [],
remove: () => {},
});

interface Props {
children?: React.ReactNode;
}

/**
* WorkspaceContextProvider component provides context for managing the current workspace file's state.
* `WorkspaceContextProvider` is a component that provides context for managing the current workspace file's state.
*
* @description This component sets up a React context for sharing workspace file information across components. It manages
* the current file's ID, label, and type, and provides a function to update these values. The context is created using
* `createContext` and provided to the component tree via `WorkspaceContext.Provider`. The context is intended for use in
* scenarios where multiple components need access to or need to update the current workspace file's details.
* @description This component sets up a React context for managing and sharing workspace file information across the
* application. It tracks the current file's ID, label, and type, and provides an API to update these values. The context
* also maintains a history of recently opened files (excluding folders) and supports removing files from this history.
*
* The context includes:
* - `fileId`: The unique identifier for the current file.
* - `fileLabel`: The label or name of the current file.
* - `fileType`: The type of the file (e.g., folder, document).
* - `update`: A function to update the current file's ID, label, and type.
* - `update`: A function to update the current file's ID, label, and type, and add the file to the history.
* - `fileHistory`: An array of recently opened files, excluding folders.
* - `remove`: A function to remove a file from the history and update the current file if the removed file was active.
*
* @component
*
Expand All @@ -52,18 +58,60 @@ export const WorkspaceContextProvider: React.FC<Props> = ({ children }) => {
const [fileId, setFileId] = useState<string>('');
const [fileLabel, setFileLabel] = useState<string>('');
const [fileType, setFileType] = useState<FileTypes>(FileTypes.FOLDER);
const [fileHistory, setFileHistory] = useState<FilebarGroupItemProps[]>([]);

const update = (newId: string, newLabel: string, newType: FileTypes) => {
setFileId(newId);
setFileLabel(newLabel);
setFileType(newType);
setFileHistory((prevHistory) => {
// Prevent adding directories to history
if (newType === FileTypes.FOLDER) {
return prevHistory;
}

// Prevent adding duplicate files
if (prevHistory.find((item) => item.fileId === newId)) {
return prevHistory;
}

// Add the new file to the history
return [...prevHistory, { fileId: newId, fileLabel: newLabel, fileType: newType }];
});
};

const remove = (fileId_remove: string) => {
setFileHistory((prevHistory) => {
// Remove the file from the history
const newHistory = prevHistory.filter((item) => item.fileId !== fileId_remove);

// Check if the file being removed was the current file
if (fileId === fileId_remove) {
// If there are no files left, reset the file state
if (newHistory.length === 0) {
setFileId('');
setFileLabel('');
setFileType(FileTypes.FOLDER);
} else {
// Set the state to the latest file in the history
const latest_file = newHistory[newHistory.length - 1];
setFileId(latest_file.fileId);
setFileLabel(latest_file.fileLabel);
setFileType(latest_file.fileType);
}
}

return newHistory;
});
};

const WorkspaceContextValue: WorkspaceContextProps = {
fileId,
fileLabel,
fileType,
update,
fileHistory,
remove,
};

return <WorkspaceContext.Provider value={WorkspaceContextValue}>{children}</WorkspaceContext.Provider>;
Expand Down

0 comments on commit 05ef057

Please sign in to comment.