This is an automated email from the ASF dual-hosted git repository.

morningman pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris-website.git


The following commit(s) were added to refs/heads/master by this push:
     new 21e7d88d27f [fix] Refine homepage navbar and profile analysis notice 
(#4027)
21e7d88d27f is described below

commit 21e7d88d27f8949ad6c44cb02a2dbcc3896879ac
Author: Mingyu Chen (Rayner) <[email protected]>
AuthorDate: Fri Jul 31 20:37:08 2026 +0800

    [fix] Refine homepage navbar and profile analysis notice (#4027)
    
    ## Summary
    
    - refine homepage navbar action styling and keep desktop actions on a
    single row down to the mobile breakpoint
    - clarify that profile analysis is provided by VeloDB and third-party
    model providers
    - move the privacy notice below the Analyze Profile button
    - render the notice as an accessible warning callout with theme-aware
    colors
    - update the consent wording and component coverage
    
    ## Validation
    
    - `node --test src/components/profile-analysis/*.test.js` (42 tests
    passed)
    - `git diff --check`
    
    ## Versions
    
    - [x] dev
    - [ ] 4.x
    - [ ] 3.x
    - [ ] 2.1 or older (not covered by version/language sync gate)
    
    ## Languages
    
    - [ ] Chinese
    - [x] English
    - [ ] Japanese candidate translation needed
    
    ## Docs Checklist
    
    - [x] Checked by AI
    - [x] Test Cases Built
    - [x] Updated required version and language counterparts, or explained
    why not
    - [x] If only one language changed, confirmed whether source/translation
    counterparts need sync
    
    These are standalone website UI changes, so versioned and localized
    documentation counterparts are not applicable.
    
    ---------
    
    Co-authored-by: morningman <[email protected]>
---
 src/components/home-next/NavbarNext.scss           | 75 +++++---------------
 .../profile-analysis/ProfileAnalysis.scss          | 36 ++++++++--
 .../profile-analysis/ProfileUploader.tsx           | 80 +++++++++++-----------
 .../profile-analysis.components.test.js            | 13 ++--
 4 files changed, 97 insertions(+), 107 deletions(-)

diff --git a/src/components/home-next/NavbarNext.scss 
b/src/components/home-next/NavbarNext.scss
index 5095deda00d..5abe8000eb6 100644
--- a/src/components/home-next/NavbarNext.scss
+++ b/src/components/home-next/NavbarNext.scss
@@ -242,20 +242,27 @@
         box-sizing: border-box;
         height: 32px;
         padding: 0 12px;
-        border: 1px solid rgb(var(--brand-primary-rgb) / 55%);
+        border: 1px solid rgba(245, 239, 228, 0.22);
         border-radius: 4px;
-        background: rgb(var(--brand-primary-rgb) / 18%);
+        background: transparent;
         color: var(--nb-cream-light);
         cursor: pointer;
         @include type.mono-text(12px, 600, 1.2, 0.02em);
         transition: border-color 0.15s, background 0.15s, transform 0.15s;
         white-space: nowrap;
 
-        svg { flex-shrink: 0; }
+        svg {
+            flex-shrink: 0;
+            color: var(--nb-yellow);
+
+            path {
+                fill: currentColor;
+            }
+        }
 
         &:hover {
-            border-color: rgb(var(--brand-primary-rgb) / 85%);
-            background: rgb(var(--brand-primary-rgb) / 28%);
+            border-color: rgba(245, 239, 228, 0.45);
+            background: rgba(245, 239, 228, 0.06);
             transform: translateY(-1px);
         }
 
@@ -275,10 +282,10 @@
         height: 32px;
         overflow: hidden;
         padding: 0 14px;
-        border: 1px solid rgb(var(--brand-primary-rgb) / 55%);
+        border: 1px solid var(--nb-yellow);
         border-radius: 4px;
-        background: rgb(var(--brand-primary-rgb) / 18%);
-        color: var(--nb-cream-light) !important;
+        background: var(--nb-yellow);
+        color: var(--nb-ink) !important;
         text-decoration: none !important;
         white-space: nowrap;
         @include type.mono-text(12px, 700, 1.2, 0.02em);
@@ -306,9 +313,9 @@
         }
 
         &:hover {
-            border-color: rgb(var(--brand-primary-rgb) / 85%);
-            background: rgb(var(--brand-primary-rgb) / 28%);
-            color: var(--nb-cream-light) !important;
+            border-color: var(--brand-accent-bright);
+            background: var(--brand-accent-bright);
+            color: var(--nb-ink) !important;
             text-decoration: none !important;
             transform: translateY(-1px);
         }
@@ -489,7 +496,7 @@
 
 // Keep every primary and utility action visible on one row across common
 // desktop widths. Type and spacing scale down only to a readable minimum.
-@media (min-width: 1281px) and (max-width: 1679px) {
+@media (min-width: 1181px) and (max-width: 1679px) {
     .navbar-next {
         &__inner {
             max-width: none;
@@ -537,50 +544,6 @@
     }
 }
 
-// Below the minimum comfortable single-row width, preserve the larger menu
-// type and move the complete utility action group onto a dedicated second row.
-@media (min-width: 1181px) and (max-width: 1280px) {
-    .navbar-next {
-        &.navbar {
-            height: 108px;
-            min-height: 108px;
-        }
-
-        &__inner {
-            display: grid;
-            grid-template-columns: auto minmax(0, 1fr);
-            grid-template-rows: 64px 44px;
-            column-gap: 28px;
-            row-gap: 0;
-            height: 108px;
-            padding: 0 32px;
-        }
-
-        &__nav {
-            min-width: 0;
-            gap: 8px;
-        }
-
-        &__actions {
-            grid-column: 1 / -1;
-            width: 100%;
-            height: 44px;
-            justify-content: flex-end;
-            gap: 12px;
-            margin-left: 0;
-            border-top: 1px solid rgba(245, 239, 228, 0.08);
-        }
-
-        &__trigger {
-            padding: 0.5rem 0.65rem;
-        }
-
-        &__dropdown {
-            z-index: 2;
-        }
-    }
-}
-
 @media (max-width: 1180px) {
     .navbar-next {
         &__inner {
diff --git a/src/components/profile-analysis/ProfileAnalysis.scss 
b/src/components/profile-analysis/ProfileAnalysis.scss
index d27d485a9e9..66604e2a1fc 100644
--- a/src/components/profile-analysis/ProfileAnalysis.scss
+++ b/src/components/profile-analysis/ProfileAnalysis.scss
@@ -53,20 +53,44 @@
     }
 
     &__privacy-notice {
-        margin-bottom: 1.25rem;
+        margin-top: 1.25rem;
         padding: 1rem;
-        border: 1px solid var(--brand-border-soft);
+        border: 1px solid var(--ifm-color-warning);
+        border-left-width: 4px;
         border-radius: 8px;
-        background: var(--brand-surface-soft);
+        color: var(--ifm-color-warning-contrast-foreground);
+        background: var(--ifm-color-warning-contrast-background);
+
+        &-title {
+            display: flex;
+            gap: 0.65rem;
+            align-items: center;
+            margin-bottom: 0.75rem;
+        }
+
+        &-icon {
+            display: inline-flex;
+            align-items: center;
+            justify-content: center;
+            width: 1.4rem;
+            height: 1.4rem;
+            flex: 0 0 1.4rem;
+            border-radius: 50%;
+            color: var(--ifm-color-warning-contrast-background);
+            background: var(--ifm-color-warning-contrast-foreground);
+            font-size: 0.95rem;
+            font-weight: 800;
+            line-height: 1;
+        }
 
         h3 {
-            margin-bottom: 0.5rem;
+            margin: 0;
             font-size: 1rem;
+            font-weight: 700;
         }
 
-        ul {
+        p {
             margin-bottom: 0.75rem;
-            padding-left: 1.25rem;
         }
     }
 
diff --git a/src/components/profile-analysis/ProfileUploader.tsx 
b/src/components/profile-analysis/ProfileUploader.tsx
index e852b3d8a34..eef4cf89e87 100644
--- a/src/components/profile-analysis/ProfileUploader.tsx
+++ b/src/components/profile-analysis/ProfileUploader.tsx
@@ -92,46 +92,6 @@ export function ProfileUploader({
                 Choose one UTF-8 .txt file up to 10 MiB after reviewing and 
accepting the notice below.
             </p>
 
-            <div className="profile-analysis__privacy-notice" 
id="profile-analysis-privacy-notice">
-                <h3>Privacy and AI processing notice</h3>
-                <ul>
-                    <li>
-                        Your Query Profile and the fixed analysis instructions 
are sent to this service and
-                        OpenAI&apos;s model service as a third-party provider 
to generate an AI-assisted diagnosis.
-                        OpenAI&apos;s approved production-account data-region, 
use, and retention terms apply
-                        separately from this application&apos;s deletion 
policy.
-                    </li>
-                    <li>
-                        Do not upload passwords, API keys, access tokens, 
personal data, customer-confidential
-                        data, regulated data, or any content you are not 
authorized to disclose.
-                        Profiles can contain SQL literals, usernames, Query 
IDs, IP addresses, hostnames, schema
-                        names, and cluster topology; redact these values 
before uploading.
-                    </li>
-                    <li>
-                        On the application server, the normal-path workspace 
is deleted immediately after the
-                        analysis succeeds or fails. Abnormal residual 
workspaces are deleted within 1 hour.
-                    </li>
-                </ul>
-                <label className="profile-analysis__consent">
-                    <input
-                        type="checkbox"
-                        checked={consentAccepted}
-                        disabled={disabled}
-                        aria-describedby="profile-analysis-privacy-notice"
-                        onChange={event => {
-                            const accepted = event.currentTarget.checked;
-                            setConsentAccepted(accepted);
-                            if (!accepted) {
-                                resetCaptcha();
-                                onFileChange(null);
-                            }
-                        }}
-                    />
-                    I have read this notice, am authorized to upload the 
Profile, and consent to the described
-                    third-party AI processing.
-                </label>
-            </div>
-
             <fieldset className="profile-analysis__language" 
disabled={disabled}>
                 <legend>Response language</legend>
                 <label>
@@ -263,6 +223,46 @@ export function ProfileUploader({
             >
                 {disabled ? 'Processing…' : 'Analyze Profile'}
             </button>
+
+            <div
+                className="profile-analysis__privacy-notice"
+                id="profile-analysis-privacy-notice"
+                role="note"
+            >
+                <div className="profile-analysis__privacy-notice-title">
+                    <span className="profile-analysis__privacy-notice-icon" 
aria-hidden="true">
+                        !
+                    </span>
+                    <h3>Privacy and AI processing notice</h3>
+                </div>
+                <p>
+                    This feature is provided by VeloDB and third-party large 
language model service providers.
+                    It is not an official Apache Doris project feature, so 
please use it at your discretion.
+                </p>
+                <p>
+                    Do not upload passwords, keys, access tokens, personal 
information, customer-confidential
+                    data, or any other sensitive content that you are not 
authorized to disclose. All uploaded
+                    information will be automatically and permanently deleted 
within one hour.
+                </p>
+                <label className="profile-analysis__consent">
+                    <input
+                        type="checkbox"
+                        checked={consentAccepted}
+                        disabled={disabled}
+                        aria-describedby="profile-analysis-privacy-notice"
+                        onChange={event => {
+                            const accepted = event.currentTarget.checked;
+                            setConsentAccepted(accepted);
+                            if (!accepted) {
+                                resetCaptcha();
+                                onFileChange(null);
+                            }
+                        }}
+                    />
+                    I have read the notice, am authorized to upload this 
profile, and consent to third-party AI
+                    processing.
+                </label>
+            </div>
         </section>
     );
 }
diff --git 
a/src/components/profile-analysis/profile-analysis.components.test.js 
b/src/components/profile-analysis/profile-analysis.components.test.js
index a6c0e1e3ee2..9e38a6d9438 100644
--- a/src/components/profile-analysis/profile-analysis.components.test.js
+++ b/src/components/profile-analysis/profile-analysis.components.test.js
@@ -82,7 +82,7 @@ test('disables Analyze until a file exists and while analysis 
is running', () =>
     assert.match(analyzing, 
/<button[^>]*disabled=""[^>]*>Processing…<\/button>/);
 });
 
-test('requires an unchecked privacy consent and displays third-party, 
prohibited-content, and deletion notices', () => {
+test('places an unchecked privacy consent after Analyze and displays provider, 
prohibited-content, and deletion notices', () => {
     const markup = renderToStaticMarkup(
         React.createElement(ProfileUploader, {
             file: null,
@@ -97,10 +97,13 @@ test('requires an unchecked privacy consent and displays 
third-party, prohibited
 
     assert.match(markup, /type="checkbox"/);
     assert.doesNotMatch(markup, /type="checkbox"[^>]*checked/);
-    assert.match(markup, /OpenAI.*third-party provider/);
-    assert.match(markup, /Do not upload passwords, API keys, access tokens, 
personal data/);
-    assert.match(markup, /deleted immediately/);
-    assert.match(markup, /deleted within 1 hour/);
+    assert.match(markup, /provided by VeloDB and third-party large language 
model service providers/);
+    assert.match(markup, /not an official Apache Doris project feature/);
+    assert.match(markup, /Do not upload passwords, keys, access tokens, 
personal information/);
+    assert.match(markup, /automatically and permanently deleted within one 
hour/);
+    assert.ok(markup.indexOf('Analyze Profile') < markup.indexOf('Privacy and 
AI processing notice'));
+    assert.match(markup, /role="note"/);
+    assert.match(markup, /profile-analysis__privacy-notice-icon" 
aria-hidden="true">!</);
     assert.match(markup, /type="file"[^>]*disabled=""/);
 });
 


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to