Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit52f03db

Browse files
fix(site): fix build logs scrolling on safari (#14884)
Fix#9687
1 parentbcdb8a4 commit52f03db

File tree

5 files changed

+97
-38
lines changed

5 files changed

+97
-38
lines changed

‎site/jest.setup.ts

Lines changed: 36 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -11,30 +11,30 @@ import { server } from "testHelpers/server";
1111
// This would fail unit testing, or at least make it very slow with
1212
// actual network requests. So just globally mock this hook.
1313
jest.mock("contexts/useProxyLatency",()=>({
14-
useProxyLatency:(proxies?:Region[])=>{
15-
// Must use `useMemo` here to avoid infinite loop.
16-
// Mocking the hook with a hook.
17-
constproxyLatencies=useMemo(()=>{
18-
if(!proxies){
19-
return{}asRecord<string,ProxyLatencyReport>;
20-
}
21-
returnproxies.reduce(
22-
(acc,proxy)=>{
23-
acc[proxy.id]={
24-
accurate:true,
25-
// Return a constant latency of 8ms.
26-
// If you make this random it could break stories.
27-
latencyMS:8,
28-
at:newDate(),
29-
};
30-
returnacc;
31-
},
32-
{}asRecord<string,ProxyLatencyReport>,
33-
);
34-
},[proxies]);
14+
useProxyLatency:(proxies?:Region[])=>{
15+
// Must use `useMemo` here to avoid infinite loop.
16+
// Mocking the hook with a hook.
17+
constproxyLatencies=useMemo(()=>{
18+
if(!proxies){
19+
return{}asRecord<string,ProxyLatencyReport>;
20+
}
21+
returnproxies.reduce(
22+
(acc,proxy)=>{
23+
acc[proxy.id]={
24+
accurate:true,
25+
// Return a constant latency of 8ms.
26+
// If you make this random it could break stories.
27+
latencyMS:8,
28+
at:newDate(),
29+
};
30+
returnacc;
31+
},
32+
{}asRecord<string,ProxyLatencyReport>,
33+
);
34+
},[proxies]);
3535

36-
return{ proxyLatencies,refetch:jest.fn()};
37-
},
36+
return{ proxyLatencies,refetch:jest.fn()};
37+
},
3838
}));
3939

4040
global.scrollTo=jest.fn();
@@ -43,28 +43,30 @@ window.HTMLElement.prototype.scrollIntoView = jest.fn();
4343
window.open=jest.fn();
4444
navigator.sendBeacon=jest.fn();
4545

46+
global.ResizeObserver=require("resize-observer-polyfill");
47+
4648
// Polyfill the getRandomValues that is used on utils/random.ts
4749
Object.defineProperty(global.self,"crypto",{
48-
value:{
49-
getRandomValues:function(buffer:Buffer){
50-
returncrypto.randomFillSync(buffer);
51-
},
52-
},
50+
value:{
51+
getRandomValues:function(buffer:Buffer){
52+
returncrypto.randomFillSync(buffer);
53+
},
54+
},
5355
});
5456

5557
// Establish API mocking before all tests through MSW.
5658
beforeAll(()=>
57-
server.listen({
58-
onUnhandledRequest:"warn",
59-
}),
59+
server.listen({
60+
onUnhandledRequest:"warn",
61+
}),
6062
);
6163

6264
// Reset any request handlers that we may add during the tests,
6365
// so they don't affect other tests.
6466
afterEach(()=>{
65-
cleanup();
66-
server.resetHandlers();
67-
jest.resetAllMocks();
67+
cleanup();
68+
server.resetHandlers();
69+
jest.resetAllMocks();
6870
});
6971

7072
// Clean up after the tests are finished.

‎site/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@
9090
"react-virtualized-auto-sizer":"1.0.24",
9191
"react-window":"1.8.10",
9292
"remark-gfm":"4.0.0",
93+
"resize-observer-polyfill":"1.5.1",
9394
"rollup-plugin-visualizer":"5.12.0",
9495
"semver":"7.6.2",
9596
"tzdata":"1.0.40",

‎site/pnpm-lock.yaml

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.

‎site/src/pages/WorkspaceBuildPage/WorkspaceBuildPage.test.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,9 @@ describe("WorkspaceBuildPage", () => {
6565

6666
test("shows selected agent logs",async()=>{
6767
constserver=newWS(
68-
`ws://localhost/api/v2/workspaceagents/${MockWorkspaceAgent.id}/logs?follow&after=0`,
68+
`ws://localhost/api/v2/workspaceagents/${
69+
MockWorkspaceAgent.id
70+
}/logs?follow&after=0`,
6971
);
7072
renderWithAuth(<WorkspaceBuildPage/>,{
7173
route:`/@${MockWorkspace.owner_name}/${MockWorkspace.name}/builds/${MockWorkspace.latest_build.build_number}?${LOGS_TAB_KEY}=${MockWorkspaceAgent.id}`,

‎site/src/pages/WorkspaceBuildPage/WorkspaceBuildPageView.tsx

Lines changed: 49 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,14 @@ import {
2424
WorkspaceBuildDataSkeleton,
2525
}from"modules/workspaces/WorkspaceBuildData/WorkspaceBuildData";
2626
import{WorkspaceBuildLogs}from"modules/workspaces/WorkspaceBuildLogs/WorkspaceBuildLogs";
27-
importtype{FC}from"react";
27+
import{
28+
typeCSSProperties,
29+
typeFC,
30+
typeHTMLProps,
31+
useLayoutEffect,
32+
useRef,
33+
useState,
34+
}from"react";
2835
import{Link}from"react-router-dom";
2936
import{displayWorkspaceBuildDuration}from"utils/workspace";
3037
import{Sidebar,SidebarCaption,SidebarItem}from"./Sidebar";
@@ -144,7 +151,7 @@ export const WorkspaceBuildPageView: FC<WorkspaceBuildPageViewProps> = ({
144151
))}
145152
</Sidebar>
146153

147-
<divcss={{height:"100%",overflowY:"auto",width:"100%"}}>
154+
<ScrollArea>
148155
<Tabsactive={tabState.value}>
149156
<TabsList>
150157
<TabLinkto={`?${LOGS_TAB_KEY}=build`}value="build">
@@ -197,12 +204,51 @@ export const WorkspaceBuildPageView: FC<WorkspaceBuildPageViewProps> = ({
197204
agent={selectedAgent!}
198205
/>
199206
)}
200-
</div>
207+
</ScrollArea>
201208
</div>
202209
</DashboardFullPage>
203210
);
204211
};
205212

213+
constScrollArea:FC<HTMLProps<HTMLDivElement>>=(props)=>{
214+
// TODO: Use only CSS to set the height of the content.
215+
// Note: On Safari, when content is rendered inside a flex container and needs
216+
// to scroll, the parent container must have a height set. Achieving this may
217+
// require significant refactoring of the layout components where we currently
218+
// use height and min-height set to 100%.
219+
// Issue: https://github.com/coder/coder/issues/9687
220+
// Reference: https://stackoverflow.com/questions/43381836/height100-works-in-chrome-but-not-in-safari
221+
constcontentRef=useRef<HTMLDivElement>(null);
222+
const[height,setHeight]=useState<CSSProperties["height"]>("100%");
223+
useLayoutEffect(()=>{
224+
constcontentEl=contentRef.current;
225+
if(!contentEl){
226+
return;
227+
}
228+
229+
constresizeObserver=newResizeObserver(()=>{
230+
constparentEl=contentEl.parentElement;
231+
if(!parentEl){
232+
return;
233+
}
234+
setHeight(parentEl.clientHeight);
235+
});
236+
resizeObserver.observe(document.body);
237+
238+
return()=>{
239+
resizeObserver.disconnect();
240+
};
241+
},[]);
242+
243+
return(
244+
<div
245+
ref={contentRef}
246+
css={{ height,overflowY:"auto",width:"100%"}}
247+
{...props}
248+
/>
249+
);
250+
};
251+
206252
constBuildLogsContent:FC<{logs?:ProvisionerJobLog[]}>=({ logs})=>{
207253
if(!logs){
208254
return<Loader/>;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp