Skip to content

Feature/garrett #11

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 12 commits into from
Dec 10, 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
12 changes: 4 additions & 8 deletions src/app/App.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import React from 'react';
import { MemoryRouter as Router } from 'react-router-dom';
import MainContainer from './containers/MainContainer';
import { ThemeProvider } from '@mui/material/styles';
import theme from './styles/theme';

/*
'currentTab' is the current active tab within Google Chrome.
Expand All @@ -12,12 +10,10 @@ import theme from './styles/theme';

function App(): JSX.Element {
return (
<ThemeProvider theme={theme}>
<Router>
{/* we wrap our application with the <Router> tag so that all components that are nested will have the react-router context */}
<MainContainer />
</Router>
</ThemeProvider>
<Router>
{/* we wrap our application with the <Router> tag so that all components that are nested will have the react-router context */}
<MainContainer />
</Router>
);
}

Expand Down
90 changes: 30 additions & 60 deletions src/app/components/Actions/Action.tsx
Original file line number Diff line number Diff line change
@@ -1,95 +1,59 @@
/* eslint-disable react/require-default-props */
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable react/no-unused-prop-types */

import React from 'react';
import ReactHover, { Trigger, Hover } from 'react-hover';
import { changeView, changeSlider } from '../../slices/mainSlice';
import { ActionProps, OptionsCursorTrueWithMargin } from '../../FrontendTypes';
import { useDispatch } from 'react-redux';

/*
This renders the individual snapshot components on the left side column
*/

/**
* @function Action
* @param selected : The selected action in the array of state changes
* @param displayName : Label showing sequence number of state change, reflects changes in Chart.tsx
* @param componentName : Displays the name of compenent's state being changed
* @param last : The last index in the array
* @param sliderIndex: Index of the slider in the array of state changes
* (clicking the block changes the slider, related to MainSlider.tsx slider)
* @param componentData: Displays react fiber data
* @param viewIndex: Index of the tab in the array when timejump is made
* @method dispatch Executes actions that changes state in reactime
* @method handleOnkeyDown Executes key commands
*
*/

const Action = (props: ActionProps): JSX.Element => {
//here we are adding useSelector and useDispatch for RTK state conversion
const dispatch = useDispatch();

// We destructure the 'props' that were passed into this component
const {
selected, // boolean on whether the current index is the same as the viewIndex in 'ActionContainer'
last, // boolean on (whether the view index is less than 0) AND if (the index is the same as the last snapshot's index value in hierarchyArr) in 'ActionContainer'
index, // from snapshot.index in "ActionContainer's" 'hierarchyArr'
sliderIndex, // from tabs[currentTab] object in 'ActionContainer'
displayName, // from snapshot.displayName in "ActionContainer's" 'hierarchyArr'
componentData, // from snapshot.componentData in "ActionContainer's" 'hierarchyArr'
viewIndex, // from tabs[currentTab] object in 'ActionContainer'
selected,
last,
index,
sliderIndex,
displayName,
componentData,
viewIndex,
isCurrIndex,
handleOnkeyDown, // function that allows arrows keys to jump between snapshots defined in 'ActionContainer.tsx'
handleOnkeyDown,
} = props;

/**
* @function cleanTime: Displays render times for state changes
* @returns render display time in seconds in milliseconds
*/

const cleanTime = (): string => {
if (!componentData || !componentData.actualDuration) {
// if there is no 'componentData' or 'componentData.actualDuration'
return 'NO TIME';
}

let seconds: number | string; // seconds is undefined but can take a number or a string
let milliseconds: any = componentData.actualDuration; // milliseconds is of any type and taken from the 'componentData.actualDuration'
let seconds: number | string;
let milliseconds: any = componentData.actualDuration;

if (Math.floor(componentData.actualDuration) > 60) {
// if the milliseconds is greater than 60
seconds = Math.floor(componentData.actualDuration / 60); // we divide our milliseconds by 60 to determine our seconds
seconds = JSON.stringify(seconds); // and we convert our seconds into a string
seconds = Math.floor(componentData.actualDuration / 60);
seconds = JSON.stringify(seconds);

if (seconds.length < 2) {
// if the seconds string is only a single digit
seconds = '0'.concat(seconds); // we can add a 0 in front of it so that if 'seconds = "1"' it will come out as 'seconds = "01"'
seconds = '0'.concat(seconds);
}
milliseconds = Math.floor(componentData.actualDuration % 60); // Our true milliseconds then becomes the remainder of dividing our initial milliseconds by 60
milliseconds = Math.floor(componentData.actualDuration % 60);
} else {
seconds = '00'; // if we haven't even reached one second yet, our seconds are 00
seconds = '00';
}

milliseconds = Number.parseFloat(milliseconds as string).toFixed(2); // we convert our milliseconds string into a floating point number that has up to two decimal places.
const arrayMilliseconds: [string, number] = milliseconds.split('.'); // we split our milliseconds using the decimal and come out with an array of two numbers
milliseconds = Number.parseFloat(milliseconds as string).toFixed(2);
const arrayMilliseconds: [string, number] = milliseconds.split('.');

if (arrayMilliseconds[0].length < 2) {
// if our millisecond string only has one digit
arrayMilliseconds[0] = '0'.concat(arrayMilliseconds[0]); // we add a 0 in front of it so that in the a sample number of '1' becomes '01'
arrayMilliseconds[0] = '0'.concat(arrayMilliseconds[0]);
}

if (index === 0) {
// if this is the initial snapshot
return `${seconds}:${arrayMilliseconds[0]}.${arrayMilliseconds[1]}`; // we give it a timestamp
return `${seconds}:${arrayMilliseconds[0]}.${arrayMilliseconds[1]}`;
}
return `+${seconds}:${arrayMilliseconds[0]}.${arrayMilliseconds[1]}`; // if these are succeeding snapshots, we add a '+' to the timestamp
return `+${seconds}:${arrayMilliseconds[0]}.${arrayMilliseconds[1]}`;
};

const displayTime: string = cleanTime(); // we run cleanTime on the creation of this component so that we can get the timestamp
const displayTime: string = cleanTime();

// creates an options object that 'ReactHover' component will use to modify it's behaviour
const optionsCursorTrueWithMargin: OptionsCursorTrueWithMargin = {
followCursor: true,
shiftX: 20,
Expand Down Expand Up @@ -123,9 +87,15 @@ const Action = (props: ActionProps): JSX.Element => {
placeholder={`Snapshot: ${displayName}`}
/>
</div>
<button className='time-button' type='button'>
{displayTime}
</button>
{isCurrIndex ? (
<button className='current-snap' type='button'>
{`Snapshot: ${displayName}`}
</button>
) : (
<button className='time-button' type='button'>
{displayTime}
</button>
)}
{isCurrIndex ? (
<button className='current-location' type='button'>
Current
Expand Down
29 changes: 11 additions & 18 deletions src/app/components/Actions/RouteDescription.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,26 +16,19 @@ const RouteDescription = (props: RouteProps): JSX.Element => {
const url: URL = new URL(actions[0].props.routePath); // Use new URL to use the url.pathname method.

return (
<div className='routedescription' >
<h3 className='route'>Route: {url.pathname}</h3>
<div style={{
// div that contains slider and snapshots
display: 'flex',
flexDirection: 'row',
height: `${actions.length * 30}px`,
marginBottom: '50px'
}}>
<div style={{maxWidth: '50px'}}>
<VerticalSlider className='main-slider' snapshots={actions} />
</div>
<div style={{marginTop: '10px'}}>
{/* actual snapshots per route */}
{actions}
</div>
</div>
<div className='route-container'>
<div className='route-header'>Route: {url.pathname}</div>
<div className='route-content' style={{ height: `${actions.length * 40.5}px` }}>
<div>
<VerticalSlider className='main-slider' snapshots={actions} />
</div>
<div className='actions-container'>
{/* actual snapshots per route */}
{actions}
</div>
</div>
</div>
);
};


export default RouteDescription;
4 changes: 1 addition & 3 deletions src/app/components/StateRoute/ComponentMap/ComponentMap.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -201,8 +201,7 @@ export default function ComponentMap({
};

let filtered = processTreeData(currentSnapshot);
console.log('filtered', filtered);
collectNodes(filtered);
collectNodes(currentSnapshot);

const keepContextAndProviderNodes = (node) => {
if (!node) return null;
Expand Down Expand Up @@ -234,7 +233,6 @@ export default function ComponentMap({
};

const contextProvidersOnly = keepContextAndProviderNodes(currentSnapshot);
console.log('context only', contextProvidersOnly);

// @ts
// find the node that has been selected and use it as the root
Expand Down
16 changes: 7 additions & 9 deletions src/app/components/TimeTravel/VerticalSlider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ const handle = (props: HandleProps): JSX.Element => {

function VerticalSlider(props: MainSliderProps): JSX.Element {
const dispatch = useDispatch();
const { snapshots} = props; // destructure props to get our total number of snapshots
const { snapshots } = props; // destructure props to get our total number of snapshots
const [sliderIndex, setSliderIndex] = useState(0); // create a local state 'sliderIndex' and set it to 0.
const { tabs, currentTab }: MainState = useSelector((state: RootState) => state.main);
const { currLocation } = tabs[currentTab]; // we destructure the currentTab object
Expand All @@ -39,27 +39,25 @@ function VerticalSlider(props: MainSliderProps): JSX.Element {
// if we have a 'currLocation'
let correctedSliderIndex;

for (let i = 0; i<snapshots.length; i++){
for (let i = 0; i < snapshots.length; i++) {
//@ts-ignore -- ignores the errors on the next line
if (snapshots[i].props.index === currLocation.index){
if (snapshots[i].props.index === currLocation.index) {
correctedSliderIndex = i;
}
}
setSliderIndex(correctedSliderIndex)

setSliderIndex(correctedSliderIndex);
} else {
setSliderIndex(0); // just set the thumb position to the beginning
}
}, [currLocation]); // if currLocation changes, rerun useEffect


return (
<Slider
className='travel-slider'
color='#0af548'
vertical = 'true'
reverse = 'true'
height = '100%'
vertical='true'
reverse='true'
height='100%'
min={0} // index of our first snapshot
max={snapshots.length - 1} // index of our last snapshot
value={sliderIndex} // currently slider thumb position
Expand Down
53 changes: 12 additions & 41 deletions src/app/containers/ActionContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,9 @@ import { Button, Switch } from '@mui/material';
This file renders the 'ActionContainer'. The action container is the leftmost column in the application. It includes the button that shrinks and expands the action container, a dropdown to select the active site, a clear button, the current selected Route, and a list of selectable snapshots with timestamps.
*/


// resetSlider locates the rc-slider elements on the document and resets it's style attributes
const resetSlider = () => {
const slider = document.querySelector('.rc-slider-handle');
const sliderTrack = document.querySelector('.rc-slider-track');
if (slider && sliderTrack) {
slider.setAttribute('style', 'left: 0');
sliderTrack.setAttribute('style', 'width: 0');
}
};

function ActionContainer(props: ActionContainerProps): JSX.Element {

const [dropdownSelection, setDropdownSelection] = useState('TimeJump');

const dispatch = useDispatch();
Expand All @@ -43,23 +33,6 @@ function ActionContainer(props: ActionContainerProps): JSX.Element {
// we create an array 'hierarchyArr' that will hold objects and numbers
const hierarchyArr: (number | {})[] = [];

/*
function to traverse state from hierarchy and also getting information on display name and component name

the obj parameter is an object with the following structure:
{
stateSnapshot: {
route: any;
children: any[];
};
name: number;
branch: number;
index: number;
children?: [];
}
*/


const displayArray = (obj: Obj): void => {
if (
obj.stateSnapshot.children.length > 0 && // if the 'stateSnapshot' has a non-empty 'children' array
Expand All @@ -72,7 +45,7 @@ function ActionContainer(props: ActionContainerProps): JSX.Element {
//This utility can be used to map the properties of a type to another type) and populate it's properties with
//relevant values from our argument 'obj'.
index: obj.index,
displayName: `${obj.name}.${obj.branch}`,
displayName: `${obj.index + 1}`,
state: obj.stateSnapshot.children[0].state,
componentName: obj.stateSnapshot.children[0].name,
routePath: obj.stateSnapshot.route.url,
Expand Down Expand Up @@ -231,31 +204,29 @@ function ActionContainer(props: ActionContainerProps): JSX.Element {
</a>
<SwitchAppDropdown />
{/* add new component here for dropdown menu for useStae/ useReducer- ragad */}
<DropDown
dropdownSelection = {dropdownSelection}
setDropdownSelection={setDropdownSelection}
/>
<div className='action-component exclude'>
<DropDown
dropdownSelection={dropdownSelection}
setDropdownSelection={setDropdownSelection}
/>
<div className='clear-button-container'>
<Button
className='clear-button'
variant='contained'
//style={{ backgroundColor: '#ff6569' }}
className='clear-button-modern'
variant='text'
onClick={() => {
dispatch(emptySnapshots()); // set slider back to zero, visually
resetSlider();
dispatch(changeSlider(0));
}}
type='button'
>
Clear
</Button>
</div>
<div className='snapshots'>
{dropdownSelection === 'Provider/Consumer' && <ProvConContainer/>}
{dropdownSelection === 'TimeJump' &&
{dropdownSelection === 'Provider/Consumer' && <ProvConContainer />}
{dropdownSelection === 'TimeJump' &&
Object.keys(routes).map((route, i) => (
<RouteDescription key={`route${i}`} actions={routes[route]} />
))
}
))}
</div>
</div>
) : null}
Expand Down
2 changes: 1 addition & 1 deletion src/app/containers/MainContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ function MainContainer(): JSX.Element {
const { connectionStatus }: MainState = useSelector((state: RootState) => state.main);

// JR 12.22.23: so far this log always returns true
// console.log('MainContainer connectionStatus at initialization: ', connectionStatus);
console.log('MainContainer connectionStatus at initialization: ', connectionStatus);

const [actionView, setActionView] = useState(true); // We create a local state 'actionView' and set it to true

Expand Down
Loading