Skip to content

Commit fc26a82

Browse files
authored
Merge pull request #5 from oslabs-beta/feature-hooks
Feature hooks
2 parents 27ee4e1 + 6560991 commit fc26a82

File tree

20 files changed

+211
-210
lines changed

20 files changed

+211
-210
lines changed

src/app/actions/actions.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@ export const save = (newSeries, newSeriesName) => ({
55
type: types.SAVE,
66
payload: { newSeries, newSeriesName },
77
});
8+
89
export const deleteSeries = () => ({
910
type: types.DELETE_SERIES,
1011
});
12+
1113
export const toggleMode = (mode) => ({
1214
type: types.TOGGLE_MODE,
1315
payload: mode,
@@ -86,10 +88,6 @@ export const noDev = (tab) => ({
8688
payload: tab,
8789
});
8890

89-
export const toggleSplit = () => ({
90-
type: types.TOGGLE_SPLIT,
91-
});
92-
9391
export const toggleExpanded = (node) => ({
9492
type: types.TOGGLE_EXPANDED,
9593
payload: node,

src/app/components/App.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ const initialState: InitialStateProps = {
1313
port: null,
1414
currentTab: null,
1515
currentTitle: 'No Target',
16-
split: false,
1716
tabs: {},
1817
currentTabInApp: null,
1918
};

src/app/components/FrontendTypes.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,6 @@ export interface InitialStateProps {
138138
port: null | number;
139139
currentTab: null | number;
140140
currentTitle: null | string;
141-
split: null | boolean;
142141
tabs: unknown;
143142
currentTabInApp: null | string;
144143
}

src/app/components/StateRoute/ComponentMap/ComponentMap.tsx

Lines changed: 26 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import { localPoint } from '@visx/event';
1717
import { useTooltip, useTooltipInPortal, defaultStyles } from '@visx/tooltip';
1818
import LinkControls from './LinkControls';
1919
import getLinkComponent from './getLinkComponent';
20+
import ToolTipDataDisplay from './ToolTipDataDisplay';
2021
import { toggleExpanded, setCurrentTabInApp } from '../../../actions/actions';
2122
import { useStoreContext } from '../../../store';
2223
import { LinkTypesProps, DefaultMargin, ToolTipStyles } from '../../../components/FrontendTypes'
@@ -93,7 +94,7 @@ export default function ComponentMap({
9394
...defaultStyles,
9495
minWidth: 60,
9596
maxWidth: 300,
96-
backgroundColor: 'rgba(0,0,0,0.9)',
97+
backgroundColor: 'rgb(15,15,15)',
9798
color: 'white',
9899
fontSize: '14px',
99100
lineHeight: '18px',
@@ -116,24 +117,6 @@ export default function ComponentMap({
116117
return `${renderTime} ms `;
117118
};
118119

119-
const formatData: [] = (data, type) => {
120-
const contextFormat: string[] = [];
121-
for (const key in data) {
122-
// Suggestion: update the front end to display as a list if we have object
123-
let inputData = data[key];
124-
if (inputData !== null && typeof inputData === 'object') {
125-
inputData = JSON.stringify(inputData);
126-
}
127-
contextFormat.push(<p className={`${type}-item`}>{`${key}: ${inputData}`}</p>);
128-
}
129-
return contextFormat;
130-
};
131-
132-
const formatState: string[] = (state) => {
133-
if (state === 'stateless') return ['stateless'];
134-
return ['stateful'];
135-
};
136-
137120
// places all nodes into a flat array
138121
const nodeList: [] = [];
139122

@@ -290,19 +273,13 @@ export default function ComponentMap({
290273
onMouseEnter={(event) => {
291274
/** This 'if' statement block checks to see if you've just left another component node
292275
* by seeing if there's a current setTimeout waiting to close that component node's
293-
* tooltip (see onMouseLeave immediately below).
294-
* This setTimeout gives the mouse time to enter the tooltip element so the tooltip
295-
* can persist. If instead of entering said tooltip element you've left the previous
296-
* component node to enter this component node, this logic will clear the timeout event,
297-
* and close the tooltip. */
276+
* tooltip (see onMouseLeave immediately below). If so it clears the tooltip generated
277+
* from that component node so a new tooltip for the node you've just entered can render. */
298278
if (toolTipTimeoutID.current !== null) {
299279
clearTimeout(toolTipTimeoutID.current);
300280
hideTooltip();
301281
}
302-
/** The following line resets the toolTipTimeoutID.current to null, showing that there
303-
* are no current setTimeouts running. I placed this outside of the above if statement
304-
* to make sure there are no edge cases that would allow for the toolTipTimeoutID.current
305-
* to hold onto an old reference. */
282+
// Removes the previous timeoutID to avoid errors
306283
toolTipTimeoutID.current = null;
307284
//This generates a tooltip for the component node the mouse has entered.
308285
handleMouseAndClickOver(event);
@@ -316,13 +293,11 @@ export default function ComponentMap({
316293
* If the mouse enters the tooltip before the timeout delay has passed, the
317294
* setTimeout event will be canceled. */
318295
onMouseLeave={() => {
319-
// This line invokes setTimeout and saves its ID to the useRef var toolTipTimeoutID
296+
// Store setTimeout ID so timeout can be cleared if necessary
320297
toolTipTimeoutID.current = setTimeout(() => {
321298
// hideTooltip unmounts the tooltip
322299
hideTooltip();
323-
// As the timeout has been executed, the timeoutID can be reset to null
324300
toolTipTimeoutID.current = null;
325-
//There is a delay of 300 ms
326301
}, 300);
327302
}}
328303
/>
@@ -355,56 +330,39 @@ export default function ComponentMap({
355330
style={tooltipStyles}
356331

357332
//------------- Mouse Over TooltipInPortal--------------------------------------------------------------------
358-
/** This onMouseEnter fires when the mouse first moves/hovers over the tooltip
359-
* The supplied event listener callback stops the setTimeout that was going to
360-
* close the tooltip from firing */
361-
333+
/** After the mouse enters the tooltip, it's able to persist by clearing the setTimeout
334+
* that would've unmounted it */
362335
onMouseEnter={() => {
363-
// The setTimeoutID stored in toolTipTimeoutID.current is from the setTimeout initiated by leaving the
364-
// component node that generated the tooltip. If you've triggered an onMouseEnter event in that tooltip,
365336
clearTimeout(toolTipTimeoutID.current);
366-
// This line resets the timeoutID to null
367337
toolTipTimeoutID.current = null;
368338
}}
369339

370340
//------------- Mouse Leave TooltipInPortal -----------------------------------------------------------------
371-
/** This onMouseLeave event fires when the mouse leaves the tooltip
372-
* The supplied event listener callback unmounts the tooltip */
341+
/** When the mouse leaves the tooltip, the tooltip unmounts */
373342
onMouseLeave={() => {
374-
// hideTooltip unmounts the tooltip
375343
hideTooltip();
376344
}}
377345
>
378346
<div>
379-
<div style={{}}>
380-
{' '}
381-
<strong>{tooltipData.name}</strong>{' '}
347+
<div>
348+
<strong>{tooltipData.name}</strong>
382349
</div>
383-
<div> Render time: {formatRenderTime(tooltipData.componentData.actualDuration)} </div>
384-
<div className='stateTip'>
385-
State: {formatState(tooltipData.state)}
350+
<div className='tooltipKey'>
351+
key: {tooltipData.componentData.key !== null ? tooltipData.componentData.key : 'null'}
386352
</div>
387-
<div style={React.scrollStyle}>
388-
<div className='tooltipWrapper'>
389-
<h2>Props:</h2>
390-
{formatData(tooltipData.componentData.props, 'props')}
391-
</div>
392-
393-
{/* Currently no use for this field
394-
<div className='tooltipWrapper'>
395-
<h2>Initial Context:</h2>
396-
{formatData(tooltipData.componentData.context, 'context')}
397-
</div> */}
398-
399-
<div className='tooltipWrapper'>
400-
<h2>State:</h2>
401-
{formatData(
402-
tooltipData.componentData.hooksIndex
403-
? tooltipData.componentData.hooksState
404-
: tooltipData.componentData.state,
405-
'state',
406-
)}
407-
</div>
353+
<div> Render time: {formatRenderTime(tooltipData.componentData.actualDuration)} </div>
354+
355+
<div>
356+
<ToolTipDataDisplay
357+
containerName='Props'
358+
dataObj={tooltipData.componentData.props}
359+
/>
360+
<ToolTipDataDisplay
361+
containerName='State'
362+
dataObj={tooltipData.componentData.hooksIndex
363+
? tooltipData.componentData.hooksState
364+
: tooltipData.componentData.state}
365+
/>
408366
</div>
409367
</div>
410368
</TooltipInPortal>
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import React from 'react';
2+
import JSONTree from 'react-json-tree';
3+
4+
5+
const colors = {
6+
scheme: 'paraiso',
7+
author: 'jan t. sott',
8+
base00: '#2f1e2e',
9+
base01: '#41323f',
10+
base02: '#4f424c',
11+
base03: '#776e71',
12+
base04: '#8d8687',
13+
base05: '#a39e9b',
14+
base06: '#b9b6b0',
15+
base07: '#e7e9db',
16+
base08: '#ef6155',
17+
//base09 is orange for booleans and numbers. This base in particular fails to match the entered color.
18+
base09: '#824508',
19+
// base09: '#592bad', // alternative purple
20+
base0A: '#fec418',
21+
base0B: '#48b685',
22+
base0C: '#5bc4bf',
23+
base0D: '#06b6ef',
24+
base0E: '#815ba4',
25+
base0F: '#e96ba8',
26+
};
27+
28+
29+
const ToolTipDataDisplay = ({ containerName, dataObj }) => {
30+
//The key:value properties of printableObject will be rendered in the JSON Tree
31+
const printableObject = {}
32+
//If state is null rather than an object, print "State: null" in tooltip
33+
if (!dataObj) {
34+
printableObject[containerName] = dataObj;
35+
} else {
36+
// Props often contain circular references and messages from the backend must be sent as JSON
37+
// objects (strings). JSON objects can't contain circular ref's, so the backend filters out problematic
38+
// values by stringifying the values of object properties and ignoring any values that fail the
39+
// conversion due to a circular ref.
40+
// The following logic converts these values back to JS so they display clearly and are collapsible.
41+
const data = {};
42+
for (const key in dataObj) {
43+
if (typeof dataObj[key] === 'string') {
44+
try {
45+
data[key] = JSON.parse(dataObj[key]);
46+
} catch {
47+
data[key] = dataObj[key];
48+
}
49+
} else {
50+
data[key] = dataObj[key];
51+
}
52+
}
53+
// Adds container name (State, Props, future different names for hooks) at top of object
54+
// so everything nested in it will collapse when you click on it.
55+
printableObject[containerName] = data
56+
}
57+
58+
return (
59+
<div
60+
className='tooltipData'
61+
key={`${containerName}-data-container`}
62+
>
63+
<JSONTree
64+
data={printableObject}
65+
theme={{ extend: colors, tree: () => ({ className: `tooltipData-JSONTree` }) }}
66+
shouldExpandNode={() => true}
67+
hideRoot={true}
68+
/>
69+
</div>
70+
)
71+
};
72+
73+
export default ToolTipDataDisplay;

src/app/components/Tutorial.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ export default class Tutorial extends Component<TutorialProps, TutorialState> {
260260
ref={(steps) => (this.steps = steps)}
261261
/>
262262
<button className='howToUse-button' type='button' onClick={() => startIntro()}>
263-
<FontAwesomeIcon icon={faQuestion} /> How to use
263+
<FontAwesomeIcon icon={faQuestion} /> Tutorial
264264
</button>
265265
</>
266266
);

src/app/constants/actionTypes.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ export const NEW_SNAPSHOTS = 'NEW_SNAPSHOTS';
1313
export const SET_TAB = 'SET_TAB';
1414
export const DELETE_TAB = 'DELETE_TAB';
1515
export const NO_DEV = 'NO_DEV';
16-
export const TOGGLE_SPLIT = 'TOGGLE_SPLIT';
1716
export const TOGGLE_EXPANDED = 'TOGGLE_EXPANDED';
1817
export const LAUNCH_CONTENT = 'LAUNCH_CONTENT';
1918
export const SLIDER_ZERO = 'SLIDER_ZERO';

src/app/containers/ButtonsContainer.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import {
88
faUnlock,
99
faLock,
1010
} from '@fortawesome/free-solid-svg-icons';
11-
import { importSnapshots, toggleMode, toggleSplit } from '../actions/actions';
11+
import { importSnapshots, toggleMode } from '../actions/actions';
1212
import { useStoreContext } from '../store';
1313

1414
import Tutorial from '../components/Tutorial';
@@ -53,7 +53,7 @@ function importHandler(dispatch: (a: unknown) => void): void {
5353
}
5454

5555
function ButtonsContainer(): JSX.Element {
56-
const [{ tabs, currentTab, split, currentTabInApp }, dispatch] = useStoreContext();
56+
const [{ tabs, currentTab, currentTabInApp }, dispatch] = useStoreContext();
5757
const {
5858
snapshots,
5959
mode: { paused },
@@ -62,8 +62,8 @@ function ButtonsContainer(): JSX.Element {
6262
return (
6363
<div className='buttons-container'>
6464
<button className='pause-button' type='button' onClick={() => dispatch(toggleMode('paused'))}>
65-
{paused ? <FontAwesomeIcon icon={faUnlock} /> : <FontAwesomeIcon icon={faLock} />}
66-
{paused ? 'Unlock' : 'Lock'}
65+
{paused ? <FontAwesomeIcon icon={faLock} /> : <FontAwesomeIcon icon={faUnlock} />}
66+
{paused ? 'Locked' : 'Unlocked'}
6767
</button>
6868
<button className='export-button' type='button' onClick={() => exportHandler(snapshots)}>
6969
<FontAwesomeIcon icon={faDownload} />

0 commit comments

Comments
 (0)