Upgrade eslint and fix issues

This commit is contained in:
Gregory Schier
2025-06-23 14:09:09 -07:00
parent 7be2767527
commit 1438e8bacc
11 changed files with 1326 additions and 1267 deletions

View File

@@ -1,6 +0,0 @@
node_modules/
dist/
.eslintrc.cjs
.prettierrc.cjs
src-web/postcss.config.cjs
src-web/vite.config.ts

View File

@@ -1,49 +0,0 @@
module.exports = {
extends: [
'eslint:recommended',
'plugin:react/recommended',
'plugin:react-hooks/recommended',
'plugin:import/recommended',
'plugin:jsx-a11y/recommended',
'plugin:@typescript-eslint/recommended',
'eslint-config-prettier',
],
plugins: ['react-refresh'],
parser: '@typescript-eslint/parser',
parserOptions: {
project: ['./tsconfig.json'],
},
ignorePatterns: [
'scripts/**/*',
'packages/plugin-runtime/**/*',
'packages/plugin-runtime-types/**/*',
'src-tauri/**/*',
'src-web/tailwind.config.cjs',
'src-web/vite.config.ts',
],
settings: {
react: {
version: 'detect',
},
'import/resolver': {
node: {
paths: ['src-web'],
extensions: ['.ts', '.tsx'],
},
},
},
rules: {
'react-refresh/only-export-components': 'error',
'jsx-a11y/no-autofocus': 'off',
'react/react-in-jsx-scope': 'off',
'import/no-unresolved': 'off',
'@typescript-eslint/consistent-type-imports': [
'error',
{
prefer: 'type-imports',
disallowTypeAnnotations: true,
fixStyle: 'separate-type-imports',
},
],
},
};

88
eslint.config.cjs Normal file
View File

@@ -0,0 +1,88 @@
const { defineConfig, globalIgnores } = require('eslint/config');
const { fixupConfigRules } = require('@eslint/compat');
const reactRefresh = require('eslint-plugin-react-refresh');
const tsParser = require('@typescript-eslint/parser');
const js = require('@eslint/js');
const { FlatCompat } = require('@eslint/eslintrc');
const compat = new FlatCompat({
baseDirectory: __dirname,
recommendedConfig: js.configs.recommended,
allConfig: js.configs.all,
});
module.exports = defineConfig([
{
extends: fixupConfigRules(
compat.extends(
'eslint:recommended',
'plugin:react/recommended',
'plugin:react-hooks/recommended',
'plugin:import/recommended',
'plugin:jsx-a11y/recommended',
'plugin:@typescript-eslint/recommended',
'eslint-config-prettier',
),
),
plugins: {
'react-refresh': reactRefresh,
},
languageOptions: {
parser: tsParser,
parserOptions: {
project: ['./tsconfig.json'],
},
},
settings: {
react: {
version: 'detect',
},
'import/resolver': {
node: {
paths: ['src-web'],
extensions: ['.ts', '.tsx'],
},
},
},
rules: {
'react-refresh/only-export-components': 'error',
'jsx-a11y/no-autofocus': 'off',
'react/react-in-jsx-scope': 'off',
'import/no-unresolved': 'off',
'@typescript-eslint/consistent-type-imports': [
'error',
{
prefer: 'type-imports',
disallowTypeAnnotations: true,
fixStyle: 'separate-type-imports',
},
],
},
},
globalIgnores([
'scripts/**/*',
'packages/plugin-runtime/**/*',
'packages/plugin-runtime-types/**/*',
'src-tauri/**/*',
'src-web/tailwind.config.cjs',
'src-web/vite.config.ts',
]),
globalIgnores([
'**/node_modules/',
'**/dist/',
'**/.eslintrc.cjs',
'**/.prettierrc.cjs',
'src-web/postcss.config.cjs',
'src-web/vite.config.ts',
]),
]);

