Skip to content

Commit 80eac73

Browse files
authored
chore: remove useLocalStorage hook (#11712)
1 parent fa99f6a commit 80eac73

File tree

17 files changed

+83
-92
lines changed

17 files changed

+83
-92
lines changed

coderd/externalauth/externalauth.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,7 @@ func (c *DeviceAuth) AuthorizeDevice(ctx context.Context) (*codersdk.ExternalAut
327327
case http.StatusTooManyRequests:
328328
return nil, xerrors.New("rate limit hit, unable to authorize device. please try again later")
329329
default:
330-
return nil, fmt.Errorf("status_code=%d: %w", resp.StatusCode, err)
330+
return nil, xerrors.Errorf("status_code=%d: %w", resp.StatusCode, err)
331331
}
332332
}
333333
if r.ErrorDescription != "" {

coderd/workspaceagents_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -1626,7 +1626,7 @@ func TestWorkspaceAgentExternalAuthListen(t *testing.T) {
16261626
cancel()
16271627
// We expect only 1
16281628
// In a failed test, you will likely see 9, as the last one
1629-
// gets cancelled.
1629+
// gets canceled.
16301630
require.Equal(t, 1, validateCalls, "validate calls duplicated on same token")
16311631
})
16321632
}

enterprise/coderd/proxyhealth/proxyhealth.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -276,17 +276,17 @@ func (p *ProxyHealth) runOnce(ctx context.Context, now time.Time) (map[uuid.UUID
276276
case err == nil && resp.StatusCode == http.StatusOK:
277277
err := json.NewDecoder(resp.Body).Decode(&status.Report)
278278
if err != nil {
279-
isCoderErr := fmt.Errorf("proxy url %q is not a coder proxy instance, verify the url is correct", reqURL)
279+
isCoderErr := xerrors.Errorf("proxy url %q is not a coder proxy instance, verify the url is correct", reqURL)
280280
if resp.Header.Get(codersdk.BuildVersionHeader) != "" {
281-
isCoderErr = fmt.Errorf("proxy url %q is a coder instance, but unable to decode the response payload. Could this be a primary coderd and not a proxy?", reqURL)
281+
isCoderErr = xerrors.Errorf("proxy url %q is a coder instance, but unable to decode the response payload. Could this be a primary coderd and not a proxy?", reqURL)
282282
}
283283

284284
// If the response is not json, then the user likely input a bad url that returns status code 200.
285285
// This is very common, since most webpages do return a 200. So let's improve the error message.
286286
if notJSONErr := codersdk.ExpectJSONMime(resp); notJSONErr != nil {
287287
err = errors.Join(
288288
isCoderErr,
289-
fmt.Errorf("attempted to query health at %q but got back the incorrect content type: %w", reqURL, notJSONErr),
289+
xerrors.Errorf("attempted to query health at %q but got back the incorrect content type: %w", reqURL, notJSONErr),
290290
)
291291

292292
status.Report.Errors = []string{
@@ -300,7 +300,7 @@ func (p *ProxyHealth) runOnce(ctx context.Context, now time.Time) (map[uuid.UUID
300300
status.Report.Errors = []string{
301301
errors.Join(
302302
isCoderErr,
303-
fmt.Errorf("received a status code 200, but failed to decode health report body: %w", err),
303+
xerrors.Errorf("received a status code 200, but failed to decode health report body: %w", err),
304304
).Error(),
305305
}
306306
status.Status = Unhealthy

enterprise/wsproxy/wsproxy.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ func New(ctx context.Context, opts *Options) (*Server, error) {
159159
info, err := client.SDKClient.BuildInfo(ctx)
160160
if err != nil {
161161
return nil, fmt.Errorf("buildinfo: %w", errors.Join(
162-
fmt.Errorf("unable to fetch build info from primary coderd. Are you sure %q is a coderd instance?", opts.DashboardURL),
162+
xerrors.Errorf("unable to fetch build info from primary coderd. Are you sure %q is a coderd instance?", opts.DashboardURL),
163163
err,
164164
))
165165
}
-2.94 KB
Binary file not shown.

site/src/components/Abbr/Abbr.stories.tsx

+13-12
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,6 @@
1-
import { type PropsWithChildren } from "react";
21
import type { Meta, StoryObj } from "@storybook/react";
32
import { Abbr } from "./Abbr";
43

5-
// Just here to make the abbreviated part more obvious in the component library
6-
const Underline = ({ children }: PropsWithChildren) => (
7-
<span css={{ textDecoration: "underline dotted" }}>{children}</span>
8-
);
9-
104
const meta: Meta<typeof Abbr> = {
115
title: "components/Abbr",
126
component: Abbr,
@@ -34,9 +28,9 @@ export const InlinedShorthand: Story = {
3428
<p css={{ maxWidth: "40em" }}>
3529
The physical pain of getting bonked on the head with a cartoon mallet
3630
lasts precisely 593{" "}
37-
<Underline>
31+
<span css={styles.underlined}>
3832
<Story />
39-
</Underline>
33+
</span>
4034
. The emotional turmoil and complete embarrassment lasts forever.
4135
</p>
4236
),
@@ -51,9 +45,9 @@ export const Acronym: Story = {
5145
},
5246
decorators: [
5347
(Story) => (
54-
<Underline>
48+
<span css={styles.underlined}>
5549
<Story />
56-
</Underline>
50+
</span>
5751
),
5852
],
5953
};
@@ -66,9 +60,16 @@ export const Initialism: Story = {
6660
},
6761
decorators: [
6862
(Story) => (
69-
<Underline>
63+
<span css={styles.underlined}>
7064
<Story />
71-
</Underline>
65+
</span>
7266
),
7367
],
7468
};
69+
70+
const styles = {
71+
// Just here to make the abbreviated part more obvious in the component library
72+
underlined: {
73+
textDecoration: "underline dotted",
74+
},
75+
};

site/src/components/Dashboard/useUpdateCheck.test.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ const createWrapper = (): FC<PropsWithChildren> => {
1414
};
1515

1616
beforeEach(() => {
17-
window.localStorage.clear();
17+
localStorage.clear();
1818
});
1919

2020
it("is dismissed when does not have permission to see it", () => {
@@ -57,7 +57,7 @@ it("is dismissed when it was dismissed previously", async () => {
5757
);
5858
}),
5959
);
60-
window.localStorage.setItem("dismissedVersion", MockUpdateCheck.version);
60+
localStorage.setItem("dismissedVersion", MockUpdateCheck.version);
6161
const { result } = renderHook(() => useUpdateCheck(true), {
6262
wrapper: createWrapper(),
6363
});

site/src/components/Resources/VSCodeDesktopButton/VSCodeDesktopButton.tsx

+12-16
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
1-
import { FC, PropsWithChildren, useState, useRef } from "react";
2-
import { getApiKey } from "api/api";
3-
import { VSCodeIcon } from "components/Icons/VSCodeIcon";
4-
import { VSCodeInsidersIcon } from "components/Icons/VSCodeInsidersIcon";
5-
import { AgentButton } from "components/Resources/AgentButton";
61
import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown";
72
import ButtonGroup from "@mui/material/ButtonGroup";
8-
import { useLocalStorage } from "hooks";
93
import Menu from "@mui/material/Menu";
104
import MenuItem from "@mui/material/MenuItem";
5+
import { type FC, useState, useRef } from "react";
6+
import { getApiKey } from "api/api";
117
import { DisplayApp } from "api/typesGenerated";
8+
import { VSCodeIcon } from "components/Icons/VSCodeIcon";
9+
import { VSCodeInsidersIcon } from "components/Icons/VSCodeInsidersIcon";
10+
import { AgentButton } from "components/Resources/AgentButton";
1211
import { DisplayAppNameMap } from "../AppLink/AppLink";
1312

1413
export interface VSCodeDesktopButtonProps {
@@ -23,12 +22,9 @@ type VSCodeVariant = "vscode" | "vscode-insiders";
2322

2423
const VARIANT_KEY = "vscode-variant";
2524

26-
export const VSCodeDesktopButton: FC<
27-
PropsWithChildren<VSCodeDesktopButtonProps>
28-
> = (props) => {
25+
export const VSCodeDesktopButton: FC<VSCodeDesktopButtonProps> = (props) => {
2926
const [isVariantMenuOpen, setIsVariantMenuOpen] = useState(false);
30-
const localStorage = useLocalStorage();
31-
const previousVariant = localStorage.getLocal(VARIANT_KEY);
27+
const previousVariant = localStorage.getItem(VARIANT_KEY);
3228
const [variant, setVariant] = useState<VSCodeVariant>(() => {
3329
if (!previousVariant) {
3430
return "vscode";
@@ -38,7 +34,7 @@ export const VSCodeDesktopButton: FC<
3834
const menuAnchorRef = useRef<HTMLDivElement>(null);
3935

4036
const selectVariant = (variant: VSCodeVariant) => {
41-
localStorage.saveLocal(VARIANT_KEY, variant);
37+
localStorage.setItem(VARIANT_KEY, variant);
4238
setVariant(variant);
4339
setIsVariantMenuOpen(false);
4440
};
@@ -109,12 +105,12 @@ export const VSCodeDesktopButton: FC<
109105
);
110106
};
111107

112-
const VSCodeButton = ({
108+
const VSCodeButton: FC<VSCodeDesktopButtonProps> = ({
113109
userName,
114110
workspaceName,
115111
agentName,
116112
folderPath,
117-
}: VSCodeDesktopButtonProps) => {
113+
}) => {
118114
const [loading, setLoading] = useState(false);
119115

120116
return (
@@ -153,12 +149,12 @@ const VSCodeButton = ({
153149
);
154150
};
155151

156-
const VSCodeInsidersButton = ({
152+
const VSCodeInsidersButton: FC<VSCodeDesktopButtonProps> = ({
157153
userName,
158154
workspaceName,
159155
agentName,
160156
folderPath,
161-
}: VSCodeDesktopButtonProps) => {
157+
}) => {
162158
const [loading, setLoading] = useState(false);
163159

164160
return (

site/src/contexts/ProxyContext.test.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import { screen } from "@testing-library/react";
1919
import { server } from "testHelpers/server";
2020
import { rest } from "msw";
2121
import { Region } from "api/typesGenerated";
22-
import "testHelpers/localstorage";
22+
import "testHelpers/localStorage";
2323
import userEvent from "@testing-library/user-event";
2424

2525
// Mock useProxyLatency to use a hard-coded latency. 'jest.mock' must be called
@@ -187,7 +187,7 @@ interface ProxyContextSelectionTest {
187187

188188
describe("ProxyContextSelection", () => {
189189
beforeEach(() => {
190-
window.localStorage.clear();
190+
localStorage.clear();
191191
});
192192

193193
// A way to simulate a user clearing the proxy selection.

site/src/contexts/ProxyContext.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -310,11 +310,11 @@ const computeUsableURLS = (proxy?: Region): PreferredProxy => {
310310
// Local storage functions
311311

312312
export const clearUserSelectedProxy = (): void => {
313-
window.localStorage.removeItem("user-selected-proxy");
313+
localStorage.removeItem("user-selected-proxy");
314314
};
315315

316316
export const saveUserSelectedProxy = (saved: Region): void => {
317-
window.localStorage.setItem("user-selected-proxy", JSON.stringify(saved));
317+
localStorage.setItem("user-selected-proxy", JSON.stringify(saved));
318318
};
319319

320320
export const loadUserSelectedProxy = (): Region | undefined => {

site/src/hooks/index.ts

-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ export * from "./useClickable";
22
export * from "./useClickableTableRow";
33
export * from "./useClipboard";
44
export * from "./useFeatureVisibility";
5-
export * from "./useLocalStorage";
65
export * from "./useMe";
76
export * from "./useOrganizationId";
87
export * from "./usePagination";

site/src/hooks/useLocalStorage.ts

-19
This file was deleted.

site/src/pages/TemplateSettingsPage/TemplateSchedulePage/TemplateSchedulePage.tsx

+4-5
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@ import { updateTemplateMeta } from "api/api";
33
import { UpdateTemplateMeta } from "api/typesGenerated";
44
import { useDashboard } from "components/Dashboard/DashboardProvider";
55
import { displaySuccess } from "components/GlobalSnackbar/utils";
6-
import { FC } from "react";
6+
import { type FC } from "react";
77
import { Helmet } from "react-helmet-async";
88
import { useNavigate, useParams } from "react-router-dom";
99
import { pageTitle } from "utils/page";
1010
import { useTemplateSettings } from "../TemplateSettingsLayout";
1111
import { TemplateSchedulePageView } from "./TemplateSchedulePageView";
12-
import { useLocalStorage, useOrganizationId } from "hooks";
12+
import { useOrganizationId } from "hooks";
1313
import { templateByNameKey } from "api/queries/templates";
1414

1515
const TemplateSchedulePage: FC = () => {
@@ -21,7 +21,6 @@ const TemplateSchedulePage: FC = () => {
2121
const { entitlements } = useDashboard();
2222
const allowAdvancedScheduling =
2323
entitlements.features["advanced_template_scheduling"].enabled;
24-
const { clearLocal } = useLocalStorage();
2524

2625
const {
2726
mutate: updateTemplate,
@@ -36,8 +35,8 @@ const TemplateSchedulePage: FC = () => {
3635
);
3736
displaySuccess("Template updated successfully");
3837
// clear browser storage of workspaces impending deletion
39-
clearLocal("dismissedWorkspaceList"); // workspaces page
40-
clearLocal("dismissedWorkspace"); // workspace page
38+
localStorage.removeItem("dismissedWorkspaceList"); // workspaces page
39+
localStorage.removeItem("dismissedWorkspace"); // workspace page
4140
},
4241
},
4342
);

site/src/pages/TemplateVersionEditorPage/TemplateVersionEditor.tsx

+3-3
Original file line numberDiff line numberDiff line change
@@ -64,13 +64,13 @@ export interface TemplateVersionEditorProps {
6464
defaultFileTree: FileTree;
6565
buildLogs?: ProvisionerJobLog[];
6666
resources?: WorkspaceResource[];
67-
disablePreview: boolean;
68-
disableUpdate: boolean;
67+
disablePreview?: boolean;
68+
disableUpdate?: boolean;
6969
onPreview: (files: FileTree) => void;
7070
onPublish: () => void;
7171
onConfirmPublish: (data: PublishVersionData) => void;
7272
onCancelPublish: () => void;
73-
publishingError: unknown;
73+
publishingError?: unknown;
7474
publishedVersion?: TemplateVersion;
7575
onCreateWorkspace: () => void;
7676
isAskingPublishParameters: boolean;

site/src/pages/WorkspacePage/WorkspacePage.test.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,7 @@ describe("WorkspacePage", () => {
317317
});
318318

319319
it("restart the workspace with one time parameters when having the confirmation dialog", async () => {
320-
window.localStorage.removeItem(`${MockUser.id}_ignoredWarnings`);
320+
localStorage.removeItem(`${MockUser.id}_ignoredWarnings`);
321321
jest.spyOn(api, "getWorkspaceParameters").mockResolvedValue({
322322
templateVersionRichParameters: [
323323
{

site/src/testHelpers/localStorage.ts

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
export const localStorageMock = (): Storage => {
2+
const store = new Map<string, string>();
3+
4+
return {
5+
getItem: (key) => {
6+
return store.get(key) ?? null;
7+
},
8+
setItem: (key: string, value: string) => {
9+
store.set(key, value);
10+
},
11+
clear: () => {
12+
store.clear();
13+
},
14+
removeItem: (key: string) => {
15+
store.delete(key);
16+
},
17+
18+
get length() {
19+
return store.size;
20+
},
21+
22+
key: (index) => {
23+
const values = store.values();
24+
let value: IteratorResult<string, undefined> = values.next();
25+
for (let i = 1; i < index && !value.done; i++) {
26+
value = values.next();
27+
}
28+
29+
return value.value ?? null;
30+
},
31+
};
32+
};
33+
34+
Object.defineProperty(globalThis, "localStorage", {
35+
value: localStorageMock(),
36+
writable: false,
37+
});

site/src/testHelpers/localstorage.ts

-22
This file was deleted.

0 commit comments

Comments
 (0)