Skip to content

Commit

Permalink
Sean 5/9 Fixed render issues with more MUI Components; added JSDoc co…
Browse files Browse the repository at this point in the history
…mment blocks throughout the codebase for better inline documentation that adheres to industry best practices; added a window resizer to iframe

>
>
Co-authored-by: Heather Pfeiffer <[email protected]>
Co-authored-by: Jesse Wowczuk <[email protected]>
Co-authored-by: Zack Vandiver <[email protected]>
Co-authored-by: Austin Alvarez <[email protected]>
  • Loading branch information
sfryan95 committed May 9, 2024
1 parent 5767d4e commit 6a6226d
Show file tree
Hide file tree
Showing 139 changed files with 5,225 additions and 2,176 deletions.
21 changes: 19 additions & 2 deletions app/src/Dashboard/NavbarDash.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,25 @@ const StyledMenuItem = withStyles((theme) => ({
}
}
}))(MenuItem);
// TO DO: set types of props validation
export default function NavBar(props) {

/**
* NavBar is a component that provides navigation and theming controls for an application.
* It includes a logo, navigation links, and buttons for sorting projects and toggling the theme.
* The NavBar uses a mix of MUI components styled with custom themes and styles.
*
* @param {Object} props - The properties passed to the component.
* @param {Function} props.optionClicked - Callback function called when a sort option is selected.
* @param {boolean} props.isThemeLight - Indicates if the light theme is currently active.
* @param {Function} props.setTheme - Function to toggle the theme between light and dark.
* @returns {JSX.Element} The NavBar component which includes a logo, navigation links, and control buttons.
*
* The NavBar is styled using `makeStyles` to handle theming and spacing. It features a responsive AppBar
* containing an Avatar with the application's logo, a Typography component for the application name,
* and various buttons for navigating the application, sorting data, and toggling the theme.
* The sorting options are presented in a custom-styled Menu component, `StyledMenu`, with specific
* icons indicating the sort method. The theme toggle button changes icon based on the current theme.
*/
export default function NavBar(props): JSX.Element {
// TO DO: import setStyle
const classes = useStyles();
const style = useSelector((store) => store.styleSlice);
Expand Down
20 changes: 20 additions & 0 deletions app/src/Dashboard/Project.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,26 @@ type props = {
const currUserSSID = window.localStorage.getItem('ssid') || 'unavailable';
const currUsername = window.localStorage.getItem('username') || 'unavailable';

/**
* `Project` is a React component that displays information about a specific project, such as its name,
* author, and the number of likes it has received. It provides functionality for liking, copying, publishing,
* commenting on, and deleting projects. The component integrates several mutations using Apollo Client to interact
* with a GraphQL backend.
* @param {Object} props - The properties passed to the component.
* @param {string} props.name - The name of the project.
* @param {string} props.id - The unique identifier for the project.
* @param {string} props.userId - The user ID of the project owner.
* @param {string} props.username - The username of the project owner.
* @param {number} props.likes - The number of likes the project has received.
* @param {boolean} props.published - Indicates if the project is currently published.
* @param {Array} props.comments - An array of comment objects associated with the project.
* @returns {JSX.Element} The rendered component which allows interaction with project data and includes
* buttons for different actions depending on the user and project status.
*
* Each button in the component is associated with a specific action (like, copy, publish, comment, delete) and
* uses GraphQL mutations to perform these actions. The component also manages local state for handling comments,
* modals, and toggling UI elements based on the user's interaction.
*/
const Project = ({
name,
likes,
Expand Down
78 changes: 59 additions & 19 deletions app/src/Dashboard/ProjectContainer.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import React, { useState} from 'react';
import { ThemeProvider, Theme, StyledEngineProvider, useTheme } from '@mui/material/styles';
import React, { useState } from 'react';
import {
ThemeProvider,
Theme,
StyledEngineProvider,
useTheme
} from '@mui/material/styles';
import makeStyles from '@mui/styles/makeStyles';
import { useQuery } from '@apollo/client';
import Tabs from '@mui/material/Tabs';
Expand All @@ -11,22 +16,27 @@ import NavBarDash from './NavbarDash';
import { useSelector } from 'react-redux';
import { theme1, theme2 } from '../public/styles/theme';


declare module '@mui/styles/defaultTheme' {
interface DefaultTheme extends Theme {}
}


// Implement Apollo Client useQuery hook to retrieve data from the server through graphQL. This includes 2 steps:
// 1) Impliment Apollo Provider in the top component in ./src/index.js, this allows children components access to the queried data
// 2) useQuery hook will update the data stored in Apollo Client's cache and automatically trigger child components rendering


// setting light and dark themes (navbar and background); linked to theme.ts
const lightTheme = theme1;
const darkTheme = theme2; // dark mode color in theme.ts not reached

const arrToComponent = arr =>
/**
* Transforms an array of project data into an array of <Project> React components.
* Each project in the array is passed as props to the <Project> component, creating a list
* of these components based on the provided array. Each component is given a unique `key` prop
* based on its index in the array to optimize React's rendering process.
* @param {Array} arr - An array of project objects, where each object contains project data.
* @returns {Array<JSX.Element>} An array of <Project> components populated with data from the input array.
*/
const arrToComponent = (arr): Array<JSX.Element> =>
arr.map((proj, index) => (
<Project
key={index}
Expand All @@ -41,8 +51,14 @@ const arrToComponent = arr =>
/>
));

// Start Pulled from materialUI to create a tab panel
const a11yProps = (index: any) => ({
/**
* Generates accessibility props for a tab component within a tab panel. These properties help in
* linking the tab to its corresponding tab panel, improving accessibility and usability for users
* with assistive technologies.
* @param {any} index - The index of the tab and its corresponding panel.
* @returns {Object} An object containing the `id` and `aria-controls` attributes for accessibility purposes.
*/
const a11yProps = (index: any): Object => ({
id: `vertical-tab-${index}`,
'aria-controls': `vertical-tabpanel-${index}`
});
Expand Down Expand Up @@ -75,7 +91,7 @@ const TabPanelItem = (props: TabPanelProps): JSX.Element => {
);
};

const useStyles = makeStyles(theme => ({
const useStyles = makeStyles((theme) => ({
root: {
flexGrow: 1,
// backgroundColor: theme.palette.background.paper,
Expand All @@ -85,7 +101,31 @@ const useStyles = makeStyles(theme => ({
// borderRight: `1px solid ${theme.palette.divider}`
}
}));
// End of prefab code to generate a tab panel

/**
* `ProjectContainer` is a React component that manages the display and sorting of project data retrieved
* from a GraphQL server using the Apollo Client. It provides a user interface with two dashboards:
* a shared dashboard that displays all published projects and a private dashboard that shows projects
* created by the currently logged-in user. The component includes sorting functionality based on project
* rating, creation date, or user.
*
* @returns {JSX.Element} The ProjectContainer component which provides a tabbed interface for navigating
* between shared and private dashboards, each displaying a list of projects.
*
* This component utilizes MUI's Tabs for navigation between the dashboards. It leverages the Apollo Client's
* `useQuery` hook to fetch projects data and automatically update the UI upon data changes. Sorting preferences
* are managed through local state and applied to the project data based on user interaction. The component
* supports theming and uses `ThemeProvider` to switch between light and dark themes based on user settings.
*
* Dependencies:
* - Apollo Client: For data fetching and state management with GraphQL.
* - Material-UI: For UI components and theming.
* - Redux: For managing application-wide state like theme settings.
*
* The component is designed to be responsive and accessible, with appropriate ARIA attributes for navigation
* and content sections. It includes error handling for data fetching issues and a loading state during data
* retrieval.
*/
const ProjectContainer = (): JSX.Element => {
const classes = useStyles();
const [value, setValue] = useState(0);
Expand All @@ -98,26 +138,26 @@ const ProjectContainer = (): JSX.Element => {
const userSSID = window.localStorage.getItem('ssid') || 'unavailable';
const username = window.localStorage.getItem('username') || 'unavailable';
const [isThemeLight, setTheme] = useState(true);
const style = useSelector(store => store.styleSlice)
const style = useSelector((store) => store.styleSlice);
// hook for sorting menu
const [selectedOption, setSelectedOption] = useState('RATING');
const sortByRating = projects => {
const sortByRating = (projects) => {
// generate a sorted array of public projects based on likes
const sortedRatings = projects.sort((a, b) => b.likes - a.likes);
return sortedRatings;
};
const sortByDate = projects => {
const sortByDate = (projects) => {
// generate a sorted array of public projects based on date
const sortedRatings = projects.sort((a, b) => b.createdAt - a.createdAt);
return sortedRatings;
};
const sortByUser = projects => {
const sortByUser = (projects) => {
// generate a sorted array of public projects based on username
const sortedRatings = projects.sort((a, b) => b.username - a.username);
return sortedRatings;
};
// function for selecting drop down sorting menu
const optionClicked = value => {
const optionClicked = (value) => {
setSelectedOption(value);
};
// useQuery hook abstracts fetch request
Expand All @@ -129,12 +169,12 @@ const ProjectContainer = (): JSX.Element => {
if (error) return <p>Error :{error}</p>;
// based on resolver(getAllProject) for this query, the data is stored in the data object with the key 'getAllProjects'
const projects = data.getAllProjects;

//create array to hold the data recieved in the public dashboard the will be conditionally rendered
let sortedProjects = projects.filter(proj => {
let sortedProjects = projects.filter((proj) => {
return proj.published;
});
const userProjects = projects.filter(proj => {
const userProjects = projects.filter((proj) => {
return proj.username === username;
});
// checking which sorting method was selected from drop down menu and invoking correct sorting function
Expand All @@ -156,7 +196,7 @@ const ProjectContainer = (): JSX.Element => {
<div className={'dashboardContainer'}>
<NavBarDash
setTheme={setTheme}
// styles={[style]}
// styles={[style]}
isThemeLight={isThemeLight}
optionClicked={optionClicked}
/>
Expand Down
16 changes: 16 additions & 0 deletions app/src/components/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,22 @@ import { useDispatch } from 'react-redux';

import AppContainer from '../containers/AppContainer';

/**
* The `App` component is the root component of the React application. It performs an initial check
* to determine if a user is logged in (not a 'guest') by inspecting local storage, and updates the
* application's state accordingly using Redux. It then renders the `AppContainer`, which serves as
* the main container for the application's user interface.
*
* The `useEffect` hook is used to perform the login check once on component mount, ensuring that
* the login state is correctly set based on the presence of a specific item in local storage.
*
* @returns {JSX.Element} Renders the `AppContainer` wrapped within a div with a class of 'app',
* serving as the root of the user interface.
*
* This component interacts with Redux by dispatching actions to modify the global state, particularly
* the logged-in status of the user. This is central for managing conditional rendering and access
* throughout the application based on user authentication status.
*/
export const App: React.FC = (): JSX.Element => {
const dispatch = useDispatch();
useEffect(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,24 @@ import { deleteElement } from '../../../redux/reducers/slice/appStateSlice';
import { RootState } from '../../../redux/store';
import { emitEvent } from '../../../../src/helperFunctions/socket';

const AssignContainer = () => {
/**
* Provides an interface for assigning components to contexts within an application.
* The component allows the selection of contexts and components through dropdown menus,
* displays related data in tables, and permits the assignment of components to selected contexts.
* It leverages Redux for state management and may trigger socket events for real-time updates across sessions.
*
* This component integrates several subcomponents:
* - `ContextDropDown` for selecting contexts which triggers updates to the data table.
* - `DataTable` for displaying key-value pairs related to the selected context.
* - `ComponentDropDown` for selecting components which triggers updates to the component table.
* - `ComponentTable` for displaying a list of contexts associated with a selected component.
* - A button for assigning the selected component to the selected context, potentially emitting socket events if a room code is present.
*
* The state management involves interaction with the Redux store to fetch state information and dispatch actions related to context and component management.
*
* @returns {JSX.Element} A React component structured with a Grid layout, integrating forms and tables for managing and viewing context and component assignments.
*/
const AssignContainer = (): JSX.Element => {
const dispatch = useDispatch();
const defaultTableData = [{ key: 'Key', value: 'Value' }];
const [tableState, setTableState] = React.useState(defaultTableData);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,26 @@ import { RootState } from '../../../../redux/store';

const filter = createFilterOptions();

/**
* Renders an autocomplete dropdown list that allows the user to select or enter a component.
* When a component is selected or entered, this triggers a specified callback to render the component table.
* The dropdown uses a custom filter for suggestions, allowing users to add components not already listed in the options.
*
* @param {Object} props - The props passed to the ComponentDropDown component.
* @param {Function} props.renderComponentTable - Callback function that is triggered to render the component table based on the selected component.
* @param {Object|null} props.componentInput - The currently selected component object or null if nothing is selected.
* @param {Function} props.setComponentInput - Sets the state of the componentInput in the parent component.
*
* Redux State Dependencies:
* - `appState`: Expects `appState.components` from the Redux store to provide the list of available components.
*
* @returns {JSX.Element} A React Fragment that includes a Box containing the Autocomplete component which provides a dropdown for selecting components.
*/
const ComponentDropDown = ({
renderComponentTable,
componentInput,
setComponentInput
}) => {
}): JSX.Element => {
const { state } = useSelector((store: RootState) => ({
state: store.appState
}));
Expand Down Expand Up @@ -70,7 +85,7 @@ const ComponentDropDown = ({

return (
<Fragment>
<Box sx={{ display: 'flex', gap: 2, mb: 4}}>
<Box sx={{ display: 'flex', gap: 2, mb: 4 }}>
<Autocomplete
id="autoCompleteContextField"
value={componentInput}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,14 @@ import Paper from '@mui/material/Paper';
import { styled } from '@mui/material/styles';
import TableCell, { tableCellClasses } from '@mui/material/TableCell';

/**
* Styles the TableCell component using Material-UI's styling system. Custom styles are applied to table head and body cells:
* - Head cells are styled with a black background and white text.
* - Body cells have a font size of 14.
*
* @param {object} theme - The theme object provided by Material-UI's ThemeProvider.
* @returns {object} A styled TableCell component with customized appearance.
*/
const StyledTableCell = styled(TableCell)(({ theme }) => ({
[`&.${tableCellClasses.head}`]: {
backgroundColor: theme.palette.common.black,
Expand All @@ -18,6 +26,14 @@ const StyledTableCell = styled(TableCell)(({ theme }) => ({
}
}));

/**
* Styles the TableRow component to enhance table row appearance. Custom styles include:
* - Every odd row is styled with a background color for hover state.
* - Removes the border from the last child table cells and headers to enhance appearance.
*
* @param {object} theme - The theme object provided by Material-UI's ThemeProvider.
* @returns {JSX.Element} A styled TableRow component with alternate row coloring and modified border visibility.
*/
const StyledTableRow = styled(TableRow)(({ theme }) => ({
'&:nth-of-type(odd)': {
backgroundColor: theme.palette.action.hover
Expand All @@ -28,6 +44,16 @@ const StyledTableRow = styled(TableRow)(({ theme }) => ({
}
}));

/**
* A styled data table component that displays a list of items in a single column format.
* This component uses Material-UI to create a visually distinct table with styled cells and rows.
* It is specifically designed to display 'contexts consumed' but can be generalized for other single-column data.
*
* @param {Object} props - Component props.
* @param {Array<string>} props.target - The data array containing strings to be displayed in the table.
*
* @returns {JSX.Element} A TableContainer component housing a Table, where each row displays an element from the `target` prop.
*/
export default function DataTable({ target }) {
return (
<TableContainer component={Paper}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,27 @@ import TextField from '@mui/material/TextField';
import Autocomplete, { createFilterOptions } from '@mui/material/Autocomplete';
import Box from '@mui/material/Box';


const filter = createFilterOptions();

/**
* A React component that provides an autocomplete dropdown for selecting or adding new contexts.
* It integrates with the contextStore to list available contexts and allows the user to create a new context by entering a unique name.
* When a context is selected or a new one is entered, the specified `renderTable` function is triggered to reflect changes elsewhere in the UI.
*
* @param {Object} props - Component props.
* @param {Object} props.contextStore - The store holding all context data.
* @param {Function} props.renderTable - Function to call when a context is selected or created to update associated data display.
* @param {Object|null} props.contextInput - The currently selected or entered context.
* @param {Function} props.setContextInput - Function to update the contextInput state.
*
* @returns {JSX.Element} A React fragment containing an Autocomplete component wrapped in a Box for layout adjustments.
*/
const ContextDropDown = ({
contextStore,
renderTable,
contextInput,
setContextInput
}) => {
}): JSX.Element => {
const { allContext } = contextStore;

const onChange = (event, newValue) => {
Expand Down
Loading

0 comments on commit 6a6226d

Please sign in to comment.