feat: Enable essential ESLint rules and refactor frontend lint config (#4923)

* Install eslint-plugin-unsued-imports

* Refactor eslint to a sane working config

* enable jsx-no-target-blank | disable no-escaped-entities

* disable react/display-name react-hooks/immutability and react-hooks/preserve-manual-memoization

* chore: remove unused imports (#4925)

remove unused imports

* fix: resolve react-hooks ESLint errors (#4929)

fix react-hooks linting errors

* fix: add rel=noreferrer to target=_blank links (#4928)

Fix no target blank errors

* fix: resolve undefined variable errors in frontend (#4927)

* delete unused file src/components/DataConnectorOption/index.jsx

* fix undefined errors

* chore: Remove unused variables in frontend (#4924)

Remove unused variables

---------

Co-authored-by: Timothy Carambat <rambat1010@gmail.com>
This commit is contained in:
Marcello Fitton 2026-01-29 17:01:39 -08:00 committed by GitHub
parent 17a399d43c
commit c734566a67
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
46 changed files with 117 additions and 117 deletions

View File

@ -4,43 +4,77 @@ import pluginReact from "eslint-plugin-react"
import pluginReactHooks from "eslint-plugin-react-hooks" import pluginReactHooks from "eslint-plugin-react-hooks"
import pluginPrettier from "eslint-plugin-prettier" import pluginPrettier from "eslint-plugin-prettier"
import configPrettier from "eslint-config-prettier" import configPrettier from "eslint-config-prettier"
import { defineConfig } from "eslint/config" import unusedImports from "eslint-plugin-unused-imports"
export default defineConfig([ export default [
{ {
ignores: ["**/*.min.js", "src/media/**/*"] ignores: ["**/*.min.js", "src/media/**/*"]
}, },
// Base JS recommended rules
js.configs.recommended,
// Your React/JSX files
{ {
files: ["src/**/*.{js,jsx}"], files: ["src/**/*.{js,jsx,mjs,cjs}"],
plugins: { js }, languageOptions: {
extends: ["js/recommended"], ecmaVersion: "latest",
languageOptions: { globals: globals.browser } sourceType: "module",
parserOptions: {
ecmaFeatures: { jsx: true }
},
globals: globals.browser
}, },
{
files: ["src/**/*.{js,jsx}"],
...pluginReact.configs.flat.recommended,
plugins: { plugins: {
react: pluginReact,
"react-hooks": pluginReactHooks, "react-hooks": pluginReactHooks,
"unused-imports": unusedImports,
prettier: pluginPrettier prettier: pluginPrettier
}, },
settings: { settings: {
react: { react: { version: "detect" }
version: "detect"
}
}, },
rules: { rules: {
// React recommended rules (inline, since we're not "extending" in flat config)
...pluginReact.configs.flat.recommended.rules,
// If you want hooks rules, add these (recommended)
...pluginReactHooks.configs.recommended.rules,
// Prettier: disable conflicting stylistic rules + optionally enforce formatting
...configPrettier.rules, ...configPrettier.rules,
"prettier/prettier": "error", "prettier/prettier": "error",
// Your overrides
"react/react-in-jsx-scope": "off", "react/react-in-jsx-scope": "off",
"react-hooks/exhaustive-deps": "off", "react-hooks/exhaustive-deps": "off",
"react/prop-types": "off",
"react-hooks/set-state-in-effect": "off",
"react/jsx-no-target-blank": "error",
"react/no-unescaped-entities": "off",
"react/display-name": "off",
"react-hooks/immutability": "off",
"react-hooks/preserve-manual-memoization": "off",
"no-extra-boolean-cast": "off", "no-extra-boolean-cast": "off",
"no-prototype-builtins": "off", "no-prototype-builtins": "off",
"no-unused-vars": "off",
"no-empty": "off", "no-empty": "off",
"no-useless-escape": "off", "no-useless-escape": "off",
"no-undef": "off", "no-undef": "error",
"no-unsafe-optional-chaining": "off", "no-unsafe-optional-chaining": "off",
"no-constant-binary-expression": "off" "no-constant-binary-expression": "off",
// Unused cleanup
"no-unused-vars": "off",
"unused-imports/no-unused-imports": "error",
"unused-imports/no-unused-vars": [
"warn",
{
vars: "all",
varsIgnorePattern: "^_",
args: "after-used",
argsIgnorePattern: "^_"
}
]
} }
} }
]) ]

View File

@ -69,6 +69,7 @@
"eslint-plugin-react": "^7.37.5", "eslint-plugin-react": "^7.37.5",
"eslint-plugin-react-hooks": "^7.0.1", "eslint-plugin-react-hooks": "^7.0.1",
"eslint-plugin-react-refresh": "^0.4.3", "eslint-plugin-react-refresh": "^0.4.3",
"eslint-plugin-unused-imports": "^4.3.0",
"flow-bin": "^0.217.0", "flow-bin": "^0.217.0",
"flow-remove-types": "^2.217.1", "flow-remove-types": "^2.217.1",
"globals": "^16.5.0", "globals": "^16.5.0",

View File

@ -4,7 +4,7 @@ import { userFromStorage } from "@/utils/request";
import renderMarkdown from "@/utils/chat/markdown"; import renderMarkdown from "@/utils/chat/markdown";
import DOMPurify from "@/utils/chat/purify"; import DOMPurify from "@/utils/chat/purify";
export default function ChatBubble({ message, type, popMsg }) { export default function ChatBubble({ message, type }) {
const isUser = type === "user"; const isUser = type === "user";
return ( return (

View File

@ -1,25 +0,0 @@
export default function DataConnectorOption({ slug }) {
if (!DATA_CONNECTORS.hasOwnProperty(slug)) return null;
const { path, image, name, description, link } = DATA_CONNECTORS[slug];
return (
<a href={path}>
<label className="transition-all duration-300 inline-flex flex-col h-full w-60 cursor-pointer items-start justify-between rounded-2xl bg-preference-gradient border-2 border-transparent shadow-md px-5 py-4 text-white hover:bg-selected-preference-gradient hover:border-white/60 peer-checked:border-white peer-checked:border-opacity-90 peer-checked:bg-selected-preference-gradient">
<div className="flex items-center">
<img src={image} alt={name} className="h-10 w-10 rounded" />
<div className="ml-4 text-sm font-semibold">{name}</div>
</div>
<div className="mt-2 text-xs font-base text-white tracking-wide">
{description}
</div>
<a
href={link}
target="_blank"
className="mt-2 text-xs text-white font-medium underline"
>
{link}
</a>
</label>
</a>
);
}

View File

@ -5,10 +5,7 @@ import PreLoader from "@/components/Preloader";
import { DPAIS_COMMON_URLS } from "@/utils/constants"; import { DPAIS_COMMON_URLS } from "@/utils/constants";
import useProviderEndpointAutoDiscovery from "@/hooks/useProviderEndpointAutoDiscovery"; import useProviderEndpointAutoDiscovery from "@/hooks/useProviderEndpointAutoDiscovery";
export default function DellProAIStudioOptions({ export default function DellProAIStudioOptions({ settings }) {
settings,
showAlert = false,
}) {
const { const {
autoDetecting: loading, autoDetecting: loading,
basePath, basePath,

View File

@ -2,6 +2,6 @@
* This component is used to select, start, and manage NVIDIA NIM * This component is used to select, start, and manage NVIDIA NIM
* containers and images via docker management tools. * containers and images via docker management tools.
*/ */
export default function ManagedNvidiaNimOptions({ settings }) { export default function ManagedNvidiaNimOptions({ settings: _settings }) {
return null; return null;
} }

View File

@ -256,7 +256,7 @@ const WatchForChanges = memo(({ workspace, docPath, item }) => {
); );
}); });
const RemoveItemFromWorkspace = ({ item, onClick }) => { const RemoveItemFromWorkspace = ({ item: _item, onClick }) => {
return ( return (
<div> <div>
<ArrowUUpLeft <ArrowUUpLeft

View File

@ -1,17 +1,5 @@
export default function CustomCell({ ...props }) { export default function CustomCell({ ...props }) {
const { const { root, depth, x, y, width, height, index, colors, name } = props;
root,
depth,
x,
y,
width,
height,
index,
payload,
colors,
rank,
name,
} = props;
return ( return (
<g> <g>
<rect <rect

View File

@ -42,12 +42,13 @@ function combineLikeSources(sources) {
} }
export default function Citations({ sources = [] }) { export default function Citations({ sources = [] }) {
if (sources.length === 0) return null;
const [open, setOpen] = useState(false); const [open, setOpen] = useState(false);
const [selectedSource, setSelectedSource] = useState(null); const [selectedSource, setSelectedSource] = useState(null);
const { t } = useTranslation(); const { t } = useTranslation();
const { textSizeClass } = useTextSize(); const { textSizeClass } = useTextSize();
if (sources.length === 0) return null;
return ( return (
<div className="flex flex-col mt-4 justify-left"> <div className="flex flex-col mt-4 justify-left">
<button <button

View File

@ -128,8 +128,8 @@ function CopyMessage({ message }) {
} }
function RegenerateMessage({ regenerateMessage, chatId }) { function RegenerateMessage({ regenerateMessage, chatId }) {
if (!chatId) return null;
const { t } = useTranslation(); const { t } = useTranslation();
if (!chatId) return null;
return ( return (
<div className="mt-3 relative"> <div className="mt-3 relative">
<button <button

View File

@ -1,3 +1,4 @@
/* eslint-disable react-hooks/refs */
import { memo, useRef, useEffect } from "react"; import { memo, useRef, useEffect } from "react";
import { Warning } from "@phosphor-icons/react"; import { Warning } from "@phosphor-icons/react";
import UserIcon from "../../../../UserIcon"; import UserIcon from "../../../../UserIcon";
@ -17,7 +18,6 @@ const PromptReply = ({
error, error,
workspace, workspace,
sources = [], sources = [],
closed = true,
}) => { }) => {
const assistantBackgroundColor = "bg-theme-bg-chat"; const assistantBackgroundColor = "bg-theme-bg-chat";

View File

@ -38,7 +38,7 @@ export function validatedModelSelection(model) {
// If the model is in the dropdown, return the model as is // If the model is in the dropdown, return the model as is
return model; return model;
} catch (error) { } catch {
return null; // If the dropdown was empty or something else went wrong, return null to abort the save return null; // If the dropdown was empty or something else went wrong, return null to abort the save
} }
} }

View File

@ -1,7 +1,7 @@
import { useEffect, useCallback, useRef } from "react"; import { useEffect, useCallback, useRef } from "react";
import { Microphone } from "@phosphor-icons/react"; import { Microphone } from "@phosphor-icons/react";
import { Tooltip } from "react-tooltip"; import { Tooltip } from "react-tooltip";
import _regeneratorRuntime from "regenerator-runtime"; import "regenerator-runtime"; //required polyfill for speech recognition;
import SpeechRecognition, { import SpeechRecognition, {
useSpeechRecognition, useSpeechRecognition,
} from "react-speech-recognition"; } from "react-speech-recognition";

View File

@ -247,7 +247,7 @@ export default function ChatContainer({ workspace, knownHistory = [] }) {
setLoadingResponse(true); setLoadingResponse(true);
try { try {
handleSocketResponse(socket, event, setChatHistory); handleSocketResponse(socket, event, setChatHistory);
} catch (e) { } catch {
console.error("Failed to parse data"); console.error("Failed to parse data");
window.dispatchEvent(new CustomEvent(AGENT_SESSION_END)); window.dispatchEvent(new CustomEvent(AGENT_SESSION_END));
socket.close(); socket.close();

View File

@ -104,12 +104,7 @@ export default function ModelTable({
); );
} }
/** function DeviceTypeTagWrapper({ text, bgClass, textClass }) {
* @param {{deviceType: ModelDefinition["deviceType"]}} deviceType
* @returns {React.ReactNode}
*/
function DeviceTypeTag({ deviceType }) {
const Wrapper = ({ text, bgClass, textClass }) => {
return ( return (
<div <div
className={ className={
@ -120,12 +115,17 @@ function DeviceTypeTag({ deviceType }) {
<p className={textClass + " text-xs"}>{text}</p> <p className={textClass + " text-xs"}>{text}</p>
</div> </div>
); );
}; }
/**
* @param {{deviceType: ModelDefinition["deviceType"]}} deviceType
* @returns {React.ReactNode}
*/
function DeviceTypeTag({ deviceType }) {
switch (deviceType?.toLowerCase()) { switch (deviceType?.toLowerCase()) {
case "cpu": case "cpu":
return ( return (
<Wrapper <DeviceTypeTagWrapper
text="CPU" text="CPU"
bgClass="bg-zinc-800 light:bg-zinc-200" bgClass="bg-zinc-800 light:bg-zinc-200"
textClass="text-theme-text-primary" textClass="text-theme-text-primary"
@ -133,7 +133,7 @@ function DeviceTypeTag({ deviceType }) {
); );
case "gpu": case "gpu":
return ( return (
<Wrapper <DeviceTypeTagWrapper
text="GPU" text="GPU"
bgClass="bg-green-800 light:bg-green-200" bgClass="bg-green-800 light:bg-green-200"
textClass="text-theme-text-primary" textClass="text-theme-text-primary"
@ -141,7 +141,7 @@ function DeviceTypeTag({ deviceType }) {
); );
case "npu": case "npu":
return ( return (
<Wrapper <DeviceTypeTagWrapper
text="NPU" text="NPU"
bgClass="bg-indigo-800 light:bg-indigo-200" bgClass="bg-indigo-800 light:bg-indigo-200"
textClass="text-theme-text-primary" textClass="text-theme-text-primary"
@ -149,7 +149,7 @@ function DeviceTypeTag({ deviceType }) {
); );
default: default:
return ( return (
<Wrapper <DeviceTypeTagWrapper
text="CPU" text="CPU"
bgClass="bg-zinc-800 light:bg-zinc-200" bgClass="bg-zinc-800 light:bg-zinc-200"
textClass="text-theme-text-primary" textClass="text-theme-text-primary"

View File

@ -1,3 +1,4 @@
/* eslint-disable react-hooks/static-components */
// https://lobehub.com/icons for all the icons // https://lobehub.com/icons for all the icons
import OpenAI from "@lobehub/icons/es/OpenAI/components/Mono"; import OpenAI from "@lobehub/icons/es/OpenAI/components/Mono";
import Anthropic from "@lobehub/icons/es/Anthropic/components/Mono"; import Anthropic from "@lobehub/icons/es/Anthropic/components/Mono";

View File

@ -17,7 +17,7 @@ export default function useProviderEndpointAutoDiscovery({
const [autoDetectAttempted, setAutoDetectAttempted] = useState(false); const [autoDetectAttempted, setAutoDetectAttempted] = useState(false);
const [showAdvancedControls, setShowAdvancedControls] = useState(true); const [showAdvancedControls, setShowAdvancedControls] = useState(true);
async function autoDetect(isInitialAttempt = false) { async function autoDetect() {
setLoading(true); setLoading(true);
setAutoDetectAttempted(true); setAutoDetectAttempted(true);
const possibleEndpoints = []; const possibleEndpoints = [];

View File

@ -1,3 +1,4 @@
/* global process */
// This script is used to normalize the translations files to ensure they are all the same. // This script is used to normalize the translations files to ensure they are all the same.
// This will take the en file and compare it to all other files and ensure they are all the same. // This will take the en file and compare it to all other files and ensure they are all the same.
// If a non-en file is missing a key, it will be added to the file and set to null // If a non-en file is missing a key, it will be added to the file and set to null
@ -75,7 +76,7 @@ function compareStructures(lang, a, b, subdir = null) {
} }
} }
function normalizeTranslations(lang, source, target, subdir = null) { function normalizeTranslations(lang, source, target, _subdir = null) {
// Handle primitives - if target exists, keep it, otherwise set null // Handle primitives - if target exists, keep it, otherwise set null
if (!source || typeof source !== "object") { if (!source || typeof source !== "object") {
return target ?? null; return target ?? null;

View File

@ -1,3 +1,4 @@
/* global process */
import { resources } from "./resources.js"; import { resources } from "./resources.js";
const languageNames = new Intl.DisplayNames(Object.keys(resources), { const languageNames = new Intl.DisplayNames(Object.keys(resources), {
type: "language", type: "language",

View File

@ -11,7 +11,7 @@ import SimpleSSOPassthrough from "@/pages/Login/SSO/simple";
import OnboardingFlow from "@/pages/OnboardingFlow"; import OnboardingFlow from "@/pages/OnboardingFlow";
import "@/index.css"; import "@/index.css";
const isDev = process.env.NODE_ENV !== "production"; const isDev = import.meta.env.DEV;
const REACTWRAP = isDev ? React.Fragment : React.StrictMode; const REACTWRAP = isDev ? React.Fragment : React.StrictMode;
const router = createBrowserRouter([ const router = createBrowserRouter([

View File

@ -58,7 +58,7 @@ const AgentFlows = {
headers: baseHeaders(), headers: baseHeaders(),
}) })
.then((res) => { .then((res) => {
if (!res.ok) throw new Error(response.error || "Failed to get flow"); if (!res.ok) throw new Error(res.error || "Failed to get flow");
return res; return res;
}) })
.then((res) => res.json()) .then((res) => res.json())
@ -107,7 +107,7 @@ const AgentFlows = {
headers: baseHeaders(), headers: baseHeaders(),
}) })
.then((res) => { .then((res) => {
if (!res.ok) throw new Error(response.error || "Failed to delete flow"); if (!res.ok) throw new Error(res.error || "Failed to delete flow");
return res; return res;
}) })
.then((res) => res.json()) .then((res) => res.json())

View File

@ -457,12 +457,11 @@ const System = {
throw new Error("Failed to fetch pfp."); throw new Error("Failed to fetch pfp.");
}) })
.then((blob) => (blob ? URL.createObjectURL(blob) : null)) .then((blob) => (blob ? URL.createObjectURL(blob) : null))
.catch((e) => { .catch(() => {
// console.log(e);
return null; return null;
}); });
}, },
removePfp: async function (id) { removePfp: async function () {
return await fetch(`${API_BASE}/system/remove-pfp`, { return await fetch(`${API_BASE}/system/remove-pfp`, {
method: "DELETE", method: "DELETE",
headers: baseHeaders(), headers: baseHeaders(),

View File

@ -348,7 +348,7 @@ const Workspace = {
throw new Error("Failed to fetch TTS."); throw new Error("Failed to fetch TTS.");
}) })
.then((blob) => (blob ? URL.createObjectURL(blob) : null)) .then((blob) => (blob ? URL.createObjectURL(blob) : null))
.catch((e) => { .catch(() => {
return null; return null;
}); });
}, },
@ -379,8 +379,7 @@ const Workspace = {
throw new Error("Failed to fetch pfp."); throw new Error("Failed to fetch pfp.");
}) })
.then((blob) => (blob ? URL.createObjectURL(blob) : null)) .then((blob) => (blob ? URL.createObjectURL(blob) : null))
.catch((e) => { .catch(() => {
// console.log(e);
return null; return null;
}); });
}, },

View File

@ -14,7 +14,7 @@ const WorkspaceThread = {
} }
) )
.then((res) => res.json()) .then((res) => res.json())
.catch((e) => { .catch(() => {
return { threads: [] }; return { threads: [] };
}); });

View File

@ -93,9 +93,9 @@ export default function HeaderMenu({
<div className="absolute top-full left-0 mt-1 w-full min-w-[200px] max-w-[350px] bg-theme-settings-input-bg border border-white/10 rounded-md shadow-lg z-50 animate-fadeUpIn"> <div className="absolute top-full left-0 mt-1 w-full min-w-[200px] max-w-[350px] bg-theme-settings-input-bg border border-white/10 rounded-md shadow-lg z-50 animate-fadeUpIn">
{availableFlows {availableFlows
.filter((flow) => flow.uuid !== flowId) .filter((flow) => flow.uuid !== flowId)
.map((flow) => ( .map((flow, index) => (
<button <button
key={flow?.uuid || Math.random()} key={flow?.uuid || `flow-${index}`}
onClick={() => { onClick={() => {
navigate(paths.agents.editAgent(flow.uuid)); navigate(paths.agents.editAgent(flow.uuid));
setShowDropdown(false); setShowDropdown(false);

View File

@ -48,9 +48,7 @@ export default function AgentBuilder() {
const [blocks, setBlocks] = useState(DEFAULT_BLOCKS); const [blocks, setBlocks] = useState(DEFAULT_BLOCKS);
const [selectedBlock, setSelectedBlock] = useState("start"); const [selectedBlock, setSelectedBlock] = useState("start");
const [showBlockMenu, setShowBlockMenu] = useState(false); const [showBlockMenu, setShowBlockMenu] = useState(false);
const [showLoadMenu, setShowLoadMenu] = useState(false);
const [availableFlows, setAvailableFlows] = useState([]); const [availableFlows, setAvailableFlows] = useState([]);
const [selectedFlowForDetails, setSelectedFlowForDetails] = useState(null);
const nameRef = useRef(null); const nameRef = useRef(null);
const descriptionRef = useRef(null); const descriptionRef = useRef(null);
const [showPublishModal, setShowPublishModal] = useState(false); const [showPublishModal, setShowPublishModal] = useState(false);
@ -122,7 +120,6 @@ export default function AgentBuilder() {
setActive(flow.config.active ?? true); setActive(flow.config.active ?? true);
setCurrentFlowUuid(flow.uuid); setCurrentFlowUuid(flow.uuid);
setBlocks(flowBlocks); setBlocks(flowBlocks);
setShowLoadMenu(false);
} catch (error) { } catch (error) {
console.error(error); console.error(error);
showToast("Failed to load flow", "error", { clear: true }); showToast("Failed to load flow", "error", { clear: true });

View File

@ -1,3 +1,4 @@
/* eslint-disable react-hooks/refs */
import React, { useRef, useState } from "react"; import React, { useRef, useState } from "react";
import { Plus, X, CaretDown } from "@phosphor-icons/react"; import { Plus, X, CaretDown } from "@phosphor-icons/react";

View File

@ -1,3 +1,4 @@
/* eslint-disable react-hooks/refs */
import React, { forwardRef } from "react"; import React, { forwardRef } from "react";
const FlowInfoNode = forwardRef(({ config, onConfigChange }, refs) => { const FlowInfoNode = forwardRef(({ config, onConfigChange }, refs) => {

View File

@ -14,6 +14,7 @@ export default function AgentFlowsList({
href="https://docs.anythingllm.com/agent-flows/getting-started" href="https://docs.anythingllm.com/agent-flows/getting-started"
target="_blank" target="_blank"
className="text-theme-text-secondary underline hover:text-cta-button" className="text-theme-text-secondary underline hover:text-cta-button"
rel="noreferrer"
> >
Learn more about Agent Flows. Learn more about Agent Flows.
</a> </a>

View File

@ -1,4 +1,4 @@
export function DefaultBadge({ title }) { export function DefaultBadge({ title: _title }) {
return ( return (
<> <>
<span <span

View File

@ -16,6 +16,7 @@ export default function ImportedSkillList({
href="https://docs.anythingllm.com/agent/custom/developer-guide" href="https://docs.anythingllm.com/agent/custom/developer-guide"
target="_blank" target="_blank"
className="text-theme-text-secondary underline hover:text-cta-button" className="text-theme-text-secondary underline hover:text-cta-button"
rel="noreferrer"
> >
AnythingLLM Agent Docs AnythingLLM Agent Docs
</a> </a>

View File

@ -10,7 +10,6 @@ import { Tooltip } from "react-tooltip";
export default function AgentSQLConnectorSelection({ export default function AgentSQLConnectorSelection({
skill, skill,
settings, // unused.
toggleSkill, toggleSkill,
enabled = false, enabled = false,
setHasChanges, setHasChanges,

View File

@ -62,6 +62,7 @@ export default function LiveSyncToggle({ enabled = false, onToggle }) {
href="https://docs.anythingllm.com/beta-preview/active-features/live-document-sync" href="https://docs.anythingllm.com/beta-preview/active-features/live-document-sync"
target="_blank" target="_blank"
className="text-sm text-blue-400 light:text-blue-500 hover:underline flex items-center gap-x-1" className="text-sm text-blue-400 light:text-blue-500 hover:underline flex items-center gap-x-1"
rel="noreferrer"
> >
<ArrowSquareOut size={14} /> <ArrowSquareOut size={14} />
<span>Feature Documentation and Warnings</span> <span>Feature Documentation and Warnings</span>

View File

@ -1,5 +1,4 @@
import LiveSyncToggle from "./Features/LiveSync/toggle"; import LiveSyncToggle from "./Features/LiveSync/toggle";
import paths from "@/utils/paths";
export const configurableFeatures = { export const configurableFeatures = {
experimental_live_file_sync: { experimental_live_file_sync: {

View File

@ -3,7 +3,7 @@ import Admin from "@/models/admin";
import paths from "@/utils/paths"; import paths from "@/utils/paths";
import { LinkSimple, Trash } from "@phosphor-icons/react"; import { LinkSimple, Trash } from "@phosphor-icons/react";
export default function WorkspaceRow({ workspace, users }) { export default function WorkspaceRow({ workspace, users: _users }) {
const rowRef = useRef(null); const rowRef = useRef(null);
const handleDelete = async () => { const handleDelete = async () => {
if ( if (

View File

@ -1,4 +1,4 @@
import React, { useEffect, useState, useRef } from "react"; import React, { useEffect, useState } from "react";
import { isMobile } from "react-device-detect"; import { isMobile } from "react-device-detect";
import Sidebar from "@/components/SettingsSidebar"; import Sidebar from "@/components/SettingsSidebar";
import System from "@/models/system"; import System from "@/models/system";

View File

@ -12,7 +12,7 @@ const md = new MarkdownIt({
if (lang && hljs.getLanguage(lang)) { if (lang && hljs.getLanguage(lang)) {
try { try {
return hljs.highlight(str, { language: lang }).value; return hljs.highlight(str, { language: lang }).value;
} catch (__) {} } catch {}
} }
return ""; // use external default escaping return ""; // use external default escaping
}, },

View File

@ -2,12 +2,10 @@ import { useState } from "react";
import Sidebar from "@/components/SettingsSidebar"; import Sidebar from "@/components/SettingsSidebar";
import { isMobile } from "react-device-detect"; import { isMobile } from "react-device-detect";
import { CaretLeft, CaretRight } from "@phosphor-icons/react"; import { CaretLeft, CaretRight } from "@phosphor-icons/react";
import { useTranslation } from "react-i18next";
import EmbedConfigsView from "./EmbedConfigs"; import EmbedConfigsView from "./EmbedConfigs";
import EmbedChatsView from "./EmbedChats"; import EmbedChatsView from "./EmbedChats";
export default function ChatEmbedWidgets() { export default function ChatEmbedWidgets() {
const { t } = useTranslation();
const [selectedView, setSelectedView] = useState("configs"); const [selectedView, setSelectedView] = useState("configs");
const [showViewModal, setShowViewModal] = useState(false); const [showViewModal, setShowViewModal] = useState(false);

View File

@ -12,7 +12,7 @@ const md = new MarkdownIt({
if (lang && hljs.getLanguage(lang)) { if (lang && hljs.getLanguage(lang)) {
try { try {
return hljs.highlight(str, { language: lang }).value; return hljs.highlight(str, { language: lang }).value;
} catch (__) {} } catch {}
} }
return ""; // use external default escaping return ""; // use external default escaping
}, },

View File

@ -17,8 +17,6 @@ export default function SlashCommand({ item, setStep }) {
} catch (e) { } catch (e) {
console.error(e); console.error(e);
showToast(`Failed to import slash command. ${e.message}`, "error"); showToast(`Failed to import slash command. ${e.message}`, "error");
} finally {
setLoading(false);
} }
} }

View File

@ -63,7 +63,7 @@ export default function EmbeddingTextSplitterPreference() {
setHasChanges(false); setHasChanges(false);
closeModal(); closeModal();
showToast("Text chunking strategy settings saved.", "success"); showToast("Text chunking strategy settings saved.", "success");
} catch (error) { } catch {
showToast("Failed to save text chunking strategy settings.", "error"); showToast("Failed to save text chunking strategy settings.", "error");
} finally { } finally {
setSaving(false); setSaving(false);

View File

@ -101,6 +101,7 @@ function TelemetryLogs({ settings }) {
href="https://github.com/search?q=repo%3AMintplex-Labs%2Fanything-llm%20.sendTelemetry(&type=code" href="https://github.com/search?q=repo%3AMintplex-Labs%2Fanything-llm%20.sendTelemetry(&type=code"
className="underline text-blue-400" className="underline text-blue-400"
target="_blank" target="_blank"
rel="noreferrer"
> >
GitHub here GitHub here
</a> </a>
@ -116,6 +117,7 @@ function TelemetryLogs({ settings }) {
href="mailto:team@mintplexlabs.com" href="mailto:team@mintplexlabs.com"
className="underline text-blue-400" className="underline text-blue-400"
target="_blank" target="_blank"
rel="noreferrer"
> >
team@mintplexlabs.com team@mintplexlabs.com
</a> </a>

View File

@ -38,7 +38,7 @@ const markdown = markdownIt({
hljs.highlight(code, { language: lang, ignoreIllegals: true }).value + hljs.highlight(code, { language: lang, ignoreIllegals: true }).value +
"</pre></div>" "</pre></div>"
); );
} catch (__) {} } catch {}
} }
return ( return (

View File

@ -33,7 +33,7 @@ function isValidDelim(state, pos) {
} }
function math_inline(state, silent) { function math_inline(state, silent) {
var start, match, token, res, pos, esc_count; var start, match, token, res, pos;
// Only process $ and \( delimiters for inline math // Only process $ and \( delimiters for inline math
if ( if (

View File

@ -13,7 +13,7 @@ export function formatDateTimeAsMoment(dateString, format = "LLL") {
if (!dateString) return moment().format(format); if (!dateString) return moment().format(format);
try { try {
return moment(dateString).format(format); return moment(dateString).format(format);
} catch (error) { } catch {
return moment().format(format); return moment().format(format);
} }
} }

View File

@ -2346,6 +2346,11 @@ eslint-plugin-react@^7.37.5:
string.prototype.matchall "^4.0.12" string.prototype.matchall "^4.0.12"
string.prototype.repeat "^1.0.0" string.prototype.repeat "^1.0.0"
eslint-plugin-unused-imports@^4.3.0:
version "4.3.0"
resolved "https://registry.yarnpkg.com/eslint-plugin-unused-imports/-/eslint-plugin-unused-imports-4.3.0.tgz#69ff9c4f83f02f7789808bbbab77636cb742af50"
integrity sha512-ZFBmXMGBYfHttdRtOG9nFFpmUvMtbHSjsKrS20vdWdbfiVYsO3yA2SGYy9i9XmZJDfMGBflZGBCm70SEnFQtOA==
eslint-scope@^8.4.0: eslint-scope@^8.4.0:
version "8.4.0" version "8.4.0"
resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-8.4.0.tgz#88e646a207fad61436ffa39eb505147200655c82" resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-8.4.0.tgz#88e646a207fad61436ffa39eb505147200655c82"