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's model service as a third-party provider
to generate an AI-assisted diagnosis.
- OpenAI's approved production-account data-region,
use, and retention terms apply
- separately from this application'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]