Skip to content

Commit

Permalink
Merge of #4012
Browse files Browse the repository at this point in the history
  • Loading branch information
mergify[bot] authored Sep 5, 2023
2 parents 3708f87 + 0cfdd5f commit a00de53
Show file tree
Hide file tree
Showing 8 changed files with 169 additions and 43 deletions.
43 changes: 38 additions & 5 deletions apps/vscode-wing/src/console/console-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import {
ViewColumn,
Uri,
ExtensionContext,
Position,
Range,
} from "vscode";

import {
Expand Down Expand Up @@ -156,6 +158,42 @@ export const createConsoleManager = (
logger.appendLine(err);
},
});

instance.client.onOpenFileInEditor({
onData: async (data) => {
const path = data?.path;
const line = data?.line - 1 || 0;
const column = data?.column || 0;

const openEditor = window.visibleTextEditors.find((editor) => {
return editor.document.uri.fsPath === path;
});

if (!openEditor || !openEditor.viewColumn) {
await commands.executeCommand(
"vscode.open",
Uri.file(path),
new Position(line, column)
);
return;
}

await commands.executeCommand("workbench.action.focusFirstEditorGroup");
for (let i = 0; i < openEditor.viewColumn - 1; i++) {
await commands.executeCommand("workbench.action.focusNextGroup");
}
await window.showTextDocument(openEditor.document, {
selection: new Range(
new Position(line, column),
new Position(line, column)
),
});
},
onError: (err) => {
logger.appendLine(err);
},
});

instances[instance.id] = instance;

await setActiveInstance(instance.id);
Expand Down Expand Up @@ -244,11 +282,6 @@ export const createConsoleManager = (
});

context.subscriptions.push(webviewPanel, explorerView, testsExplorerView);

const node = await resourcesExplorer.getChildren();
if (node[0]?.id) {
await explorerView?.reveal(new ResourceItem(node[0].id));
}
activeInstanceId = instanceId;
};

Expand Down
9 changes: 9 additions & 0 deletions apps/vscode-wing/src/console/services/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export interface Client {
runAllTests: () => Promise<any>;
listResources: () => Promise<ExplorerItem>;
onInvalidateQuery: (options: SubscriptionOptions) => void;
onOpenFileInEditor: (options: SubscriptionOptions) => void;
close: () => void;
}

Expand Down Expand Up @@ -98,6 +99,13 @@ export const createClient = (host: string): Client => {
return client["app.invalidateQuery"].subscribe(undefined, options);
};

const onOpenFileInEditor = (options: SubscriptionOptions) => {
return client["app.openFileInEditorSubscription"].subscribe(
undefined,
options
);
};

const close = () => {
wsClient.close();
};
Expand All @@ -112,6 +120,7 @@ export const createClient = (host: string): Client => {
runAllTests,
listResources,
onInvalidateQuery,
onOpenFileInEditor,
close,
};
};
1 change: 1 addition & 0 deletions apps/wing-console/console/server/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export type {
TestsStateManager,
TestStatus,
TestItem,
FileLink,
} from "./utils/createRouter.js";
export type { Trace, State } from "./types.js";
export type { LogInterface } from "./utils/LogInterface.js";
Expand Down
31 changes: 30 additions & 1 deletion apps/wing-console/console/server/src/router/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@ import {
NodeConnection,
ConstructTreeNodeMap,
} from "../utils/constructTreeNodeMap.js";
import { createProcedure, createRouter } from "../utils/createRouter.js";
import {
FileLink,
createProcedure,
createRouter,
} from "../utils/createRouter.js";
import {
isTermsAccepted,
acceptTerms,
Expand Down Expand Up @@ -561,6 +565,31 @@ export const createAppRouter = () => {
.mutation(async ({ ctx, input }) => {
await ctx.hostUtils?.openExternal(input.url);
}),
"app.openFileInEditor": createProcedure
.input(
z.object({
path: z.string(),
line: z.number().optional(),
column: z.number().optional(),
}),
)
.mutation(async ({ ctx, input }) => {
ctx.emitter.emit("openFileInEditor", {
path: input.path,
line: input.line,
column: input.column,
});
}),
"app.openFileInEditorSubscription": createProcedure.subscription(
({ ctx }) => {
return observable<FileLink>((emit) => {
ctx.emitter.on("openFileInEditor", emit.next);
return () => {
ctx.emitter.off("openFileInEditor", emit.next);
};
});
},
),
});

return { router };
Expand Down
7 changes: 7 additions & 0 deletions apps/wing-console/console/server/src/utils/createRouter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,12 @@ export interface TestsStateManager {
setTest: (test: TestItem) => void;
}

export interface FileLink {
path: string;
line?: number;
column?: number;
}

