UI: tweak grid & list collections (#8804)
Some checks are pending
Checks / main (push) Waiting to run
CodeQL Advanced / Analyze (actions) (push) Waiting to run
CodeQL Advanced / Analyze (javascript-typescript) (push) Waiting to run
Dev / Test development (push) Waiting to run
Dev / Build Docker image (push) Blocked by required conditions
Dev / Check Docker build (Dockerfile) (push) Blocked by required conditions
Dev / Check Docker build (Dockerfile.alpine) (push) Blocked by required conditions
/ Check Docker build (Dockerfile) (push) Waiting to run
/ Check Docker build (Dockerfile.alpine) (push) Waiting to run
/ Build Docker images (Dockerfile, ubuntu-24.04-arm, linux/arm64) (push) Blocked by required conditions
/ Build Docker images (Dockerfile.alpine, ubuntu-latest, linux/amd64) (push) Blocked by required conditions
/ Build Docker images (Dockerfile.legacy, ubuntu-24.04-arm, linux/arm/v7) (push) Blocked by required conditions
/ Build Docker images (Dockerfile.legacy, ubuntu-24.04-arm, linux/arm/v8) (push) Blocked by required conditions
/ Merge manifest lists (push) Blocked by required conditions
playwright / E2E tests on linux-arm64 (push) Waiting to run
playwright / E2E tests on linux-x64 (push) Waiting to run

This commit is contained in:
Adorian Doran 2026-02-24 10:16:39 +02:00 committed by GitHub
commit 64371a6b9c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 82 additions and 58 deletions

View File

@ -9,7 +9,8 @@ import Button from "../react/Button";
import "./Pagination.css";
import clsx from "clsx";
interface PaginationContext {
export interface PaginationContext {
className?: string;
page: number;
setPage: Dispatch<StateUpdater<number>>;
pageNotes?: FNote[];
@ -18,11 +19,11 @@ interface PaginationContext {
totalNotes: number;
}
export function Pager({ page, pageSize, setPage, pageCount, totalNotes }: Omit<PaginationContext, "pageNotes">) {
export function Pager({ className, page, pageSize, setPage, pageCount, totalNotes }: Omit<PaginationContext, "pageNotes">) {
if (pageCount < 2) return;
return (
<div className="note-list-pager-container">
<div className={clsx("note-list-pager-container", className)}>
<div className="note-list-pager">
<ActionButton
icon="bx bx-chevron-left"

View File

@ -13,6 +13,14 @@
flex-wrap: wrap;
gap: 10px;
}
.note-list-bottom-pager {
margin-block: 8px;
}
&:not(:has(.note-list-bottom-pager)) {
margin-bottom: 48px;
}
}
/* #region List view / Grid view common styles */
@ -107,7 +115,7 @@
.nested-note-list .note-book-content,
.note-list-container .note-book-content {
display: none;
animation: note-preview-show .25s ease-out;
animation: note-preview-show .35s ease-out;
will-change: opacity;
&.note-book-content-ready {
@ -368,6 +376,10 @@
padding: 0;
}
&.type-video video {
max-height: 200px;
}
h1, h2, h3, h4, h5, h6 {
font-size: 1rem;
color: var(--active-item-text-color);

View File

@ -13,13 +13,13 @@ import { useImperativeSearchHighlighlighting, useNoteLabel, useNoteLabelBoolean,
import Icon from "../../react/Icon";
import NoteLink from "../../react/NoteLink";
import { ViewModeProps } from "../interface";
import { Pager, usePagination } from "../Pagination";
import { Pager, usePagination, PaginationContext } from "../Pagination";
import { filterChildNotes, useFilteredNoteIds } from "./utils";
import { JSX } from "preact/jsx-runtime";
import { clsx } from "clsx";
import ActionButton from "../../react/ActionButton";
import linkContextMenuService from "../../../menus/link_context_menu";
import { TargetedMouseEvent } from "preact";
import { ComponentChildren, TargetedMouseEvent } from "preact";
export function ListView({ note, noteIds: unfilteredNoteIds, highlightedTokens }: ViewModeProps<{}>) {
const expandDepth = useExpansionDepth(note);
@ -27,32 +27,18 @@ export function ListView({ note, noteIds: unfilteredNoteIds, highlightedTokens }
const { pageNotes, ...pagination } = usePagination(note, noteIds);
const [ includeArchived ] = useNoteLabelBoolean(note, "includeArchived");
const noteType = useNoteProperty(note, "type");
const hasCollectionProperties = [ "book", "search" ].includes(noteType ?? "");
return (
<div className="note-list list-view">
<CollectionProperties
note={note}
centerChildren={<Pager {...pagination} />}
/>
{ noteIds.length > 0 && <div className="note-list-wrapper">
{!hasCollectionProperties && <Pager {...pagination} />}
<Card className={clsx("nested-note-list", {"search-results": (noteType === "search")})}>
{pageNotes?.map(childNote => (
<ListNoteCard
key={childNote.noteId}
note={childNote} parentNote={note}
expandDepth={expandDepth} highlightedTokens={highlightedTokens}
currentLevel={1} includeArchived={includeArchived} />
))}
</Card>
<Pager {...pagination} />
</div>}
</div>
);
return <NoteList note={note} viewMode="list-view" noteIds={noteIds} pagination={pagination}>
<Card className={clsx("nested-note-list", {"search-results": (noteType === "search")})}>
{pageNotes?.map(childNote => (
<ListNoteCard
key={childNote.noteId}
note={childNote} parentNote={note}
expandDepth={expandDepth} highlightedTokens={highlightedTokens}
currentLevel={1} includeArchived={includeArchived} />
))}
</Card>
</NoteList>;
}
export function GridView({ note, noteIds: unfilteredNoteIds, highlightedTokens }: ViewModeProps<{}>) {
@ -60,32 +46,47 @@ export function GridView({ note, noteIds: unfilteredNoteIds, highlightedTokens }
const { pageNotes, ...pagination } = usePagination(note, noteIds);
const [ includeArchived ] = useNoteLabelBoolean(note, "includeArchived");
const noteType = useNoteProperty(note, "type");
const hasCollectionProperties = [ "book", "search" ].includes(noteType ?? "");
return (
<div className="note-list grid-view">
<CollectionProperties
note={note}
centerChildren={<Pager {...pagination} />}
/>
<div className="note-list-wrapper">
{!hasCollectionProperties && <Pager {...pagination} />}
<div className={clsx("note-list-container use-tn-links", {"search-results": (noteType === "search")})}>
{pageNotes?.map(childNote => (
<GridNoteCard key={childNote.noteId}
note={childNote}
parentNote={note}
highlightedTokens={highlightedTokens}
includeArchived={includeArchived} />
))}
</div>
<Pager {...pagination} />
</div>
return <NoteList note={note} viewMode="grid-view" noteIds={noteIds} pagination={pagination}>
<div className={clsx("note-list-container use-tn-links", {"search-results": (noteType === "search")})}>
{pageNotes?.map(childNote => (
<GridNoteCard key={childNote.noteId}
note={childNote}
parentNote={note}
highlightedTokens={highlightedTokens}
includeArchived={includeArchived} />
))}
</div>
);
</NoteList>
}
interface NoteListProps {
note: FNote,
viewMode: "list-view" | "grid-view",
noteIds: string[],
pagination: PaginationContext,
children: ComponentChildren
}
function NoteList(props: NoteListProps) {
const noteType = useNoteProperty(props.note, "type");
const hasCollectionProperties = ["book", "search"].includes(noteType ?? "");
return <div className={clsx("note-list", props.viewMode)}>
<CollectionProperties
note={props.note}
centerChildren={<Pager className="note-list-top-pager" {...props.pagination} />}
/>
{props.noteIds.length > 0 && <div className="note-list-wrapper">
{!hasCollectionProperties && <Pager {...props.pagination} />}
{props.children}
<Pager className="note-list-bottom-pager" {...props.pagination} />
</div>}
</div>
}
function ListNoteCard({ note, parentNote, highlightedTokens, currentLevel, expandDepth, includeArchived }: {
@ -175,7 +176,8 @@ function GridNoteCard(props: GridNoteCardProps) {
showNotePath={props.parentNote.type === "search"}
highlightedTokens={props.highlightedTokens}
/>
<NoteMenuButton notePath={notePath} />
{!props.note.isOptions() && <NoteMenuButton notePath={notePath} />}
</h5>
<NoteContent note={props.note}
trim

View File

@ -1,5 +1,5 @@
.collection-properties {
padding: 0.55em 12px;
padding: 0.55em var(--content-margin-inline);
display: flex;
gap: 0.25em;
align-items: center;

View File

@ -94,6 +94,11 @@ export default class NoteWrapperWidget extends FlexContainer<BasicWidget> {
"application/pdf"
]
const COLLECTIONS_WITH_BACKGROUND_EFFECTS = [
"grid",
"list"
]
if (note.isOptions()) {
return true;
}
@ -102,6 +107,10 @@ export default class NoteWrapperWidget extends FlexContainer<BasicWidget> {
return true;
}
if (note.type === "book" && COLLECTIONS_WITH_BACKGROUND_EFFECTS.includes(note.getLabelValue("viewType") ?? "none")) {
return true;
}
return false;
}

View File

@ -7,7 +7,7 @@
}
.tn-card-frame,
.tn-card-section {
.tn-card-body .tn-card-section {
padding: var(--card-padding-block) var(--card-padding-inline);
border: 1px solid var(--card-border-color, var(--main-border-color));
background: var(--card-background-color);