More linting fixes

This commit is contained in:
Adam Shiervani 2025-03-25 10:44:08 +01:00
parent 396f7f348d
commit 9979bb4161
17 changed files with 115 additions and 109 deletions

View File

@ -13,8 +13,8 @@
"build:device": "tsc && vite build --mode=device --emptyOutDir",
"build:staging": "tsc && vite build --mode=cloud-staging",
"build:prod": "tsc && vite build --mode=cloud-production",
"lint": "eslint ./src/**/*.{ts,tsx} --no-error-on-unmatched-pattern",
"lint:fix": "eslint ./src/**/*.{ts,tsx} --no-error-on-unmatched-pattern --fix",
"lint": "eslint './src/**/*.{ts,tsx}'",
"lint:fix": "eslint './src/**/*.{ts,tsx}' --fix",
"preview": "vite preview"
},
"dependencies": {

View File

@ -16,12 +16,9 @@ import Container from "@components/Container";
import { cx } from "@/cva.config";
import PasteModal from "@/components/popovers/PasteModal";
import WakeOnLanModal from "@/components/popovers/WakeOnLan/Index";
import { useDeviceUiNavigation } from "../hooks/useAppNavigation";
import MountPopopover from "./popovers/MountPopover";
import ExtensionPopover from "./popovers/ExtensionPopover";
import MountPopopover from "@/components/popovers/MountPopover";
import ExtensionPopover from "@/components/popovers/ExtensionPopover";
import { useDeviceUiNavigation } from "@/hooks/useAppNavigation";
export default function Actionbar({
requestFullscreen,

View File

@ -47,8 +47,8 @@ export default function AuthLayout({
}
/>
<Container>
<div className="flex items-center justify-center w-full h-full isolate">
<div className="max-w-2xl -mt-16 space-y-8">
<div className="isolate flex h-full w-full items-center justify-center">
<div className="-mt-16 max-w-2xl space-y-8">
{showCounter ? (
<div className="text-center">
<StepCounter currStepIdx={0} nSteps={2} />
@ -62,11 +62,8 @@ export default function AuthLayout({
</div>
<Fieldset className="space-y-12">
<div className="max-w-sm mx-auto space-y-4">
<form
action={`${CLOUD_API}/oidc/google`}
method="POST"
>
<div className="mx-auto max-w-sm space-y-4">
<form action={`${CLOUD_API}/oidc/google`} method="POST">
{/*This could be the KVM ID*/}
{deviceId ? (
<input type="hidden" name="deviceId" value={deviceId} />

View File

@ -1,11 +1,13 @@
import { Button } from "@components/Button";
import { LuHardDrive, LuPower, LuRotateCcw } from "react-icons/lu";
import { useEffect, useState } from "react";
import { Button } from "@components/Button";
import Card from "@components/Card";
import { SettingsPageHeader } from "@components/SettingsPageheader";
import { useEffect, useState } from "react";
import notifications from "@/notifications";
import LoadingSpinner from "@/components/LoadingSpinner";
import { useJsonRpc } from "../../hooks/useJsonRpc";
import LoadingSpinner from "../LoadingSpinner";
const LONG_PRESS_DURATION = 3000; // 3 seconds for long press
@ -102,11 +104,11 @@ export function ATXPowerControl() {
{atxState === null ? (
<Card className="flex h-[120px] items-center justify-center p-3">
<LoadingSpinner className="w-6 h-6 text-blue-500 dark:text-blue-400" />
<LoadingSpinner className="h-6 w-6 text-blue-500 dark:text-blue-400" />
</Card>
) : (
<Card className="h-[120px] animate-fadeIn opacity-0">
<div className="p-3 space-y-4">
<div className="space-y-4 p-3">
{/* Control Buttons */}
<div className="flex items-center space-x-2">
<Button

View File

@ -1,12 +1,13 @@
import { Button } from "@components/Button";
import { LuPower } from "react-icons/lu";
import { useCallback, useEffect, useState } from "react";
import { Button } from "@components/Button";
import Card from "@components/Card";
import { SettingsPageHeader } from "@components/SettingsPageheader";
import FieldLabel from "../FieldLabel";
import { useJsonRpc } from "@/hooks/useJsonRpc";
import { useCallback, useEffect, useState } from "react";
import notifications from "@/notifications";
import LoadingSpinner from "../LoadingSpinner";
import FieldLabel from "@components/FieldLabel";
import LoadingSpinner from "@components/LoadingSpinner";
interface DCPowerState {
isOn: boolean;
@ -59,11 +60,11 @@ export function DCPowerControl() {
{powerState === null ? (
<Card className="flex h-[160px] justify-center p-3">
<LoadingSpinner className="w-6 h-6 text-blue-500 dark:text-blue-400" />
<LoadingSpinner className="h-6 w-6 text-blue-500 dark:text-blue-400" />
</Card>
) : (
<Card className="h-[160px] animate-fadeIn opacity-0">
<div className="p-3 space-y-4">
<div className="space-y-4 p-3">
{/* Power Controls */}
<div className="flex items-center space-x-2">
<Button

View File

@ -1,12 +1,13 @@
import { Button } from "@components/Button";
import { LuTerminal } from "react-icons/lu";
import { useEffect, useState } from "react";
import { Button } from "@components/Button";
import Card from "@components/Card";
import { SettingsPageHeader } from "@components/SettingsPageheader";
import { SelectMenuBasic } from "../SelectMenuBasic";
import { useJsonRpc } from "@/hooks/useJsonRpc";
import { useEffect, useState } from "react";
import notifications from "@/notifications";
import { useUiStore } from "@/hooks/stores";
import { SelectMenuBasic } from "@components/SelectMenuBasic";
interface SerialSettings {
baudRate: string;

View File

@ -1,19 +1,20 @@
import { useEffect, useState } from "react";
import { LuPower, LuTerminal, LuPlugZap } from "react-icons/lu";
import { useJsonRpc } from "@/hooks/useJsonRpc";
import Card, { GridCard } from "@components/Card";
import { SettingsPageHeader } from "@components/SettingsPageheader";
import { Button } from "../Button";
import { LuPower, LuTerminal, LuPlugZap } from "react-icons/lu";
import { ATXPowerControl } from "@components/extensions/ATXPowerControl";
import { DCPowerControl } from "@components/extensions/DCPowerControl";
import { SerialConsole } from "@components/extensions/SerialConsole";
import notifications from "../../notifications";
import { Button } from "@components/Button";
import notifications from "@/notifications";
interface Extension {
id: string;
name: string;
description: string;
icon: any;
icon: React.ElementType;
}
const AVAILABLE_EXTENSIONS: Extension[] = [
@ -58,7 +59,9 @@ export default function ExtensionPopover() {
const handleSetActiveExtension = (extension: Extension | null) => {
send("setActiveExtension", { extensionId: extension?.id || "" }, resp => {
if ("error" in resp) {
notifications.error(`Failed to set active extension: ${resp.error.data || "Unknown error"}`);
notifications.error(
`Failed to set active extension: ${resp.error.data || "Unknown error"}`,
);
return;
}
setActiveExtension(extension);
@ -80,7 +83,7 @@ export default function ExtensionPopover() {
return (
<GridCard>
<div className="p-4 py-3 space-y-4">
<div className="space-y-4 p-4 py-3">
<div className="grid h-full grid-rows-headerBody">
<div className="space-y-4">
{activeExtension ? (
@ -89,7 +92,7 @@ export default function ExtensionPopover() {
{renderActiveExtension()}
<div
className="flex items-center justify-end space-x-2 opacity-0 animate-fadeIn"
className="flex animate-fadeIn items-center justify-end space-x-2 opacity-0"
style={{
animationDuration: "0.7s",
animationDelay: "0.2s",
@ -110,7 +113,7 @@ export default function ExtensionPopover() {
title="Extensions"
description="Load and manage your extensions"
/>
<Card className="opacity-0 animate-fadeIn">
<Card className="animate-fadeIn opacity-0">
<div className="w-full divide-y divide-slate-700/30 dark:divide-slate-600/30">
{AVAILABLE_EXTENSIONS.map(extension => (
<div

View File

@ -1,11 +1,6 @@
import { Button } from "@components/Button";
import { ExclamationTriangleIcon } from "@heroicons/react/24/outline";
import Card, { GridCard } from "@components/Card";
import { PlusCircleIcon } from "@heroicons/react/20/solid";
import { useMemo, forwardRef, useEffect, useCallback } from "react";
import { formatters } from "@/utils";
import { RemoteVirtualMediaState, useMountMediaStore, useRTCStore } from "@/hooks/stores";
import { SettingsPageHeader } from "@components/SettingsPageheader";
import {
LuArrowUpFromLine,
LuCheckCheck,
@ -13,11 +8,17 @@ import {
LuPlus,
LuRadioReceiver,
} from "react-icons/lu";
import { useJsonRpc } from "@/hooks/useJsonRpc";
import notifications from "../../notifications";
import { useClose } from "@headlessui/react";
import { useLocation } from "react-router-dom";
import { Button } from "@components/Button";
import Card, { GridCard } from "@components/Card";
import { formatters } from "@/utils";
import { RemoteVirtualMediaState, useMountMediaStore, useRTCStore } from "@/hooks/stores";
import { SettingsPageHeader } from "@components/SettingsPageheader";
import { useJsonRpc } from "@/hooks/useJsonRpc";
import { useDeviceUiNavigation } from "@/hooks/useAppNavigation";
import notifications from "@/notifications";
const MountPopopover = forwardRef<HTMLDivElement, object>((_props, ref) => {
const diskDataChannelStats = useRTCStore(state => state.diskDataChannelStats);

View File

@ -1,15 +1,16 @@
import { useCallback, useEffect, useRef, useState } from "react";
import { LuCornerDownLeft } from "react-icons/lu";
import { ExclamationCircleIcon } from "@heroicons/react/16/solid";
import { useClose } from "@headlessui/react";
import { Button } from "@components/Button";
import { GridCard } from "@components/Card";
import { TextAreaWithLabel } from "@components/TextArea";
import { SettingsPageHeader } from "@components/SettingsPageheader";
import { useJsonRpc } from "@/hooks/useJsonRpc";
import { useHidStore, useRTCStore, useUiStore } from "@/hooks/stores";
import notifications from "../../notifications";
import { useCallback, useEffect, useRef, useState } from "react";
import { LuCornerDownLeft } from "react-icons/lu";
import { ExclamationCircleIcon } from "@heroicons/react/16/solid";
import { useClose } from "@headlessui/react";
import { chars, keys, modifiers } from "@/keyboardMappings";
import notifications from "@/notifications";
const hidKeyboardPayload = (keys: number[], modifier: number) => {
return { keys, modifier };
@ -59,6 +60,7 @@ export default function PasteModal() {
});
}
} catch (error) {
console.error(error);
notifications.error("Failed to paste text");
}
}, [rpcDataChannel?.readyState, send, setDisableVideoFocusTrap, setPasteMode]);
@ -71,7 +73,7 @@ export default function PasteModal() {
return (
<GridCard>
<div className="p-4 py-3 space-y-4">
<div className="space-y-4 p-4 py-3">
<div className="grid h-full grid-rows-headerBody">
<div className="h-full space-y-4">
<div className="space-y-4">
@ -81,7 +83,7 @@ export default function PasteModal() {
/>
<div
className="space-y-2 opacity-0 animate-fadeIn"
className="animate-fadeIn space-y-2 opacity-0"
style={{
animationDuration: "0.7s",
animationDelay: "0.1s",
@ -120,8 +122,8 @@ export default function PasteModal() {
/>
{invalidChars.length > 0 && (
<div className="flex items-center mt-2 gap-x-2">
<ExclamationCircleIcon className="w-4 h-4 text-red-500 dark:text-red-400" />
<div className="mt-2 flex items-center gap-x-2">
<ExclamationCircleIcon className="h-4 w-4 text-red-500 dark:text-red-400" />
<span className="text-xs text-red-500 dark:text-red-400">
The following characters won&apos;t be pasted:{" "}
{invalidChars.join(", ")}
@ -135,7 +137,7 @@ export default function PasteModal() {
</div>
</div>
<div
className="flex items-center justify-end opacity-0 animate-fadeIn gap-x-2"
className="flex animate-fadeIn items-center justify-end gap-x-2 opacity-0"
style={{
animationDuration: "0.7s",
animationDelay: "0.2s",

View File

@ -1,8 +1,8 @@
import { InputFieldWithLabel } from "@components/InputField";
import { useState, useRef } from "react";
import { LuPlus } from "react-icons/lu";
import { Button } from "../../Button";
import { LuArrowLeft } from "react-icons/lu";
import { LuPlus, LuArrowLeft } from "react-icons/lu";
import { InputFieldWithLabel } from "@/components/InputField";
import { Button } from "@/components/Button";
interface AddDeviceFormProps {
onAddDevice: (name: string, macAddress: string) => void;
@ -26,7 +26,7 @@ export default function AddDeviceForm({
return (
<div className="space-y-4">
<div
className="space-y-4 opacity-0 animate-fadeIn"
className="animate-fadeIn space-y-4 opacity-0"
style={{
animationDuration: "0.5s",
animationFillMode: "forwards",
@ -73,7 +73,7 @@ export default function AddDeviceForm({
/>
</div>
<div
className="flex items-center justify-end space-x-2 opacity-0 animate-fadeIn"
className="flex animate-fadeIn items-center justify-end space-x-2 opacity-0"
style={{
animationDuration: "0.7s",
animationDelay: "0.2s",

View File

@ -1,8 +1,9 @@
import { Button } from "@components/Button";
import Card from "@components/Card";
import { FieldError } from "@components/InputField";
import { LuPlus, LuSend, LuTrash2 } from "react-icons/lu";
import { Button } from "@/components/Button";
import Card from "@/components/Card";
import { FieldError } from "@/components/InputField";
export interface StoredDevice {
name: string;
macAddress: string;
@ -27,12 +28,14 @@ export default function DeviceList({
}: DeviceListProps) {
return (
<div className="space-y-4">
<Card className="opacity-0 animate-fadeIn">
<Card className="animate-fadeIn opacity-0">
<div className="w-full divide-y divide-slate-700/30 dark:divide-slate-600/30">
{storedDevices.map((device, index) => (
<div key={index} className="flex items-center justify-between p-3 gap-x-2">
<div key={index} className="flex items-center justify-between gap-x-2 p-3">
<div className="space-y-0.5">
<p className="text-sm font-semibold leading-none text-slate-900 dark:text-slate-100">{device?.name}</p>
<p className="text-sm font-semibold leading-none text-slate-900 dark:text-slate-100">
{device?.name}
</p>
<p className="text-sm text-slate-600 dark:text-slate-400">
{device.macAddress?.toLowerCase()}
</p>
@ -60,18 +63,13 @@ export default function DeviceList({
</div>
</Card>
<div
className="flex items-center justify-end space-x-2 opacity-0 animate-fadeIn"
className="flex animate-fadeIn items-center justify-end space-x-2 opacity-0"
style={{
animationDuration: "0.7s",
animationDelay: "0.2s",
}}
>
<Button
size="SM"
theme="blank"
text="Close"
onClick={onCancelWakeOnLanModal}
/>
<Button size="SM" theme="blank" text="Close" onClick={onCancelWakeOnLanModal} />
<Button
size="SM"
theme="primary"

View File

@ -1,7 +1,8 @@
import Card from "@components/Card";
import { PlusCircleIcon } from "@heroicons/react/16/solid";
import { LuPlus } from "react-icons/lu";
import { Button } from "../../Button";
import Card from "@/components/Card";
import { Button } from "@/components/Button";
export default function EmptyStateCard({
onCancelWakeOnLanModal,
@ -11,15 +12,15 @@ export default function EmptyStateCard({
setShowAddForm: (show: boolean) => void;
}) {
return (
<div className="space-y-4 select-none">
<Card className="opacity-0 animate-fadeIn">
<div className="select-none space-y-4">
<Card className="animate-fadeIn opacity-0">
<div className="flex items-center justify-center py-8 text-center">
<div className="space-y-3">
<div className="space-y-1">
<div className="inline-block">
<Card>
<div className="p-1">
<PlusCircleIcon className="w-4 h-4 text-blue-700 shrink-0 dark:text-white" />
<PlusCircleIcon className="h-4 w-4 shrink-0 text-blue-700 dark:text-white" />
</div>
</Card>
</div>
@ -34,7 +35,7 @@ export default function EmptyStateCard({
</div>
</Card>
<div
className="flex items-center justify-end space-x-2 opacity-0 animate-fadeIn"
className="flex animate-fadeIn items-center justify-end space-x-2 opacity-0"
style={{
animationDuration: "0.7s",
animationDelay: "0.2s",

View File

@ -1,10 +1,12 @@
import { useCallback, useEffect, useState } from "react";
import { useClose } from "@headlessui/react";
import { GridCard } from "@components/Card";
import { SettingsPageHeader } from "@components/SettingsPageheader";
import { useJsonRpc } from "@/hooks/useJsonRpc";
import { useRTCStore, useUiStore } from "@/hooks/stores";
import notifications from "@/notifications";
import { useCallback, useEffect, useState } from "react";
import { useClose } from "@headlessui/react";
import EmptyStateCard from "./EmptyStateCard";
import DeviceList, { StoredDevice } from "./DeviceList";
import AddDeviceForm from "./AddDeviceForm";
@ -99,7 +101,7 @@ export default function WakeOnLanModal() {
return (
<GridCard>
<div className="p-4 py-3 space-y-4">
<div className="space-y-4 p-4 py-3">
<div className="grid h-full grid-rows-headerBody">
<div className="space-y-4">
<SettingsPageHeader

View File

@ -1,9 +1,10 @@
import SidebarHeader from "@components/SidebarHeader";
import { GridCard } from "@components/Card";
import { useRTCStore, useUiStore } from "@/hooks/stores";
import StatChart from "@components/StatChart";
import { useInterval } from "usehooks-ts";
import SidebarHeader from "@/components/SidebarHeader";
import { GridCard } from "@/components/Card";
import { useRTCStore, useUiStore } from "@/hooks/stores";
import StatChart from "@/components/StatChart";
function createChartArray<T, K extends keyof T>(
stream: Map<number, T>,
metric: K,

View File

@ -1,8 +1,9 @@
import toast, { Toast, Toaster, useToasterStore } from "react-hot-toast";
import React, { useEffect } from "react";
import { CheckCircleIcon, XCircleIcon } from "@heroicons/react/20/solid";
import Card from "@/components/Card";
import { CheckCircleIcon, XCircleIcon } from "@heroicons/react/20/solid";
interface NotificationOptions {
duration?: number;

View File

@ -2,19 +2,18 @@ import { useLoaderData, useNavigate } from "react-router-dom";
import { ShieldCheckIcon } from "@heroicons/react/24/outline";
import { useCallback, useEffect, useState } from "react";
import api from "@/api";
import { SettingsPageHeader } from "@components/SettingsPageheader";
import { useDeviceUiNavigation } from "../hooks/useAppNavigation";
import { GridCard } from "../components/Card";
import notifications from "../notifications";
import api from "../api";
import { DEVICE_API } from "../ui.config";
import { Button, LinkButton } from "../components/Button";
import { useJsonRpc } from "../hooks/useJsonRpc";
import { InputFieldWithLabel } from "../components/InputField";
import { SelectMenuBasic } from "../components/SelectMenuBasic";
import { SettingsSectionHeader } from "../components/SettingsSectionHeader";
import { isOnDevice } from "../main";
import { GridCard } from "@/components/Card";
import { Button, LinkButton } from "@/components/Button";
import { InputFieldWithLabel } from "@/components/InputField";
import { SelectMenuBasic } from "@/components/SelectMenuBasic";
import { SettingsSectionHeader } from "@/components/SettingsSectionHeader";
import { useDeviceUiNavigation } from "@/hooks/useAppNavigation";
import notifications from "@/notifications";
import { DEVICE_API } from "@/ui.config";
import { useJsonRpc } from "@/hooks/useJsonRpc";
import { isOnDevice } from "@/main";
import { LocalDevice } from "./devices.$id";
import { SettingsItem } from "./devices.$id.settings";

View File

@ -51,8 +51,8 @@ export const formatters = {
];
let duration = (date.valueOf() - new Date().valueOf()) / 1000;
for (let i = 0; i < DIVISIONS.length; i++) {
const division = DIVISIONS[i];
for (const division of DIVISIONS) {
if (Math.abs(duration) < division.amount) {
return relativeTimeFormat.format(Math.round(duration), division.name);
}
@ -61,7 +61,7 @@ export const formatters = {
},
price: (price: number | bigint | string, options?: Intl.NumberFormatOptions) => {
let opts: Intl.NumberFormatOptions = {
const opts: Intl.NumberFormatOptions = {
style: "currency",
currency: "USD",
...(options || {}),