From babfb3dc7f97cae015981355b7b5a180eda7b303 Mon Sep 17 00:00:00 2001
From: ahyang <53590964+zAhYAng@users.noreply.github.com>
Date: Sun, 9 Aug 2026 08:58:21 +0800
Subject: [PATCH] =?UTF-8?q?fix(assets):=20=E7=B4=A0=E6=9D=90=E5=BA=93=20-?=
=?UTF-8?q?=20=E4=BF=AE=E5=A4=8D=E4=B8=BB=E9=A2=98=E6=8C=89=E9=92=AE?=
=?UTF-8?q?=E5=B9=B6=E6=96=B0=E5=A2=9E=E6=89=B9=E9=87=8F=E5=85=A8=E9=80=89?=
=?UTF-8?q?=20(#193)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
web/src/pages/assets/index.tsx | 5 ++++-
web/src/styles/globals.css | 10 ++++++----
web/test/asset-header-button-style.test.ts | 17 +++++++++++++++++
web/test/assets-page-batch-toolbar.test.ts | 15 +++++++++++++++
4 files changed, 42 insertions(+), 5 deletions(-)
create mode 100644 web/test/asset-header-button-style.test.ts
create mode 100644 web/test/assets-page-batch-toolbar.test.ts
diff --git a/web/src/pages/assets/index.tsx b/web/src/pages/assets/index.tsx
index 5835b1092..1d8526400 100644
--- a/web/src/pages/assets/index.tsx
+++ b/web/src/pages/assets/index.tsx
@@ -1,4 +1,4 @@
-import { Copy, Download, FileUp, MoreHorizontal, PencilLine, Plus, Search, Trash2, Upload } from "lucide-react";
+import { CheckCheck, Copy, Download, FileUp, MoreHorizontal, PencilLine, Plus, Search, Trash2, Upload } from "lucide-react";
import { useEffect, useMemo, useRef, useState } from "react";
import { App, Button, Drawer, Dropdown, Form, Input, Modal, Select, Space, Tag, Typography } from "antd";
@@ -95,6 +95,8 @@ export default function AssetsPage() {
return assetSearchText(asset).includes(query);
});
}, [validAssets, keyword, kindFilter, categoryFilter]);
+ const filteredAssetIds = useMemo(() => filteredAssets.map((asset) => asset.id), [filteredAssets]);
+ const allFilteredSelected = filteredAssetIds.length > 0 && filteredAssetIds.every((id) => selectedIds.includes(id));
const visibleAssets = useMemo(() => {
const start = (page - 1) * pageSize;
@@ -283,6 +285,7 @@ export default function AssetsPage() {
{selectedAssets.length ? (
已选择 {selectedAssets.length} 个素材
+ } disabled={allFilteredSelected} onClick={() => setSelectedIds((current) => Array.from(new Set([...current, ...filteredAssetIds])))}>全选
} onClick={() => void exportSelectedAssets()}>导出
} onClick={() => setBatchDeleteOpen(true)}>删除
diff --git a/web/src/styles/globals.css b/web/src/styles/globals.css
index 67c18eccd..5ea8093d9 100644
--- a/web/src/styles/globals.css
+++ b/web/src/styles/globals.css
@@ -3419,17 +3419,19 @@
.library-page .app-page-header p { max-width: 560px; }
/* 页面头部按钮优化 - 去除重边框 */
- .library-page .app-page-header .ant-btn,
- .canvas-library-page .app-page-header .ant-btn {
+ html:not(.dark) .library-page .app-page-header .ant-btn,
+ html:not(.dark) .canvas-library-page .app-page-header .ant-btn {
border: 1px solid rgba(17, 17, 17, 0.08) !important;
background: #ffffff !important;
+ color: #171717 !important;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04) !important;
transition: all 180ms ease-out !important;
}
- .library-page .app-page-header .ant-btn:hover,
- .canvas-library-page .app-page-header .ant-btn:hover {
+ html:not(.dark) .library-page .app-page-header .ant-btn:hover,
+ html:not(.dark) .canvas-library-page .app-page-header .ant-btn:hover {
border-color: rgba(17, 17, 17, 0.12) !important;
background: #ffffff !important;
+ color: #171717 !important;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.08) !important;
transform: translateY(-1px);
}
diff --git a/web/test/asset-header-button-style.test.ts b/web/test/asset-header-button-style.test.ts
new file mode 100644
index 000000000..0b9ad39e9
--- /dev/null
+++ b/web/test/asset-header-button-style.test.ts
@@ -0,0 +1,17 @@
+import { describe, expect, test } from "bun:test";
+import { readFileSync } from "node:fs";
+import { resolve } from "node:path";
+
+describe("asset library header buttons", () => {
+ test("only forces white header buttons in light mode", () => {
+ const css = readFileSync(resolve(import.meta.dir, "../src/styles/globals.css"), "utf8");
+ const headerButtonRule = css.match(/html:not\(\.dark\) \.library-page \.app-page-header \.ant-btn,[\s\S]*?transition: all 180ms ease-out !important;\s*}/)?.[0] || "";
+ const headerButtonHoverRule = css.match(/html:not\(\.dark\) \.library-page \.app-page-header \.ant-btn:hover,[\s\S]*?transform: translateY\(-1px\);\s*}/)?.[0] || "";
+
+ expect(headerButtonRule).toContain("background: #ffffff !important;");
+ expect(headerButtonRule).toContain("color: #171717 !important;");
+ expect(headerButtonHoverRule).toContain("background: #ffffff !important;");
+ expect(headerButtonHoverRule).toContain("color: #171717 !important;");
+ expect(css).not.toContain("\n .library-page .app-page-header .ant-btn,\n");
+ });
+});
diff --git a/web/test/assets-page-batch-toolbar.test.ts b/web/test/assets-page-batch-toolbar.test.ts
new file mode 100644
index 000000000..479b67499
--- /dev/null
+++ b/web/test/assets-page-batch-toolbar.test.ts
@@ -0,0 +1,15 @@
+import { describe, expect, test } from "bun:test";
+import { readFileSync } from "node:fs";
+import { resolve } from "node:path";
+
+describe("assets page batch toolbar", () => {
+ test("places select all before cancel selection", () => {
+ const source = readFileSync(resolve(import.meta.dir, "../src/pages/assets/index.tsx"), "utf8");
+ const selectAllIndex = source.indexOf(">全选");
+ const clearSelectionIndex = source.indexOf(">取消选择");
+
+ expect(selectAllIndex).toBeGreaterThanOrEqual(0);
+ expect(clearSelectionIndex).toBeGreaterThanOrEqual(0);
+ expect(selectAllIndex).toBeLessThan(clearSelectionIndex);
+ });
+});