Skip to content

MDE/PKFE-32 #55

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Sep 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 1 addition & 5 deletions app/back-end/src/routes/workspace_aggregate_route.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,11 +104,7 @@ def get_workspace_aggregate_all(relative_path):
or header_values[field] == float("-inf")
or (
header_values[field] == float(0)
and (
header_actions[field] != "min"
or header_actions[field] != "max"
or header_actions[field] != "cnt"
)
and header_actions[field] not in ["min", "max", "cnt"]
)
else (
str(int(header_values[field]))
Expand Down
6 changes: 4 additions & 2 deletions app/front-end/src/app/provider.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { SessionContextProvider, ThemeContextProvider } from '@/stores';
import { SessionContextProvider, StatusContextProvider, ThemeContextProvider } from '@/stores';
import { CircularProgress } from '@mui/material';
import React from 'react';

Expand Down Expand Up @@ -40,7 +40,9 @@ export const AppProvider = ({ children }: AppProviderProps) => {
fallback={<CircularProgress sx={{ display: 'flex', justifyItems: 'center', alignContent: 'center' }} />}
>
<SessionContextProvider>
<ThemeContextProvider>{children}</ThemeContextProvider>
<StatusContextProvider>
<ThemeContextProvider>{children}</ThemeContextProvider>
</StatusContextProvider>
</SessionContextProvider>
</React.Suspense>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const StyledGridColumnMenuContainer = styled(GridColumnMenuContainer)(({ theme }
}));

interface GridColumnMenuContainerProps extends GridColumnMenuProps {
disabled: boolean;
handleAggregation: (column: string, action: FileContentAggregationActions) => void;
}

Expand All @@ -30,6 +31,7 @@ interface GridColumnMenuContainerProps extends GridColumnMenuProps {
* @component
*/
export const EditorColumnMenu: React.FC<GridColumnMenuContainerProps> = ({
disabled,
handleAggregation,
hideMenu,
colDef,
Expand All @@ -40,7 +42,7 @@ export const EditorColumnMenu: React.FC<GridColumnMenuContainerProps> = ({
? fileContent.aggregations[colDef.field].action
: FileContentAggregationActions.NONE;

return (
return !disabled ? (
<StyledGridColumnMenuContainer hideMenu={hideMenu} colDef={colDef} {...other}>
<EditorColumnMenuAggregationItem
initialValue={aggregationActiveAction}
Expand All @@ -50,5 +52,5 @@ export const EditorColumnMenu: React.FC<GridColumnMenuContainerProps> = ({
<Divider />
<GridColumnMenuHideItem onClick={hideMenu} colDef={colDef!} />
</StyledGridColumnMenuContainer>
);
) : null;
};
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { useStatusContext } from '@/hooks';
import { socket } from '@/lib';
import { Events } from '@/types';
import { Done as DoneIcon, Error as ErrorIcon } from '@mui/icons-material';
Expand All @@ -12,7 +13,6 @@ import {
import { useEffect, useState } from 'react';

interface EditorToolbarProps extends GridToolbarProps, ToolbarPropsOverrides {
disabled?: boolean;
handleSave: () => void;
}

Expand Down Expand Up @@ -47,11 +47,12 @@ interface EditorToolbarProps extends GridToolbarProps, ToolbarPropsOverrides {
*
* @returns {JSX.Element} The rendered toolbar component with buttons for DataGrid actions and a save button with status feedback.
*/
export const EditorToolbar: React.FC<EditorToolbarProps> = ({ disabled, handleSave }) => {
export const EditorToolbar: React.FC<EditorToolbarProps> = ({ handleSave }) => {
const [isSaving, setIsSaving] = useState(false);
const [saveStatus, setSaveStatus] = useState(true);

const Theme = useTheme();
const { blocked } = useStatusContext();

useEffect(() => {
const handleWorkspaceFileSaveFeedback = (data: { status: 'success' | 'error' }) => {
Expand All @@ -63,7 +64,7 @@ export const EditorToolbar: React.FC<EditorToolbarProps> = ({ disabled, handleSa
return () => {
socket.off(Events.WORKSPACE_FILE_SAVE_FEEDBACK_EVENT);
};
});
}, []);

return (
<GridToolbarContainer>
Expand All @@ -77,7 +78,7 @@ export const EditorToolbar: React.FC<EditorToolbarProps> = ({ disabled, handleSa
setIsSaving(true);
handleSave();
}}
disabled={disabled || isSaving}
disabled={blocked}
startIcon={
isSaving ? (
<CircularProgress size={16} sx={{ color: Theme.palette.primary.main }} />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { EditorColumnMenu, EditorHeader, EditorToolbar } from '@/features/editor/components/editorView';
import { useWorkspaceContext } from '@/features/editor/hooks';
import { FileContentAggregationActions, FileDataRequestDTO, FileDataResponseDTO } from '@/features/editor/types';
import { useSessionContext } from '@/hooks';
import { useSessionContext, useStatusContext } from '@/hooks';
import { axios } from '@/lib';
import { Endpoints } from '@/types';
import { DataGrid, useGridApiRef } from '@mui/x-data-grid';
import { DataGrid, GridPagination, useGridApiRef } from '@mui/x-data-grid';
import { useCallback, useEffect, useState } from 'react';

/**
Expand Down Expand Up @@ -56,10 +56,13 @@ export const EditorView: React.FC = () => {
});

const { connected } = useSessionContext();
const { file, fileContent, filePagination, fileStateReset, fileStateUpdate } = useWorkspaceContext();
const { file, fileContent, filePagination, fileStateUpdate } = useWorkspaceContext();
const { blocked, blockedStateUpdate } = useStatusContext();
const ref = useGridApiRef();

const handleSave = async () => {
blockedStateUpdate(true);

const data: FileDataRequestDTO = {
page: filePagination.page,
rowsPerPage: filePagination.rowsPerPage,
Expand All @@ -83,6 +86,8 @@ export const EditorView: React.FC = () => {
fileStateUpdate(undefined, { ...fileContent, aggregations: responseColumnsAggregation }, undefined);
} catch (error) {
console.error('Failed to save file content:', error);
} finally {
blockedStateUpdate(false);
}
};

Expand All @@ -94,20 +99,27 @@ export const EditorView: React.FC = () => {
break;
default:
{
const response = await axios.get(`${Endpoints.WORKSPACE_AGGREGATE}/${file.id}`, {
params: {
field: column,
action: action,
},
});

const { field: responseField, action: responseAction, value: responseValue } = response.data;

const newAggregations = {
...fileContent.aggregations,
[responseField]: { action: responseAction, value: responseValue },
};
fileStateUpdate(undefined, { ...fileContent, aggregations: newAggregations }, undefined);
blockedStateUpdate(true);
try {
const response = await axios.get(`${Endpoints.WORKSPACE_AGGREGATE}/${file.id}`, {
params: {
field: column,
action: action,
},
});

const { field: responseField, action: responseAction, value: responseValue } = response.data;

const newAggregations = {
...fileContent.aggregations,
[responseField]: { action: responseAction, value: responseValue },
};
fileStateUpdate(undefined, { ...fileContent, aggregations: newAggregations }, undefined);
} catch (error) {
console.error('Failed to fetch aggregation data:', error);
} finally {
blockedStateUpdate(false);
}
}
break;
}
Expand All @@ -119,7 +131,7 @@ export const EditorView: React.FC = () => {
return;
}

setIsLoading(true);
blockedStateUpdate(true);

try {
const response = await axios.get<FileDataResponseDTO>(`${Endpoints.WORKSPACE_FILE}/${file.id}`, {
Expand All @@ -134,6 +146,7 @@ export const EditorView: React.FC = () => {
console.error('Failed to fetch file content:', error);
} finally {
setIsLoading(false);
blockedStateUpdate(false);
}
}, [file.id, filePagination.page, filePagination.rowsPerPage]);

Expand Down Expand Up @@ -186,7 +199,7 @@ export const EditorView: React.FC = () => {
return (
<DataGrid
sx={{ height: '100%', border: 'none' }}
loading={isLoading}
loading={blocked || isLoading}
rows={fileContent.rows}
columns={fileContent.columns}
pagination
Expand All @@ -198,6 +211,7 @@ export const EditorView: React.FC = () => {
paginationModel: { pageSize: filePagination.rowsPerPage, page: filePagination.page },
},
}}
disableColumnMenu={blocked}
pageSizeOptions={[25, 50, 100]}
onPaginationModelChange={(model) => {
fileStateUpdate(undefined, undefined, {
Expand All @@ -207,8 +221,9 @@ export const EditorView: React.FC = () => {
});
}}
slots={{
toolbar: (props) => <EditorToolbar {...props} disabled={isLoading} handleSave={handleSave} />,
columnMenu: (props) => <EditorColumnMenu {...props} handleAggregation={handleAggregation} />,
toolbar: (props) => <EditorToolbar {...props} disabled={blocked || !file.id} handleSave={handleSave} />,
columnMenu: (props) => <EditorColumnMenu {...props} disabled={blocked} handleAggregation={handleAggregation} />,
pagination: (props) => <GridPagination disabled={blocked} {...props} />,
}}
slotProps={{
toolbar: {},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { FileTreeItemContextMenu, FileTreeItemLabel } from '@/features/editor/co
import { useWorkspaceContext } from '@/features/editor/hooks';
import { FileTypes } from '@/features/editor/types';
import { getIconFromFileType, isExpandable } from '@/features/editor/utils';
import { useStatusContext } from '@/hooks';
import { FolderRounded as FolderRoundedIcon } from '@mui/icons-material';
import Collapse from '@mui/material/Collapse';
import { alpha, styled } from '@mui/material/styles';
Expand Down Expand Up @@ -136,6 +137,7 @@ export const FileTreeItem = React.forwardRef(function CustomTreeItem(
}

const { fileStateUpdate, filesHistoryStateUpdate } = useWorkspaceContext();
const { blocked } = useStatusContext();
const [contextMenu, setContextMenu] = useState<(EventTarget & HTMLDivElement) | null>(null);
const [contextMenuPosition, setContextMenuPosition] = useState<{ top: number; left: number }>({
top: 0,
Expand Down Expand Up @@ -170,10 +172,15 @@ export const FileTreeItem = React.forwardRef(function CustomTreeItem(
<StyledFileTreeItemContent
{...getContentProps({
onClick: (event) => {
if (getContentProps().onClick) getContentProps().onClick(event);
handleClick(item.id, item.label, item.fileType);
if (!blocked) {
if (getContentProps().onClick) getContentProps().onClick(event);
handleClick(item.id, item.label, item.fileType);
}
},

onContextMenu: (event) => {
if (!blocked) handleOpenContextMenu(event);
},
onContextMenu: (event) => handleOpenContextMenu(event),
className: clsx('content', {
'Mui-expanded': status.expanded,
'Mui-selected': status.selected,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { FileTreeItem, FileTreeItemContextMenu } from '@/features/editor/components/fileTreeView/fileTreeItem';
import { useWorkspaceContext } from '@/features/editor/hooks';
import { useStatusContext } from '@/hooks';
import { Box, Button, LinearProgress } from '@mui/material';
import { RichTreeView } from '@mui/x-tree-view/RichTreeView';
import { useState } from 'react';
Expand Down Expand Up @@ -43,6 +44,7 @@ export const FileTreeView: React.FC = () => {
});

const { fileTree, fileTreeIsLoading } = useWorkspaceContext();
const { blocked } = useStatusContext();

const handleOpenContextMenu = (event: React.MouseEvent<HTMLButtonElement>) => {
event.stopPropagation();
Expand All @@ -67,7 +69,12 @@ export const FileTreeView: React.FC = () => {
</Box>
) : (
<>
<Button variant='outlined' onClick={(event) => handleOpenContextMenu(event)} sx={{ mb: '1.5rem' }}>
<Button
variant='outlined'
disabled={blocked}
onClick={(event) => handleOpenContextMenu(event)}
sx={{ mb: '1.5rem' }}
>
New
</Button>
<FileTreeItemContextMenu
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { useWorkspaceContext } from '@/features/editor/hooks';
import { FileModel } from '@/features/editor/types';
import { useStatusContext } from '@/hooks';
import { Close as CloseIcon } from '@mui/icons-material';
import { alpha, Box, IconButton, Typography, useTheme } from '@mui/material';

Expand All @@ -25,6 +26,7 @@ import { alpha, Box, IconButton, Typography, useTheme } from '@mui/material';
export const FilebarGroupItem: React.FC<FileModel> = (file) => {
const Theme = useTheme();
const Workspace = useWorkspaceContext();
const { blocked } = useStatusContext();

const { id, label } = file;

Expand All @@ -39,18 +41,24 @@ export const FilebarGroupItem: React.FC<FileModel> = (file) => {
borderRadius: '0rem',
':hover': {
backgroundColor:
Workspace.file.id === id ? Theme.palette.background.default : alpha(Theme.palette.background.default, 0.5),
Workspace.file.id === id
? Theme.palette.background.default
: blocked
? Theme.palette.action.selected
: alpha(Theme.palette.background.default, 0.5),
},
cursor: 'pointer',
cursor: blocked ? 'default' : 'pointer',
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
gap: '0.5rem',
}}
onClick={() => {
// Update the workspace to the selected file
Workspace.fileStateUpdate(file);
Workspace.filesHistoryStateUpdate(file);
if (!blocked) {
Workspace.fileStateUpdate(file);
Workspace.filesHistoryStateUpdate(file);
}
}}
>
<Typography
Expand All @@ -68,6 +76,7 @@ export const FilebarGroupItem: React.FC<FileModel> = (file) => {
</Typography>
<IconButton
size='small'
disabled={blocked}
onClick={(event) => {
event.stopPropagation();
}}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { useStatusContext } from '@/hooks';
import { SvgIconComponent } from '@mui/icons-material';
import { alpha, Box, Button, useTheme } from '@mui/material';

Expand Down Expand Up @@ -36,11 +37,13 @@ export interface ToolbarGroupItemProps {
*/
export const ToolbarGroupItem: React.FC<ToolbarGroupItemProps> = ({ icon: Icon, label, onClick }) => {
const Theme = useTheme();
const { blocked } = useStatusContext();

return (
<Box sx={{ height: '40%', alignContent: 'center' }}>
<Button
startIcon={<Icon sx={{ color: Theme.palette.text.primary }} />}
disabled={blocked}
onClick={() => onClick()}
sx={{
color: Theme.palette.text.primary,
Expand Down
Loading
Loading