1295
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -67,16 +67,19 @@
"jotai": "^2.12.2"
},
"devDependencies": {
"@eslint/compat": "^1.3.0",
"@eslint/eslintrc": "^3.3.1",
"@eslint/js": "^9.29.0",
"@tauri-apps/cli": "2.4.1",
"@typescript-eslint/eslint-plugin": "^8.27.0",
"@typescript-eslint/parser": "^8.27.0",
"@yaakapp/cli": "^0.1.5",
"eslint": "^8",
"eslint-config-prettier": "^8",
"eslint-plugin-import": "^2.31.0",
"eslint": "^9.29.0",
"eslint-config-prettier": "^10.1.5",
"eslint-plugin-import": "^2.32.0",
"eslint-plugin-jsx-a11y": "^6.10.2",
"eslint-plugin-react": "^7.37.2",
"eslint-plugin-react-hooks": "^5.1.0",
"eslint-plugin-react": "^7.37.5",
"eslint-plugin-react-hooks": "^5.2.0",
"nodejs-file-downloader": "^4.13.0",
"npm-run-all": "^4.1.5",
"prettier": "^3.4.2",

View File

@@ -113,7 +113,6 @@ function ExportDataDialogContent({
}
/>
</td>
{/* eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions,jsx-a11y/click-events-have-key-events */}
<td
className="py-1 pl-4 text whitespace-nowrap overflow-x-auto hide-scrollbars"
onClick={() => setSelectedWorkspaces((prev) => ({ ...prev, [w.id]: !prev[w.id] }))}

View File

@@ -1,8 +1,6 @@
import {
useAtomValue
} from 'jotai';
import { graphqlSchemaAtom } from "../atoms/graphqlSchemaAtom";
import { Input } from "./core/Input";
import { useAtomValue } from 'jotai';
import { graphqlSchemaAtom } from '../atoms/graphqlSchemaAtom';
import { Input } from './core/Input';
import type {
GraphQLSchema,
GraphQLOutputType,
@@ -11,38 +9,35 @@ import type {
GraphQLList,
GraphQLInputType,
GraphQLNonNull,
GraphQLObjectType
} from "graphql";
import { isNonNullType, isListType } from "graphql";
import { Button } from "./core/Button";
GraphQLObjectType,
} from 'graphql';
import { isNonNullType, isListType } from 'graphql';
import { Button } from './core/Button';
import { useEffect, useState } from 'react';
import { IconButton } from "./core/IconButton";
import { IconButton } from './core/IconButton';
import { fuzzyFilter } from 'fuzzbunny';
function getRootTypes(graphqlSchema: GraphQLSchema) {
return ([
return (
[
graphqlSchema.getQueryType(),
graphqlSchema.getMutationType(),
graphqlSchema.getSubscriptionType(),
]
.filter(Boolean) as NonNullable<ReturnType<GraphQLSchema['getQueryType']>>[])
.reduce(
(
prev,
curr
) => {
].filter(Boolean) as NonNullable<ReturnType<GraphQLSchema['getQueryType']>>[]
).reduce(
(prev, curr) => {
return {
...prev,
[curr.name]: curr,
};
},
{} as Record<string, NonNullable<ReturnType<GraphQLSchema['getQueryType']>>>
)
{} as Record<string, NonNullable<ReturnType<GraphQLSchema['getQueryType']>>>,
);
}
function getTypeIndices(
type: GraphQLAnyType,
context: IndexGenerationContext
context: IndexGenerationContext,
): SearchIndexRecord[] {
const indices: SearchIndexRecord[] = [];
@@ -54,60 +49,48 @@ function getTypeIndices(
name: (type as GraphQLObjectType).name,
type: 'type',
schemaPointer: type,
args: ''
args: '',
});
if ((type as GraphQLObjectType).getFields) {
indices.push(
...getFieldsIndices((type as GraphQLObjectType).getFields(), context)
)
indices.push(...getFieldsIndices((type as GraphQLObjectType).getFields(), context));
}
// remove duplicates from index
return indices.filter(
(x, i, array) => array.findIndex(
(y) => y.name === x.name && y.type === x.type
) === i
(x, i, array) => array.findIndex((y) => y.name === x.name && y.type === x.type) === i,
);
}
function getFieldsIndices(
fieldMap: FieldsMap,
context: IndexGenerationContext
context: IndexGenerationContext,
): SearchIndexRecord[] {
const indices: SearchIndexRecord[] = [];
Object.values(fieldMap)
.forEach(
(field) => {
Object.values(fieldMap).forEach((field) => {
if (!field.name) {
return;
}
const args = field.args && field.args.length > 0
? field.args.map((arg) => arg.name).join(', ')
: '';
const args =
field.args && field.args.length > 0 ? field.args.map((arg) => arg.name).join(', ') : '';
indices.push({
name: field.name,
type: context.rootType,
schemaPointer: field as unknown as Field,
args
args,
});
if (field.type) {
indices.push(
...getTypeIndices(field.type, context)
)
indices.push(...getTypeIndices(field.type, context));
}
}
);
});
// remove duplicates from index
return indices.filter(
(x, i, array) => array.findIndex(
(y) => y.name === x.name && y.type === x.type
) === i
(x, i, array) => array.findIndex((y) => y.name === x.name && y.type === x.type) === i,
);
}
@@ -116,10 +99,10 @@ type FieldsMap = ReturnType<Field['getFields']>;
type GraphQLAnyType = FieldsMap[string]['type'];
type SearchIndexRecord = {
name: string,
args: string,
type: 'field' | 'type' | 'Query' | 'Mutation' | 'Subscription',
schemaPointer: SchemaPointer
name: string;
args: string;
type: 'field' | 'type' | 'Query' | 'Mutation' | 'Subscription';
schemaPointer: SchemaPointer;
};
type IndexGenerationContext = {
@@ -131,13 +114,11 @@ type SchemaPointer = Field | GraphQLOutputType | GraphQLInputType | null;
type ViewMode = 'explorer' | 'search' | 'field';
type HistoryRecord = {
schemaPointer: SchemaPointer,
viewMode: ViewMode
schemaPointer: SchemaPointer;
viewMode: ViewMode;
};
function DocsExplorer({
graphqlSchema
}: { graphqlSchema: GraphQLSchema }) {
function DocsExplorer({ graphqlSchema }: { graphqlSchema: GraphQLSchema }) {
const [rootTypes, setRootTypes] = useState(getRootTypes(graphqlSchema));
const [schemaPointer, setSchemaPointer] = useState<SchemaPointer>(null);
const [history, setHistory] = useState<HistoryRecord[]>([]);
@@ -154,56 +135,41 @@ function DocsExplorer({
const typeMap = graphqlSchema.getTypeMap();
const index: SearchIndexRecord[] = Object.values(typeMap)
.filter(
(x) => !x.name.startsWith('__')
)
.map(
(x) => ({
.filter((x) => !x.name.startsWith('__'))
.map((x) => ({
name: x.name,
type: 'type',
schemaPointer: x,
args: ''
})
);
args: '',
}));
Object.values(rootTypes)
.forEach(
(type) => {
Object.values(rootTypes).forEach((type) => {
index.push(
...getFieldsIndices(type.getFields(), { rootType: type.name as any })
)
}
)
...getFieldsIndices(type.getFields(), {
rootType: type.name as IndexGenerationContext['rootType'],
}),
);
});
setSearchIndex(
index
.filter(
(x, i, array) => array.findIndex(
(y) => y.name === x.name && y.type === x.type
) === i
)
index.filter(
(x, i, array) => array.findIndex((y) => y.name === x.name && y.type === x.type) === i,
),
);
}, [graphqlSchema, rootTypes]);
useEffect(
() => {
useEffect(() => {
if (!searchQuery) {
setSearchResults([]);
return;
}
const results = fuzzyFilter(
searchIndex,
searchQuery,
{ fields: ['name', 'args'] }
)
const results = fuzzyFilter(searchIndex, searchQuery, { fields: ['name', 'args'] })
.sort((a, b) => b.score - a.score)
.map((v) => v.item);
setSearchResults(results);
},
[searchIndex, searchQuery]
);
}, [searchIndex, searchQuery]);
const goBack = () => {
if (history.length === 0) {
@@ -224,67 +190,53 @@ function DocsExplorer({
}
goHome();
}
};
const addToHistory = (historyRecord: HistoryRecord) => {
setHistory([...history, historyRecord]);
}
};
const goHome = () => {
setHistory([]);
setSchemaPointer(null);
setViewMode('explorer');
}
};
const renderRootTypes = () => {
return (
<div
className="mt-5 flex flex-col gap-3"
>
{
Object
.values(rootTypes)
.map(
(x) => (
<div className="mt-5 flex flex-col gap-3">
{Object.values(rootTypes).map((x) => (
<button
key={x.name}
className="block text-primary cursor-pointer w-fit"
onClick={
() => {
onClick={() => {
addToHistory({
schemaPointer: x,
viewMode: 'explorer',
});
setSchemaPointer(x);
}
}
}}
>
{x.name}
</button>
)
)
}
))}
</div>
);
}
};
const extractActualType = (
type: GraphQLField<never, never>['type'] | GraphQLInputType
) => {
const extractActualType = (type: GraphQLField<never, never>['type'] | GraphQLInputType) => {
// check if non-null
if (isNonNullType(type) || isListType(type)) {
return extractActualType((type as GraphQLNonNull<GraphQLOutputType>).ofType)
return extractActualType((type as GraphQLNonNull<GraphQLOutputType>).ofType);
}
return type;
}
};
const onTypeClick = (
type: GraphQLField<never, never>['type'] | GraphQLInputType
) => {
const onTypeClick = (type: GraphQLField<never, never>['type'] | GraphQLInputType) => {
// check if non-null
if (isNonNullType(type)) {
onTypeClick((type as GraphQLNonNull<GraphQLOutputType>).ofType)
onTypeClick((type as GraphQLNonNull<GraphQLOutputType>).ofType);
return;
}
@@ -304,7 +256,7 @@ function DocsExplorer({
setViewMode('explorer');
};
const onFieldClick = (field: GraphQLField<any, any>) => {
const onFieldClick = (field: GraphQLField<unknown, unknown>) => {
setSchemaPointer(field as unknown as Field);
setViewMode('field');
addToHistory({
@@ -316,86 +268,48 @@ function DocsExplorer({
const renderSubFieldRecord = (
field: FieldsMap[string],
options?: {
addable?: boolean,
}
addable?: boolean;
},
) => {
return (
<div
className="flex flex-row justify-start items-center"
>
{
options?.addable
? (
<div className="flex flex-row justify-start items-center">
{options?.addable ? (
<IconButton size="sm" icon="plus_circle" iconColor="secondary" title="Add to query" />
)
: null
}
<div
className="flex flex-col"
>
) : null}
<div className="flex flex-col">
<div>
<span>
{ " " }
</span>
<button
className="cursor-pointer text-primary"
onClick={ () => onFieldClick(field) }
>
<span> </span>
<button className="cursor-pointer text-primary" onClick={() => onFieldClick(field)}>
{field.name}
</button>
{/* Arguments block */}
{
field.args && field.args.length > 0
? (
{field.args && field.args.length > 0 ? (
<>
<span>
{ " " }
(
{ " " }
<span> ( </span>
{field.args.map((arg, i, array) => (
<>
<button key={arg.name} onClick={() => onTypeClick(arg.type)}>
<span className="text-primary cursor-pointer">{arg.name}</span>
<span> </span>
<span className="text-success underline cursor-pointer">
{arg.type.toString()}
</span>
{
field.args.map(
(arg, i, array) => (
{i < array.length - 1 ? (
<>
<button
key={ arg.name }
onClick={ () => onTypeClick(arg.type) }
>
<span
className="text-primary cursor-pointer"
>
{ arg.name }
</span>
<span>{ " " }</span>
<span
className="text-success underline cursor-pointer"
>{ arg.type.toString() }</span>
{
i < array.length - 1
? (
<>
<span>{ " " }</span>
<span> </span>
<span> , </span>
<span>{ " " }</span>
<span> </span>
</>
)
: null
}
) : null}
</button>
<span>{ " " }</span>
<span> </span>
</>
)
)
}
<span>
)
</span>
))}
<span>)</span>
</>
)
: null
}
) : null}
{/* End of Arguments Block */}
<span>{ " " }</span>
<span> </span>
<button
className="text-success underline cursor-pointer"
onClick={() => onTypeClick(field.type)}
@@ -403,15 +317,7 @@ function DocsExplorer({
{field.type.toString()}
</button>
</div>
{
field.description
? (
<div>
{ field.description }
</div>
)
: null
}
{field.description ? <div>{field.description}</div> : null}
</div>
</div>
);
@@ -420,11 +326,7 @@ function DocsExplorer({
const renderScalarField = () => {
const scalarField = schemaPointer as GraphQLScalarType;
return (
<div>
{ scalarField.toConfig().description }
</div>
);
return <div>{scalarField.toConfig().description}</div>;
};
const renderSubFields = () => {
@@ -432,9 +334,7 @@ function DocsExplorer({
return null;
}
if (
!(schemaPointer as Field).getFields
) {
if (!(schemaPointer as Field).getFields) {
// Scalar field
return renderScalarField();
}
@@ -443,10 +343,9 @@ function DocsExplorer({
return null;
}
return Object.values((schemaPointer as Field).getFields())
.map(
(x) => renderSubFieldRecord(x, { addable: true })
)
return Object.values((schemaPointer as Field).getFields()).map((x) =>
renderSubFieldRecord(x, { addable: true }),
);
};
const renderFieldDocView = () => {
@@ -456,37 +355,19 @@ function DocsExplorer({
return (
<div>
<div
className="text-primary mt-5"
>
{ (schemaPointer as Field).name }
<div className="text-primary mt-5">{(schemaPointer as Field).name}</div>
{(schemaPointer as Field).getFields ? <div className="my-3">Fields</div> : null}
<div className="flex flex-col gap-7">{renderSubFields()}</div>
</div>
{
(schemaPointer as Field).getFields
? (
<div
className="my-3"
>
Fields
</div>
)
: null
}
<div
className="flex flex-col gap-7"
>
{ renderSubFields() }
</div>
</div>
)
}
);
};
const renderExplorerView = () => {
if (history.length === 0) {
return renderRootTypes();
}
return renderFieldDocView()
return renderFieldDocView();
};
const renderFieldView = () => {
@@ -494,109 +375,60 @@ function DocsExplorer({
return null;
}
const field = schemaPointer as unknown as GraphQLField<any, any>;
const field = schemaPointer as unknown as GraphQLField<unknown, unknown>;
const returnType = extractActualType(field.type);
return (
<div>
<div
className="text-primary mt-10"
>
{ field.name }
</div>
<div className="text-primary mt-10">{field.name}</div>
{/* Arguments */}
{
field.args && field.args.length > 0
? (
<div
className="mt-8"
>
{field.args && field.args.length > 0 ? (
<div className="mt-8">
<div>Arguments</div>
<div className="mt-2">
<div>
Arguments
</div>
<div
className="mt-2"
>
<div>
{
field.args.map(
(arg, i, array) => (
{field.args.map((arg, i, array) => (
<>
<button
key={ arg.name }
onClick={ () => onTypeClick(arg.type) }
>
<span
className="text-primary cursor-pointer"
>
{ arg.name }
<button key={arg.name} onClick={() => onTypeClick(arg.type)}>
<span className="text-primary cursor-pointer">{arg.name}</span>
<span> </span>
<span className="text-success underline cursor-pointer">
{arg.type.toString()}
</span>
<span>{ " " }</span>
<span
className="text-success underline cursor-pointer"
>{ arg.type.toString() }</span>
{
i < array.length - 1
? (
{i < array.length - 1 ? (
<>
<span>{ " " }</span>
<span> </span>
<span> , </span>
<span>{ " " }</span>
<span> </span>
</>
)
: null
}
) : null}
</button>
<span>{ " " }</span>
<span> </span>
</>
)
)
}
))}
</div>
</div>
</div>
)
: null
}
) : null}
{/* End of Arguments */}
{/* Return type */}
<div
className="mt-8"
>
<div>
Type
</div>
<div
className="text-primary mt-2"
>
{ returnType.name }
</div>
<div className="mt-8">
<div>Type</div>
<div className="text-primary mt-2">{returnType.name}</div>
</div>
{/* End of Return type */}
{/* Fields */}
{
(returnType as GraphQLObjectType).getFields && Object.values((returnType as GraphQLObjectType).getFields()).length > 0
? (
<div
className="mt-8"
>
<div>
Fields
</div>
<div
className="flex flex-col gap-3 mt-2"
>
{
Object.values((returnType as GraphQLObjectType).getFields())
.map(
(x) => renderSubFieldRecord(x)
)
}
{(returnType as GraphQLObjectType).getFields &&
Object.values((returnType as GraphQLObjectType).getFields()).length > 0 ? (
<div className="mt-8">
<div>Fields</div>
<div className="flex flex-col gap-3 mt-2">
{Object.values((returnType as GraphQLObjectType).getFields()).map((x) =>
renderSubFieldRecord(x),
)}
</div>
</div>
)
: null
}
) : null}
{/* End of Fields */}
</div>
);
@@ -604,19 +436,9 @@ function DocsExplorer({
const renderTopBar = () => {
return (
<div
className="flex flex-row gap-2"
>
<Button
onClick={ goBack }
>
Back
</Button>
<IconButton
onClick={ goHome }
icon="house"
title="Go to beginning"
/>
<div className="flex flex-row gap-2">
<Button onClick={goBack}>Back</Button>
<IconButton onClick={goHome} icon="house" title="Go to beginning" />
</div>
);
};
@@ -624,23 +446,13 @@ function DocsExplorer({
const renderSearchView = () => {
return (
<div>
<div
className="mt-5 text-primary"
>
Search results
</div>
<div
className="mt-4 flex flex-col gap-3"
>
{
searchResults
.map(
(result) => (
<div className="mt-5 text-primary">Search results</div>
<div className="mt-4 flex flex-col gap-3">
{searchResults.map((result) => (
<button
key={`${result.name}-${result.type}`}
className="cursor-pointer border border-1 border-border-subtle rounded-md p-2 flex flex-row justify-between hover:bg-surface-highlight transition-colors"
onClick={
() => {
onClick={() => {
if (!result.schemaPointer) {
throw new Error('somehow search result record contains no schema pointer');
}
@@ -653,41 +465,22 @@ function DocsExplorer({
return;
}
onFieldClick(result.schemaPointer as unknown as GraphQLField<any, any>);
}
}
onFieldClick(result.schemaPointer as unknown as GraphQLField<unknown, unknown>);
}}
>
<div
className="flex flex-row"
>
<div
className="cursor-pointer"
>
{ result.name }
</div>
{
result.args
? (
<div
className="cursor-pointer"
>
{ "( " }
<div className="flex flex-row">
<div className="cursor-pointer">{result.name}</div>
{result.args ? (
<div className="cursor-pointer">
{'( '}
{result.args}
{ " )" }
{' )'}
</div>
)
: null
}
</div>
<div
className="cursor-pointer"
>
{ result.type }
) : null}
</div>
<div className="cursor-pointer">{result.type}</div>
</button>
)
)
}
))}
</div>
</div>
);
@@ -706,51 +499,35 @@ function DocsExplorer({
};
return (
<div
className="overflow-y-auto pe-3"
>
<div
className="min-h-[35px]"
>
{
history.length > 0 || viewMode === 'search'
? renderTopBar()
: null
}
<div className="overflow-y-auto pe-3">
<div className="min-h-[35px]">
{history.length > 0 || viewMode === 'search' ? renderTopBar() : null}
</div>
{/* Search bar */}
<div
className="relative"
>
<div className="relative">
<Input
label="Search docs"
stateKey="search_graphql_docs"
placeholder="Search docs"
hideLabel
defaultValue={searchQuery}
onChange={
(value) => {
onChange={(value) => {
setSearchQuery(value);
}
}
onKeyDown={
(e) => {
}}
onKeyDown={(e) => {
// check if enter
if (e.key === 'Enter' && viewMode !== 'search') {
addToHistory({
schemaPointer: null,
viewMode: 'search',
})
});
setViewMode('search');
}
}
}
}}
/>
</div>
{/* End of search bar */}
<div>
{ renderView() }
</div>
<div>{renderView()}</div>
</div>
);
}

View File

@@ -1,13 +1,10 @@
import { useMutation, useQuery } from '@tanstack/react-query';
import { openUrl } from '@tauri-apps/plugin-opener';
import { Plugin, pluginsAtom } from '@yaakapp-internal/models';
import {
checkPluginUpdates,
installPlugin,
PluginVersion,
searchPlugins,
} from '@yaakapp-internal/plugins';
import { PluginUpdatesResponse } from '@yaakapp-internal/plugins/bindings/gen_api';
import type { Plugin } from '@yaakapp-internal/models';
import { pluginsAtom } from '@yaakapp-internal/models';
import type { PluginVersion } from '@yaakapp-internal/plugins';
import { checkPluginUpdates, installPlugin, searchPlugins } from '@yaakapp-internal/plugins';
import type { PluginUpdatesResponse } from '@yaakapp-internal/plugins/bindings/gen_api';
import { useAtomValue } from 'jotai';
import React, { useState } from 'react';
import { useDebouncedValue } from '../../hooks/useDebouncedValue';
@@ -190,7 +187,7 @@ function PluginSearch() {
<TableHeaderCell>Name</TableHeaderCell>
<TableHeaderCell>Version</TableHeaderCell>
<TableHeaderCell>Description</TableHeaderCell>
<TableHeaderCell children="" />
<TableHeaderCell />
</TableRow>
</TableHead>
<TableBody>

View File

@@ -3,7 +3,8 @@ import type { ReactNode } from 'react';
import { memo, useEffect, useRef } from 'react';
import { ErrorBoundary } from '../../ErrorBoundary';
import { Icon } from '../Icon';
import { RadioDropdown, RadioDropdownProps } from '../RadioDropdown';
import type { RadioDropdownProps } from '../RadioDropdown';
import { RadioDropdown } from '../RadioDropdown';
export type TabItem =
| {
@@ -49,7 +50,7 @@ export function Tabs({
const tabs = ref.current?.querySelectorAll<HTMLDivElement>(`[data-tab]`);
for (const tab of tabs ?? []) {
const v = tab.getAttribute('data-tab');
let parent = tab.closest('.tabs-container');
const parent = tab.closest('.tabs-container');
if (parent !== ref.current) {
// Tab is part of a nested tab container, so ignore it
} else if (v === value) {

View File

@@ -18,7 +18,6 @@ export function useSyncWorkspaceRequestTitle() {
newTitle += ` [${activeEnvironment.name}]`;
}
if (activeRequest) {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
newTitle += ` ${resolvedModelName(activeRequest)}`;
}

View File

@@ -9,9 +9,8 @@ export async function tryFormatJson(text: string): Promise<string> {
try {
const result = await invokeCmd<string>('cmd_format_json', { text });
return result;
// eslint-disable-next-line @typescript-eslint/no-unused-vars
} catch (err) {
console.warn("Failed to format JSON", err);
console.warn('Failed to format JSON', err);
// Nothing
}