export interface RouterContext {
simulator(): Promise<testing.Simulator>;
appDetails(): Promise<{
Expand All @@ -77,6 +83,7 @@ export interface RouterContext {
emitter: Emittery<{
invalidateQuery: string | undefined;
trace: Trace;
openFileInEditor: FileLink;
}>;
appState(): State;
logger: ConsoleLogger;
Expand Down
53 changes: 23 additions & 30 deletions apps/wing-console/console/ui/src/features/console-logs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ import classNames from "classnames";
import throttle from "lodash.throttle";
import { Fragment, useEffect, useRef, useState } from "react";

import {
OpenFileInEditorButton,
useFileLink,
} from "../shared/use-file-link.js";
import { createHtmlLink } from "../shared/use-file-link.js";

const dateTimeFormat = new Intl.DateTimeFormat(undefined, {
hour: "2-digit",
minute: "2-digit",
Expand All @@ -23,21 +29,6 @@ interface LogEntryProps {
showIcons?: boolean;
}

export const formatAbsolutePaths = (
error: string,
className: string,
expanded: boolean = false,
) => {
return error
.replaceAll(
/\B((?:[a-z]:)?[/\\]\S+):(\d+):(\d+)/gi,
(match, path, line, column) => {
return `<a class="${className}" onclick="event.stopPropagation()" href="vscode://file/${path}:${line}:${column}">${match}</a>`;
},
)
.replaceAll(/(\r\n|\n|\r)/gm, expanded ? "<br />" : "\n");
};

const LogEntryRow = ({
log,
showIcons = true,
Expand Down Expand Up @@ -77,7 +68,7 @@ const LogEntryRow = ({
if (expandableRef.current === null) {
return;
}
const html = formatAbsolutePaths(
const html = createHtmlLink(
log.message,
"text-sky-500 underline hover:text-sky-800",
expanded,
Expand Down Expand Up @@ -154,20 +145,22 @@ const LogEntryRow = ({
/>
</button>
)}
<span
className={classNames(
log.ctx?.messageType === "info" && theme.text2,
log.ctx?.messageType === "title" && theme.text1,
log.ctx?.messageType === "success" &&
"text-green-700 dark:text-green-500",
log.ctx?.messageType === "fail" && "text-red-500",
log.ctx?.messageType === "summary" && [
"font-medium",
theme.text1,
],
)}
ref={expandableRef}
/>
<OpenFileInEditorButton>
<span
className={classNames(
log.ctx?.messageType === "info" && theme.text2,
log.ctx?.messageType === "title" && theme.text1,
log.ctx?.messageType === "success" &&
"text-green-700 dark:text-green-500",
log.ctx?.messageType === "fail" && "text-red-500",
log.ctx?.messageType === "summary" && [
"font-medium",
theme.text1,
],
)}
ref={expandableRef}
/>
</OpenFileInEditorButton>
</div>

{onResourceClick && (
Expand Down
49 changes: 49 additions & 0 deletions apps/wing-console/console/ui/src/shared/use-file-link.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { PropsWithChildren } from "react";

import { trpc } from "../services/trpc.js";

export const createHtmlLink = (
error: string,
className: string,
expanded: boolean = false,
) => {
return error
.replaceAll(
/\B((?:[a-z]:)?[/\\]\S+):(\d+):(\d+)/gi,
(match, path, line, column) => {
const link = `vscode://file/${path}:${line}:${column}`;
return `<a class="${className}" href="${link}" path="${path}" line="${line}" column="${column}" >${match}</a>`;
},
)
.replaceAll(/(\r\n|\n|\r)/gm, expanded ? "<br />" : "\n");
};

export const OpenFileInEditorButton = ({ children }: PropsWithChildren) => {
const openFileInEditor = trpc["app.openFileInEditor"].useMutation();

return (
<button
className="appearance-none text-left"
onClick={(event) => {
const target = event.target as HTMLElement;
if (target.tagName === "A") {
const path = target.getAttribute("path")!;
const line = target.getAttribute("line")!;
const column = target.getAttribute("column")!;

if (!path || !line || !column) {
return;
}

openFileInEditor.mutate({
path,
line: Number.parseInt(line),
column: Number.parseInt(column),
});
}
}}
>
{children}
</button>
);
};
19 changes: 12 additions & 7 deletions apps/wing-console/console/ui/src/ui/blue-screen-of-death.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import classNames from "classnames";
import { useEffect, useRef, useState } from "react";
import { useEffect, useState } from "react";

import { formatAbsolutePaths } from "../features/console-logs.js";
import {
OpenFileInEditorButton,
createHtmlLink,
} from "../shared/use-file-link.js";

export const BlueScreenOfDeath = ({
title,
Expand All @@ -22,7 +25,7 @@ export const BlueScreenOfDeath = ({
return;
}
setFormattedPathsError(
formatAbsolutePaths(
createHtmlLink(
error,
"underline text-slate-300 hover:text-slate-400",
true,
Expand All @@ -46,10 +49,12 @@ export const BlueScreenOfDeath = ({
<div className="space-y-4">
<div>{title}</div>
<div className="py-4">
<span
className="outline-none select-text whitespace-pre-wrap"
dangerouslySetInnerHTML={{ __html: formattedPathsError }}
/>
<OpenFileInEditorButton>
<span
className="outline-none select-text whitespace-pre-wrap"
dangerouslySetInnerHTML={{ __html: formattedPathsError }}
/>
</OpenFileInEditorButton>
</div>
{displayLinks && (
<div className="w-full text-center py-4">
Expand Down

0 comments on commit a00de53

Please sign in to comment.