mirror of
https://github.com/gethomepage/homepage.git
synced 2026-09-16 00:55:48 -07:00
Fix: re-enable global lint, fix un-caught warnings / errors (#6990)
This commit is contained in:
@@ -17,6 +17,8 @@ const compat = new FlatCompat({
|
||||
|
||||
export default defineConfig([
|
||||
{
|
||||
files: ["**/*.{js,mjs,cjs,jsx}"],
|
||||
|
||||
extends: fixupConfigRules(compat.extends("next/core-web-vitals", "prettier", "plugin:react-hooks/recommended")),
|
||||
|
||||
plugins: {
|
||||
|
||||
@@ -15,7 +15,6 @@ export default class ErrorBoundary extends React.Component {
|
||||
|
||||
// You can also log error messages to an error reporting service here
|
||||
if (error || errorInfo) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error("component error: %s, info: %s", error, errorInfo);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -147,7 +147,7 @@ export default function QuickLaunch({ servicesAndBookmarks, searchString, setSea
|
||||
let descriptionMatch;
|
||||
if (searchDescriptions) {
|
||||
descriptionMatch = r.description?.toLowerCase().includes(searchString);
|
||||
r.priority = nameMatch ? 2 * +nameMatch : +descriptionMatch; // eslint-disable-line no-param-reassign
|
||||
r.priority = nameMatch ? 2 * +nameMatch : +descriptionMatch;
|
||||
}
|
||||
return nameMatch || descriptionMatch;
|
||||
});
|
||||
@@ -244,7 +244,6 @@ export default function QuickLaunch({ servicesAndBookmarks, searchString, setSea
|
||||
<span>
|
||||
{parts.map((part, i) =>
|
||||
part.toLowerCase() === searchString.toLowerCase() ? (
|
||||
// eslint-disable-next-line react/no-array-index-key
|
||||
<span key={`${searchString}_${i}`} className="bg-theme-300/10">
|
||||
{part}
|
||||
</span>
|
||||
|
||||
@@ -13,13 +13,13 @@ export default function Error({ error }) {
|
||||
const { t } = useTranslation();
|
||||
|
||||
if (typeof error === "string") {
|
||||
error = { message: error }; // eslint-disable-line no-param-reassign
|
||||
error = { message: error };
|
||||
} else if (typeof error === "number") {
|
||||
error = { message: `Error ${error}` }; // eslint-disable-line no-param-reassign
|
||||
error = { message: `Error ${error}` };
|
||||
}
|
||||
|
||||
if (error?.data?.error) {
|
||||
error = error.data.error; // eslint-disable-line no-param-reassign
|
||||
error = error.data.error;
|
||||
}
|
||||
|
||||
return (
|
||||
|
||||
@@ -7,7 +7,6 @@ import Resource from "../widget/resource";
|
||||
|
||||
export default function Network({ options, refresh = 1500 }) {
|
||||
const { t } = useTranslation();
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
if (options.network === true) options.network = "default";
|
||||
|
||||
const { data, error } = useSWR(`/api/widgets/resources?type=network&interfaceName=${options.network}`, {
|
||||
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
} from "@headlessui/react";
|
||||
import classNames from "classnames";
|
||||
import { useTranslation } from "next-i18next/pages";
|
||||
import { Fragment, useEffect, useState } from "react";
|
||||
import { Fragment, useEffect, useMemo, useState } from "react";
|
||||
import { BiLogoBing } from "react-icons/bi";
|
||||
import { FiSearch } from "react-icons/fi";
|
||||
import { SiBaidu, SiBrave, SiDuckduckgo, SiGoogle } from "react-icons/si";
|
||||
@@ -57,12 +57,12 @@ export const searchProviders = {
|
||||
},
|
||||
};
|
||||
|
||||
function getAvailableProviderIds(options) {
|
||||
if (options.provider && Array.isArray(options.provider)) {
|
||||
return options.provider.filter((value) => searchProviders.hasOwnProperty(value));
|
||||
function getAvailableProviderIds(provider) {
|
||||
if (provider && Array.isArray(provider)) {
|
||||
return provider.filter((value) => searchProviders.hasOwnProperty(value));
|
||||
}
|
||||
if (options.provider && searchProviders[options.provider]) {
|
||||
return [options.provider];
|
||||
if (provider && searchProviders[provider]) {
|
||||
return [provider];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -82,7 +82,8 @@ export function getStoredProvider() {
|
||||
export default function Search({ options }) {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const availableProviderIds = getAvailableProviderIds(options) ?? [];
|
||||
// options is a fresh object each render, so memo on provider itself
|
||||
const availableProviderIds = useMemo(() => getAvailableProviderIds(options.provider) ?? [], [options.provider]);
|
||||
|
||||
const [query, setQuery] = useState("");
|
||||
const [selectedProvider, setSelectedProvider] = useState(searchProviders[availableProviderIds[0] ?? "google"]);
|
||||
@@ -184,7 +185,6 @@ export default function Search({ options }) {
|
||||
autoCapitalize="off"
|
||||
autoCorrect="off"
|
||||
autoComplete="off"
|
||||
// eslint-disable-next-line jsx-a11y/no-autofocus
|
||||
autoFocus={options.focus}
|
||||
onBlur={(e) => e.preventDefault()}
|
||||
onKeyDown={handleSearchKeyDown}
|
||||
|
||||
@@ -14,7 +14,6 @@ import useWidgetAPI from "utils/proxy/use-widget-api";
|
||||
export default function Widget({ options }) {
|
||||
const { t } = useTranslation();
|
||||
|
||||
// eslint-disable-next-line no-param-reassign, no-multi-assign
|
||||
options.service_group = options.service_name = "unifi_console";
|
||||
const { data: statsData, error: statsError } = useWidgetAPI(options, "stat/sites", { index: options.index });
|
||||
|
||||
@@ -39,8 +38,8 @@ export default function Widget({ options }) {
|
||||
const lan = defaultSite.health.find((h) => h.subsystem === "lan");
|
||||
const wlan = defaultSite.health.find((h) => h.subsystem === "wlan");
|
||||
[wan, lan, wlan].forEach((s) => {
|
||||
s.up = s.status === "ok"; // eslint-disable-line no-param-reassign
|
||||
s.show = s.status !== "unknown"; // eslint-disable-line no-param-reassign
|
||||
s.up = s.status === "ok";
|
||||
s.show = s.status !== "unknown";
|
||||
});
|
||||
const name = wan.gw_name ?? defaultSite.desc;
|
||||
const uptime = wan["gw_system-stats"] ? wan["gw_system-stats"].uptime : null;
|
||||
|
||||
@@ -10,7 +10,6 @@ import WidgetIcon from "./widget_icon";
|
||||
export function getAllClasses(options, additionalClassNames = "") {
|
||||
if (options?.style?.header === "boxedWidgets") {
|
||||
if (options?.style?.cardBlur !== undefined) {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
additionalClassNames = [
|
||||
additionalClassNames,
|
||||
`backdrop-blur${options.style.cardBlur.length ? "-" : ""}${options.style.cardBlur}`,
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
/* eslint-disable react/jsx-props-no-spreading */
|
||||
import { SessionProvider } from "next-auth/react";
|
||||
import { appWithTranslation } from "next-i18next/pages";
|
||||
import Head from "next/head";
|
||||
@@ -13,7 +12,6 @@ import { ThemeProvider } from "utils/contexts/theme";
|
||||
|
||||
import nextI18nextConfig from "../../next-i18next.config";
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const tailwindSafelist = [
|
||||
// TODO: remove pending https://github.com/tailwindlabs/tailwindcss/pull/17147
|
||||
"backdrop-blur",
|
||||
|
||||
+1
-2
@@ -1,4 +1,3 @@
|
||||
/* eslint-disable react/no-array-index-key */
|
||||
import classNames from "classnames";
|
||||
import BookmarksGroup from "components/bookmarks/group";
|
||||
import ErrorBoundary from "components/errorboundry";
|
||||
@@ -175,7 +174,7 @@ function Index({ initialSettings, fallback }) {
|
||||
</div>
|
||||
<div className="p-2 text-theme-100 dark:text-theme-200">
|
||||
<pre className="opacity-50 font-bold pb-2">
|
||||
Reason: "{error.reason}" at line {error.mark?.line}
|
||||
Reason: "{error.reason}" at line {error.mark?.line}
|
||||
</pre>
|
||||
<pre className="font-italic">Check logs for details.</pre>
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { render } from "@testing-library/react";
|
||||
|
||||
import { SettingsContext } from "utils/contexts/settings";
|
||||
|
||||
export function renderWithProviders(ui, { settings = {} } = {}) {
|
||||
|
||||
@@ -32,7 +32,6 @@ export function ColorProvider({ initialTheme, children }) {
|
||||
|
||||
useEffect(() => {
|
||||
if (initialTheme !== undefined) setColor(initialTheme ?? getInitialColor());
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [initialTheme]);
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
@@ -33,7 +33,6 @@ export function ThemeProvider({ initialTheme, children }) {
|
||||
|
||||
useEffect(() => {
|
||||
if (initialTheme !== undefined) setTheme(initialTheme ?? getInitialTheme());
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [initialTheme]);
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
@@ -16,14 +16,16 @@ export default function Component({ service }) {
|
||||
widget.fields = widget.fields.slice(0, MAX_FIELDS);
|
||||
}
|
||||
|
||||
if (widget?.env == null || widget.env === "") {
|
||||
const envNotSet = widget.env == null || widget.env === "";
|
||||
|
||||
const { data: containers, error: containersError } = useWidgetAPI(widget, envNotSet ? "" : "containers");
|
||||
const { data: images, error: imagesError } = useWidgetAPI(widget, envNotSet ? "" : "images");
|
||||
const { data: updates, error: updatesError } = useWidgetAPI(widget, envNotSet ? "" : "updates");
|
||||
|
||||
if (envNotSet) {
|
||||
return <Container service={service} error={t("arcane.environment_required")} />;
|
||||
}
|
||||
|
||||
const { data: containers, error: containersError } = useWidgetAPI(widget, "containers");
|
||||
const { data: images, error: imagesError } = useWidgetAPI(widget, "images");
|
||||
const { data: updates, error: updatesError } = useWidgetAPI(widget, "updates");
|
||||
|
||||
const error =
|
||||
containersError ?? imagesError ?? updatesError ?? containers?.detail ?? images?.detail ?? updates?.detail;
|
||||
if (error) {
|
||||
|
||||
@@ -20,11 +20,15 @@ describe("widgets/arcane/component", () => {
|
||||
});
|
||||
|
||||
it("shows an environment required error when env is missing", () => {
|
||||
useWidgetAPI.mockImplementation(() => ({ data: undefined, error: undefined }));
|
||||
|
||||
renderWithProviders(<Component service={{ widget: { type: "arcane" } }} />, {
|
||||
settings: { hideErrors: false },
|
||||
});
|
||||
|
||||
expect(useWidgetAPI).not.toHaveBeenCalled();
|
||||
// hooks always run; the empty endpoint is what skips the request
|
||||
expect(useWidgetAPI).toHaveBeenCalledTimes(3);
|
||||
useWidgetAPI.mock.calls.forEach((call) => expect(call[1]).toBe(""));
|
||||
expect(screen.getByText("arcane.environment_required")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
|
||||
@@ -27,7 +27,6 @@ export default function Component({ service }) {
|
||||
}
|
||||
|
||||
// uptime info
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const [hour, minutes, seconds] = infoData.data.up_time.split(":");
|
||||
const days = Math.floor(hour / 24);
|
||||
const uptime = `${t("common.number", { value: days })} ${t("diskstation.days")}`;
|
||||
|
||||
@@ -28,7 +28,6 @@ export default function Component({ service }) {
|
||||
|
||||
useEffect(() => {
|
||||
if (data && !data.error) {
|
||||
// eslint-disable-next-line eqeqeq
|
||||
const gpuData = data.find((item) => item[item.key] == gpuName);
|
||||
|
||||
if (gpuData) {
|
||||
@@ -56,7 +55,6 @@ export default function Component({ service }) {
|
||||
);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line eqeqeq
|
||||
const gpuData = data.find((item) => item[item.key] == gpuName);
|
||||
|
||||
if (!gpuData) {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import Block from "components/services/widget/block";
|
||||
import Container from "components/services/widget/container";
|
||||
import { useTranslation } from "next-i18next/pages";
|
||||
|
||||
import useWidgetAPI from "utils/proxy/use-widget-api";
|
||||
|
||||
export default function Component({ service }) {
|
||||
|
||||
@@ -8,7 +8,6 @@ export default function Component({ service }) {
|
||||
const { t } = useTranslation();
|
||||
const { widget } = service;
|
||||
|
||||
// eslint-disable-next-line prefer-const
|
||||
let { data: spoolData, error: spoolError } = useWidgetAPI(widget, "spools");
|
||||
|
||||
if (spoolError) {
|
||||
@@ -20,7 +19,6 @@ export default function Component({ service }) {
|
||||
return (
|
||||
<Container service={service}>
|
||||
{[...Array(nBlocksGuess)].map((_, i) => (
|
||||
// eslint-disable-next-line react/no-array-index-key
|
||||
<Block key={i} label="spoolman.loading" />
|
||||
))}
|
||||
</Container>
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
/* eslint-disable camelcase */
|
||||
import Container from "components/services/widget/container";
|
||||
import { useTranslation } from "next-i18next/pages";
|
||||
import { BsCpu, BsFillCpuFill, BsFillPlayFill, BsPauseFill } from "react-icons/bs";
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
/* eslint-disable camelcase */
|
||||
import Block from "components/services/widget/block";
|
||||
import Container from "components/services/widget/container";
|
||||
import { useTranslation } from "next-i18next/pages";
|
||||
|
||||
@@ -38,8 +38,8 @@ export default function Component({ service }) {
|
||||
const lan = defaultSite.health.find((h) => h.subsystem === "lan");
|
||||
const wlan = defaultSite.health.find((h) => h.subsystem === "wlan");
|
||||
[wan, lan, wlan].forEach((s) => {
|
||||
s.up = s.status === "ok"; // eslint-disable-line no-param-reassign
|
||||
s.show = s.status !== "unknown"; // eslint-disable-line no-param-reassign
|
||||
s.up = s.status === "ok";
|
||||
s.show = s.status !== "unknown";
|
||||
});
|
||||
|
||||
const uptime = wan["gw_system-stats"]
|
||||
|
||||
Reference in New Issue
Block a user