mirror of
https://github.com/zadam/trilium.git
synced 2025-10-30 11:09:05 +01:00
chore(react/collections): calculate note Ids
This commit is contained in:
parent
5fb843268f
commit
ecf44deecf
18
apps/client/src/widgets/collections/NoteList.css
Normal file
18
apps/client/src/widgets/collections/NoteList.css
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
.note-list-widget {
|
||||||
|
min-height: 0;
|
||||||
|
overflow: auto;
|
||||||
|
contain: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.note-list-widget .note-list {
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.note-list-widget.full-height,
|
||||||
|
.note-list-widget.full-height .note-list-widget-content {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.note-list-widget video {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
@ -1,7 +1,80 @@
|
|||||||
|
import { allViewTypes, ViewTypeOptions } from "./interface";
|
||||||
|
import { useNoteContext, useNoteLabel, useTriliumEvent } from "../react/hooks";
|
||||||
|
import FNote from "../../entities/fnote";
|
||||||
|
import "./NoteList.css";
|
||||||
|
import ListView from "./legacy/ListView";
|
||||||
|
import { useEffect, useState } from "preact/hooks";
|
||||||
|
|
||||||
interface NoteListProps {
|
interface NoteListProps {
|
||||||
displayOnlyCollections?: boolean;
|
displayOnlyCollections?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function NoteList({ }: NoteListProps) {
|
export default function NoteList({ }: NoteListProps) {
|
||||||
return <p>Hi</p>
|
const { note } = useNoteContext();
|
||||||
|
const viewType = useNoteViewType(note);
|
||||||
|
const noteIds = useNoteIds(note, viewType);
|
||||||
|
const isEnabled = (!!viewType);
|
||||||
|
|
||||||
|
// Refresh note Ids
|
||||||
|
console.log("Got note ids", noteIds);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="note-list-widget">
|
||||||
|
{isEnabled && (
|
||||||
|
<div className="note-list-widget-content">
|
||||||
|
{getComponentByViewType(viewType)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getComponentByViewType(viewType: ViewTypeOptions) {
|
||||||
|
console.log("Got ", viewType);
|
||||||
|
switch (viewType) {
|
||||||
|
case "list":
|
||||||
|
return <ListView />;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function useNoteViewType(note?: FNote | null): ViewTypeOptions | undefined {
|
||||||
|
const [ viewType ] = useNoteLabel(note, "viewType");
|
||||||
|
|
||||||
|
if (!note) {
|
||||||
|
return undefined;
|
||||||
|
} else if (!(allViewTypes as readonly string[]).includes(viewType || "")) {
|
||||||
|
// when not explicitly set, decide based on the note type
|
||||||
|
return note.type === "search" ? "list" : "grid";
|
||||||
|
} else {
|
||||||
|
return viewType as ViewTypeOptions;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function useNoteIds(note: FNote | null | undefined, viewType: ViewTypeOptions | undefined) {
|
||||||
|
const [ noteIds, setNoteIds ] = useState<string[]>([]);
|
||||||
|
|
||||||
|
async function refreshNoteIds() {
|
||||||
|
console.log("Refreshed note IDs");
|
||||||
|
if (!note) {
|
||||||
|
setNoteIds([]);
|
||||||
|
} else if (viewType === "list" || viewType === "grid") {
|
||||||
|
setNoteIds(note.getChildNoteIds());
|
||||||
|
} else {
|
||||||
|
setNoteIds(await note.getSubtreeNoteIds());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Refresh on note switch.
|
||||||
|
useEffect(() => { refreshNoteIds() }, [ note ]);
|
||||||
|
|
||||||
|
// Refresh on alterations to the note subtree.
|
||||||
|
useTriliumEvent("entitiesReloaded", ({ loadResults }) => {
|
||||||
|
if (note && loadResults.getBranchRows().some(branch =>
|
||||||
|
branch.parentNoteId === note.noteId
|
||||||
|
|| noteIds.includes(branch.parentNoteId ?? ""))) {
|
||||||
|
refreshNoteIds();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return noteIds;
|
||||||
}
|
}
|
||||||
@ -1,5 +1,5 @@
|
|||||||
import type { ViewModeArgs } from "../view_widgets/view_mode";
|
import type { ViewModeArgs } from "../view_widgets/view_mode";
|
||||||
|
|
||||||
const allViewTypes = ["list", "grid", "calendar", "table", "geoMap", "board"] as const;
|
export const allViewTypes = ["list", "grid", "calendar", "table", "geoMap", "board"] as const;
|
||||||
export type ArgsWithoutNoteId = Omit<ViewModeArgs, "noteIds">;
|
export type ArgsWithoutNoteId = Omit<ViewModeArgs, "noteIds">;
|
||||||
export type ViewTypeOptions = typeof allViewTypes[number];
|
export type ViewTypeOptions = typeof allViewTypes[number];
|
||||||
|
|||||||
138
apps/client/src/widgets/collections/legacy/ListOrGridView.css
Normal file
138
apps/client/src/widgets/collections/legacy/ListOrGridView.css
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
.note-list {
|
||||||
|
overflow: hidden;
|
||||||
|
position: relative;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.note-book-card {
|
||||||
|
border-radius: 10px;
|
||||||
|
background-color: var(--accented-background-color);
|
||||||
|
padding: 10px 15px 15px 8px;
|
||||||
|
margin: 5px 5px 5px 5px;
|
||||||
|
overflow: hidden;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
flex-shrink: 0;
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.note-book-card:not(.expanded) .note-book-content {
|
||||||
|
display: none !important;
|
||||||
|
padding: 10px
|
||||||
|
}
|
||||||
|
|
||||||
|
.note-book-card.expanded .note-book-content {
|
||||||
|
display: block;
|
||||||
|
min-height: 0;
|
||||||
|
height: 100%;
|
||||||
|
padding-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.note-book-content .rendered-content {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.note-book-header {
|
||||||
|
border-bottom: 1px solid var(--main-border-color);
|
||||||
|
margin-bottom: 0;
|
||||||
|
padding-bottom: .5rem;
|
||||||
|
word-break: break-all;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* not-expanded title is limited to one line only */
|
||||||
|
.note-book-card:not(.expanded) .note-book-header {
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
.note-book-header .rendered-note-attributes {
|
||||||
|
font-size: medium;
|
||||||
|
}
|
||||||
|
|
||||||
|
.note-book-header .rendered-note-attributes:before {
|
||||||
|
content: "\\00a0\\00a0";
|
||||||
|
}
|
||||||
|
|
||||||
|
.note-book-header .note-icon {
|
||||||
|
font-size: 100%;
|
||||||
|
display: inline-block;
|
||||||
|
padding-right: 7px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.note-book-card .note-book-card {
|
||||||
|
border: 1px solid var(--main-border-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.note-book-content.type-image, .note-book-content.type-file, .note-book-content.type-protectedSession {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
text-align: center;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.note-book-content.type-image img, .note-book-content.type-canvas svg {
|
||||||
|
max-width: 100%;
|
||||||
|
max-height: 100%;
|
||||||
|
object-fit: contain;
|
||||||
|
}
|
||||||
|
|
||||||
|
.note-book-card.type-image .note-book-content img,
|
||||||
|
.note-book-card.type-text .note-book-content img,
|
||||||
|
.note-book-card.type-canvas .note-book-content img {
|
||||||
|
max-width: 100%;
|
||||||
|
max-height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.note-book-header {
|
||||||
|
flex-grow: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.note-list-wrapper {
|
||||||
|
height: 100%;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.note-expander {
|
||||||
|
font-size: x-large;
|
||||||
|
position: relative;
|
||||||
|
top: 3px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.note-list-pager {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* #region Grid view */
|
||||||
|
.note-list.grid-view .note-list-container {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.note-list.grid-view .note-book-card {
|
||||||
|
flex-basis: 300px;
|
||||||
|
border: 1px solid transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.note-list.grid-view .note-expander {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.note-list.grid-view .note-book-card {
|
||||||
|
max-height: 300px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.note-list.grid-view .note-book-card img {
|
||||||
|
max-height: 220px;
|
||||||
|
object-fit: contain;
|
||||||
|
}
|
||||||
|
|
||||||
|
.note-list.grid-view .note-book-card:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
border: 1px solid var(--main-border-color);
|
||||||
|
background: var(--more-accented-background-color);
|
||||||
|
}
|
||||||
|
/* #endregion */
|
||||||
14
apps/client/src/widgets/collections/legacy/ListView.tsx
Normal file
14
apps/client/src/widgets/collections/legacy/ListView.tsx
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
export default function ListView() {
|
||||||
|
return (
|
||||||
|
<div class="note-list">
|
||||||
|
<div class="note-list-wrapper">
|
||||||
|
List view goes here.
|
||||||
|
<div class="note-list-pager"></div>
|
||||||
|
|
||||||
|
<div class="note-list-container use-tn-links"></div>
|
||||||
|
|
||||||
|
<div class="note-list-pager"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -4,32 +4,6 @@ import type FNote from "../../entities/fnote.js";
|
|||||||
import type { CommandListener, CommandListenerData, CommandMappings, CommandNames, EventData, EventNames } from "../../components/app_context.js";
|
import type { CommandListener, CommandListenerData, CommandMappings, CommandNames, EventData, EventNames } from "../../components/app_context.js";
|
||||||
import type ViewMode from "../view_widgets/view_mode.js";
|
import type ViewMode from "../view_widgets/view_mode.js";
|
||||||
|
|
||||||
const TPL = /*html*/`
|
|
||||||
<div class="note-list-widget">
|
|
||||||
<style>
|
|
||||||
.note-list-widget {
|
|
||||||
min-height: 0;
|
|
||||||
overflow: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.note-list-widget .note-list {
|
|
||||||
padding: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.note-list-widget.full-height,
|
|
||||||
.note-list-widget.full-height .note-list-widget-content {
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.note-list-widget video {
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<div class="note-list-widget-content">
|
|
||||||
</div>
|
|
||||||
</div>`;
|
|
||||||
|
|
||||||
export default class NoteListWidget extends NoteContextAwareWidget {
|
export default class NoteListWidget extends NoteContextAwareWidget {
|
||||||
|
|
||||||
private $content!: JQuery<HTMLElement>;
|
private $content!: JQuery<HTMLElement>;
|
||||||
@ -49,10 +23,6 @@ export default class NoteListWidget extends NoteContextAwareWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
isEnabled() {
|
isEnabled() {
|
||||||
if (!super.isEnabled()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.displayOnlyCollections && this.note?.type !== "book") {
|
if (this.displayOnlyCollections && this.note?.type !== "book") {
|
||||||
const viewType = this.note?.getLabelValue("viewType");
|
const viewType = this.note?.getLabelValue("viewType");
|
||||||
if (!viewType || ["grid", "list"].includes(viewType)) {
|
if (!viewType || ["grid", "list"].includes(viewType)) {
|
||||||
|
|||||||
@ -17,17 +17,6 @@ export default class NoteListRenderer {
|
|||||||
this.viewType = this.#getViewType(args.parentNote);
|
this.viewType = this.#getViewType(args.parentNote);
|
||||||
}
|
}
|
||||||
|
|
||||||
#getViewType(parentNote: FNote): ViewTypeOptions {
|
|
||||||
const viewType = parentNote.getLabelValue("viewType");
|
|
||||||
|
|
||||||
if (!(allViewTypes as readonly string[]).includes(viewType || "")) {
|
|
||||||
// when not explicitly set, decide based on the note type
|
|
||||||
return parentNote.type === "search" ? "list" : "grid";
|
|
||||||
} else {
|
|
||||||
return viewType as ViewTypeOptions;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
get isFullHeight() {
|
get isFullHeight() {
|
||||||
switch (this.viewType) {
|
switch (this.viewType) {
|
||||||
case "list":
|
case "list":
|
||||||
|
|||||||
@ -8,156 +8,6 @@ import type FNote from "../../entities/fnote.js";
|
|||||||
import ViewMode, { type ViewModeArgs } from "./view_mode.js";
|
import ViewMode, { type ViewModeArgs } from "./view_mode.js";
|
||||||
import { ViewTypeOptions } from "../collections/interface.js";
|
import { ViewTypeOptions } from "../collections/interface.js";
|
||||||
|
|
||||||
const TPL = /*html*/`
|
|
||||||
<div class="note-list">
|
|
||||||
<style>
|
|
||||||
.note-list {
|
|
||||||
overflow: hidden;
|
|
||||||
position: relative;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.note-list.grid-view .note-list-container {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.note-list.grid-view .note-book-card {
|
|
||||||
flex-basis: 300px;
|
|
||||||
border: 1px solid transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
.note-list.grid-view .note-expander {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.note-list.grid-view .note-book-card {
|
|
||||||
max-height: 300px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.note-list.grid-view .note-book-card img {
|
|
||||||
max-height: 220px;
|
|
||||||
object-fit: contain;
|
|
||||||
}
|
|
||||||
|
|
||||||
.note-list.grid-view .note-book-card:hover {
|
|
||||||
cursor: pointer;
|
|
||||||
border: 1px solid var(--main-border-color);
|
|
||||||
background: var(--more-accented-background-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
.note-book-card {
|
|
||||||
border-radius: 10px;
|
|
||||||
background-color: var(--accented-background-color);
|
|
||||||
padding: 10px 15px 15px 8px;
|
|
||||||
margin: 5px 5px 5px 5px;
|
|
||||||
overflow: hidden;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
flex-shrink: 0;
|
|
||||||
flex-grow: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.note-book-card:not(.expanded) .note-book-content {
|
|
||||||
display: none !important;
|
|
||||||
padding: 10px
|
|
||||||
}
|
|
||||||
|
|
||||||
.note-book-card.expanded .note-book-content {
|
|
||||||
display: block;
|
|
||||||
min-height: 0;
|
|
||||||
height: 100%;
|
|
||||||
padding-top: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.note-book-content .rendered-content {
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.note-book-header {
|
|
||||||
border-bottom: 1px solid var(--main-border-color);
|
|
||||||
margin-bottom: 0;
|
|
||||||
padding-bottom: .5rem;
|
|
||||||
word-break: break-all;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* not-expanded title is limited to one line only */
|
|
||||||
.note-book-card:not(.expanded) .note-book-header {
|
|
||||||
overflow: hidden;
|
|
||||||
white-space: nowrap;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
}
|
|
||||||
|
|
||||||
.note-book-header .rendered-note-attributes {
|
|
||||||
font-size: medium;
|
|
||||||
}
|
|
||||||
|
|
||||||
.note-book-header .rendered-note-attributes:before {
|
|
||||||
content: "\\00a0\\00a0";
|
|
||||||
}
|
|
||||||
|
|
||||||
.note-book-header .note-icon {
|
|
||||||
font-size: 100%;
|
|
||||||
display: inline-block;
|
|
||||||
padding-right: 7px;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.note-book-card .note-book-card {
|
|
||||||
border: 1px solid var(--main-border-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
.note-book-content.type-image, .note-book-content.type-file, .note-book-content.type-protectedSession {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
text-align: center;
|
|
||||||
padding: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.note-book-content.type-image img, .note-book-content.type-canvas svg {
|
|
||||||
max-width: 100%;
|
|
||||||
max-height: 100%;
|
|
||||||
object-fit: contain;
|
|
||||||
}
|
|
||||||
|
|
||||||
.note-book-card.type-image .note-book-content img,
|
|
||||||
.note-book-card.type-text .note-book-content img,
|
|
||||||
.note-book-card.type-canvas .note-book-content img {
|
|
||||||
max-width: 100%;
|
|
||||||
max-height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.note-book-header {
|
|
||||||
flex-grow: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.note-list-wrapper {
|
|
||||||
height: 100%;
|
|
||||||
overflow: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.note-expander {
|
|
||||||
font-size: x-large;
|
|
||||||
position: relative;
|
|
||||||
top: 3px;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.note-list-pager {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<div class="note-list-wrapper">
|
|
||||||
<div class="note-list-pager"></div>
|
|
||||||
|
|
||||||
<div class="note-list-container use-tn-links"></div>
|
|
||||||
|
|
||||||
<div class="note-list-pager"></div>
|
|
||||||
</div>
|
|
||||||
</div>`;
|
|
||||||
|
|
||||||
class ListOrGridView extends ViewMode<{}> {
|
class ListOrGridView extends ViewMode<{}> {
|
||||||
private $noteList: JQuery<HTMLElement>;
|
private $noteList: JQuery<HTMLElement>;
|
||||||
|
|
||||||
|
|||||||
@ -48,10 +48,6 @@ export default abstract class ViewMode<T extends object> extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async entitiesReloadedEvent(e: EventData<"entitiesReloaded">) {
|
async entitiesReloadedEvent(e: EventData<"entitiesReloaded">) {
|
||||||
if (e.loadResults.getBranchRows().some(branch => branch.parentNoteId === this.parentNote.noteId || this.noteIds.includes(branch.parentNoteId ?? ""))) {
|
|
||||||
this.#refreshNoteIds();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (await this.onEntitiesReloaded(e)) {
|
if (await this.onEntitiesReloaded(e)) {
|
||||||
appContext.triggerEvent("refreshNoteList", { noteId: this.parentNote.noteId });
|
appContext.triggerEvent("refreshNoteList", { noteId: this.parentNote.noteId });
|
||||||
}
|
}
|
||||||
@ -70,14 +66,4 @@ export default abstract class ViewMode<T extends object> extends Component {
|
|||||||
return this._viewStorage;
|
return this._viewStorage;
|
||||||
}
|
}
|
||||||
|
|
||||||
async #refreshNoteIds() {
|
|
||||||
let noteIds: string[];
|
|
||||||
if (this.viewType === "list" || this.viewType === "grid") {
|
|
||||||
noteIds = this.args.parentNote.getChildNoteIds();
|
|
||||||
} else {
|
|
||||||
noteIds = await this.args.parentNote.getSubtreeNoteIds();
|
|
||||||
}
|
|
||||||
this.noteIds = noteIds;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user