Skip to content

Commit

Permalink
WIP: feat: new panels: evaluations and transformations
Browse files Browse the repository at this point in the history
  • Loading branch information
weareoutman committed Apr 16, 2020
1 parent 998ef81 commit 13f5277
Show file tree
Hide file tree
Showing 10 changed files with 247 additions and 44 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ npm install
npm start
```

Follow [Official Tutorial](https://developer.chrome.com/extensions/getstarted), when loading unpacked extension, choose the `brick-next-devtools/extension` directory.
Follow [official tutorial](https://developer.chrome.com/extensions/getstarted), when loading unpacked extension, choose the `brick-next-devtools/extension` directory.

## Testing

Expand All @@ -32,7 +32,7 @@ npm test src/some-file.spec.ts -- --watch
To test a specified file and collect coverage from related files only:

```
npm test src/some-file.spec.ts -- no-collect-coverage-from
npm test src/some-file.spec.ts -- --no-collect-coverage-from
```

## Publish
Expand Down
49 changes: 49 additions & 0 deletions src/components/BricksPanel.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import React from "react";
import { TreeWrapper } from "./TreeWrapper";
import { SelectedBrickWrapper } from "./SelectedBrickWrapper";
import { BrickTreeContext } from "../libs/BrickTreeContext";
import { BrickData, BricksByMountPoint } from "../libs/interfaces";
import { SelectedBrickContext } from "../libs/SelectedBrickContext";
import { CollapsedBrickIdsContext } from "../libs/CollapsedBrickIdsContext";
import { ShowFullNameContext } from "../libs/ShowFullNameContext";

export function BricksPanel(): React.ReactElement {
const [tree, setTree] = React.useState<BricksByMountPoint>();
const [collapsedBrickIds, setCollapsedBrickIds] = React.useState<number[]>(
[]
);
const [showFullName, setShowFullName] = React.useState<boolean>(false);
const [selectedBrick, setSelectedBrick] = React.useState<BrickData>();

return (
<div className="panel bricks-panel">
<SelectedBrickContext.Provider
value={{
selectedBrick,
setSelectedBrick,
}}
>
<BrickTreeContext.Provider
value={{
tree,
setTree,
}}
>
<CollapsedBrickIdsContext.Provider
value={{
collapsedBrickIds,
setCollapsedBrickIds,
}}
>
<ShowFullNameContext.Provider
value={{ showFullName, setShowFullName }}
>
<TreeWrapper />
</ShowFullNameContext.Provider>
</CollapsedBrickIdsContext.Provider>
</BrickTreeContext.Provider>
<SelectedBrickWrapper />
</SelectedBrickContext.Provider>
</div>
);
}
69 changes: 69 additions & 0 deletions src/components/EvaluationsPanel.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import React from "react";
import { PanelSelector } from "./PanelSelector";
import { PropTree, StandaloneValue } from "./PropTree";

export function EvaluationsPanel(): React.ReactElement {
return (
<div className="panel evaluations-panel">
<div className="evaluations-toolbar">
<PanelSelector />
</div>
<div className="table-view">
<table className="bp3-html-table bp3-html-table-bordered bp3-html-table-condensed">
<thead>
<tr>
<th>Expression</th>
<th>Context</th>
<th>Result</th>
</tr>
</thead>
<tbody className="source-code">
<tr>
<td>
<StandaloneValue value="<% EVENT.detail %>" />
{/* <span className="prop-value-punctuation">{'"'}</span>
<span className="prop-value-string">{'<% EVENT.detail %>'}</span>
<span className="prop-value-punctuation">{'"'}</span> */}
</td>
<td>
<PropTree
properties={{
EVENT: {
type: "oops",
detail: "good",
},
}}
/>
</td>
<td>
<StandaloneValue value="good" />
</td>
</tr>
<tr>
<td>
<StandaloneValue value="<% DATA.map(item => item.id) %>" />
</td>
<td>
<PropTree
properties={{
DATA: [
{
id: 1,
},
{
id: 2,
},
],
}}
/>
</td>
<td>
<StandaloneValue value={[1, 2]} />
</td>
</tr>
</tbody>
</table>
</div>
</div>
);
}
55 changes: 16 additions & 39 deletions src/components/Layout.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,14 @@
import React from "react";
import classNames from "classnames";
import { TreeWrapper } from "./TreeWrapper";
import { SelectedBrickWrapper } from "./SelectedBrickWrapper";
import { BrickTreeContext } from "../libs/BrickTreeContext";
import { BrickData, BricksByMountPoint } from "../libs/interfaces";
import { SelectedBrickContext } from "../libs/SelectedBrickContext";
import { BrowserThemeContext } from "../libs/BrowserThemeContext";
import { CollapsedBrickIdsContext } from "../libs/CollapsedBrickIdsContext";
import { ShowFullNameContext } from "../libs/ShowFullNameContext";
import { BricksPanel } from "./BricksPanel";
import { SelectedPanelContext } from "../libs/SelectedPanelContext";
import { EvaluationsPanel } from "./EvaluationsPanel";
import { TransformationsPanel } from "./TransformationsPanel";

export function Layout(): React.ReactElement {
const [tree, setTree] = React.useState<BricksByMountPoint>();
const [collapsedBrickIds, setCollapsedBrickIds] = React.useState<number[]>(
[]
);
const [showFullName, setShowFullName] = React.useState<boolean>(false);
const [selectedBrick, setSelectedBrick] = React.useState<BrickData>();
const [selectedPanel, setSelectedPanel] = React.useState("Bricks");

const theme = chrome.devtools.panels.themeName === "dark" ? "dark" : "light";

return (
Expand All @@ -25,33 +18,17 @@ export function Layout(): React.ReactElement {
})}
>
<BrowserThemeContext.Provider value={theme}>
<SelectedBrickContext.Provider
value={{
selectedBrick,
setSelectedBrick,
}}
<SelectedPanelContext.Provider
value={{ selectedPanel, setSelectedPanel }}
>
<BrickTreeContext.Provider
value={{
tree,
setTree,
}}
>
<CollapsedBrickIdsContext.Provider
value={{
collapsedBrickIds,
setCollapsedBrickIds,
}}
>
<ShowFullNameContext.Provider
value={{ showFullName, setShowFullName }}
>
<TreeWrapper />
</ShowFullNameContext.Provider>
</CollapsedBrickIdsContext.Provider>
</BrickTreeContext.Provider>
<SelectedBrickWrapper />
</SelectedBrickContext.Provider>
{selectedPanel === "Evaluations" ? (
<EvaluationsPanel />
) : selectedPanel === "Transformations" ? (
<TransformationsPanel />
) : (
<BricksPanel />
)}
</SelectedPanelContext.Provider>
</BrowserThemeContext.Provider>
</div>
);
Expand Down
24 changes: 24 additions & 0 deletions src/components/PanelSelector.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import React from "react";
import { HTMLSelect } from "@blueprintjs/core";
import { useSelectedPanelContext } from "../libs/SelectedPanelContext";

export function PanelSelector(): React.ReactElement {
const { selectedPanel, setSelectedPanel } = useSelectedPanelContext();

const handleChange = (event: React.ChangeEvent<HTMLSelectElement>): void => {
setSelectedPanel(event.target.value);
};

return (
<div>
{
<HTMLSelect
value={selectedPanel}
options={["Bricks", "Evaluations", "Transformations"]}
onChange={handleChange}
minimal
/>
}
</div>
);
}
27 changes: 27 additions & 0 deletions src/components/PropTree.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,33 @@ export function PropItem({
);
}

export function StandaloneValue({ value }: { value: any }): React.ReactElement {
const [expanded, setExpanded] = React.useState(false);

const handleClick = React.useCallback(() => {
setExpanded(!expanded);
}, [expanded]);

const hasChildren = isObject(value);

return (
<div className={classNames("prop-item", { expanded })}>
<div
className="bp3-text-overflow-ellipsis prop-item-label"
onClick={handleClick}
>
{hasChildren && (
<Icon icon={expanded ? "caret-down" : "caret-right"} iconSize={16} />
)}
<span className="prop-value">
<ValueStringify value={value} expanded={expanded} />
</span>
</div>
{isObject(value) && expanded && <PropTree properties={value} />}
</div>
);
}

interface ValueStringifyProps {
value: any;
expanded?: boolean;
Expand Down
13 changes: 13 additions & 0 deletions src/components/TransformationsPanel.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import React from "react";
import { PanelSelector } from "./PanelSelector";

export function TransformationsPanel(): React.ReactElement {
return (
<div className="panel transformations-panel">
<div className="transformations-toolbar">
<PanelSelector />
</div>
<div className="table-view">TransformationsPanel</div>
</div>
);
}
2 changes: 2 additions & 0 deletions src/components/TreeToolbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { useSelectedBrickContext } from "../libs/SelectedBrickContext";
import { BricksByMountPoint } from "../libs/interfaces";
import { useCollapsedBrickIdsContext } from "../libs/CollapsedBrickIdsContext";
import { useShowFullNameContext } from "../libs/ShowFullNameContext";
import { PanelSelector } from "./PanelSelector";

export function TreeToolbar(): React.ReactElement {
const { setTree } = useBrickTreeContext();
Expand Down Expand Up @@ -55,6 +56,7 @@ export function TreeToolbar(): React.ReactElement {

return (
<div className="tree-toolbar">
<PanelSelector />
<ButtonGroup>
<Tooltip content="Refresh bricks" hoverOpenDelay={300}>
<Button icon="refresh" minimal onClick={handleRefresh} />
Expand Down
14 changes: 14 additions & 0 deletions src/libs/SelectedPanelContext.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import React from "react";

export interface ContextOfSelectedPanel {
selectedPanel?: string;
setSelectedPanel?: React.Dispatch<string>;
}

export const SelectedPanelContext = React.createContext<ContextOfSelectedPanel>(
{}
);

// istanbul ignore next
export const useSelectedPanelContext = (): ContextOfSelectedPanel =>
React.useContext(SelectedPanelContext);
34 changes: 31 additions & 3 deletions src/style.css
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
:root {
--pane-border-color: #ccc;
--pane-border-color: rgba(16, 22, 26, 0.15);
--brick-label-color: rgb(136, 18, 128);
--caret-color: #999;
--source-code-color: rgb(33, 33, 33);
Expand All @@ -11,7 +11,7 @@
}

.bp3-dark {
--pane-border-color: #444;
--pane-border-color: rgba(255, 255, 255, 0.15);
--brick-label-color: rgb(93, 176, 215);
--caret-color: #727272;
--source-code-name: rgb(227, 110, 236);
Expand Down Expand Up @@ -40,13 +40,23 @@ body {
.layout {
width: 100%;
height: 100%;
}

.panel {
width: 100%;
height: 100%;
display: flex;
}

.layout * {
box-sizing: border-box;
}

.evaluations-panel,
.transformations-panel {
flex-direction: column;
}

.tree-wrapper,
.selected-brick-wrapper {
display: flex;
Expand All @@ -58,6 +68,8 @@ body {
border-left: 1px solid var(--pane-border-color);
}

.evaluations-toolbar,
.transformations-toolbar,
.tree-toolbar,
.selected-brick-toolbar {
padding: 10px;
Expand All @@ -75,7 +87,8 @@ body {
}

.brick-tree,
.prop-view {
.prop-view,
.table-view {
flex: 1 0 auto;
overflow: hidden;
height: calc(100vh - 50px);
Expand Down Expand Up @@ -158,3 +171,18 @@ body {
.prop-value-array-length {
color: var(--source-code-gray);
}

.table-view .bp3-html-table {
width: 100%;
table-layout: fixed;
font-size: 12px;
}

.table-view .bp3-html-table,
.bp3-dark .table-view .bp3-html-table {
border-bottom: 1px solid var(--pane-border-color);
}

.table-view td > .prop-tree {
padding-left: 0;
}

0 comments on commit 13f5277

Please sign in to comment.