mirror of
https://github.com/zadam/trilium.git
synced 2025-11-11 08:58:58 +01:00
chore(react/type_widgets): fix type errors
This commit is contained in:
parent
6ffe8a2eb5
commit
7930745a01
@ -13,7 +13,6 @@ import MainTreeExecutors from "./main_tree_executors.js";
|
||||
import toast from "../services/toast.js";
|
||||
import ShortcutComponent from "./shortcut_component.js";
|
||||
import { t, initLocale } from "../services/i18n.js";
|
||||
import type NoteDetailWidget from "../widgets/note_detail.js";
|
||||
import type { ResolveOptions } from "../widgets/dialogs/delete_notes.js";
|
||||
import type { PromptDialogOptions } from "../widgets/dialogs/prompt.js";
|
||||
import type { ConfirmWithMessageOptions, ConfirmWithTitleOptions } from "../widgets/dialogs/confirm.js";
|
||||
@ -21,8 +20,6 @@ import type LoadResults from "../services/load_results.js";
|
||||
import type { Attribute } from "../services/attribute_parser.js";
|
||||
import type NoteTreeWidget from "../widgets/note_tree.js";
|
||||
import type { default as NoteContext, GetTextEditorCallback } from "./note_context.js";
|
||||
import type TypeWidget from "../widgets/type_widgets_old/type_widget.js";
|
||||
import type EditableTextTypeWidget from "../widgets/type_widgets_old/editable_text.js";
|
||||
import type { NativeImage, TouchBar } from "electron";
|
||||
import TouchBarComponent from "./touch_bar.js";
|
||||
import type { CKTextEditor } from "@triliumnext/ckeditor5";
|
||||
@ -36,6 +33,7 @@ import { SqlExecuteResults } from "@triliumnext/commons";
|
||||
import { AddLinkOpts } from "../widgets/dialogs/add_link.jsx";
|
||||
import { IncludeNoteOpts } from "../widgets/dialogs/include_note.jsx";
|
||||
import { ReactWrappedWidget } from "../widgets/basic_widget.js";
|
||||
import { TypeWidget } from "../widgets/note_types.jsx";
|
||||
|
||||
interface Layout {
|
||||
getRootWidget: (appContext: AppContext) => RootContainer;
|
||||
@ -214,7 +212,7 @@ export type CommandMappings = {
|
||||
* Generally should not be invoked manually, as it is used by {@link NoteContext.getContentElement}.
|
||||
*/
|
||||
executeWithContentElement: CommandData & ExecuteCommandData<JQuery<HTMLElement>>;
|
||||
executeWithTypeWidget: CommandData & ExecuteCommandData<TypeWidget | null>;
|
||||
executeWithTypeWidget: CommandData & ExecuteCommandData<ReactWrappedWidget | null>;
|
||||
addTextToActiveEditor: CommandData & {
|
||||
text: string;
|
||||
};
|
||||
@ -487,13 +485,8 @@ type EventMappings = {
|
||||
relationMapResetZoomIn: { ntxId: string | null | undefined };
|
||||
relationMapResetZoomOut: { ntxId: string | null | undefined };
|
||||
activeNoteChanged: {};
|
||||
showAddLinkDialog: {
|
||||
textTypeWidget: EditableTextTypeWidget;
|
||||
text: string;
|
||||
};
|
||||
showIncludeDialog: {
|
||||
textTypeWidget: EditableTextTypeWidget;
|
||||
};
|
||||
showAddLinkDialog: AddLinkOpts;
|
||||
showIncludeDialog: IncludeNoteOpts;
|
||||
openBulkActionsDialog: {
|
||||
selectedOrActiveNoteIds: string[];
|
||||
};
|
||||
|
||||
@ -9,10 +9,11 @@ import hoistedNoteService from "../services/hoisted_note.js";
|
||||
import options from "../services/options.js";
|
||||
import type { ViewScope } from "../services/link.js";
|
||||
import type FNote from "../entities/fnote.js";
|
||||
import type TypeWidget from "../widgets/type_widgets_old/type_widget.js";
|
||||
import type { CKTextEditor } from "@triliumnext/ckeditor5";
|
||||
import type CodeMirror from "@triliumnext/codemirror";
|
||||
import { closeActiveDialog } from "../services/dialog.js";
|
||||
import { TypeWidget } from "../widgets/note_types.jsx";
|
||||
import { ReactWrappedWidget } from "../widgets/basic_widget.js";
|
||||
|
||||
export interface SetNoteOpts {
|
||||
triggerSwitchEvent?: unknown;
|
||||
@ -395,7 +396,7 @@ class NoteContext extends Component implements EventListener<"entitiesReloaded">
|
||||
|
||||
async getTypeWidget() {
|
||||
return this.timeout(
|
||||
new Promise<TypeWidget | null>((resolve) =>
|
||||
new Promise<ReactWrappedWidget | null>((resolve) =>
|
||||
appContext.triggerCommand("executeWithTypeWidget", {
|
||||
resolve,
|
||||
ntxId: this.ntxId
|
||||
|
||||
@ -11,7 +11,7 @@ import RightPanelWidget from "../widgets/right_panel_widget.js";
|
||||
import ws from "./ws.js";
|
||||
import appContext from "../components/app_context.js";
|
||||
import NoteContextAwareWidget from "../widgets/note_context_aware_widget.js";
|
||||
import BasicWidget from "../widgets/basic_widget.js";
|
||||
import BasicWidget, { ReactWrappedWidget } from "../widgets/basic_widget.js";
|
||||
import SpacedUpdate from "./spaced_update.js";
|
||||
import shortcutService from "./shortcuts.js";
|
||||
import dialogService from "./dialog.js";
|
||||
@ -19,7 +19,6 @@ import type FNote from "../entities/fnote.js";
|
||||
import { t } from "./i18n.js";
|
||||
import dayjs from "dayjs";
|
||||
import type NoteContext from "../components/note_context.js";
|
||||
import type NoteDetailWidget from "../widgets/note_detail.js";
|
||||
import type Component from "../components/component.js";
|
||||
import { formatLogMessage } from "@triliumnext/commons";
|
||||
|
||||
@ -317,7 +316,7 @@ export interface Api {
|
||||
* Get access to the widget handling note detail. Methods like `getWidgetType()` and `getTypeWidget()` to get to the
|
||||
* implementation of actual widget type.
|
||||
*/
|
||||
getActiveNoteDetailWidget(): Promise<NoteDetailWidget>;
|
||||
getActiveNoteDetailWidget(): Promise<ReactWrappedWidget>;
|
||||
/**
|
||||
* @returns returns a note path of active note or null if there isn't active note
|
||||
*/
|
||||
|
||||
11
apps/client/src/types-lib.d.ts
vendored
11
apps/client/src/types-lib.d.ts
vendored
@ -60,3 +60,14 @@ declare global {
|
||||
windowControlsOverlay?: unknown;
|
||||
}
|
||||
}
|
||||
|
||||
declare module "preact" {
|
||||
namespace JSX {
|
||||
interface IntrinsicElements {
|
||||
webview: {
|
||||
src: string;
|
||||
class: string;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,9 +7,8 @@ import { isValidElement, VNode } from "preact";
|
||||
import { TypeWidgetProps } from "./type_widgets/type_widget";
|
||||
import "./NoteDetail.css";
|
||||
import attributes from "../services/attributes";
|
||||
import { ExtendedNoteType, TYPE_MAPPINGS } from "./note_types";
|
||||
import { ExtendedNoteType, TYPE_MAPPINGS, TypeWidget } from "./note_types";
|
||||
import { dynamicRequire, isMobile } from "../services/utils";
|
||||
import { ReactWrappedWidget } from "./basic_widget";
|
||||
|
||||
/**
|
||||
* The note detail is in charge of rendering the content of a note, by determining its type (e.g. text, code) and using the appropriate view widget.
|
||||
@ -214,7 +213,7 @@ function useNoteInfo() {
|
||||
return { note, type, mime, noteContext, parentComponent };
|
||||
}
|
||||
|
||||
async function getCorrespondingWidget(type: ExtendedNoteType): Promise<null | ((props: TypeWidgetProps) => VNode)> {
|
||||
async function getCorrespondingWidget(type: ExtendedNoteType): Promise<null | TypeWidget> {
|
||||
const correspondingType = TYPE_MAPPINGS[type].view;
|
||||
if (!correspondingType) return null;
|
||||
|
||||
|
||||
@ -8,9 +8,8 @@ import Button from "../react/Button";
|
||||
import { Suggestion, triggerRecentNotes } from "../../services/note_autocomplete";
|
||||
import tree from "../../services/tree";
|
||||
import froca from "../../services/froca";
|
||||
import EditableTextTypeWidget, { type BoxSize } from "../type_widgets_old/editable_text";
|
||||
import { useTriliumEvent } from "../react/hooks";
|
||||
import { CKEditorApi } from "../type_widgets/text/CKEditorWithWatchdog";
|
||||
import { type BoxSize, CKEditorApi } from "../type_widgets/text/CKEditorWithWatchdog";
|
||||
|
||||
export interface IncludeNoteOpts {
|
||||
editorApi: CKEditorApi;
|
||||
@ -19,7 +18,7 @@ export interface IncludeNoteOpts {
|
||||
export default function IncludeNoteDialog() {
|
||||
const editorApiRef = useRef<CKEditorApi>(null);
|
||||
const [suggestion, setSuggestion] = useState<Suggestion | null>(null);
|
||||
const [boxSize, setBoxSize] = useState("medium");
|
||||
const [boxSize, setBoxSize] = useState<string>("medium");
|
||||
const [shown, setShown] = useState(false);
|
||||
|
||||
useTriliumEvent("showIncludeNoteDialog", ({ editorApi }) => {
|
||||
|
||||
@ -1,9 +1,8 @@
|
||||
import type { EventNames, EventData } from "../../components/app_context.js";
|
||||
import NoteContext from "../../components/note_context.js";
|
||||
import { openDialog } from "../../services/dialog.js";
|
||||
import BasicWidget from "../basic_widget.js";
|
||||
import BasicWidget, { ReactWrappedWidget } from "../basic_widget.js";
|
||||
import Container from "../containers/container.js";
|
||||
import TypeWidget from "../type_widgets_old/type_widget.js";
|
||||
|
||||
const TPL = /*html*/`\
|
||||
<div class="popup-editor-dialog modal fade mx-auto" tabindex="-1" role="dialog">
|
||||
@ -130,7 +129,7 @@ export default class PopupEditorDialog extends Container<BasicWidget> {
|
||||
$dialog.on("hidden.bs.modal", () => {
|
||||
const $typeWidgetEl = $dialog.find(".note-detail-printable");
|
||||
if ($typeWidgetEl.length) {
|
||||
const typeWidget = glob.getComponentByEl($typeWidgetEl[0]) as TypeWidget;
|
||||
const typeWidget = glob.getComponentByEl($typeWidgetEl[0]) as ReactWrappedWidget;
|
||||
typeWidget.cleanup();
|
||||
}
|
||||
|
||||
|
||||
@ -4,9 +4,8 @@
|
||||
*/
|
||||
|
||||
import { NoteType } from "@triliumnext/commons";
|
||||
import TypeWidget from "./type_widgets_old/type_widget";
|
||||
import { VNode, type JSX } from "preact";
|
||||
import { TypeWidgetProps } from "./type_widgets/type_widget";
|
||||
import { VNode } from "preact";
|
||||
|
||||
/**
|
||||
* A `NoteType` altered by the note detail widget, taking into consideration whether the note is editable or not and adding special note types such as an empty one,
|
||||
@ -14,7 +13,8 @@ import { VNode } from "preact";
|
||||
*/
|
||||
export type ExtendedNoteType = Exclude<NoteType, "launcher" | "text" | "code"> | "empty" | "readOnlyCode" | "readOnlyText" | "editableText" | "editableCode" | "attachmentDetail" | "attachmentList" | "protectedSession" | "aiChat";
|
||||
|
||||
type NoteTypeView = () => Promise<{ default: TypeWidget } | TypeWidget> | ((props: TypeWidgetProps) => VNode);
|
||||
export type TypeWidget = ((props: TypeWidgetProps) => VNode | JSX.Element);
|
||||
type NoteTypeView = () => (Promise<{ default: TypeWidget } | TypeWidget> | TypeWidget);
|
||||
|
||||
interface NoteTypeMapping {
|
||||
view: NoteTypeView;
|
||||
@ -36,7 +36,7 @@ export const TYPE_MAPPINGS: Record<ExtendedNoteType, NoteTypeMapping> = {
|
||||
printable: true
|
||||
},
|
||||
search: {
|
||||
view: () => <></>,
|
||||
view: () => (props: TypeWidgetProps) => <></>,
|
||||
className: "note-detail-none",
|
||||
printable: true
|
||||
},
|
||||
|
||||
@ -23,9 +23,13 @@ export default function Book({ note }: TypeWidgetProps) {
|
||||
}
|
||||
});
|
||||
|
||||
return (shouldDisplayNoChildrenWarning &&
|
||||
return (
|
||||
<>
|
||||
{shouldDisplayNoChildrenWarning && (
|
||||
<Alert type="warning" className="note-detail-book-empty-help">
|
||||
<RawHtml html={t("book.no_children_help")} />
|
||||
</Alert>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
@ -86,7 +86,7 @@ export default function Canvas({ note, noteContext }: TypeWidgetProps) {
|
||||
)
|
||||
}
|
||||
|
||||
function usePersistence(note: FNote, noteContext: NoteContext, apiRef: RefObject<ExcalidrawImperativeAPI>, theme: AppState["theme"], isReadOnly: boolean): Partial<ExcalidrawProps> {
|
||||
function usePersistence(note: FNote, noteContext: NoteContext | null | undefined, apiRef: RefObject<ExcalidrawImperativeAPI>, theme: AppState["theme"], isReadOnly: boolean): Partial<ExcalidrawProps> {
|
||||
const libraryChanged = useRef(false);
|
||||
|
||||
/**
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
import { TypeWidgetProps } from "./type_widget";
|
||||
import { JSX } from "preact/jsx-runtime";
|
||||
import { OptionPages } from "../type_widgets_old/content_widget";
|
||||
import AppearanceSettings from "./options/appearance";
|
||||
import ShortcutSettings from "./options/shortcuts";
|
||||
import TextNoteSettings from "./options/text_notes";
|
||||
|
||||
@ -181,7 +181,7 @@ export default function CKEditorWithWatchdog({ containerRef: externalContainerRe
|
||||
);
|
||||
}
|
||||
|
||||
function buildWatchdog(isClassicEditor: boolean, watchdogConfig?: WatchdogConfig) {
|
||||
function buildWatchdog(isClassicEditor: boolean, watchdogConfig?: WatchdogConfig): EditorWatchdog<CKTextEditor> {
|
||||
if (isClassicEditor) {
|
||||
return new EditorWatchdog(ClassicEditor, watchdogConfig);
|
||||
} else {
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import appContext from "../../../components/app_context";
|
||||
import content_renderer from "../../../services/content_renderer";
|
||||
import froca from "../../../services/froca";
|
||||
import link from "../../../services/link";
|
||||
import link, { ViewScope } from "../../../services/link";
|
||||
import utils from "../../../services/utils";
|
||||
|
||||
export async function loadIncludedNote(noteId: string, $el: JQuery<HTMLElement>) {
|
||||
@ -66,7 +66,7 @@ async function openImageInNewTab($img: JQuery<HTMLElement>, activate: boolean =
|
||||
}
|
||||
}
|
||||
|
||||
async function parseFromImage($img: JQuery<HTMLElement>) {
|
||||
async function parseFromImage($img: JQuery<HTMLElement>): Promise<{ noteId: string; viewScope: ViewScope } | null> {
|
||||
const imgSrc = $img.prop("src");
|
||||
|
||||
const imageNoteMatch = imgSrc.match(/\/api\/images\/([A-Za-z0-9_]+)\//);
|
||||
@ -81,9 +81,10 @@ async function parseFromImage($img: JQuery<HTMLElement>) {
|
||||
if (attachmentMatch) {
|
||||
const attachmentId = attachmentMatch[1];
|
||||
const attachment = await froca.getAttachment(attachmentId);
|
||||
if (!attachment) return null;
|
||||
|
||||
return {
|
||||
noteId: attachment?.ownerId,
|
||||
noteId: attachment.ownerId,
|
||||
viewScope: {
|
||||
viewMode: "attachments",
|
||||
attachmentId: attachmentId
|
||||
|
||||
@ -1,87 +0,0 @@
|
||||
import NoteContextAwareWidget from "../note_context_aware_widget.js";
|
||||
import appContext, { type EventData, type EventNames } from "../../components/app_context.js";
|
||||
import type FNote from "../../entities/fnote.js";
|
||||
import type NoteDetailWidget from "../note_detail.js";
|
||||
import type SpacedUpdate from "../../services/spaced_update.js";
|
||||
import type EmptyTypeWidget from "./empty.js";
|
||||
|
||||
/**
|
||||
* The base class for all the note types.
|
||||
*/
|
||||
export default abstract class TypeWidget extends NoteContextAwareWidget {
|
||||
|
||||
spacedUpdate!: SpacedUpdate;
|
||||
|
||||
// for overriding
|
||||
static getType() {}
|
||||
|
||||
doRender() {
|
||||
return super.doRender();
|
||||
}
|
||||
|
||||
doRefresh(note: FNote): void | Promise<void> {}
|
||||
|
||||
async refresh() {
|
||||
const thisWidgetType = (this.constructor as any).getType();
|
||||
const noteWidgetType = await (this.parent as NoteDetailWidget).getWidgetType();
|
||||
|
||||
if (thisWidgetType !== noteWidgetType) {
|
||||
this.toggleInt(false);
|
||||
|
||||
this.cleanup();
|
||||
} else {
|
||||
this.toggleInt(true);
|
||||
|
||||
// Avoid passing nullable this.note down to doRefresh().
|
||||
if (thisWidgetType !== "empty" && this.note) {
|
||||
await this.doRefresh(this.note);
|
||||
} else if (thisWidgetType === "empty") {
|
||||
// EmptyTypeWidget is a special case, since it's used for a new tab where there's no note.
|
||||
await (this as unknown as EmptyTypeWidget).doRefresh();
|
||||
}
|
||||
|
||||
this.triggerEvent("noteDetailRefreshed", { ntxId: this.noteContext?.ntxId });
|
||||
}
|
||||
}
|
||||
|
||||
isActive() {
|
||||
return this.$widget.is(":visible") && this.noteContext?.ntxId === appContext.tabManager.activeNtxId;
|
||||
}
|
||||
|
||||
/** @returns {Promise<Object>|*} promise resolving note data. Note data is an object with content. */
|
||||
getData() {}
|
||||
|
||||
focus() {}
|
||||
|
||||
scrollToEnd() {
|
||||
// Do nothing by default.
|
||||
}
|
||||
|
||||
dataSaved() {
|
||||
// Do nothing by default.
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* By default:
|
||||
*
|
||||
* - `activeContextChanged` is intercepted and converted to a `setNoteContext` event to avoid `refresh()`.
|
||||
* - `entitiesReloaded` and `refreshData` are passed as-is.
|
||||
* - any other event is not passed to the children.
|
||||
*/
|
||||
handleEventInChildren<T extends EventNames>(name: T, data: EventData<T>) {
|
||||
if (["activeContextChanged", "setNoteContext"].includes(name)) {
|
||||
// won't trigger .refresh();
|
||||
return super.handleEventInChildren("setNoteContext", data as EventData<"activeContextChanged">);
|
||||
} else if (name === "entitiesReloaded" || name === "refreshData") {
|
||||
return super.handleEventInChildren(name, data);
|
||||
} else {
|
||||
return Promise.resolve();
|
||||
}
|
||||
}
|
||||
|
||||
cleanup(): void {
|
||||
super.cleanup();
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user