chore(client): fix most type errors

This commit is contained in:
Elian Doran 2025-05-28 20:42:21 +03:00
parent cb7aee742e
commit 26c1cbeff1
No known key found for this signature in database
26 changed files with 75 additions and 79 deletions

View File

@ -27,6 +27,7 @@ import type EditableTextTypeWidget from "../widgets/type_widgets/editable_text.j
import type { NativeImage, TouchBar } from "electron"; import type { NativeImage, TouchBar } from "electron";
import TouchBarComponent from "./touch_bar.js"; import TouchBarComponent from "./touch_bar.js";
import type { CKTextEditor } from "@triliumnext/ckeditor5"; import type { CKTextEditor } from "@triliumnext/ckeditor5";
import type CodeMirror from "@triliumnext/codemirror";
interface Layout { interface Layout {
getRootWidget: (appContext: AppContext) => RootWidget; getRootWidget: (appContext: AppContext) => RootWidget;
@ -191,7 +192,7 @@ export type CommandMappings = {
ExecuteCommandData<CKTextEditor> & { ExecuteCommandData<CKTextEditor> & {
callback?: GetTextEditorCallback; callback?: GetTextEditorCallback;
}; };
executeWithCodeEditor: CommandData & ExecuteCommandData<CodeMirrorInstance>; executeWithCodeEditor: CommandData & ExecuteCommandData<CodeMirror>;
/** /**
* Called upon when attempting to retrieve the content element of a {@link NoteContext}. * Called upon when attempting to retrieve the content element of a {@link NoteContext}.
* Generally should not be invoked manually, as it is used by {@link NoteContext.getContentElement}. * Generally should not be invoked manually, as it is used by {@link NoteContext.getContentElement}.

View File

@ -54,7 +54,7 @@ export default class TouchBarComponent extends Component {
#refreshTouchBar() { #refreshTouchBar() {
const { TouchBar } = this.remote; const { TouchBar } = this.remote;
const parentComponent = this.lastFocusedComponent; const parentComponent = this.lastFocusedComponent;
let touchBar = null; let touchBar: Electron.CrossProcessExports.TouchBar | null = null;
if (this.$activeModal?.length) { if (this.$activeModal?.length) {
touchBar = this.#buildModalTouchBar(); touchBar = this.#buildModalTouchBar();

View File

@ -789,7 +789,7 @@ class FNote {
*/ */
async getRelationTargets(name: string) { async getRelationTargets(name: string) {
const relations = this.getRelations(name); const relations = this.getRelations(name);
const targets = []; const targets: (FNote | null)[] = [];
for (const relation of relations) { for (const relation of relations) {
targets.push(await this.froca.getNote(relation.value)); targets.push(await this.froca.getNote(relation.value));

View File

@ -80,7 +80,7 @@ async function copy(branchIds: string[]) {
if (utils.isElectron()) { if (utils.isElectron()) {
// https://github.com/zadam/trilium/issues/2401 // https://github.com/zadam/trilium/issues/2401
const { clipboard } = require("electron"); const { clipboard } = require("electron");
const links = []; const links: string[] = [];
for (const branch of froca.getBranches(clipboardBranchIds)) { for (const branch of froca.getBranches(clipboardBranchIds)) {
const $link = await linkService.createLink(`${branch.parentNoteId}/${branch.noteId}`, { referenceLink: true }); const $link = await linkService.createLink(`${branch.parentNoteId}/${branch.noteId}`, { referenceLink: true });

View File

@ -50,7 +50,7 @@ async function processEntityChanges(entityChanges: EntityChange[]) {
// To this we count: standard parent-child relationships and template/inherit relations (attribute inheritance follows them). // To this we count: standard parent-child relationships and template/inherit relations (attribute inheritance follows them).
// Here we watch for changes which might violate this principle - e.g., an introduction of a new "inherit" relation might // Here we watch for changes which might violate this principle - e.g., an introduction of a new "inherit" relation might
// mean we need to load the target of the relation (and then perhaps transitively the whole note path of this target). // mean we need to load the target of the relation (and then perhaps transitively the whole note path of this target).
const missingNoteIds = []; const missingNoteIds: string[] = [];
for (const { entityName, entity } of entityChanges) { for (const { entityName, entity } of entityChanges) {
if (!entity) { if (!entity) {

View File

@ -215,9 +215,9 @@ export function parseNavigationStateFromUrl(url: string | undefined) {
const viewScope: ViewScope = { const viewScope: ViewScope = {
viewMode: "default" viewMode: "default"
}; };
let ntxId = null; let ntxId: string | null = null;
let hoistedNoteId = null; let hoistedNoteId: string | null = null;
let searchString = null; let searchString: string | null = null;
if (paramString) { if (paramString) {
for (const pair of paramString.split("&")) { for (const pair of paramString.split("&")) {

View File

@ -1,7 +1,7 @@
type LabelType = "text" | "number" | "boolean" | "date" | "datetime" | "time" | "url"; type LabelType = "text" | "number" | "boolean" | "date" | "datetime" | "time" | "url";
type Multiplicity = "single" | "multi"; type Multiplicity = "single" | "multi";
interface DefinitionObject { export interface DefinitionObject {
isPromoted?: boolean; isPromoted?: boolean;
labelType?: LabelType; labelType?: LabelType;
multiplicity?: Multiplicity; multiplicity?: Multiplicity;

View File

@ -34,8 +34,8 @@ async function resolveNotePathToSegments(notePath: string, hoistedNoteId = "root
path.push("root"); path.push("root");
} }
const effectivePathSegments = []; const effectivePathSegments: string[] = [];
let childNoteId = null; let childNoteId: string | null = null;
let i = 0; let i = 0;
while (true) { while (true) {
@ -197,7 +197,7 @@ function getNotePath(node: Fancytree.FancytreeNode) {
return ""; return "";
} }
const path = []; const path: string[] = [];
while (node) { while (node) {
if (node.data.noteId) { if (node.data.noteId) {
@ -236,7 +236,7 @@ async function getNoteTitle(noteId: string, parentNoteId: string | null = null)
} }
async function getNotePathTitleComponents(notePath: string) { async function getNotePathTitleComponents(notePath: string) {
const titleComponents = []; const titleComponents: string[] = [];
if (notePath.startsWith("root/")) { if (notePath.startsWith("root/")) {
notePath = notePath.substr(5); notePath = notePath.substr(5);

View File

@ -51,7 +51,7 @@ function getMonthsInDateRange(startDate: string, endDate: string) {
const end = endDate.split("-"); const end = endDate.split("-");
const startYear = parseInt(start[0]); const startYear = parseInt(start[0]);
const endYear = parseInt(end[0]); const endYear = parseInt(end[0]);
const dates = []; const dates: string[] = [];
for (let i = startYear; i <= endYear; i++) { for (let i = startYear; i <= endYear; i++) {
const endMonth = i != endYear ? 11 : parseInt(end[1]) - 1; const endMonth = i != endYear ? 11 : parseInt(end[1]) - 1;
@ -84,7 +84,7 @@ function formatTimeInterval(ms: number) {
const hours = Math.floor(minutes / 60); const hours = Math.floor(minutes / 60);
const days = Math.floor(hours / 24); const days = Math.floor(hours / 24);
const plural = (count: number, name: string) => `${count} ${name}${count > 1 ? "s" : ""}`; const plural = (count: number, name: string) => `${count} ${name}${count > 1 ? "s" : ""}`;
const segments = []; const segments: string[] = [];
if (days > 0) { if (days > 0) {
segments.push(plural(days, "day")); segments.push(plural(days, "day"));
@ -149,7 +149,7 @@ function isMac() {
export const hasTouchBar = (isMac() && isElectron()); export const hasTouchBar = (isMac() && isElectron());
function isCtrlKey(evt: KeyboardEvent | MouseEvent | JQuery.ClickEvent | JQuery.ContextMenuEvent | JQuery.TriggeredEvent | React.PointerEvent<HTMLCanvasElement>) { function isCtrlKey(evt: KeyboardEvent | MouseEvent | JQuery.ClickEvent | JQuery.ContextMenuEvent | JQuery.TriggeredEvent | React.PointerEvent<HTMLCanvasElement> | JQueryEventObject) {
return (!isMac() && evt.ctrlKey) || (isMac() && evt.metaKey); return (!isMac() && evt.ctrlKey) || (isMac() && evt.metaKey);
} }

View File

@ -28,7 +28,7 @@ interface NoteDefinition extends AttributeDefinitions, RelationDefinitions {
* ]); * ]);
*/ */
export function buildNotes(notes: NoteDefinition[]) { export function buildNotes(notes: NoteDefinition[]) {
const ids = []; const ids: string[] = [];
for (const noteDef of notes) { for (const noteDef of notes) {
ids.push(buildNote(noteDef).noteId); ids.push(buildNote(noteDef).noteId);

View File

@ -718,7 +718,7 @@ export default class AttributeDetailWidget extends NoteContextAwareWidget {
} }
buildDefinitionValue() { buildDefinitionValue() {
const props = []; const props: string[] = [];
if (this.$inputPromoted.is(":checked")) { if (this.$inputPromoted.is(":checked")) {
props.push("promoted"); props.push("promoted");
@ -728,10 +728,10 @@ export default class AttributeDetailWidget extends NoteContextAwareWidget {
} }
} }
props.push(this.$inputMultiplicity.val()); props.push(this.$inputMultiplicity.val() as string);
if (this.attrType === "label-definition") { if (this.attrType === "label-definition") {
props.push(this.$inputLabelType.val()); props.push(this.$inputLabelType.val() as string);
if (this.$inputLabelType.val() === "number" && this.$inputNumberPrecision.val() !== "") { if (this.$inputLabelType.val() === "number" && this.$inputNumberPrecision.val() !== "") {
props.push(`precision=${this.$inputNumberPrecision.val()}`); props.push(`precision=${this.$inputNumberPrecision.val()}`);

View File

@ -29,7 +29,7 @@ export default class LauncherContainer extends FlexContainer<LauncherWidget> {
return; return;
} }
const newChildren = []; const newChildren: LauncherWidget[] = [];
for (const launcherNote of await visibleLaunchersRoot.getChildNotes()) { for (const launcherNote of await visibleLaunchersRoot.getChildNotes()) {
try { try {

View File

@ -217,7 +217,7 @@ export default class SplitNoteContainer extends FlexContainer<SplitNoteWidget> {
} }
refreshNotShown(data: NoteSwitchedContext | EventData<"activeContextChanged">) { refreshNotShown(data: NoteSwitchedContext | EventData<"activeContextChanged">) {
const promises = []; const promises: (Promise<unknown> | null | undefined)[] = [];
for (const subContext of data.noteContext.getMainContext().getSubContexts()) { for (const subContext of data.noteContext.getMainContext().getSubContexts()) {
if (!subContext.ntxId) { if (!subContext.ntxId) {

View File

@ -2,16 +2,6 @@ import type { FindAndReplaceState, FindCommandResult } from "@triliumnext/ckedit
import type { FindResult } from "./find.js"; import type { FindResult } from "./find.js";
import type FindWidget from "./find.js"; import type FindWidget from "./find.js";
// TODO: Deduplicate.
interface Match {
className: string;
clear(): void;
find(): {
from: number;
to: number;
};
}
export default class FindInText { export default class FindInText {
private parent: FindWidget; private parent: FindWidget;
@ -35,7 +25,7 @@ export default class FindInText {
} }
const model = textEditor.model; const model = textEditor.model;
let findResult = null; let findResult: FindCommandResult | null = null;
let totalFound = 0; let totalFound = 0;
let currentFound = -1; let currentFound = -1;

View File

@ -243,7 +243,7 @@ export default class HighlightsListWidget extends RightPanelWidget {
// Used to determine if a string is only a formula // Used to determine if a string is only a formula
const onlyMathRegex = /^<span class="math-tex">\\\([^\)]*?\)<\/span>(?:<span class="math-tex">\\\([^\)]*?\)<\/span>)*$/; const onlyMathRegex = /^<span class="math-tex">\\\([^\)]*?\)<\/span>(?:<span class="math-tex">\\\([^\)]*?\)<\/span>)*$/;
for (let match = null, hltIndex = 0; (match = combinedRegex.exec(content)) !== null; hltIndex++) { for (let match: RegExpMatchArray | null = null, hltIndex = 0; (match = combinedRegex.exec(content)) !== null; hltIndex++) {
const subHtml = match[0]; const subHtml = match[0];
const startIndex = match.index; const startIndex = match.index;
const endIndex = combinedRegex.lastIndex; const endIndex = combinedRegex.lastIndex;
@ -324,8 +324,9 @@ export default class HighlightsListWidget extends RightPanelWidget {
}); });
} else { } else {
const textEditor = await this.noteContext.getTextEditor(); const textEditor = await this.noteContext.getTextEditor();
if (textEditor) { const el = textEditor?.editing.view.domRoots.values().next().value;
targetElement = $(textEditor.editing.view.domRoots.values().next().value) if (el) {
targetElement = $(el)
.find(findSubStr) .find(findSubStr)
.filter(function () { .filter(function () {
// When finding span[style*="color"] but not looking for span[style*="background-color"], // When finding span[style*="color"] but not looking for span[style*="background-color"],

View File

@ -350,7 +350,7 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
}, },
scrollParent: this.$tree, scrollParent: this.$tree,
minExpandLevel: 2, // root can't be collapsed minExpandLevel: 2, // root can't be collapsed
click: (event: MouseEvent | JQuery.ClickEvent | JQuery.MouseDownEvent | React.PointerEvent<HTMLCanvasElement>, data): boolean => { click: (event, data): boolean => {
this.activityDetected(); this.activityDetected();
const targetType = data.targetType; const targetType = data.targetType;
@ -745,7 +745,7 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
prepareChildren(parentNote: FNote) { prepareChildren(parentNote: FNote) {
utils.assertArguments(parentNote); utils.assertArguments(parentNote);
const noteList = []; const noteList: Node[] = [];
const hideArchivedNotes = this.hideArchivedNotes; const hideArchivedNotes = this.hideArchivedNotes;
@ -839,7 +839,7 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
getExtraClasses(note: FNote) { getExtraClasses(note: FNote) {
utils.assertArguments(note); utils.assertArguments(note);
const extraClasses = []; const extraClasses: string[] = [];
if (note.isProtected) { if (note.isProtected) {
extraClasses.push("protected"); extraClasses.push("protected");
@ -1265,8 +1265,8 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
const allBranchesDeleted = branchRows.every((branchRow) => !!branchRow.isDeleted); const allBranchesDeleted = branchRows.every((branchRow) => !!branchRow.isDeleted);
// activeNode is supposed to be moved when we find out activeNode is deleted but not all branches are deleted. save it for fixing activeNodePath after all nodes loaded. // activeNode is supposed to be moved when we find out activeNode is deleted but not all branches are deleted. save it for fixing activeNodePath after all nodes loaded.
let movedActiveNode = null; let movedActiveNode: Fancytree.FancytreeNode | null = null;
let parentsOfAddedNodes = []; let parentsOfAddedNodes: Fancytree.FancytreeNode[] = [];
for (const branchRow of branchRows) { for (const branchRow of branchRows) {
if (branchRow.noteId) { if (branchRow.noteId) {

View File

@ -85,7 +85,7 @@ export default class NotePathsWidget extends NoteContextAwareWidget {
this.$notePathIntro.text(t("note_paths.intro_not_placed")); this.$notePathIntro.text(t("note_paths.intro_not_placed"));
} }
const renderedPaths = []; const renderedPaths: JQuery<HTMLElement>[] = [];
for (const notePathRecord of sortedNotePaths) { for (const notePathRecord of sortedNotePaths) {
const notePath = notePathRecord.notePath; const notePath = notePathRecord.notePath;
@ -100,7 +100,7 @@ export default class NotePathsWidget extends NoteContextAwareWidget {
const $pathItem = $("<li>"); const $pathItem = $("<li>");
const pathSegments: string[] = []; const pathSegments: string[] = [];
const lastIndex = notePath.length - 1; const lastIndex = notePath.length - 1;
for (let i = 0; i < notePath.length; i++) { for (let i = 0; i < notePath.length; i++) {
const noteId = notePath[i]; const noteId = notePath[i];
pathSegments.push(noteId); pathSegments.push(noteId);
@ -109,13 +109,13 @@ export default class NotePathsWidget extends NoteContextAwareWidget {
$noteLink.find("a").addClass("no-tooltip-preview tn-link"); $noteLink.find("a").addClass("no-tooltip-preview tn-link");
$pathItem.append($noteLink); $pathItem.append($noteLink);
if (i != lastIndex) { if (i != lastIndex) {
$pathItem.append(" / "); $pathItem.append(" / ");
} }
} }
const icons = []; const icons: string[] = [];
if (this.notePath === notePath.join("/")) { if (this.notePath === notePath.join("/")) {
$pathItem.addClass("path-current"); $pathItem.addClass("path-current");

View File

@ -122,7 +122,7 @@ export default class PromotedAttributesWidget extends NoteContextAwareWidget {
return; return;
} }
const $cells = []; const $cells: JQuery<HTMLElement>[] = [];
for (const definitionAttr of promotedDefAttrs) { for (const definitionAttr of promotedDefAttrs) {
const valueType = definitionAttr.name.startsWith("label:") ? "label" : "relation"; const valueType = definitionAttr.name.startsWith("label:") ? "label" : "relation";

View File

@ -208,7 +208,7 @@ const TAB_ROW_TPL = `
color: var(--active-tab-text-color); color: var(--active-tab-text-color);
box-shadow: inset -1px 0 0 0 var(--main-border-color); box-shadow: inset -1px 0 0 0 var(--main-border-color);
} }
.tab-scroll-button-right { .tab-scroll-button-right {
color: var(--active-tab-text-color); color: var(--active-tab-text-color);
box-shadow: inset 1px 0 0 0 var(--main-border-color); box-shadow: inset 1px 0 0 0 var(--main-border-color);
@ -279,7 +279,7 @@ const TAB_ROW_TPL = `
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
.tab-row-widget-scrolling-container { .tab-row-widget-scrolling-container {
overflow-x: auto; overflow-x: auto;
overflow-y: hidden; overflow-y: hidden;
@ -287,9 +287,9 @@ const TAB_ROW_TPL = `
} }
/* Chrome/Safari */ /* Chrome/Safari */
.tab-row-widget-scrolling-container::-webkit-scrollbar { .tab-row-widget-scrolling-container::-webkit-scrollbar {
display: none; display: none;
} }
</style> </style>
<div class="tab-scroll-button-left bx bx-chevron-left"></div> <div class="tab-scroll-button-left bx bx-chevron-left"></div>
<div class="tab-row-widget-scrolling-container"> <div class="tab-row-widget-scrolling-container">
@ -480,7 +480,7 @@ export default class TabRowWidget extends BasicWidget {
const totalTabsWidthUsingTarget = flooredClampedTargetWidth * numberOfTabs + marginWidth; const totalTabsWidthUsingTarget = flooredClampedTargetWidth * numberOfTabs + marginWidth;
const totalExtraWidthDueToFlooring = tabsContainerWidth - totalTabsWidthUsingTarget; const totalExtraWidthDueToFlooring = tabsContainerWidth - totalTabsWidthUsingTarget;
const widths = []; const widths: number[] = [];
let extraWidthRemaining = totalExtraWidthDueToFlooring; let extraWidthRemaining = totalExtraWidthDueToFlooring;
for (let i = 0; i < numberOfTabs; i += 1) { for (let i = 0; i < numberOfTabs; i += 1) {

View File

@ -64,7 +64,7 @@ const TPL = /*html*/`<div class="toc-widget">
} }
.toc > ol { .toc > ol {
--toc-depth-level: 1; --toc-depth-level: 1;
} }
.toc > ol > ol { .toc > ol > ol {
--toc-depth-level: 2; --toc-depth-level: 2;
@ -84,7 +84,7 @@ const TPL = /*html*/`<div class="toc-widget">
} }
.toc li { .toc li {
padding-left: calc((var(--toc-depth-level) - 1) * 20px + 4px); padding-left: calc((var(--toc-depth-level) - 1) * 20px + 4px);
} }
.toc li .collapse-button { .toc li .collapse-button {
@ -304,7 +304,7 @@ export default class TocWidget extends RightPanelWidget {
const validHeadingKeys = new Set<string>(); // Used to clean up obsolete entries in tocCollapsedHeadings const validHeadingKeys = new Set<string>(); // Used to clean up obsolete entries in tocCollapsedHeadings
let headingCount = 0; let headingCount = 0;
for (let m = null, headingIndex = 0; (m = headingTagsRegex.exec(html)) !== null; headingIndex++) { for (let m: RegExpMatchArray | null = null, headingIndex = 0; (m = headingTagsRegex.exec(html)) !== null; headingIndex++) {
// //
// Nest/unnest whatever necessary number of ordered lists // Nest/unnest whatever necessary number of ordered lists
// //
@ -394,12 +394,14 @@ export default class TocWidget extends RightPanelWidget {
const isDocNote = this.note.type === "doc"; const isDocNote = this.note.type === "doc";
const isReadOnly = await this.noteContext.isReadOnly(); const isReadOnly = await this.noteContext.isReadOnly();
let $container; let $container: JQuery<HTMLElement> | null = null;
if (isReadOnly || isDocNote) { if (isReadOnly || isDocNote) {
$container = await this.noteContext.getContentElement(); $container = await this.noteContext.getContentElement();
} else { } else {
const textEditor = await this.noteContext.getTextEditor(); const textEditor = await this.noteContext.getTextEditor();
$container = $(textEditor.sourceElement); if (textEditor?.sourceElement) {
$container = $(textEditor.sourceElement);
}
} }
const headingElement = $container?.find(":header:not(section.include-note :header)")?.[headingIndex]; const headingElement = $container?.find(":header:not(section.include-note :header)")?.[headingIndex];

View File

@ -138,8 +138,8 @@ export default abstract class AbstractSvgSplitTypeWidget extends AbstractSplitTy
*/ */
async #setupPanZoom(preservePanZoom: boolean) { async #setupPanZoom(preservePanZoom: boolean) {
// Clean up // Clean up
let pan = null; let pan: SvgPanZoom.Point | null = null;
let zoom = null; let zoom: number | null = null;
if (preservePanZoom && this.zoomInstance) { if (preservePanZoom && this.zoomInstance) {
// Store pan and zoom for same note, when the user is editing the note. // Store pan and zoom for same note, when the user is editing the note.
pan = this.zoomInstance.getPan(); pan = this.zoomInstance.getPan();

View File

@ -134,7 +134,7 @@ export function buildToolbarConfig(isClassicToolbar: boolean) {
export function buildMobileToolbar() { export function buildMobileToolbar() {
const classicConfig = buildClassicToolbar(false); const classicConfig = buildClassicToolbar(false);
const items = []; const items: string[] = [];
for (const item of classicConfig.toolbar.items) { for (const item of classicConfig.toolbar.items) {
if (typeof item === "object" && "items" in item) { if (typeof item === "object" && "items" in item) {

View File

@ -589,7 +589,7 @@ export default class EditableTextTypeWidget extends AbstractTextTypeWidget {
backgroundColor: buildSelectedBackgroundColor(editor.commands.get(command)?.value as boolean) backgroundColor: buildSelectedBackgroundColor(editor.commands.get(command)?.value as boolean)
}); });
let headingSelectedIndex = undefined; let headingSelectedIndex: number | undefined = undefined;
const headingCommand = editor.commands.get("heading"); const headingCommand = editor.commands.get("heading");
const paragraphCommand = editor.commands.get("paragraph"); const paragraphCommand = editor.commands.get("paragraph");
if (paragraphCommand?.value) { if (paragraphCommand?.value) {

View File

@ -207,8 +207,8 @@ export default class MindMapWidget extends TypeWidget {
await this.#initLibrary(content?.direction); await this.#initLibrary(content?.direction);
} }
this.mind.refresh(content ?? this.MindElixir.new(NEW_TOPIC_NAME)); this.mind!.refresh(content ?? this.MindElixir.new(NEW_TOPIC_NAME));
this.mind.toCenter(); this.mind!.toCenter();
} }
async #initLibrary(direction?: number) { async #initLibrary(direction?: number) {
@ -259,7 +259,7 @@ export default class MindMapWidget extends TypeWidget {
} }
async renderSvg() { async renderSvg() {
return await this.mind.exportSvg().text(); return await this.mind!.exportSvg().text();
} }
async entitiesReloadedEvent({ loadResults }: EventData<"entitiesReloaded">) { async entitiesReloadedEvent({ loadResults }: EventData<"entitiesReloaded">) {

View File

@ -198,7 +198,7 @@ export default class AiSettingsWidget extends OptionsWidget {
const providerPrecedence = (this.$widget.find('.ai-provider-precedence').val() as string || '').split(','); const providerPrecedence = (this.$widget.find('.ai-provider-precedence').val() as string || '').split(',');
// Check for OpenAI configuration if it's in the precedence list // Check for OpenAI configuration if it's in the precedence list
const openaiWarnings = []; const openaiWarnings: string[] = [];
if (providerPrecedence.includes('openai')) { if (providerPrecedence.includes('openai')) {
const openaiApiKey = this.$widget.find('.openai-api-key').val(); const openaiApiKey = this.$widget.find('.openai-api-key').val();
if (!openaiApiKey) { if (!openaiApiKey) {
@ -207,7 +207,7 @@ export default class AiSettingsWidget extends OptionsWidget {
} }
// Check for Anthropic configuration if it's in the precedence list // Check for Anthropic configuration if it's in the precedence list
const anthropicWarnings = []; const anthropicWarnings: string[] = [];
if (providerPrecedence.includes('anthropic')) { if (providerPrecedence.includes('anthropic')) {
const anthropicApiKey = this.$widget.find('.anthropic-api-key').val(); const anthropicApiKey = this.$widget.find('.anthropic-api-key').val();
if (!anthropicApiKey) { if (!anthropicApiKey) {
@ -216,7 +216,7 @@ export default class AiSettingsWidget extends OptionsWidget {
} }
// Check for Voyage configuration if it's in the precedence list // Check for Voyage configuration if it's in the precedence list
const voyageWarnings = []; const voyageWarnings: string[] = [];
if (providerPrecedence.includes('voyage')) { if (providerPrecedence.includes('voyage')) {
const voyageApiKey = this.$widget.find('.voyage-api-key').val(); const voyageApiKey = this.$widget.find('.voyage-api-key').val();
if (!voyageApiKey) { if (!voyageApiKey) {
@ -225,7 +225,7 @@ export default class AiSettingsWidget extends OptionsWidget {
} }
// Check for Ollama configuration if it's in the precedence list // Check for Ollama configuration if it's in the precedence list
const ollamaWarnings = []; const ollamaWarnings: string[] = [];
if (providerPrecedence.includes('ollama')) { if (providerPrecedence.includes('ollama')) {
const ollamaBaseUrl = this.$widget.find('.ollama-base-url').val(); const ollamaBaseUrl = this.$widget.find('.ollama-base-url').val();
if (!ollamaBaseUrl) { if (!ollamaBaseUrl) {
@ -234,7 +234,7 @@ export default class AiSettingsWidget extends OptionsWidget {
} }
// Similar checks for embeddings // Similar checks for embeddings
const embeddingWarnings = []; const embeddingWarnings: string[] = [];
const embeddingsEnabled = this.$widget.find('.enable-automatic-indexing').prop('checked'); const embeddingsEnabled = this.$widget.find('.enable-automatic-indexing').prop('checked');
if (embeddingsEnabled) { if (embeddingsEnabled) {

View File

@ -83,6 +83,13 @@ interface CreateChildResponse {
}; };
} }
interface Event {
startDate: string,
endDate?: string | null,
startTime?: string | null,
endTime?: string | null
}
const CALENDAR_VIEWS = [ const CALENDAR_VIEWS = [
"timeGridWeek", "timeGridWeek",
"dayGridMonth", "dayGridMonth",
@ -325,8 +332,8 @@ export default class CalendarView extends ViewMode {
} }
#parseStartEndTimeFromEvent(e: DateSelectArg | EventImpl) { #parseStartEndTimeFromEvent(e: DateSelectArg | EventImpl) {
let startTime = null; let startTime: string | undefined | null = null;
let endTime = null; let endTime: string | undefined | null = null;
if (!e.allDay) { if (!e.allDay) {
startTime = CalendarView.#formatTimeToLocalISO(e.start); startTime = CalendarView.#formatTimeToLocalISO(e.start);
endTime = CalendarView.#formatTimeToLocalISO(e.end); endTime = CalendarView.#formatTimeToLocalISO(e.end);
@ -391,7 +398,7 @@ export default class CalendarView extends ViewMode {
} }
async #buildEventsForCalendar(e: EventSourceFuncArg) { async #buildEventsForCalendar(e: EventSourceFuncArg) {
const events = []; const events: EventInput[] = [];
// Gather all the required date note IDs. // Gather all the required date note IDs.
const dateRange = utils.getMonthsInDateRange(e.startStr, e.endStr); const dateRange = utils.getMonthsInDateRange(e.startStr, e.endStr);
@ -483,12 +490,7 @@ export default class CalendarView extends ViewMode {
return note.getLabelValue(defaultLabelName); return note.getLabelValue(defaultLabelName);
} }
static async buildEvent(note: FNote, { startDate, endDate, startTime, endTime }: { static async buildEvent(note: FNote, { startDate, endDate, startTime, endTime }: Event) {
startDate: string,
endDate?: string | null,
startTime?: string | null,
endTime?: string | null
}) {
const customTitleAttributeName = note.getLabelValue("calendar:title"); const customTitleAttributeName = note.getLabelValue("calendar:title");
const titles = await CalendarView.#parseCustomTitle(customTitleAttributeName, note); const titles = await CalendarView.#parseCustomTitle(customTitleAttributeName, note);
const color = note.getLabelValue("calendar:color") ?? note.getLabelValue("color"); const color = note.getLabelValue("calendar:color") ?? note.getLabelValue("color");
@ -553,7 +555,7 @@ export default class CalendarView extends ViewMode {
if (relations.length > 0) { if (relations.length > 0) {
const noteIds = relations.map((r) => r.targetNoteId); const noteIds = relations.map((r) => r.targetNoteId);
const notesFromRelation = await froca.getNotes(noteIds); const notesFromRelation = await froca.getNotes(noteIds);
const titles = []; const titles: string[][] = [];
for (const targetNote of notesFromRelation) { for (const targetNote of notesFromRelation) {
const targetCustomTitleValue = targetNote.getAttributeValue("label", "calendar:title"); const targetCustomTitleValue = targetNote.getAttributeValue("label", "calendar:title");
@ -631,7 +633,7 @@ export default class CalendarView extends ViewMode {
// Icon button. // Icon button.
const iconEl = subItem.querySelector("span.fc-icon"); const iconEl = subItem.querySelector("span.fc-icon");
let icon = null; let icon: string | null = null;
if (iconEl?.classList.contains("fc-icon-chevron-left")) { if (iconEl?.classList.contains("fc-icon-chevron-left")) {
icon = "NSImageNameTouchBarGoBackTemplate"; icon = "NSImageNameTouchBarGoBackTemplate";
mode = "buttons"; mode = "buttons";