mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-04-23 17:18:32 +02:00
Align lint fixes with main and resolve merge conflicts
- Convert biome-ignore to oxlint-disable-next-line across client app - Fix no-base-to-string with type narrowing instead of suppressions - Fix no-floating-promises with fireAndForget() in proxy app - Fix restrict-template-expressions with String() wrapping - Resolve leftover merge conflict markers in manager.rs - Remove duplicate cmd_plugin_init_errors from lib.rs - Add graphql as explicit dependency in yaak-client Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import type { DnsOverride, Workspace } from "@yaakapp-internal/models";
|
||||
import { patchModel } from "@yaakapp-internal/models";
|
||||
import { fireAndForget } from "../lib/fireAndForget";
|
||||
import {
|
||||
HStack,
|
||||
Table,
|
||||
@@ -37,7 +38,7 @@ export function DnsOverridesEditor({ workspace }: Props) {
|
||||
|
||||
const handleChange = useCallback(
|
||||
(overrides: DnsOverride[]) => {
|
||||
patchModel(workspace, { settingDnsOverrides: overrides });
|
||||
fireAndForget(patchModel(workspace, { settingDnsOverrides: overrides }));
|
||||
},
|
||||
[workspace],
|
||||
);
|
||||
|
||||
@@ -511,16 +511,14 @@ function HttpRequestArg({
|
||||
help={arg.description}
|
||||
value={value}
|
||||
disabled={arg.disabled}
|
||||
options={[
|
||||
...httpRequests.map((r) => {
|
||||
options={httpRequests.map((r) => {
|
||||
return {
|
||||
label:
|
||||
buildRequestBreadcrumbs(r, folders).join(" / ") +
|
||||
(r.id === activeHttpRequest?.id ? " (current)" : ""),
|
||||
value: r.id,
|
||||
};
|
||||
}),
|
||||
]}
|
||||
})}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ import {
|
||||
import { useHotKey } from "../hooks/useHotKey";
|
||||
import { atomWithKVStorage } from "../lib/atoms/atomWithKVStorage";
|
||||
import { deleteModelWithConfirm } from "../lib/deleteModelWithConfirm";
|
||||
import { fireAndForget } from "../lib/fireAndForget";
|
||||
import { jotaiStore } from "../lib/jotai";
|
||||
import { isBaseEnvironment, isSubEnvironment } from "../lib/model_util";
|
||||
import { resolvedModelName } from "../lib/resolvedModelName";
|
||||
@@ -116,7 +117,7 @@ function EnvironmentEditDialogSidebar({
|
||||
const treeRef = useRef<TreeHandle>(null);
|
||||
const { baseEnvironment, baseEnvironments } = useEnvironmentsBreakdown();
|
||||
|
||||
// biome-ignore lint/correctness/useExhaustiveDependencies: none
|
||||
// oxlint-disable-next-line react-hooks/exhaustive-deps -- none
|
||||
useLayoutEffect(() => {
|
||||
if (selectedEnvironmentId == null) return;
|
||||
treeRef.current?.selectItem(selectedEnvironmentId);
|
||||
@@ -173,7 +174,9 @@ function EnvironmentEditDialogSidebar({
|
||||
"sidebar.selected.delete",
|
||||
useCallback(() => {
|
||||
const items = getSelectedTreeModels();
|
||||
if (items) handleDeleteSelected(items);
|
||||
if (items) {
|
||||
fireAndForget(handleDeleteSelected(items));
|
||||
}
|
||||
}, [getSelectedTreeModels, handleDeleteSelected]),
|
||||
{ enable: treeHasFocus, priority: 100 },
|
||||
);
|
||||
|
||||
@@ -55,7 +55,7 @@ function ExportDataDialogContent({
|
||||
|
||||
const handleToggleAll = () => {
|
||||
setSelectedWorkspaces(
|
||||
// biome-ignore lint/performance/noAccumulatingSpread: none
|
||||
// oxlint-disable-next-line no-accumulating-spread
|
||||
allSelected ? {} : workspaces.reduce((acc, w) => ({ ...acc, [w.id]: true }), {}),
|
||||
);
|
||||
};
|
||||
|
||||
@@ -42,7 +42,7 @@ export function FolderLayout({ folder, style }: Props) {
|
||||
}, [folder.id, folders, requests]);
|
||||
|
||||
const handleSendAll = useCallback(() => {
|
||||
sendAllAction?.call(folder);
|
||||
void sendAllAction?.call(folder);
|
||||
}, [sendAllAction, folder]);
|
||||
|
||||
return (
|
||||
|
||||
@@ -27,7 +27,7 @@ function GrpcProtoSelectionDialogWithRequest({ request }: Props & { request: Grp
|
||||
const services = grpc.reflect.data;
|
||||
const serverReflection = protoFiles.length === 0 && services != null;
|
||||
let reflectError = grpc.reflect.error ?? null;
|
||||
const reflectionUnimplemented = `${reflectError}`.match(/unimplemented/i);
|
||||
const reflectionUnimplemented = String(reflectError).match(/unimplemented/i);
|
||||
|
||||
if (reflectionUnimplemented) {
|
||||
reflectError = null;
|
||||
@@ -100,7 +100,7 @@ function GrpcProtoSelectionDialogWithRequest({ request }: Props & { request: Grp
|
||||
Found services{" "}
|
||||
{services?.slice(0, 5).map((s, i) => {
|
||||
return (
|
||||
<span key={s.name + s.methods.join(",")}>
|
||||
<span key={s.name + s.methods.map((m) => m.name).join(",")}>
|
||||
<InlineCode>{s.name}</InlineCode>
|
||||
{i === services.length - 1 ? "" : i === services.length - 2 ? " and " : ", "}
|
||||
</span>
|
||||
@@ -116,7 +116,7 @@ function GrpcProtoSelectionDialogWithRequest({ request }: Props & { request: Grp
|
||||
Server reflection found services
|
||||
{services?.map((s, i) => {
|
||||
return (
|
||||
<span key={s.name + s.methods.join(",")}>
|
||||
<span key={s.name + s.methods.map((m) => m.name).join(",")}>
|
||||
<InlineCode>{s.name}</InlineCode>
|
||||
{i === services.length - 1 ? "" : i === services.length - 2 ? " and " : ", "}
|
||||
</span>
|
||||
@@ -140,8 +140,8 @@ function GrpcProtoSelectionDialogWithRequest({ request }: Props & { request: Grp
|
||||
<tbody className="divide-y divide-surface-highlight">
|
||||
{protoFiles.map((f, i) => {
|
||||
const parts = f.split("/");
|
||||
// oxlint-disable-next-line no-array-index-key -- none
|
||||
return (
|
||||
// biome-ignore lint/suspicious/noArrayIndexKey: none
|
||||
<tr key={f + i} className="group">
|
||||
<td>
|
||||
<Icon icon={f.endsWith(".proto") ? "file_code" : "folder_code"} />
|
||||
|
||||
@@ -48,7 +48,7 @@ export function GrpcResponsePane({ style, methodType, activeRequest }: Props) {
|
||||
);
|
||||
|
||||
// Set the active message to the first message received if unary
|
||||
// biome-ignore lint/correctness/useExhaustiveDependencies: none
|
||||
// oxlint-disable-next-line react-hooks/exhaustive-deps
|
||||
useEffect(() => {
|
||||
if (events.length === 0 || activeEvent != null || methodType !== "unary") {
|
||||
return;
|
||||
|
||||
@@ -13,9 +13,9 @@ export function ImportCurlButton() {
|
||||
const importCurl = useImportCurl();
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
|
||||
// biome-ignore lint/correctness/useExhaustiveDependencies: none
|
||||
// oxlint-disable-next-line react-hooks/exhaustive-deps -- none
|
||||
useEffect(() => {
|
||||
readText().then(setClipboardText);
|
||||
void readText().then(setClipboardText);
|
||||
}, [focused]);
|
||||
|
||||
if (!clipboardText?.trim().startsWith("curl ")) {
|
||||
|
||||
@@ -4,6 +4,7 @@ import { patchModel } from "@yaakapp-internal/models";
|
||||
import { Banner, Icon } from "@yaakapp-internal/ui";
|
||||
import { useCallback, useMemo } from "react";
|
||||
import { useKeyValue } from "../hooks/useKeyValue";
|
||||
import { fireAndForget } from "../lib/fireAndForget";
|
||||
import { textLikelyContainsJsonComments } from "../lib/jsonComments";
|
||||
import type { DropdownItem } from "./core/Dropdown";
|
||||
import { Dropdown } from "./core/Dropdown";
|
||||
@@ -57,12 +58,12 @@ export function JsonBodyEditor({ forceUpdateKey, heightMode, request }: Props) {
|
||||
} else {
|
||||
delete newBody.sendJsonComments;
|
||||
}
|
||||
patchModel(request, { body: newBody });
|
||||
fireAndForget(patchModel(request, { body: newBody }));
|
||||
}, [request, autoFix]);
|
||||
|
||||
const handleDropdownOpen = useCallback(() => {
|
||||
if (!bannerDismissed) {
|
||||
setBannerDismissed(true);
|
||||
fireAndForget(setBannerDismissed(true));
|
||||
}
|
||||
}, [bannerDismissed, setBannerDismissed]);
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import { DetailsBanner } from "./core/DetailsBanner";
|
||||
export default function RouteError({ error }: { error: unknown }) {
|
||||
console.log("Error", error);
|
||||
const stringified = JSON.stringify(error);
|
||||
// biome-ignore lint/suspicious/noExplicitAny: none
|
||||
// oxlint-disable-next-line no-explicit-any -- none
|
||||
const message = (error as any).message ?? stringified;
|
||||
const stack =
|
||||
typeof error === "object" && error != null && "stack" in error ? String(error.stack) : null;
|
||||
|
||||
@@ -236,7 +236,7 @@ export function SettingsCertificates() {
|
||||
<VStack space={3}>
|
||||
{certificates.map((cert, index) => (
|
||||
<CertificateEditor
|
||||
// biome-ignore lint/suspicious/noArrayIndexKey: Index is fine here
|
||||
// oxlint-disable-next-line react/no-array-index-key
|
||||
key={index}
|
||||
certificate={cert}
|
||||
index={index}
|
||||
|
||||
@@ -317,7 +317,7 @@ function Sidebar({ className }: { className?: string }) {
|
||||
"sidebar.selected.delete",
|
||||
useCallback(() => {
|
||||
const items = getSelectedTreeModels();
|
||||
if (items) handleDeleteSelected(items);
|
||||
if (items) void handleDeleteSelected(items);
|
||||
}, [getSelectedTreeModels, handleDeleteSelected]),
|
||||
{ enable: treeHasFocus },
|
||||
);
|
||||
|
||||
@@ -138,7 +138,7 @@ function InitializedTemplateFunctionDialog({
|
||||
});
|
||||
|
||||
const tooLarge = rendered.data ? rendered.data.length > 10000 : false;
|
||||
// biome-ignore lint/correctness/useExhaustiveDependencies: Only update this on rendered data change to keep secrets hidden on input change
|
||||
// oxlint-disable-next-line react-hooks/exhaustive-deps -- Only update this on rendered data change to keep secrets hidden on input change
|
||||
const dataContainsSecrets = useMemo(() => {
|
||||
for (const [name, value] of Object.entries(argValues)) {
|
||||
const arg = templateFunction.data?.args.find((a) => "name" in a && a.name === name);
|
||||
|
||||
@@ -126,7 +126,7 @@ export function WorkspaceEncryptionSetting({ size, expanded, onDone, onEnabledEn
|
||||
await enableEncryption(workspaceMeta.workspaceId);
|
||||
setJustEnabledEncryption(true);
|
||||
} catch (err) {
|
||||
setError(`Failed to enable encryption: ${err}`);
|
||||
setError(`Failed to enable encryption: ${String(err)}`);
|
||||
}
|
||||
}}
|
||||
>
|
||||
@@ -284,7 +284,7 @@ function HighlightedKey({ keyText, show }: { keyText: string; show: boolean }) {
|
||||
keyText.split("").map((c, i) => {
|
||||
return (
|
||||
<span
|
||||
// biome-ignore lint/suspicious/noArrayIndexKey: it's fine
|
||||
// oxlint-disable-next-line no-array-index-key -- it's fine
|
||||
key={i}
|
||||
className={classNames(
|
||||
c.match(/[0-9]/) && "text-info",
|
||||
|
||||
@@ -22,7 +22,7 @@ export function DetailsBanner({
|
||||
storageKey,
|
||||
...extraProps
|
||||
}: Props) {
|
||||
// biome-ignore lint/correctness/useExhaustiveDependencies: We only want to recompute the atom when storageKey changes
|
||||
// oxlint-disable-next-line react-hooks/exhaustive-deps -- We only want to recompute the atom when storageKey changes
|
||||
const openAtom = useMemo(
|
||||
() =>
|
||||
storageKey
|
||||
|
||||
@@ -32,6 +32,7 @@ import { useStateWithDeps } from "../../hooks/useStateWithDeps";
|
||||
import { generateId } from "../../lib/generateId";
|
||||
import { getNodeText } from "../../lib/getNodeText";
|
||||
import { jotaiStore } from "../../lib/jotai";
|
||||
import { fireAndForget } from "../../lib/fireAndForget";
|
||||
import { ErrorBoundary } from "../ErrorBoundary";
|
||||
import { Button } from "./Button";
|
||||
import { Hotkey } from "./Hotkey";
|
||||
@@ -611,7 +612,7 @@ const Menu = forwardRef<Omit<DropdownRef, "open" | "isOpen" | "toggle" | "items"
|
||||
setActiveSubmenu({ item, parent, viaKeyboard: true });
|
||||
}
|
||||
} else if (item.onSelect) {
|
||||
handleSelect(item);
|
||||
fireAndForget(handleSelect(item));
|
||||
}
|
||||
},
|
||||
{},
|
||||
@@ -749,7 +750,7 @@ const Menu = forwardRef<Omit<DropdownRef, "open" | "isOpen" | "toggle" | "items"
|
||||
if (item.type === "separator") {
|
||||
return (
|
||||
<Separator
|
||||
// biome-ignore lint/suspicious/noArrayIndexKey: Nothing else available
|
||||
// oxlint-disable-next-line no-array-index-key -- Nothing else available
|
||||
key={i}
|
||||
className={classNames("my-1.5", item.label ? "ml-2" : null)}
|
||||
>
|
||||
@@ -759,8 +760,7 @@ const Menu = forwardRef<Omit<DropdownRef, "open" | "isOpen" | "toggle" | "items"
|
||||
}
|
||||
if (item.type === "content") {
|
||||
return (
|
||||
// biome-ignore lint/a11y/noStaticElementInteractions: Needs to be clickable but want to support nested buttons
|
||||
// biome-ignore lint/suspicious/noArrayIndexKey: index is fine
|
||||
// oxlint-disable-next-line no-array-index-key -- index is fine
|
||||
<div key={i} className={classNames("my-1 mx-2 max-w-xs")} onClick={onClose}>
|
||||
{item.label}
|
||||
</div>
|
||||
@@ -774,7 +774,7 @@ const Menu = forwardRef<Omit<DropdownRef, "open" | "isOpen" | "toggle" | "items"
|
||||
onFocus={handleFocus}
|
||||
onSelect={handleSelect}
|
||||
onHover={handleItemHover}
|
||||
// biome-ignore lint/suspicious/noArrayIndexKey: It's fine
|
||||
// oxlint-disable-next-line no-array-index-key -- It's fine
|
||||
key={i}
|
||||
item={item}
|
||||
/>
|
||||
@@ -782,7 +782,6 @@ const Menu = forwardRef<Omit<DropdownRef, "open" | "isOpen" | "toggle" | "items"
|
||||
})}
|
||||
</VStack>
|
||||
{activeSubmenu && (
|
||||
// biome-ignore lint/a11y/noStaticElementInteractions: Container div that cancels hover timeout
|
||||
<div
|
||||
ref={submenuRef}
|
||||
onMouseEnter={() => {
|
||||
|
||||
@@ -327,7 +327,7 @@ function EditorInner({
|
||||
);
|
||||
|
||||
// Update the language extension when the language changes
|
||||
// biome-ignore lint/correctness/useExhaustiveDependencies: intentionally limited deps
|
||||
// oxlint-disable-next-line react-hooks/exhaustive-deps -- intentionally limited deps
|
||||
useEffect(() => {
|
||||
if (cm.current === null) return;
|
||||
const { view, languageCompartment } = cm.current;
|
||||
@@ -361,7 +361,7 @@ function EditorInner({
|
||||
]);
|
||||
|
||||
// Initialize the editor when ref mounts
|
||||
// biome-ignore lint/correctness/useExhaustiveDependencies: only reinitialize when necessary
|
||||
// oxlint-disable-next-line react-hooks/exhaustive-deps -- only reinitialize when necessary
|
||||
const initEditorRef = useCallback(
|
||||
function initEditorRef(container: HTMLDivElement | null) {
|
||||
if (container === null) {
|
||||
|
||||
@@ -35,7 +35,7 @@ export function HotkeyRaw({ labelParts, className, variant }: HotkeyRawProps) {
|
||||
)}
|
||||
>
|
||||
{labelParts.map((char, index) => (
|
||||
// biome-ignore lint/suspicious/noArrayIndexKey: none
|
||||
// oxlint-disable-next-line react/no-array-index-key
|
||||
<div key={index} className="min-w-[1em] text-center">
|
||||
{char}
|
||||
</div>
|
||||
|
||||
@@ -142,7 +142,7 @@ function BaseInput({
|
||||
isFocused: () => editorRef.current?.hasFocus ?? false,
|
||||
value: () => editorRef.current?.state.doc.toString() ?? "",
|
||||
dispatch: (...args) => {
|
||||
// biome-ignore lint/suspicious/noExplicitAny: none
|
||||
// oxlint-disable-next-line no-explicit-any
|
||||
editorRef.current?.dispatch(...(args as any));
|
||||
},
|
||||
selectAll() {
|
||||
@@ -327,7 +327,11 @@ function BaseInput({
|
||||
</HStack>
|
||||
{type === "password" && !disableObscureToggle && (
|
||||
<IconButton
|
||||
title={obscured ? `Show ${label}` : `Obscure ${label}`}
|
||||
title={
|
||||
obscured
|
||||
? `Show ${typeof label === "string" ? label : "field"}`
|
||||
: `Obscure ${typeof label === "string" ? label : "field"}`
|
||||
}
|
||||
size="xs"
|
||||
className={classNames("mr-0.5 !h-auto my-0.5", disabled && "opacity-disabled")}
|
||||
color={tint}
|
||||
|
||||
@@ -5,7 +5,7 @@ import { Icon } from "@yaakapp-internal/ui";
|
||||
|
||||
interface Props {
|
||||
depth?: number;
|
||||
// biome-ignore lint/suspicious/noExplicitAny: none
|
||||
// oxlint-disable-next-line no-explicit-any -- none
|
||||
attrValue: any;
|
||||
attrKey?: string | number;
|
||||
attrKeyJsonPath?: string;
|
||||
@@ -54,10 +54,10 @@ export const JsonAttributeTree = ({
|
||||
if (jsonType === "[object Array]") {
|
||||
return {
|
||||
children: isExpanded
|
||||
? // biome-ignore lint/suspicious/noExplicitAny: none
|
||||
? // oxlint-disable-next-line no-explicit-any -- none
|
||||
attrValue.flatMap((v: any, i: number) => (
|
||||
<JsonAttributeTree
|
||||
// biome-ignore lint/suspicious/noArrayIndexKey: none
|
||||
// oxlint-disable-next-line no-array-index-key -- none
|
||||
key={i}
|
||||
depth={depth + 1}
|
||||
attrValue={v}
|
||||
|
||||
@@ -144,7 +144,7 @@ export function PairEditor({
|
||||
[handle, pairs, setRef],
|
||||
);
|
||||
|
||||
// biome-ignore lint/correctness/useExhaustiveDependencies: Only care about forceUpdateKey
|
||||
// oxlint-disable-next-line react-hooks/exhaustive-deps -- Only care about forceUpdateKey
|
||||
useEffect(() => {
|
||||
// Remove empty headers on initial render and ensure they all have valid ids (pairs didn't use to have IDs)
|
||||
const newPairs: PairWithId[] = [];
|
||||
|
||||
@@ -195,7 +195,7 @@ export const PlainInput = forwardRef<{ focus: () => void }, PlainInputProps>(fun
|
||||
key={forceUpdateKey}
|
||||
type={type === "password" && !obscured ? "text" : type}
|
||||
name={name}
|
||||
// biome-ignore lint/a11y/noAutofocus: Who cares
|
||||
// oxlint-disable-next-line jsx-a11y/no-autofocus
|
||||
autoFocus={autoFocus}
|
||||
defaultValue={defaultValue ?? undefined}
|
||||
autoComplete="off"
|
||||
@@ -213,7 +213,11 @@ export const PlainInput = forwardRef<{ focus: () => void }, PlainInputProps>(fun
|
||||
</HStack>
|
||||
{type === "password" && !hideObscureToggle && (
|
||||
<IconButton
|
||||
title={obscured ? `Show ${label}` : `Obscure ${label}`}
|
||||
title={
|
||||
obscured
|
||||
? `Show ${typeof label === "string" ? label : "field"}`
|
||||
: `Obscure ${typeof label === "string" ? label : "field"}`
|
||||
}
|
||||
size="xs"
|
||||
className="mr-0.5 group/obscure !h-auto my-0.5"
|
||||
iconClassName="group-hover/obscure:text"
|
||||
|
||||
@@ -62,13 +62,13 @@ export function SegmentedControl<T extends string>({
|
||||
if (e.key === "ArrowRight") {
|
||||
e.preventDefault();
|
||||
const newIndex = Math.abs((selectedIndex + 1) % options.length);
|
||||
options[newIndex] && setSelectedValue(options[newIndex].value);
|
||||
if (options[newIndex]) { setSelectedValue(options[newIndex].value); }
|
||||
const child = containerRef.current?.children[newIndex] as HTMLButtonElement;
|
||||
child.focus();
|
||||
} else if (e.key === "ArrowLeft") {
|
||||
e.preventDefault();
|
||||
const newIndex = Math.abs((selectedIndex - 1) % options.length);
|
||||
options[newIndex] && setSelectedValue(options[newIndex].value);
|
||||
if (options[newIndex]) { setSelectedValue(options[newIndex].value); }
|
||||
const child = containerRef.current?.children[newIndex] as HTMLButtonElement;
|
||||
child.focus();
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import {
|
||||
} from "react";
|
||||
import { useKeyValue } from "../../../hooks/useKeyValue";
|
||||
import { computeSideForDragMove, DropMarker } from "@yaakapp-internal/ui";
|
||||
import { fireAndForget } from "../../../lib/fireAndForget";
|
||||
import { ErrorBoundary } from "../../ErrorBoundary";
|
||||
import type { ButtonProps } from "../Button";
|
||||
import { Button } from "../Button";
|
||||
@@ -142,7 +143,7 @@ export const Tabs = forwardRef<TabsRef, Props>(function Tabs(
|
||||
forwardedRef,
|
||||
() => ({
|
||||
setActiveTab: (value: string) => {
|
||||
onChangeValue(value);
|
||||
fireAndForget(onChangeValue(value));
|
||||
},
|
||||
}),
|
||||
[onChangeValue],
|
||||
|
||||
@@ -110,7 +110,7 @@ export function Tooltip({ children, className, content, tabIndex, size = "md" }:
|
||||
/>
|
||||
</div>
|
||||
</Portal>
|
||||
{/** biome-ignore lint/a11y/useSemanticElements: Needs to be usable in other buttons */}
|
||||
{/* oxlint-disable-next-line jsx-a11y/prefer-tag-over-role -- Needs to be usable in other buttons */}
|
||||
<span
|
||||
ref={triggerRef}
|
||||
role="button"
|
||||
|
||||
@@ -10,6 +10,7 @@ import { useKeyValue } from "../../hooks/useKeyValue";
|
||||
import { useRandomKey } from "../../hooks/useRandomKey";
|
||||
import { sync } from "../../init/sync";
|
||||
import { showConfirm, showConfirmDelete } from "../../lib/confirm";
|
||||
import { fireAndForget } from "../../lib/fireAndForget";
|
||||
import { showDialog } from "../../lib/dialog";
|
||||
import { showPrompt } from "../../lib/prompt";
|
||||
import { showErrorToast, showToast } from "../../lib/toast";
|
||||
@@ -244,7 +245,7 @@ function SyncDropdownWithSyncDir({ syncDir }: { syncDir: string }) {
|
||||
message: "Changes have been reset",
|
||||
color: "success",
|
||||
});
|
||||
sync({ force: true });
|
||||
fireAndForget(sync({ force: true }));
|
||||
},
|
||||
onError(err) {
|
||||
showErrorToast({
|
||||
@@ -291,7 +292,7 @@ function SyncDropdownWithSyncDir({ syncDir }: { syncDir: string }) {
|
||||
</>
|
||||
),
|
||||
});
|
||||
sync({ force: true });
|
||||
fireAndForget(sync({ force: true }));
|
||||
},
|
||||
onError(err) {
|
||||
showErrorToast({
|
||||
|
||||
@@ -27,7 +27,7 @@ export function HistoryDialog({ log }: Props) {
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
{log.map((l) => (
|
||||
<TableRow key={l.author + (l.message ?? "n/a") + l.when}>
|
||||
<TableRow key={(l.author.name ?? "") + (l.message ?? "n/a") + l.when}>
|
||||
<TruncatedWideTableCell>
|
||||
{l.message || <em className="text-text-subtle">No message</em>}
|
||||
</TruncatedWideTableCell>
|
||||
|
||||
@@ -43,7 +43,7 @@ interface Props {
|
||||
|
||||
type ExplorerItem =
|
||||
| { kind: "type"; type: GraphQLType; from: ExplorerItem }
|
||||
// biome-ignore lint/suspicious/noExplicitAny: none
|
||||
// oxlint-disable-next-line no-explicit-any -- none
|
||||
| { kind: "field"; type: GraphQLField<any, any>; from: ExplorerItem }
|
||||
| { kind: "input_field"; type: GraphQLInputField; from: ExplorerItem }
|
||||
| null;
|
||||
@@ -144,7 +144,7 @@ export const GraphQLDocsExplorer = memo(function GraphQLDocsExplorer({
|
||||
</div>
|
||||
) : (
|
||||
<div
|
||||
key={activeItem.type.toString()} // Reset scroll position to top
|
||||
key={"name" in activeItem.type ? activeItem.type.name : String(activeItem.type)} // Reset scroll position to top
|
||||
className="overflow-y-auto h-full w-full p-3 grid grid-cols-[minmax(0,1fr)]"
|
||||
>
|
||||
<GqlTypeInfo item={activeItem} setItem={setActiveItem} schema={schema} />
|
||||
@@ -180,14 +180,14 @@ function GraphQLExplorerHeader({
|
||||
<Icon icon="book_open_text" />
|
||||
{crumbs.map((crumb, i) => {
|
||||
return (
|
||||
// biome-ignore lint/suspicious/noArrayIndexKey: none
|
||||
// oxlint-disable-next-line no-array-index-key -- none
|
||||
<Fragment key={i}>
|
||||
{i > 0 && <Icon icon="chevron_right" className="text-text-subtlest" />}
|
||||
{crumb === item || item == null ? (
|
||||
<GqlTypeLabel noTruncate item={item} />
|
||||
) : crumb === item ? null : (
|
||||
<GqlTypeLink
|
||||
// biome-ignore lint/suspicious/noArrayIndexKey: none
|
||||
// oxlint-disable-next-line no-array-index-key -- none
|
||||
key={i}
|
||||
noTruncate
|
||||
item={crumb}
|
||||
@@ -200,7 +200,7 @@ function GraphQLExplorerHeader({
|
||||
})}
|
||||
</div>
|
||||
<GqlSchemaSearch
|
||||
key={item?.type.toString()} // Force reset when changing items
|
||||
key={item != null && "name" in item.type ? item.type.name : "search"} // Force reset when changing items
|
||||
maxHeight={containerHeight}
|
||||
currentItem={item}
|
||||
schema={schema}
|
||||
@@ -268,7 +268,7 @@ function GqlTypeInfo({
|
||||
{Object.entries(fields).map(([fieldName, field]) => {
|
||||
const fieldItem: ExplorerItem = toExplorerItem(field, item);
|
||||
return (
|
||||
<div key={`${field.type}::${field.name}`} className="my-4">
|
||||
<div key={`${String(field.type)}::${field.name}`} className="my-4">
|
||||
<GqlTypeRow
|
||||
item={fieldItem}
|
||||
setItem={setItem}
|
||||
@@ -361,7 +361,7 @@ function GqlTypeInfo({
|
||||
<Subheading>Arguments</Subheading>
|
||||
{item.type.args.map((a) => {
|
||||
return (
|
||||
<div key={`${a.type}::${a.name}`} className="my-4">
|
||||
<div key={`${String(a.type)}::${a.name}`} className="my-4">
|
||||
<GqlTypeRow
|
||||
name={{ value: a.name, color: "info" }}
|
||||
item={{ kind: "type", type: a.type, from: item }}
|
||||
@@ -391,7 +391,7 @@ function GqlTypeInfo({
|
||||
from: item,
|
||||
};
|
||||
return (
|
||||
<div key={`${field.type}::${field.name}`} className="my-4">
|
||||
<div key={`${String(field.type)}::${field.name}`} className="my-4">
|
||||
<GqlTypeRow
|
||||
item={fieldItem}
|
||||
setItem={setItem}
|
||||
@@ -429,7 +429,7 @@ function GqlTypeInfo({
|
||||
if (field == null) return null;
|
||||
const fieldItem: ExplorerItem = { kind: "field", type: field, from: item };
|
||||
return (
|
||||
<div key={`${field.type}::${field.name}`} className="my-4">
|
||||
<div key={`${String(field.type)}::${field.name}`} className="my-4">
|
||||
<GqlTypeRow
|
||||
item={fieldItem}
|
||||
setItem={setItem}
|
||||
@@ -510,7 +510,7 @@ function GqlTypeRow({
|
||||
<span className="text-text-subtle">(</span>
|
||||
{item.type.args.map((arg) => (
|
||||
<div
|
||||
key={`${arg.type}::${arg.name}`}
|
||||
key={`${String(arg.type)}::${arg.name}`}
|
||||
className={classNames(item.type.args.length === 1 && "inline-flex")}
|
||||
>
|
||||
{item.type.args.length > 1 && <> </>}
|
||||
@@ -672,7 +672,7 @@ function Subheading({ children, count }: { children: ReactNode; count?: number }
|
||||
|
||||
interface SearchResult {
|
||||
name: string;
|
||||
// biome-ignore lint/suspicious/noExplicitAny: none
|
||||
// oxlint-disable-next-line no-explicit-any -- none
|
||||
type: GraphQLNamedType | GraphQLField<any, any> | GraphQLInputField;
|
||||
score: number;
|
||||
from: GraphQLNamedType | null;
|
||||
@@ -796,7 +796,11 @@ function GqlSchemaSearch({
|
||||
label="search"
|
||||
hideLabel
|
||||
defaultValue={value}
|
||||
placeholder={focused ? `Search ${currentItem?.type.toString() ?? "Schema"}` : "Search"}
|
||||
placeholder={
|
||||
focused
|
||||
? `Search ${currentItem != null && "name" in currentItem.type ? currentItem.type.name : "Schema"}`
|
||||
: "Search"
|
||||
}
|
||||
leftSlot={
|
||||
<div className="w-10 flex justify-center items-center">
|
||||
<Icon size="sm" icon="search" color="secondary" />
|
||||
@@ -895,10 +899,10 @@ function DocMarkdown({ children, className }: { children: string | null; classNa
|
||||
|
||||
function walkTypeGraph(
|
||||
schema: GraphQLSchema,
|
||||
// biome-ignore lint/suspicious/noExplicitAny: none
|
||||
// oxlint-disable-next-line no-explicit-any -- none
|
||||
start: GraphQLType | GraphQLField<any, any> | GraphQLInputField | null,
|
||||
cb: (
|
||||
// biome-ignore lint/suspicious/noExplicitAny: none
|
||||
// oxlint-disable-next-line no-explicit-any -- none
|
||||
type: GraphQLNamedType | GraphQLField<any, any> | GraphQLInputField,
|
||||
from: GraphQLNamedType | null,
|
||||
path: string[],
|
||||
@@ -906,7 +910,7 @@ function walkTypeGraph(
|
||||
) {
|
||||
const visited = new Set<string>();
|
||||
const queue: Array<{
|
||||
// biome-ignore lint/suspicious/noExplicitAny: none
|
||||
// oxlint-disable-next-line no-explicit-any -- none
|
||||
current: GraphQLType | GraphQLField<any, any> | GraphQLInputField;
|
||||
from: GraphQLNamedType | null;
|
||||
path: string[];
|
||||
@@ -926,7 +930,7 @@ function walkTypeGraph(
|
||||
}
|
||||
|
||||
while (queue.length > 0) {
|
||||
// biome-ignore lint/style/noNonNullAssertion: none
|
||||
// oxlint-disable-next-line no-non-null-assertion -- none
|
||||
const { current, from, path } = queue.shift()!;
|
||||
if (!isNamedType(current)) continue;
|
||||
|
||||
@@ -979,7 +983,7 @@ function walkTypeGraph(
|
||||
}
|
||||
}
|
||||
|
||||
// biome-ignore lint/suspicious/noExplicitAny: none
|
||||
// oxlint-disable-next-line no-explicit-any -- none
|
||||
function toExplorerItem(t: any, from: ExplorerItem | null): ExplorerItem | null {
|
||||
if (t == null) return null;
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ export function CsvViewerInner({ text, className }: { text: string | null; class
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
{parsed.data.map((row, i) => (
|
||||
// biome-ignore lint/suspicious/noArrayIndexKey: none
|
||||
// oxlint-disable-next-line react/no-array-index-key
|
||||
<TableRow key={i}>
|
||||
{parsed.meta.fields?.map((key) => (
|
||||
<TableCell key={key}>{row[key] ?? ""}</TableCell>
|
||||
|
||||
@@ -73,7 +73,7 @@ export function MultipartViewer({ data, boundary, idPrefix = "multipart" }: Prop
|
||||
>
|
||||
{parts.map((part, i) => (
|
||||
<TabContent
|
||||
// biome-ignore lint/suspicious/noArrayIndexKey: Nothing else to key on
|
||||
// oxlint-disable-next-line react/no-array-index-key -- Nothing else to key on
|
||||
key={idPrefix + part.name + i}
|
||||
value={tabValue(part, i)}
|
||||
className="pl-3 !pt-0"
|
||||
|
||||
@@ -6,13 +6,14 @@ import type { PDFDocumentProxy } from "pdfjs-dist";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { Document, Page } from "react-pdf";
|
||||
import { useContainerSize } from "@yaakapp-internal/ui";
|
||||
import { fireAndForget } from "../../lib/fireAndForget";
|
||||
|
||||
import("react-pdf").then(({ pdfjs }) => {
|
||||
fireAndForget(import("react-pdf").then(({ pdfjs }) => {
|
||||
pdfjs.GlobalWorkerOptions.workerSrc = new URL(
|
||||
"pdfjs-dist/build/pdf.worker.min.mjs",
|
||||
import.meta.url,
|
||||
).toString();
|
||||
});
|
||||
}));
|
||||
|
||||
interface Props {
|
||||
bodyPath?: string;
|
||||
@@ -56,7 +57,7 @@ export function PdfViewer({ bodyPath, data }: Props) {
|
||||
externalLinkTarget="_blank"
|
||||
externalLinkRel="noopener noreferrer"
|
||||
>
|
||||
{Array.from(new Array(numPages), (_, index) => (
|
||||
{Array.from({ length: numPages ?? 0 }, (_, index) => (
|
||||
<Page
|
||||
className="mb-6 select-all"
|
||||
renderTextLayer
|
||||
|
||||
Reference in New Issue
Block a user