mirror of
https://github.com/OpenHands/OpenHands.git
synced 2025-12-25 21:36:52 +08:00
feat(frontend): add prefer-optional-chain ESLint rule and apply fixes (#12073)
Co-authored-by: openhands <openhands@all-hands.dev>
This commit is contained in:
parent
afce58a27d
commit
aff9d69d41
@ -18,6 +18,8 @@
|
||||
"i18next/no-literal-string": "error",
|
||||
"unused-imports/no-unused-imports": "error",
|
||||
"prettier/prettier": ["error"],
|
||||
// Enforce using optional chaining (?.) instead of && chains for null/undefined checks
|
||||
"@typescript-eslint/prefer-optional-chain": "error",
|
||||
// Resolves https://stackoverflow.com/questions/59265981/typescript-eslint-missing-file-extension-ts-import-extensions/59268871#59268871
|
||||
"import/extensions": [
|
||||
"error",
|
||||
|
||||
@ -12,10 +12,9 @@ export function BrowserPanel() {
|
||||
reset();
|
||||
}, [conversationId, reset]);
|
||||
|
||||
const imgSrc =
|
||||
screenshotSrc && screenshotSrc.startsWith("data:image/png;base64,")
|
||||
? screenshotSrc
|
||||
: `data:image/png;base64,${screenshotSrc || ""}`;
|
||||
const imgSrc = screenshotSrc?.startsWith("data:image/png;base64,")
|
||||
? screenshotSrc
|
||||
: `data:image/png;base64,${screenshotSrc ?? ""}`;
|
||||
|
||||
return (
|
||||
<div className="h-full w-full flex flex-col text-neutral-400">
|
||||
|
||||
@ -140,7 +140,7 @@ const getTaskTrackingObservationContent = (
|
||||
content += "\n\n**Task List:** Empty";
|
||||
}
|
||||
|
||||
if (event.content && event.content.trim()) {
|
||||
if (event.content?.trim()) {
|
||||
content += `\n\n**Result:** ${event.content.trim()}`;
|
||||
}
|
||||
|
||||
|
||||
@ -192,8 +192,7 @@ export const Messages: React.FC<MessagesProps> = React.memo(
|
||||
) => {
|
||||
const conversationInstructions = `Target file: ${target}\n\nDescription: ${query}\n\nTriggers: ${triggers.join(", ")}`;
|
||||
if (
|
||||
!conversation ||
|
||||
!conversation.selected_repository ||
|
||||
!conversation?.selected_repository ||
|
||||
!conversation.selected_branch ||
|
||||
!conversation.git_provider ||
|
||||
!selectedEventId
|
||||
|
||||
@ -75,7 +75,7 @@ export function GitProviderDropdown({
|
||||
}
|
||||
|
||||
// If no input value, show all providers
|
||||
if (!inputValue || !inputValue.trim()) {
|
||||
if (!inputValue?.trim()) {
|
||||
return providers;
|
||||
}
|
||||
|
||||
|
||||
@ -99,7 +99,7 @@ export function GitRepoDropdown({
|
||||
);
|
||||
|
||||
// If no input value, return all recent repos for this provider
|
||||
if (!inputValue || !inputValue.trim()) {
|
||||
if (!inputValue?.trim()) {
|
||||
return providerFilteredRepos;
|
||||
}
|
||||
|
||||
@ -139,7 +139,7 @@ export function GitRepoDropdown({
|
||||
baseRepositories = repositories;
|
||||
}
|
||||
// If no input value, show all repositories
|
||||
else if (!inputValue || !inputValue.trim()) {
|
||||
else if (!inputValue?.trim()) {
|
||||
baseRepositories = repositories;
|
||||
}
|
||||
// For URL inputs, use the processed search input for filtering
|
||||
@ -246,8 +246,7 @@ export function GitRepoDropdown({
|
||||
// Create sticky footer item for GitHub provider
|
||||
const stickyFooterItem = useMemo(() => {
|
||||
if (
|
||||
!config ||
|
||||
!config.APP_SLUG ||
|
||||
!config?.APP_SLUG ||
|
||||
provider !== ProviderOptions.github ||
|
||||
config.APP_MODE !== "saas"
|
||||
)
|
||||
|
||||
@ -45,7 +45,7 @@ export function DropdownItem<T>({
|
||||
// eslint-disable-next-line react/jsx-props-no-spreading
|
||||
<li key={getItemKey(item)} {...itemProps}>
|
||||
<div className="flex items-center gap-2">
|
||||
{renderIcon && renderIcon(item)}
|
||||
{renderIcon?.(item)}
|
||||
<span className="font-medium">{getDisplayText(item)}</span>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
@ -5,7 +5,7 @@ export const parseMessageFromEvent = (event: MessageEvent): string => {
|
||||
const message = event.llm_message;
|
||||
|
||||
// Safety check: ensure llm_message exists and has content
|
||||
if (!message || !message.content) {
|
||||
if (!message?.content) {
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
@ -34,7 +34,7 @@ export const SECRETS_HANDLERS = [
|
||||
|
||||
http.post("/api/secrets", async ({ request }) => {
|
||||
const body = (await request.json()) as CustomSecret;
|
||||
if (typeof body === "object" && body && body.name) {
|
||||
if (typeof body === "object" && body?.name) {
|
||||
secrets.set(body.name, body);
|
||||
return HttpResponse.json(true);
|
||||
}
|
||||
@ -48,7 +48,7 @@ export const SECRETS_HANDLERS = [
|
||||
|
||||
if (typeof id === "string" && typeof body === "object") {
|
||||
const secret = secrets.get(id);
|
||||
if (secret && body && body.name) {
|
||||
if (secret && body?.name) {
|
||||
const newSecret: CustomSecret = { ...secret, ...body };
|
||||
secrets.delete(id);
|
||||
secrets.set(body.name, newSecret);
|
||||
|
||||
@ -134,7 +134,7 @@ export const SETTINGS_HANDLERS = [
|
||||
const providerTokensSet: Partial<Record<Provider, string | null>> =
|
||||
Object.fromEntries(
|
||||
Object.entries(rawTokens)
|
||||
.filter(([, val]) => val && val.token)
|
||||
.filter(([, val]) => val?.token)
|
||||
.map(([provider]) => [provider as Provider, ""]),
|
||||
);
|
||||
|
||||
|
||||
@ -51,7 +51,7 @@ function VSCodeTab() {
|
||||
);
|
||||
}
|
||||
|
||||
if (error || (data && data.error) || !data?.url || iframeError) {
|
||||
if (error || data?.error || !data?.url || iframeError) {
|
||||
return (
|
||||
<div className="w-full h-full flex items-center text-center justify-center text-2xl text-tertiary-light">
|
||||
{iframeError ||
|
||||
|
||||
@ -16,7 +16,7 @@ import {
|
||||
* splitIsActuallyVersion(split) // returns true
|
||||
*/
|
||||
const splitIsActuallyVersion = (split: string[]) =>
|
||||
split[1] && split[1][0] && isNumber(split[1][0]);
|
||||
split[1]?.[0] && isNumber(split[1][0]);
|
||||
|
||||
/**
|
||||
* Given a model string, extract the provider and model name. Currently the supported separators are "/" and "."
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user