fix: use page scrolling for dragon tiger

This commit is contained in:
leefer
2026-08-02 14:08:48 +08:00
parent 104b267627
commit 9f691a47a0
6 changed files with 147 additions and 48 deletions
+2 -2
View File
@@ -314,8 +314,8 @@
},
{
"path": "frontend/styles/redesign-v2.css",
"bytes": 262826,
"lines": 8554
"bytes": 262113,
"lines": 8533
},
{
"path": "frontend/index.html",
-10
View File
@@ -771,7 +771,6 @@ tbody tr.clickable{cursor:pointer}
[data-active-view="auctionView"],
[data-active-view="themeLibraryView"],
[data-active-view="popularityView"],
[data-active-view="dragonView"],
[data-active-view="mentorView"],
[data-active-view="rotationView"]
) .app-main{
@@ -786,7 +785,6 @@ tbody tr.clickable{cursor:pointer}
[data-active-view="auctionView"],
[data-active-view="themeLibraryView"],
[data-active-view="popularityView"],
[data-active-view="dragonView"],
[data-active-view="mentorView"],
[data-active-view="rotationView"]
) .overview-strip{flex:0 0 auto}
@@ -795,7 +793,6 @@ tbody tr.clickable{cursor:pointer}
[data-active-view="auctionView"],
[data-active-view="themeLibraryView"],
[data-active-view="popularityView"],
[data-active-view="dragonView"],
[data-active-view="mentorView"],
[data-active-view="rotationView"]
) .workspace-view.active-view{
@@ -807,7 +804,6 @@ tbody tr.clickable{cursor:pointer}
#auctionView.active-view,
#themeLibraryView.active-view,
#popularityView.active-view,
#dragonView.active-view,
#mentorView.active-view{display:flex;flex-direction:column}
#rotationView.active-view{
@@ -827,7 +823,6 @@ tbody tr.clickable{cursor:pointer}
#themeLibraryView .theme-summary-v2,
#popularityView .popularity-page-head-v2,
#popularityView .popularity-glance-v2,
#dragonView .dragon-page-head-v2,
#mentorView .mentor-page-header,
#mentorView .member-gate,
#mentorView #mentorNotice{flex:0 0 auto}
@@ -835,7 +830,6 @@ tbody tr.clickable{cursor:pointer}
#auctionView .auction-workspace-v2,
#themeLibraryView .theme-library-workspace-v2,
#popularityView .popularity-table-card-v2,
#dragonView .dragon-daily-content-v2,
#mentorView .mentor-layout{min-height:0;flex:1 1 auto}
#auctionView .auction-workspace-v2{height:100%;grid-template-columns:minmax(0,1fr) var(--right-rail-wide);grid-template-rows:minmax(0,1fr);align-items:stretch;overflow:hidden}
@@ -853,10 +847,6 @@ tbody tr.clickable{cursor:pointer}
#popularityView .popularity-table-card-v2{display:flex;flex-direction:column;overflow:hidden}
#popularityView .popularity-table-frame-v2{min-height:0;flex:1 1 auto;overflow:auto}
#dragonView .dragon-daily-content-v2{overflow:hidden}
#dragonView .dragon-trader-detail-v2{min-height:0}
#dragonView .dragon-trader-detail .trader-operations{min-height:0;overflow:auto}
#mentorView .mentor-layout{height:auto;overflow:hidden}
#mentorView .mentor-sidebar,
#mentorView .mentor-chat-panel,
+10 -31
View File
@@ -4350,17 +4350,11 @@ body.sidebar-collapsed .status-bar { left: 64px; }
.dragon-empty-actions-v2 .lucide { width: 15px; height: 15px; }
@media (min-width: 721px) {
body[data-active-view="dragonView"] .app-main { display: flex; flex-direction: column; overflow: hidden; }
body[data-active-view="dragonView"] .overview-strip { flex: 0 0 auto; }
body[data-active-view="dragonView"] .app-main { height: var(--workspace-height); min-height: 0; display: block; overflow: auto; }
body[data-active-view="dragonView"] #dragonView.active-view {
min-height: 0;
flex: 1 1 auto;
display: flex;
flex-direction: column;
display: block;
overflow: visible;
}
body[data-active-view="dragonView"] .dragon-page-head-v2 { flex: 0 0 auto; }
body[data-active-view="dragonView"] .dragon-daily-content-v2,
body[data-active-view="dragonView"] .dragon-empty-state-v2 { flex: 1 1 auto; }
}
@media (min-width: 721px) and (max-height: 900px) {
@@ -8372,40 +8366,25 @@ body.sidebar-collapsed .status-bar { left: 64px; }
white-space: nowrap;
}
/* The Dragon-Tiger page stays still; only the selected trader's operations scroll. */
/* The Dragon-Tiger page owns vertical scrolling; wide operation tables scroll horizontally. */
@media (min-width: 721px) {
body[data-active-view="dragonView"] .dragon-daily-content-v2 {
min-height: 0;
display: grid;
grid-template-rows: auto auto auto minmax(150px, 1fr) auto;
overflow: hidden;
}
body[data-active-view="dragonView"] #dragonView .dragon-card-stage-v2 {
flex: 0 0 auto;
display: block;
overflow: visible;
}
body[data-active-view="dragonView"] #dragonView .dragon-trader-detail-v2 {
min-height: 0;
display: flex;
flex-direction: column;
}
body[data-active-view="dragonView"] #dragonView .dragon-detail-header {
flex: 0 0 auto;
display: block;
}
body[data-active-view="dragonView"] #dragonView .dragon-trader-detail .trader-operations {
min-height: 0;
flex: 1 1 auto;
max-height: none;
overflow: auto;
overscroll-behavior: contain;
scrollbar-gutter: stable;
}
body[data-active-view="dragonView"] #dragonView .dragon-unclassified-v2 {
max-height: 180px;
overflow: auto;
max-height: none;
overflow: visible;
}
:is(
+9 -3
View File
@@ -1400,25 +1400,31 @@ test("dragon-tiger redesign keeps the merged empty state and independent card hi
await expect(page.locator("#stockDialog")).toBeVisible();
await page.locator("#closeStockDialog").click();
await page.setViewportSize({ width: 1366, height: 768 });
const scrollOwnership = await page.evaluate(() => {
const body = document.querySelector("#dragonTraderDetail tbody");
const seed = body.querySelector("tr");
for (let index = 0; index < 20; index += 1) body.appendChild(seed.cloneNode(true));
const main = document.querySelector(".app-main");
const daily = document.querySelector("#dragonDailyContent");
const operations = document.querySelector("#dragonTraderDetail .trader-operations");
return {
mainOverflow: getComputedStyle(main).overflowY,
pageScrolls: main.scrollHeight > main.clientHeight,
dailyOverflow: getComputedStyle(daily).overflowY,
dailyFits: daily.scrollHeight <= daily.clientHeight + 1,
operationOverflow: getComputedStyle(operations).overflowY,
operationsScroll: operations.scrollHeight > operations.clientHeight,
operationsFit: operations.scrollHeight <= operations.clientHeight + 1,
descriptionSize: parseFloat(getComputedStyle(document.querySelector("#dragonTraderDetail .dragon-detail-header p")).fontSize),
};
});
expect(scrollOwnership).toEqual({
dailyOverflow: "hidden",
mainOverflow: "auto",
pageScrolls: true,
dailyOverflow: "visible",
dailyFits: true,
operationOverflow: "auto",
operationsScroll: true,
operationsFit: true,
descriptionSize: 13,
});
+111 -2
View File
@@ -151,6 +151,106 @@ AUDITED_CSS_RETIREMENTS = {
),
}
# User-approved product behavior changes remain separate from code-retirement
# records. Each entry is an exact source/replacement pair. Optional trailing
# values declare the expected source count and how many leading occurrences to
# transform when one identical occurrence must remain.
AUDITED_CSS_REPLACEMENTS = {
"redesign-v2.css": (
(
(
'@media (min-width: 721px) {\n'
' body[data-active-view="dragonView"] .app-main { display: flex; flex-direction: column; overflow: hidden; }\n'
' body[data-active-view="dragonView"] .overview-strip { flex: 0 0 auto; }\n'
' body[data-active-view="dragonView"] #dragonView.active-view {\n'
' min-height: 0;\n'
' flex: 1 1 auto;\n'
' display: flex;\n'
' flex-direction: column;\n'
' }\n'
' body[data-active-view="dragonView"] .dragon-page-head-v2 { flex: 0 0 auto; }\n'
' body[data-active-view="dragonView"] .dragon-daily-content-v2,\n'
' body[data-active-view="dragonView"] .dragon-empty-state-v2 { flex: 1 1 auto; }\n'
'}\n'
),
(
'@media (min-width: 721px) {\n'
' body[data-active-view="dragonView"] .app-main { height: var(--workspace-height); min-height: 0; display: block; overflow: auto; }\n'
' body[data-active-view="dragonView"] #dragonView.active-view {\n'
' display: block;\n'
' overflow: visible;\n'
' }\n'
'}\n'
),
),
(
(
"/* The Dragon-Tiger page stays still; only the selected trader's operations scroll. */\n"
'@media (min-width: 721px) {\n'
' body[data-active-view="dragonView"] .dragon-daily-content-v2 {\n'
' min-height: 0;\n'
' display: grid;\n'
' grid-template-rows: auto auto auto minmax(150px, 1fr) auto;\n'
' overflow: hidden;\n'
' }\n\n'
' body[data-active-view="dragonView"] #dragonView .dragon-card-stage-v2 {\n'
' flex: 0 0 auto;\n'
' }\n\n'
' body[data-active-view="dragonView"] #dragonView .dragon-trader-detail-v2 {\n'
' min-height: 0;\n'
' display: flex;\n'
' flex-direction: column;\n'
' }\n\n'
' body[data-active-view="dragonView"] #dragonView .dragon-detail-header {\n'
' flex: 0 0 auto;\n'
' }\n\n'
' body[data-active-view="dragonView"] #dragonView .dragon-trader-detail .trader-operations {\n'
' min-height: 0;\n'
' flex: 1 1 auto;\n'
' overflow: auto;\n'
' overscroll-behavior: contain;\n'
' scrollbar-gutter: stable;\n'
' }\n\n'
' body[data-active-view="dragonView"] #dragonView .dragon-unclassified-v2 {\n'
' max-height: 180px;\n'
' overflow: auto;\n'
' }\n'
),
(
'/* The Dragon-Tiger page owns vertical scrolling; wide operation tables scroll horizontally. */\n'
'@media (min-width: 721px) {\n'
' body[data-active-view="dragonView"] .dragon-daily-content-v2 {\n'
' display: block;\n'
' overflow: visible;\n'
' }\n\n'
' body[data-active-view="dragonView"] #dragonView .dragon-trader-detail-v2 {\n'
' display: block;\n'
' }\n\n'
' body[data-active-view="dragonView"] #dragonView .dragon-trader-detail .trader-operations {\n'
' max-height: none;\n'
' overflow: auto;\n'
' }\n\n'
' body[data-active-view="dragonView"] #dragonView .dragon-unclassified-v2 {\n'
' max-height: none;\n'
' overflow: visible;\n'
' }\n'
),
),
),
"design-system.css": (
(' [data-active-view="dragonView"],\n', "", 4, 3),
(' #dragonView.active-view,\n', ""),
(' #dragonView .dragon-page-head-v2,\n', ""),
(' #dragonView .dragon-daily-content-v2,\n', ""),
(
' #dragonView .dragon-daily-content-v2{overflow:hidden}\n'
' #dragonView .dragon-trader-detail-v2{min-height:0}\n'
' #dragonView .dragon-trader-detail .trader-operations{min-height:0;overflow:auto}\n\n',
"",
),
),
}
def sha256(path: Path) -> str:
return hashlib.sha256(path.read_bytes()).hexdigest()
@@ -245,12 +345,21 @@ def assert_moved_asset_matches(
frontend_relative: str | None = None,
) -> None:
target_relative = frontend_relative or original_relative
if original_relative in AUDITED_CSS_RETIREMENTS:
if (
original_relative in AUDITED_CSS_RETIREMENTS
or original_relative in AUDITED_CSS_REPLACEMENTS
):
original = (ORIGINAL_STATIC / original_relative).read_text(encoding="utf-8")
for retired in AUDITED_CSS_RETIREMENTS[original_relative]:
for retired in AUDITED_CSS_RETIREMENTS.get(original_relative, ()):
source, replacement = retired if isinstance(retired, tuple) else (retired, "")
testcase.assertEqual(original.count(source), 1, source)
original = original.replace(source, replacement, 1)
for replacement in AUDITED_CSS_REPLACEMENTS.get(original_relative, ()):
source, target, *count_override = replacement
expected_count = count_override[0] if count_override else 1
replacement_count = count_override[1] if len(count_override) > 1 else expected_count
testcase.assertEqual(original.count(source), expected_count, source)
original = original.replace(source, target, replacement_count)
testcase.assertEqual(
(FRONTEND_ROOT / target_relative).read_text(encoding="utf-8"),
original,