mirror of
https://github.com/RayLabsHQ/gitea-mirror.git
synced 2026-10-30 22:21:58 +01:00
fix(ui): sort the Activity Log name filter case-insensitively too (#490)
Follow-up to #487: the owner, organization and Activity Log name filters share one compareNames (an Intl.Collator built once), so the Activity Log filter no longer puts capitalized names first.
This commit is contained in:
1 parent
2485513973
commit
ecdba3cad7
5 files changed
+48
-10
No files matched your search
@@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
### Fixed
|
||||
- The Activity Log came back as an error instead of the feed once a sync had finished with a warning. A run whose release filter matched nothing on the destination leaves a job whose status is `warning`, and the feed validated the status with the repository status list, which has no such value
|
||||
- Long lists no longer put every row in the page. The Repositories page built a card for every repository even on desktop, where the cards are hidden, and the Storage table rendered every row; with 3,000 repositories the Repositories page held over 120,000 elements. Only the layout on screen is rendered now, and the mobile cards and Storage rows are virtualized like the desktop table, so a few hundred elements are on the page whatever the count
|
||||
- The owner and organization filters on the Repositories page and the name filter on the Activity Log list names in alphabetical order regardless of case (#487). A plain sort put every capitalized name before the lowercase ones and accented names last
|
||||
- Scrolling the Repositories table on desktop dropped frames on slower machines. Each scroll step rendered the filters and every visible row again, and each row coming into view forced a style recalculation for its name. Only the rows coming into view render now; with the CPU slowed 4x, a scroll frame went from about 31 ms to about 13 ms
|
||||
- Destination release listings stopped after 30 releases. Gitea and Forgejo ignore `per_page` and answer 30 a page, and the listing stopped on any page shorter than the 100 it asked for. The release limit only trimmed within the newest 30 on each sync, the Storage page counted at most 30 releases per repository, and the release filter preview showed only the newest 30 tags. Listings now page with `limit` until the total the destination reports
|
||||
- The sync button on an archived repository says **Sync** like every other row instead of **Manual Sync**, so the wider label no longer pushes the row's status badge out of line. Hovering it explains that automatic syncs are off for archived mirrors
|
||||
|
||||
@@ -15,6 +15,7 @@ import {
|
||||
} from "@/components/ui/popover";
|
||||
import { selectTriggerClassName } from "@/components/ui/select";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { compareNames } from "@/lib/utils/compare-names";
|
||||
|
||||
type ActivityNameComboboxProps = {
|
||||
activities: any[];
|
||||
@@ -39,7 +40,7 @@ export function ActivityNameCombobox({
|
||||
if (a.repositoryName) set.add(a.repositoryName);
|
||||
if (a.organizationName) set.add(a.organizationName);
|
||||
});
|
||||
return Array.from(set).sort();
|
||||
return Array.from(set).sort(compareNames);
|
||||
}, [activities]);
|
||||
|
||||
const [open, setOpen] = React.useState(false);
|
||||
|
||||
@@ -53,6 +53,7 @@ import { useConfigStatus } from "@/hooks/useConfigStatus";
|
||||
import { useNavigation } from "@/components/layout/MainLayout";
|
||||
import { withBase } from "@/lib/base-path";
|
||||
import { getRepositorySource, normalizeSourceUrl } from "@/lib/source-providers/kinds";
|
||||
import { compareNames } from "@/lib/utils/compare-names";
|
||||
|
||||
type RepositoriesPageCache = {
|
||||
repositories: Repository[];
|
||||
@@ -912,25 +913,19 @@ export default function Repository() {
|
||||
}
|
||||
};
|
||||
|
||||
// Get unique owners and organizations for comboboxes.
|
||||
// Plain `.sort()` orders by code unit, so "Zebra" lands before "apple" and
|
||||
// umlauts sort wrong; compare case-insensitively like the repo name sort.
|
||||
const collator = new Intl.Collator(undefined, {
|
||||
sensitivity: "base",
|
||||
numeric: true,
|
||||
});
|
||||
// Get unique owners and organizations for comboboxes
|
||||
const ownerOptions = Array.from(
|
||||
new Set(
|
||||
repositories.map((repo) => repo.owner).filter((v): v is string => !!v)
|
||||
)
|
||||
).sort(collator.compare);
|
||||
).sort(compareNames);
|
||||
const orgOptions = Array.from(
|
||||
new Set(
|
||||
repositories
|
||||
.map((repo) => repo.organization)
|
||||
.filter((v): v is string => !!v)
|
||||
)
|
||||
).sort(collator.compare);
|
||||
).sort(compareNames);
|
||||
|
||||
const handleConfirmDuplicateRepository = async () => {
|
||||
if (!duplicateRepoCandidate) {
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
import { describe, expect, test } from "bun:test";
|
||||
import { compareNames } from "./compare-names";
|
||||
|
||||
describe("compareNames", () => {
|
||||
test("ignores case", () => {
|
||||
expect(["Zebra", "apple", "Mango"].sort(compareNames)).toEqual([
|
||||
"apple",
|
||||
"Mango",
|
||||
"Zebra",
|
||||
]);
|
||||
});
|
||||
|
||||
test("sorts accented names with their base letter", () => {
|
||||
expect(["Zeta", "Ärger", "Bravo"].sort(compareNames)).toEqual([
|
||||
"Ärger",
|
||||
"Bravo",
|
||||
"Zeta",
|
||||
]);
|
||||
});
|
||||
|
||||
test("compares numbers by value", () => {
|
||||
expect(["repo-10", "repo-2", "repo-1"].sort(compareNames)).toEqual([
|
||||
"repo-1",
|
||||
"repo-2",
|
||||
"repo-10",
|
||||
]);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,13 @@
|
||||
/**
|
||||
* Order for owner, organization and repository names in filter lists: case
|
||||
* and accent insensitive, with numbers compared by value. A plain `.sort()`
|
||||
* compares code units, so "Zebra" lands before "apple" and umlauts sort last.
|
||||
*/
|
||||
const nameCollator = new Intl.Collator(undefined, {
|
||||
sensitivity: "base",
|
||||
numeric: true,
|
||||
});
|
||||
|
||||
export function compareNames(a: string, b: string): number {
|
||||
return nameCollator.compare(a, b);
|
||||
}
|
||||
Reference in new issue
Block a user