Skip to content

Commit

Permalink
Merge pull request #28 from easyops-cn/jojiang/edit-placeholders
Browse files Browse the repository at this point in the history
feat(): devtools transformmationsPanel and evaluationsPanel support edit
  • Loading branch information
weareoutman committed Aug 5, 2020
2 parents 3774667 + b64b3f2 commit d97abbe
Show file tree
Hide file tree
Showing 12 changed files with 348 additions and 55 deletions.
16 changes: 15 additions & 1 deletion src/content.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import { MESSAGE_SOURCE_HOOK } from "./shared/constants";
import {
MESSAGE_SOURCE_HOOK,
EVALUATION_EDIT,
TRANSFORMATION_EDIT,
MESSAGE_SOURCE_PANEL,
} from "./shared/constants";

function injectScript(file: string): void {
const script = document.createElement("script");
Expand All @@ -16,6 +21,15 @@ function initPort(): void {
port.onDisconnect.addListener(() => {
port = null;
});

port.onMessage.addListener((message) => {
if (
message.source === MESSAGE_SOURCE_PANEL &&
[EVALUATION_EDIT, TRANSFORMATION_EDIT].includes(message.payload?.type)
) {
window.postMessage(message, "*");
}
});
}

if (document.contentType === "text/html") {
Expand Down
17 changes: 16 additions & 1 deletion src/devtools.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import {
EVALUATION_EDIT,
HOOK_NAME,
MESSAGE_SOURCE_DEVTOOLS,
MESSAGE_SOURCE_HOOK,
MESSAGE_SOURCE_PANEL,
TRANSFORMATION_EDIT,
} from "./shared/constants";

let panelCreated = false;

// Check to see if BrickNext has loaded once per second in case BrickNext is added
// after page load
const loadCheckInterval = setInterval(function () {
Expand Down Expand Up @@ -46,15 +48,28 @@ function createPanelForBricks(): void {
}
}

function onPanelMessage(event: MessageEvent): void {
if (
event?.data.source === MESSAGE_SOURCE_PANEL &&
[EVALUATION_EDIT, TRANSFORMATION_EDIT].includes(
event.data.payload?.type
)
) {
port?.postMessage(event.data);
}
}

port.onMessage.addListener(onPortMessage);

chrome.devtools.panels.create(
"🧩 Bricks",
"",
"build/panel.html",
function (panel) {
// istanbul ignore next
panel.onShown.addListener((win) => {
panelWindow = win;
panelWindow.addEventListener("message", onPanelMessage);
});
}
);
Expand Down
56 changes: 46 additions & 10 deletions src/panel/components/EvaluationsPanel.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,28 @@ const savePreserveLogs = jest.fn();
(useEvaluationsContext as jest.Mock).mockReturnValue({
evaluations: [
{
raw: "<% EVENT.detail %>",
result: "good",
context: {
EVENT: {
detail: "good",
detail: {
raw: "<% EVENT.detail %>",
result: "good",
context: {
EVENT: {
detail: "good",
},
DATA: {
name: "easyops",
},
},
},
id: 0,
},
{
raw: "<% DATA.quality %>",
result: "better",
context: {
EVENT: {
detail: "better",
detail: {
raw: "<% DATA.quality %>",
result: "better",
context: {
EVENT: {
detail: "better",
},
},
},
},
Expand Down Expand Up @@ -82,4 +90,32 @@ describe("EvaluationsPanel", () => {
"<% EVENT.detail %>"
);
});

it("should post edited text message", () => {
const wrapper = shallow(<EvaluationsPanel />);
const postMessage = jest.spyOn(window, "postMessage");

wrapper.find(PropItem).at(0).invoke("overrideProps")(
"propName",
"propValue",
"<% DATA.name %>"
);

expect(postMessage.mock.calls[0][0]).toEqual({
payload: {
context: {
data: {
name: "easyops",
},
event: {
detail: "good",
},
},
id: 0,
raw: "<% DATA.name %>",
type: "devtools-evaluation-edit",
},
source: "brick-next-devtools-panel",
});
});
});
39 changes: 35 additions & 4 deletions src/panel/components/EvaluationsPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import classNames from "classnames";
import { PanelSelector } from "./PanelSelector";
import { useEvaluationsContext } from "../libs/EvaluationsContext";
import { PropList, PropItem } from "./PropList";
import { EVALUATION_EDIT, MESSAGE_SOURCE_PANEL } from "../../shared/constants";
import { Evaluation } from "../../shared/interfaces";

export function EvaluationsPanel(): React.ReactElement {
const {
Expand Down Expand Up @@ -37,7 +39,7 @@ export function EvaluationsPanel(): React.ReactElement {
return evaluations;
}
return evaluations.filter((item) =>
item.raw.toLocaleLowerCase().includes(q.toLocaleLowerCase())
item.detail?.raw.toLocaleLowerCase().includes(q.toLocaleLowerCase())
);
}, [evaluations, q]);

Expand All @@ -55,6 +57,28 @@ export function EvaluationsPanel(): React.ReactElement {
[savePreserveLogs]
);

const handleEvaluations = (item: Evaluation, value: string) => {
const {
context: { DATA, EVENT },
} = item.detail;

window.postMessage(
{
source: MESSAGE_SOURCE_PANEL,
payload: {
type: EVALUATION_EDIT,
context: {
data: DATA,
event: EVENT,
},
id: item.id,
raw: value,
},
},
"*"
);
};

return (
<div
className={classNames("panel evaluations-panel", {
Expand Down Expand Up @@ -103,13 +127,20 @@ export function EvaluationsPanel(): React.ReactElement {
{filteredEvaluations.map((item, key) => (
<tr key={key}>
<td>
<PropItem propValue={item.raw} standalone />
<PropItem
propValue={item.detail?.raw}
standalone
editable
overrideProps={(_name, _prop, value) =>
handleEvaluations(item, value)
}
/>
</td>
<td>
<PropItem propValue={item.result} standalone />
<PropItem propValue={item.detail?.result} standalone />
</td>
<td>
<PropList list={item.context || {}} />
<PropList list={item.detail?.context || {}} />
</td>
</tr>
))}
Expand Down
78 changes: 78 additions & 0 deletions src/panel/components/Layout.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,45 @@ describe("Layout", () => {
wrapper.unmount();
});

it("should work for edit evaluations", async () => {
storageGetItem.mockReturnValue("Evaluations");
const wrapper = mount(<Layout />);
await act(async () => {
window.postMessage(
{
source: MESSAGE_SOURCE_HOOK,
payload: {
type: "evaluation",
payload: {
id: 0,
result: "good",
},
},
},
location.origin
);
await new Promise((resolve) => setTimeout(resolve));
});
await act(async () => {
window.postMessage(
{
source: MESSAGE_SOURCE_HOOK,
payload: {
type: "re-evaluation",
payload: {
id: 0,
result: "new",
},
},
},
location.origin
);
await new Promise((resolve) => setTimeout(resolve));
});
expect(wrapper.text()).toBe("EvaluationsPanel (1)");
wrapper.unmount();
});

it("should work for new transformations", async () => {
storageGetItem.mockReturnValue("Transformations");
const wrapper = mount(<Layout />);
Expand All @@ -136,6 +175,45 @@ describe("Layout", () => {
wrapper.unmount();
});

it("should work for edit transformations", async () => {
storageGetItem.mockReturnValue("Transformations");
const wrapper = mount(<Layout />);
await act(async () => {
window.postMessage(
{
source: MESSAGE_SOURCE_HOOK,
payload: {
type: "transformation",
payload: {
result: "good",
id: 0,
},
},
},
location.origin
);
await new Promise((resolve) => setTimeout(resolve));
});
await act(async () => {
window.postMessage(
{
source: MESSAGE_SOURCE_HOOK,
payload: {
type: "re-transformation",
payload: {
id: 0,
result: "new",
},
},
},
location.origin
);
await new Promise((resolve) => setTimeout(resolve));
});
expect(wrapper.text()).toBe("TransformationsPanel (1)");
wrapper.unmount();
});

it.each([
[true, 1],
[false, 0],
Expand Down
44 changes: 42 additions & 2 deletions src/panel/components/Layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ import { TransformationsContext } from "../libs/TransformationsContext";
import { Storage } from "../libs/Storage";
import { hydrate } from "../libs/hydrate";

let uniqueIdCounter = 0;
function getUniqueId(): number {
return (uniqueIdCounter += 1);
}

export function Layout(): React.ReactElement {
const [selectedPanel, setSelectedPanel] = React.useState(
Storage.getItem("selectedPanel") ?? "Bricks"
Expand All @@ -33,7 +38,26 @@ export function Layout(): React.ReactElement {
event.data?.source === MESSAGE_SOURCE_HOOK &&
((data = event.data.payload), data?.type === "evaluation")
) {
setEvaluations((prev) => prev.concat(hydrate(data.payload, data.repo)));
setEvaluations((prev) =>
prev.concat({
detail: hydrate(data.payload, data.repo),
id: getUniqueId(),
})
);
}

if (
event.data?.source === MESSAGE_SOURCE_HOOK &&
((data = event.data.payload), data?.type === "re-evaluation")
) {
const value = hydrate(data.payload, data.repo);
const { id, ...changeData } = value;
setEvaluations((prev) => {
const selected = prev.find((item) => item.id === id);
selected && Object.assign(selected.detail, changeData);

return [...prev];
});
}
}
window.addEventListener("message", onMessage);
Expand All @@ -48,9 +72,25 @@ export function Layout(): React.ReactElement {
((data = event.data.payload), data?.type === "transformation")
) {
setTransformations((prev) =>
prev.concat(hydrate(data.payload, data.repo))
prev.concat({
detail: hydrate(data.payload, data.repo),
id: getUniqueId(),
})
);
}

if (
event.data?.source === MESSAGE_SOURCE_HOOK &&
((data = event.data.payload), data?.type === "re-transformation")
) {
const value = hydrate(data.payload, data.repo);
const { id, ...changeData } = value;
setTransformations((prev) => {
const selected = prev.find((item) => item.id === id);
selected && Object.assign(selected.detail, changeData);
return [...prev];
});
}
}
window.addEventListener("message", onMessage);
return (): void => window.removeEventListener("message", onMessage);
Expand Down
6 changes: 3 additions & 3 deletions src/panel/components/PropList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { isDehydrated, isObject } from "../libs/utils";
interface PropListProps {
list: any[] | Record<string, any>;
editable?: boolean;
overrideProps?: (propName: string, propValue: string) => void;
overrideProps?: (propName: string, propValue: string, result?: any) => void;
}

export function PropList({
Expand Down Expand Up @@ -49,7 +49,7 @@ interface PropItemProps {
propName?: string;
standalone?: boolean;
editable?: boolean;
overrideProps?: (propName: string, propValue: string) => void;
overrideProps?: (propName: string, propValue: string, result?: any) => void;
}

export function PropItem({
Expand Down Expand Up @@ -84,7 +84,7 @@ export function PropItem({
} else {
result = JSON.parse(changeValue);
}
overrideProps?.(propName, changeValue);
overrideProps?.(propName, changeValue, result);
setEditing(false);
setError(false);
} catch (error) {
Expand Down
Loading

0 comments on commit d97abbe

Please sign in to comment.