diff --git a/app/editor/extensions/FindAndReplace.tsx b/app/editor/extensions/FindAndReplace.tsx index 97c1d3749e..d7be21a71c 100644 --- a/app/editor/extensions/FindAndReplace.tsx +++ b/app/editor/extensions/FindAndReplace.tsx @@ -402,13 +402,14 @@ export default class FindAndReplaceExtension extends Extension { */ private get decorations() { return this.results.map((deco, index) => { - const decorationType = - deco.type === "node" ? Decoration.node : Decoration.inline; - return decorationType(deco.from, deco.to, { + const attrs = { class: "find-result" + (this.currentResultIndex === index ? " current-result" : ""), - }); + }; + return deco.type === "node" + ? Decoration.node(deco.from, deco.to, attrs) + : Decoration.inline(deco.from, deco.to, attrs); }); } diff --git a/app/scenes/Errors/Error403.tsx b/app/scenes/Errors/Error403.tsx index 3a9260e163..5c0c51d213 100644 --- a/app/scenes/Errors/Error403.tsx +++ b/app/scenes/Errors/Error403.tsx @@ -1,3 +1,4 @@ +import { useCallback } from "react"; import { useTranslation } from "react-i18next"; import { useHistory } from "react-router-dom"; import Button from "~/components/Button"; @@ -11,6 +12,7 @@ import { VStack } from "~/components/primitives/VStack"; const Error403 = () => { const { t } = useTranslation(); const history = useHistory(); + const handleGoBack = useCallback(() => history.goBack(), [history]); return ( @@ -26,7 +28,7 @@ const Error403 = () => { - diff --git a/app/scenes/Search/Search.tsx b/app/scenes/Search/Search.tsx index fca52e9bc2..bdbe4abd15 100644 --- a/app/scenes/Search/Search.tsx +++ b/app/scenes/Search/Search.tsx @@ -52,6 +52,7 @@ function Search() { const location = useLocation(); const history = useHistory(); const routeMatch = useRouteMatch<{ query: string }>(); + const handleGoBack = React.useCallback(() => history.goBack(), [history]); // refs const searchInputRef = React.useRef(null); @@ -249,7 +250,7 @@ function Search() { textTitle={query ? `${query} – ${t("Search")}` : t("Search")} actions={isMobile ? sortInput : null} > - + {loading && }
diff --git a/plugins/linear/server/linear.ts b/plugins/linear/server/linear.ts index 1557e64038..0c44992ca8 100644 --- a/plugins/linear/server/linear.ts +++ b/plugins/linear/server/linear.ts @@ -174,7 +174,7 @@ export class Linear { const [author, state, labels] = await Promise.all([ issue.creator, issue.state, - issue.paginate(issue.labels, {}), + issue.paginate((args) => issue.labels(args), {}), ]); if (!state || !labels) { @@ -229,7 +229,7 @@ export class Linear { const [lead, status, labels] = await Promise.all([ project.lead, project.status, - project.paginate(project.labels, {}), + project.paginate((args) => project.labels(args), {}), ]); if (!status || !labels) { @@ -280,12 +280,15 @@ export class Linear { return defaultCompletionPercentage; } - const allStates = await client.paginate(client.workflowStates, { - filter: { - team: { id: { eq: team.id } }, - type: { eq: "started" }, - }, - }); + const allStates = await client.paginate( + (args) => client.workflowStates(args), + { + filter: { + team: { id: { eq: team.id } }, + type: { eq: "started" }, + }, + } + ); const states = sortBy( allStates.map((s) => ({ name: s.name, diff --git a/server/storage/database.ts b/server/storage/database.ts index a6b078f197..89adbfba1e 100644 --- a/server/storage/database.ts +++ b/server/storage/database.ts @@ -249,18 +249,16 @@ export function monkeyPatchSequelizeErrorsForJest(instance: Sequelize) { ); } - const origQueryFunc = instance.query; - instance.query = async function query(this: Sequelize, ...args: any[]) { - let result; + const origQueryFunc = instance.query.bind(instance); + instance.query = (async (...args: any[]) => { try { - result = await origQueryFunc.apply(this, args as any); + return await origQueryFunc(...(args as Parameters)); } catch (err: any) { // Ensure error appears in Jest output, not swallowed by Sequelize internals Logger.error(err.message, err.parent); throw err; } - return result; - } as typeof origQueryFunc; + }) as typeof instance.query; return instance; } diff --git a/shared/editor/commands/insertFiles.ts b/shared/editor/commands/insertFiles.ts index 08f4cc62c3..615c553fc5 100644 --- a/shared/editor/commands/insertFiles.ts +++ b/shared/editor/commands/insertFiles.ts @@ -85,9 +85,9 @@ const insertFiles = async function ( !options.isAttachment && !!schema.nodes.video; const getDimensions = isImage - ? FileHelper.getImageDimensions + ? (f: File) => FileHelper.getImageDimensions(f) : isVideo - ? FileHelper.getVideoDimensions + ? (f: File) => FileHelper.getVideoDimensions(f) : undefined; return { diff --git a/shared/editor/lib/ExtensionManager.ts b/shared/editor/lib/ExtensionManager.ts index ce5bbb1366..12150bfdae 100644 --- a/shared/editor/lib/ExtensionManager.ts +++ b/shared/editor/lib/ExtensionManager.ts @@ -67,7 +67,8 @@ export default class ExtensionManager { .reduce( (memo, node: Node) => ({ ...memo, - [node.name]: observer(node.widget as React.FC), + [node.name]: observer(((props: WidgetProps) => + node.widget(props)) as React.FC), }), {} ); @@ -131,7 +132,8 @@ export default class ExtensionManager { .reduce( (memo, extension: Node) => ({ ...memo, - [extension.name]: extension.toMarkdown, + [extension.name]: (...args: Parameters) => + extension.toMarkdown(...args), }), {} ); @@ -141,7 +143,8 @@ export default class ExtensionManager { .reduce( (memo, extension: Mark) => ({ ...memo, - [extension.name]: extension.toMarkdown, + [extension.name]: (...args: Parameters) => + extension.toMarkdown(...args), }), {} ); diff --git a/shared/editor/nodes/ReactNode.ts b/shared/editor/nodes/ReactNode.ts index 458f86731b..f193cc293b 100644 --- a/shared/editor/nodes/ReactNode.ts +++ b/shared/editor/nodes/ReactNode.ts @@ -2,9 +2,7 @@ import type { ComponentProps } from "../types"; import Node from "./Node"; export default abstract class ReactNode extends Node { - abstract component({ - node, - isSelected, - isEditable, - }: Omit): React.ReactElement; + abstract component: ( + props: Omit + ) => React.ReactElement; } diff --git a/shared/editor/plugins/AnchorPlugin.ts b/shared/editor/plugins/AnchorPlugin.ts index 33172ba30d..dbd8b00aaf 100644 --- a/shared/editor/plugins/AnchorPlugin.ts +++ b/shared/editor/plugins/AnchorPlugin.ts @@ -28,8 +28,8 @@ export class AnchorPlugin extends Plugin { }); } - private createAnchorDecoration(anchor: NodeAnchor) { - return Decoration.widget( + private createAnchorDecoration = (anchor: NodeAnchor) => + Decoration.widget( anchor.pos, () => { const anchorElement = document.createElement("a"); @@ -39,7 +39,6 @@ export class AnchorPlugin extends Plugin { }, { side: -1, key: anchor.id } ); - } private createDecorations(state: EditorState) { const anchors = ProsemirrorHelper.getAnchors(state.doc); diff --git a/shared/utils/events.ts b/shared/utils/events.ts index 9cfc2c78fc..91e2990adb 100644 --- a/shared/utils/events.ts +++ b/shared/utils/events.ts @@ -18,8 +18,11 @@ export default class EventEmitter { ); } - public on = this.addListener; - public off = this.removeListener; + public on = (name: string, callback: (data: unknown) => unknown) => + this.addListener(name, callback); + + public off = (name: string, callback: (data: unknown) => unknown) => + this.removeListener(name, callback); public emit(name: string, data?: unknown) { this.listeners[name]?.forEach((callback) => { diff --git a/shared/utils/rfc6902/diff.ts b/shared/utils/rfc6902/diff.ts index cf5c99c8b5..75ab50d9a1 100644 --- a/shared/utils/rfc6902/diff.ts +++ b/shared/utils/rfc6902/diff.ts @@ -1,6 +1,6 @@ import isEqual from "lodash/isEqual"; import type { Pointer } from "./pointer"; -import { hasOwnProperty, objectType } from "./util"; +import { hasOwn, objectType } from "./util"; /** * All diff* functions should return a list of operations, often empty. @@ -102,20 +102,14 @@ export function subtract( const obj: { [index: string]: number } = {}; // build up obj with all the properties of minuend for (const add_key in minuend) { - if ( - hasOwnProperty.call(minuend, add_key) && - minuend[add_key] !== undefined - ) { + if (hasOwn(minuend, add_key) && minuend[add_key] !== undefined) { obj[add_key] = 1; } } // now delete all the properties of subtrahend from obj // (deleting a missing key has no effect) for (const del_key in subtrahend) { - if ( - hasOwnProperty.call(subtrahend, del_key) && - subtrahend[del_key] !== undefined - ) { + if (hasOwn(subtrahend, del_key) && subtrahend[del_key] !== undefined) { delete obj[del_key]; } } @@ -141,7 +135,7 @@ export function intersection( for (let i = 0; i < length; i++) { const object = objects[i]; for (const key in object) { - if (hasOwnProperty.call(object, key) && object[key] !== undefined) { + if (hasOwn(object, key) && object[key] !== undefined) { counter[key] = (counter[key] || 0) + 1; } } diff --git a/shared/utils/rfc6902/util.ts b/shared/utils/rfc6902/util.ts index a6af6c931b..b55a1a246d 100644 --- a/shared/utils/rfc6902/util.ts +++ b/shared/utils/rfc6902/util.ts @@ -1,4 +1,5 @@ -export const hasOwnProperty = Object.prototype.hasOwnProperty; +export const hasOwn = (obj: object, key: PropertyKey): boolean => + Object.prototype.hasOwnProperty.call(obj, key); export function objectType(object: unknown) { if (object === undefined) { @@ -51,9 +52,8 @@ export function clone(source: T): T { const objectTarget = {} as T; // declaring the variable (with const) inside the loop is faster for (const key in source) { - // hasOwnProperty costs a bit of performance, but it's semantically necessary - // using a global helper is MUCH faster than calling source.hasOwnProperty(key) - if (hasOwnProperty.call(source, key)) { + // hasOwn costs a bit of performance, but it's semantically necessary + if (hasOwn(source, key)) { (objectTarget as Record)[key] = clone( (source as Record)[key] );