Skip to content

chore: 添加了登陆后页面标题自定义配置项#1720

Merged
looplj merged 4 commits into
looplj:unstablefrom
sxueck:unstable
May 28, 2026
Merged

chore: 添加了登陆后页面标题自定义配置项#1720
looplj merged 4 commits into
looplj:unstablefrom
sxueck:unstable

Conversation

@sxueck

@sxueck sxueck commented May 26, 2026

Copy link
Copy Markdown
Contributor

本次 PR 共处理了以下两个问题:

  1. /sign-up 路由当前即使已经处于登陆状态,二次访问的时候依旧要求登陆,现在处于登陆态会自动跳转概览页
  2. 在设置初添加了登陆态下页面 Title 的自定义配置,解耦了硬编码 'Axonhub' 代码

参考效果

image

@greptile-apps

greptile-apps Bot commented May 26, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds a configurable browser page title setting for authenticated users and fixes the sign-in page so logged-in users are redirected away automatically.

  • Page title customization: Adds a title field to BrandSettings across the GraphQL schema, Go biz layer, and frontend; a new DocumentTitleSync component reads the setting after login and applies it via document.title, falling back to 'AxonHub' when unset.
  • Auth redirect on sign-in: Adds a beforeLoad guard to sign-in.tsx that redirects already-authenticated users to /; the same guard is missing from sign-up.tsx, which the PR description identifies as the route that needed fixing.
  • Type mismatch on clear: brand-settings.tsx passes null for an empty title, but UpdateBrandSettingsInput.title is typed string | undefined; with strict: true in tsconfig this is a compile-time type error.

Confidence Score: 4/5

Safe to merge after fixing the missing sign-up redirect and the TypeScript null type mismatch.

Two concrete defects exist in the changed code: the beforeLoad redirect guard was added to sign-in.tsx but the PR description says /sign-up was the broken route, leaving logged-in users able to reach the registration page; and brand-settings.tsx passes null for an empty title where the TypeScript interface only allows string | undefined, which fails under strict: true. The backend and GraphQL changes are straightforward and low-risk.

frontend/src/routes/(auth)/sign-up.tsx (missing beforeLoad guard) and frontend/src/features/system/data/system.ts (UpdateBrandSettingsInput.title type)

Important Files Changed

Filename Overview
frontend/src/routes/(auth)/sign-up.tsx No changes made; the PR description says the sign-up redirect was the bug being fixed, but the beforeLoad guard was not added here.
frontend/src/features/system/data/system.ts Adds title field to BrandSettings and UpdateBrandSettingsInput; the latter types title as string
frontend/src/features/system/components/brand-settings.tsx Adds title input field to brand settings UI; sends null (not undefined) for empty title to enable clearing, but the TypeScript type for the mutation input doesn't include null.
frontend/src/routes/__root.tsx Adds DocumentTitleSync component that reads brand title from the API when authenticated and updates document.title, falling back to 'AxonHub'.
frontend/src/routes/(auth)/sign-in.tsx Adds beforeLoad guard to redirect already-authenticated users away from the sign-in page; correct implementation.
internal/server/biz/system.go Adds Title() and SetTitle() following the same pattern as BrandName/BrandLogo; consistent with existing code.
internal/server/gql/system.resolvers.go Wires Title into BrandSettings query and UpdateBrandSettings mutation with standard nil-guard pattern.
internal/server/gql/system.graphql Adds nullable title field to BrandSettings type and UpdateBrandSettingsInput; straightforward schema extension.

Sequence Diagram

sequenceDiagram
    participant Browser
    participant Router as TanStack Router
    participant RootLayout as Root Layout
    participant GQL as GraphQL API

    Browser->>Router: Visit sign-in page
    Router->>Router: beforeLoad check
    alt Logged in
        Router-->>Browser: Redirect to home
    else Not logged in
        Router-->>Browser: Render sign-in form
    end

    Browser->>Router: Login succeeds
    Router->>RootLayout: Mount DocumentTitleSync
    RootLayout->>GQL: Query brandSettings title
    GQL-->>RootLayout: Return title value
    RootLayout->>Browser: Set document.title

    Browser->>GQL: Update brand title setting
    GQL-->>Browser: Confirm success
    Browser->>GQL: Re-fetch brandSettings
    GQL-->>Browser: New title value
    Browser->>Browser: Update document.title
Loading

Reviews (2): Last reviewed commit: "Update frontend/src/features/system/comp..." | Re-trigger Greptile

Comment thread frontend/src/features/system/components/brand-settings.tsx Outdated
Comment on lines 36 to +44
}
}

if input.Title != nil {
err := r.systemService.SetTitle(ctx, *input.Title)
if err != nil {
return false, fmt.Errorf("failed to update title setting: %w", err)
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Title cannot be cleared once set

This follows the same nil = "not provided" pattern as brandName, but there is no path for the user to reset the title to the default. On the frontend, the empty-string case maps to undefined which is omitted from the request, leaving input.Title as nil here and bypassing SetTitle entirely. To support clearing, the frontend should send "" (not undefined) when the field is emptied, and the resolver should call SetTitle(ctx, "") for a non-nil empty pointer — which the DB layer already handles correctly because an empty value returns "" and the frontend falls back to 'AxonHub'.

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Comment on lines 266 to 270
export interface UpdateBrandSettingsInput {
brandName?: string;
brandLogo?: string;
title?: string;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 null not allowed by UpdateBrandSettingsInput.title in strict mode

brand-settings.tsx passes null when the title field is emptied, but title in this interface is typed as string | undefined. With "strict": true enabled in tsconfig.app.json, null is not assignable to string | undefined and will produce a TypeScript compilation error. The interface needs to explicitly allow null to reflect what the frontend sends and what the GraphQL schema accepts.

Suggested change
export interface UpdateBrandSettingsInput {
brandName?: string;
brandLogo?: string;
title?: string;
}
export interface UpdateBrandSettingsInput {
brandName?: string;
brandLogo?: string;
title?: string | null;
}

@looplj looplj merged commit 090b779 into looplj:unstable May 28, 2026
4 checks passed
ldm0206 added a commit to ldm2060/axonhub that referenced this pull request May 29, 2026
…ge title config, request filter preservation, structured response items

Upstream commits merged:
- fix: model settings dialog overflow (looplj#1716)
- chore: custom page title config after login (looplj#1720)
- feat: preserve request log filters on detail navigation (looplj#1723)
- feat(llm): support responses websocket sessions (looplj#1730)
- chore: add claude-opus-4-7 to claudecode DefaultModels (looplj#1733)
- fix(channels): show real i18n label for single-variant types (looplj#1734)
- fix(llm): accept structured response item arguments (looplj#1728)

Resolved 4 import-path conflicts (looplj -> ldm2060) and adapted
session scope integration in auth middleware. Fixed Windows flaky
WebSocket test for platform-specific socket error messages.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
junjiangao pushed a commit to junjiangao/axonhub that referenced this pull request May 30, 2026
* fix: 修复了多图输入情况下转发失效的问题

* chore: 添加了登陆后页面标题自定义配置项

* Update frontend/src/features/system/components/brand-settings.tsx

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants