Skip to content

Fixing lint errors in dashboard #17156

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions components/dashboard/src/admin/License.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,6 @@ import { getGitpodService } from "../service/service";
import { ReactComponent as Alert } from "../images/exclamation.svg";
import { ReactComponent as Success } from "../images/check-circle.svg";
import { LicenseInfo } from "@gitpod/gitpod-protocol";
import { ReactComponent as XSvg } from "../images/x.svg";
import { ReactComponent as CheckSvg } from "../images/check.svg";
import { ReactComponent as LinkSvg } from "../images/external-link.svg";
import SolidCard from "../components/SolidCard";
import Card from "../components/Card";
import { isGitpodIo } from "../utils";
Expand Down
1 change: 1 addition & 0 deletions components/dashboard/src/admin/ProjectsSearch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ export function ProjectsSearch() {
} else {
setCurrentProject(undefined);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [location]);

useEffect(() => {
Expand Down
1 change: 1 addition & 0 deletions components/dashboard/src/admin/Settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export default function Settings() {
const setting = await getGitpodService().server.adminGetSettings();
setAdminSettings(setting);
})();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

const actuallySetTelemetryPrefs = async (value: InstallationAdminSettings) => {
Expand Down
1 change: 1 addition & 0 deletions components/dashboard/src/admin/TeamsSearch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ export function TeamsSearch() {
} else {
setCurrentTeam(undefined);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [location]);

if (currentTeam) {
Expand Down
2 changes: 1 addition & 1 deletion components/dashboard/src/admin/UserDetail.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -473,7 +473,7 @@ function renderBillingModeProperty(billingMode?: BillingMode): JSX.Element {
>
<p className="flex justify-left text-gitpod-red">
<span>UBP blocked by:</span>
<img className="m-2" src={CaretDown} />
<img className="m-2" src={CaretDown} alt="caret icon pointing down" />
</p>
</ContextMenu>
)}
Expand Down
1 change: 1 addition & 0 deletions components/dashboard/src/admin/UserSearch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export default function UserSearch() {
} else {
setCurrentUserState(undefined);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [location]);

if (currentUser) {
Expand Down
2 changes: 2 additions & 0 deletions components/dashboard/src/admin/WorkspacesSearch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,14 @@ export function WorkspaceSearch(props: Props) {
} else {
setCurrentWorkspaceState(undefined);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [location]);

useEffect(() => {
if (props.user) {
search();
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [props.user]);

if (currentWorkspace) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export default function ConfirmationModal(props: {
const buttonDisabled = useRef(props.buttonDisabled);
useEffect(() => {
buttonDisabled.current = props.buttonDisabled;
// eslint-disable-next-line react-hooks/exhaustive-deps
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the reason the linter gets this one wrong so often? And if it's the case, can we tweak the rules/disable?

Copy link
Contributor Author

@selfcontained selfcontained Apr 11, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's more often overly-using or improperly using the useEffect() hook (from what I've bumped into so far). This linter rule makes sure you include any "dependencies" for your hook, cause if you miss some, it can behave unexpectedly (using stale variable values), so I think it's still preferred to keep the hook as is, and when we have an exception, it's called out with a disabled line like this. In many of these fixes I've opted for the safer approach of not changing existing behavior and disabling the warning vs. adjusting behavior to what might be more correct.

}, []);

return (
Expand Down
11 changes: 1 addition & 10 deletions components/dashboard/src/components/ContextMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,16 +36,6 @@ export interface ContextMenuEntry {
function ContextMenu(props: ContextMenuProps) {
const [expanded, setExpanded] = useState(false);

const { changeMenuState } = props;

useEffect(() => {
return () => {
if (changeMenuState) {
changeMenuState(!expanded);
}
};
}, [expanded]);

const toggleExpanded = () => {
setExpanded(!expanded);
if (props.changeMenuState) {
Expand Down Expand Up @@ -80,6 +70,7 @@ function ContextMenu(props: ContextMenuProps) {
window.removeEventListener("keydown", keydownHandler);
window.removeEventListener("click", clickHandler);
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []); // Empty array ensures that effect is only run on mount and unmount

// Default 'children' is the three dots hamburger button.
Expand Down
2 changes: 1 addition & 1 deletion components/dashboard/src/components/DropDown2.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ export const DropDown2: FunctionComponent<DropDown2Props> = (props) => {
e.preventDefault();
}
},
[filteredOptions, props, selectedElementTemp, setFocussedElement, showDropDown, toggleDropDown],
[filteredOptions, props, search, selectedElementTemp, setFocussedElement, showDropDown, toggleDropDown],
);

const handleBlur = useCallback(
Expand Down
2 changes: 1 addition & 1 deletion components/dashboard/src/components/InfoBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export default function InfoBox(p: { className?: string; children?: React.ReactN
(p.className || "")
}
>
<img className="w-4 h-4 m-1 ml-2 mr-4" src={info} />
<img className="w-4 h-4 m-1 ml-2 mr-4" src={info} alt="info icon" />
<span>{p.children}</span>
</div>
);
Expand Down
1 change: 1 addition & 0 deletions components/dashboard/src/components/MonacoEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ export default function MonacoEditor(props: MonacoEditorProps) {
});
}
return () => editorRef.current?.dispose();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

useEffect(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export default function PendingChangesDropdown(props: { workspaceInstance?: Work
<span>
{totalChanges} Change{totalChanges === 1 ? "" : "s"}
</span>
<img className="m-2" src={CaretDown} />
<img className="m-2" src={CaretDown} alt="caret icon pointing down" />
</p>
</ContextMenu>
);
Expand Down
27 changes: 15 additions & 12 deletions components/dashboard/src/components/PrebuildLogs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
*/

import EventEmitter from "events";
import React, { Suspense, useEffect, useState } from "react";
import React, { Suspense, useCallback, useEffect, useState } from "react";
import {
WorkspaceInstance,
DisposableCollection,
Expand All @@ -32,18 +32,21 @@ export default function PrebuildLogs(props: PrebuildLogsProps) {
const [logsEmitter] = useState(new EventEmitter());
const [prebuild, setPrebuild] = useState<PrebuildWithStatus | undefined>();

function handlePrebuildUpdate(prebuild: PrebuildWithStatus) {
if (prebuild.info.buildWorkspaceId === props.workspaceId) {
setPrebuild(prebuild);
const handlePrebuildUpdate = useCallback(
(prebuild: PrebuildWithStatus) => {
if (prebuild.info.buildWorkspaceId === props.workspaceId) {
setPrebuild(prebuild);

// In case the Prebuild got "aborted" or "time(d)out" we want to user to proceed anyway
if (props.onIgnorePrebuild && (prebuild.status === "aborted" || prebuild.status === "timeout")) {
props.onIgnorePrebuild();
// In case the Prebuild got "aborted" or "time(d)out" we want to user to proceed anyway
if (props.onIgnorePrebuild && (prebuild.status === "aborted" || prebuild.status === "timeout")) {
props.onIgnorePrebuild();
}
// TODO(gpl) We likely want to move the "happy path" logic (for status "available")
// here as well at some point. For that to work we need a "registerPrebuildUpdate(prebuildId)" API
}
// TODO(gpl) We likely want to move the "happy path" logic (for status "available")
// here as well at some point. For that to work we need a "registerPrebuildUpdate(prebuildId)" API
}
}
},
[props],
);

useEffect(() => {
const disposables = new DisposableCollection();
Expand Down Expand Up @@ -105,7 +108,7 @@ export default function PrebuildLogs(props: PrebuildLogsProps) {
return function cleanup() {
disposables.dispose();
};
}, [logsEmitter, props.workspaceId]);
}, [handlePrebuildUpdate, logsEmitter, props.workspaceId]);

useEffect(() => {
const workspaceId = props.workspaceId;
Expand Down
4 changes: 4 additions & 0 deletions components/dashboard/src/components/WorkspaceLogs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ export default function WorkspaceLogs(props: WorkspaceLogsProps) {
return function cleanUp() {
terminal.dispose();
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

useEffect(() => {
Expand All @@ -70,19 +71,22 @@ export default function WorkspaceLogs(props: WorkspaceLogsProps) {
clearTimeout(timeout!);
window.removeEventListener("resize", onWindowResize);
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

useEffect(() => {
if (terminalRef.current && props.errorMessage) {
terminalRef.current.write(`\r\n\u001b[38;5;196m${props.errorMessage}\u001b[0m\r\n`);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [terminalRef.current, props.errorMessage]);

useEffect(() => {
if (!terminalRef.current) {
return;
}
terminalRef.current.setOption("theme", isDark ? darkTheme : lightTheme);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [terminalRef.current, isDark]);

return (
Expand Down
4 changes: 1 addition & 3 deletions components/dashboard/src/user-settings/selectClass.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,9 @@
* See License.AGPL.txt in the project root for license information.
*/

import { useEffect, useState } from "react";
import { getGitpodService } from "../service/service";
import { useState } from "react";
import { trackEvent } from "../Analytics";
import WorkspaceClass from "../components/WorkspaceClass";
import { SupportedWorkspaceClass } from "@gitpod/gitpod-protocol/lib/workspace-class";
import { useWorkspaceClasses } from "../data/workspaces/workspace-classes-query";

interface SelectWorkspaceClassProps {
Expand Down