diff --git a/electron/debug.ts b/electron/debug.ts index 87377362b..a66ab7bc0 100644 --- a/electron/debug.ts +++ b/electron/debug.ts @@ -73,7 +73,15 @@ function inspectElements(): void { // } // }; -export const initDebug = (opts: any, isAddReload: boolean): void => { +export const initDebug = ( + opts: { + enabled?: boolean | null; + showDevTools?: boolean; + devToolsMode?: string; + mode?: string; + }, + isAddReload: boolean, +): void => { opts = Object.assign( { enabled: null, diff --git a/electron/error-handler-with-frontend-inform.ts b/electron/error-handler-with-frontend-inform.ts index 7550d55d7..c1162b544 100644 --- a/electron/error-handler-with-frontend-inform.ts +++ b/electron/error-handler-with-frontend-inform.ts @@ -6,7 +6,7 @@ const WAIT_FOR_WIN_TIMEOUT_DURATION = 4000; export const errorHandlerWithFrontendInform = ( e: Error | unknown | string = 'UNDEFINED ERROR', - additionalLogInfo?: any, + additionalLogInfo?: unknown, ): void => { const errObj = new Error(e as string); @@ -30,8 +30,8 @@ function _isReadyForFrontEndError(): boolean { // eslint-disable-next-line prefer-arrow/prefer-arrow-functions function _handleError( e: Error | unknown | string, - additionalLogInfo: any, - errObj: any, + additionalLogInfo: unknown, + errObj: Error, ): void { const mainWin = getWin(); const stack = errObj.stack; @@ -47,7 +47,7 @@ function _handleError( if (_isReadyForFrontEndError()) { mainWin.webContents.send(IPC.ERROR, { error: e, - errorStr: e && (e as any).toString(), + errorStr: e && String(e), stack, }); } else { diff --git a/electron/idle-time-handler.ts b/electron/idle-time-handler.ts index 812cb4ab2..645ecc3a6 100644 --- a/electron/idle-time-handler.ts +++ b/electron/idle-time-handler.ts @@ -267,7 +267,7 @@ export class IdleTimeHandler { return this.getIdleTime(); } - private logError(context: string, error: any): void { + private logError(context: string, error: unknown): void { const now = Date.now(); if (now - this.lastErrorLog > this.ERROR_LOG_INTERVAL) { log.debug(`${context} (falling back to 0):`, error); diff --git a/electron/jira.ts b/electron/jira.ts index dbd31c5ad..fa0a83c0c 100644 --- a/electron/jira.ts +++ b/electron/jira.ts @@ -32,7 +32,7 @@ export const sendJiraRequest = ({ } : {}), } as RequestInit) - .then(async (response: any) => { + .then(async (response) => { // log('JIRA_RAW_RESPONSE', response); if (!response.ok) { error('Jira Error Error Response ELECTRON: ', response); @@ -50,8 +50,8 @@ export const sendJiraRequest = ({ } return response; }) - .then((res: any) => res.text()) - .then((text: any) => { + .then((res) => res.text()) + .then((text) => { try { return text ? JSON.parse(text) : {}; } catch (e) { @@ -61,13 +61,13 @@ export const sendJiraRequest = ({ return text; } }) - .then((response: any) => { + .then((response) => { mainWin.webContents.send(IPC.JIRA_CB_EVENT, { response, requestId, }); }) - .catch((err: any) => { + .catch((err: unknown) => { mainWin.webContents.send(IPC.JIRA_CB_EVENT, { error: err, requestId, diff --git a/electron/main-window.ts b/electron/main-window.ts index 61f98a269..eb846289d 100644 --- a/electron/main-window.ts +++ b/electron/main-window.ts @@ -188,7 +188,7 @@ export const createWindow = ({ }; // eslint-disable-next-line prefer-arrow/prefer-arrow-functions -function initWinEventListeners(app: any): void { +function initWinEventListeners(app: Electron.App): void { const openUrlInBrowser = (url: string): void => { // needed for mac; especially for jira urls we might have a host like this www.host.de// const urlObj = new URL(url); diff --git a/electron/plugin-node-executor.ts b/electron/plugin-node-executor.ts index 35b7ca073..9a01e7f7f 100644 --- a/electron/plugin-node-executor.ts +++ b/electron/plugin-node-executor.ts @@ -121,8 +121,8 @@ class PluginNodeExecutor { throw new Error(`Module '${module}' is not allowed`); }, console: { - log: (...logArgs: any[]) => console.log('[Plugin]:', ...logArgs), - error: (...errorArgs: any[]) => console.error('[Plugin]:', ...errorArgs), + log: (...logArgs: unknown[]) => console.log('[Plugin]:', ...logArgs), + error: (...errorArgs: unknown[]) => console.error('[Plugin]:', ...errorArgs), }, JSON, args: args || [], diff --git a/electron/shared-with-frontend/lazy-set-interval.ts b/electron/shared-with-frontend/lazy-set-interval.ts index 891552d10..66e0263fd 100644 --- a/electron/shared-with-frontend/lazy-set-interval.ts +++ b/electron/shared-with-frontend/lazy-set-interval.ts @@ -4,7 +4,7 @@ export const lazySetInterval = ( func: () => void, intervalDuration: number, ): (() => void) => { - let lastTimeoutId: any; + let lastTimeoutId: ReturnType; const interval = (): void => { lastTimeoutId = setTimeout(interval, intervalDuration); diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 3f4be71c9..13d3a8af8 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -85,6 +85,11 @@ import { ProjectService } from './features/project/project.service'; import { TagService } from './features/tag/tag.service'; import { ContextMenuComponent } from './ui/context-menu/context-menu.component'; +interface BeforeInstallPromptEvent extends Event { + prompt(): Promise; + userChoice: Promise<{ outcome: 'accepted' | 'dismissed' }>; +} + const w = window as any; const productivityTip: string[] = w.productivityTips && w.productivityTips[w.randomIndex]; @@ -269,8 +274,8 @@ export class AppComponent implements OnDestroy, AfterViewInit { effect(() => { window.ea.on(IPC.ERROR, (ev: IpcRendererEvent, ...args: unknown[]) => { const data = args[0] as { - error: any; - stack: any; + error: unknown; + stack: unknown; errorStr: string | unknown; }; const errMsg = @@ -390,7 +395,7 @@ export class AppComponent implements OnDestroy, AfterViewInit { } @HostListener('window:beforeinstallprompt', ['$event']) onBeforeInstallPrompt( - e: any, + e: BeforeInstallPromptEvent, ): void { if (IS_ELECTRON || localStorage.getItem(LS.WEB_APP_INSTALL)) { return; @@ -621,7 +626,7 @@ export class AppComponent implements OnDestroy, AfterViewInit { if (navigator.storage) { // try to avoid data-loss Promise.all([navigator.storage.persisted()]) - .then(([persisted]): any => { + .then(([persisted]) => { if (!persisted) { return navigator.storage.persist().then((granted) => { if (granted) { @@ -636,6 +641,7 @@ export class AppComponent implements OnDestroy, AfterViewInit { }); } else { Log.log('Persistence already allowed'); + return; } }) .catch((e) => { diff --git a/src/app/core-ui/layout/store/layout.effects.ts b/src/app/core-ui/layout/store/layout.effects.ts index 2a4feb403..2623b0dff 100644 --- a/src/app/core-ui/layout/store/layout.effects.ts +++ b/src/app/core-ui/layout/store/layout.effects.ts @@ -30,7 +30,7 @@ export class LayoutEffects { hideNotesNavigatingToDailySummary$ = createEffect(() => this.router.events.pipe( - filter((event: any) => event instanceof NavigationEnd), + filter((event): event is NavigationEnd => event instanceof NavigationEnd), filter((event) => !!event.url.match(/(daily-summary)$/)), mapTo(hideNonTaskSidePanelContent()), ), diff --git a/src/app/core/error-handler/global-error-handler.class.ts b/src/app/core/error-handler/global-error-handler.class.ts index f65450034..4abf4fb87 100644 --- a/src/app/core/error-handler/global-error-handler.class.ts +++ b/src/app/core/error-handler/global-error-handler.class.ts @@ -20,10 +20,18 @@ export class GlobalErrorHandler implements ErrorHandler { private injector = inject(Injector); // TODO Cleanup this mess - async handleError(err: any): Promise { - const errStr = typeof err === 'string' ? err : err.toString(); + async handleError(err: unknown): Promise { + const errStr = typeof err === 'string' ? err : String(err); // eslint-disable-next-line - const simpleStack = err && err.stack; + let simpleStack = ''; + if ( + err && + typeof err === 'object' && + 'stack' in err && + typeof err.stack === 'string' + ) { + simpleStack = err.stack; + } Log.err('GLOBAL_ERROR_HANDLER', err); // if not our custom error handler we have a critical error on our hands @@ -60,7 +68,7 @@ export class GlobalErrorHandler implements ErrorHandler { ? str : 'Unable to parse error string. Please see console error'; } else { - return (err as any).toString(); + return String(err); } } diff --git a/src/app/core/error-handler/global-error-handler.util.ts b/src/app/core/error-handler/global-error-handler.util.ts index c4468b1a9..98de9884f 100644 --- a/src/app/core/error-handler/global-error-handler.util.ts +++ b/src/app/core/error-handler/global-error-handler.util.ts @@ -5,7 +5,6 @@ import { getBeforeLastErrorActionLog } from '../../util/action-logger'; import { download, downloadLogs } from '../../util/download'; import { privacyExport } from '../../imex/file-imex/privacy-export'; import { getAppVersionStr } from '../../util/get-app-version-str'; -import { CompleteBackup } from '../../pfapi/api'; import { Log } from '../log'; let isWasErrorAlertCreated = false; @@ -14,7 +13,7 @@ let isWasErrorAlertCreated = false; const createSimpleThrottle = (limit: number, interval: number) => { const timestamps: number[] = []; - return any>(fn: T) => { + return unknown>(fn: T) => { return ((...args: Parameters) => { const now = Date.now(); @@ -99,8 +98,8 @@ const _cleanHtml = (str: string): string => { export const createErrorAlert = ( err: string = '', stackTrace: string, - origErr: any, - userData?: CompleteBackup | undefined, + origErr: unknown, + userData?: unknown, ): void => { if (isWasErrorAlertCreated) { return; @@ -165,9 +164,10 @@ export const createErrorAlert = ( btnPrivacyExport.title = 'Export anonymized data (to send to contact@super-productivity.com for debugging)'; btnPrivacyExport.addEventListener('click', () => { + // Type assertion needed for privacy export function download( 'ANONYMIZED-super-productivity-crash-user-data-export.json', - privacyExport(userData), + privacyExport(userData as Parameters[0]), ); }); innerWrapper.append(btnPrivacyExport); diff --git a/src/app/core/errors/errors.ts b/src/app/core/errors/errors.ts deleted file mode 100644 index b5c26fd62..000000000 --- a/src/app/core/errors/errors.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Log } from '../log'; - -export class AdditionalLogErrorBase extends Error { - constructor(...additional: any) { - super(...additional); - Log.log(1, this.name, ...additional); - } -} - -/// ------------------------- diff --git a/src/app/core/ipc-events.ts b/src/app/core/ipc-events.ts index 3f9dc9d9f..5b410c830 100644 --- a/src/app/core/ipc-events.ts +++ b/src/app/core/ipc-events.ts @@ -5,9 +5,7 @@ import { EMPTY, Observable } from 'rxjs'; import { IS_ELECTRON } from '../app.constants'; export const ipcIdleTime$: Observable = IS_ELECTRON - ? ipcEvent$(IPC.IDLE_TIME).pipe( - map(([ev, idleTimeInMs]: any) => idleTimeInMs as number), - ) + ? ipcEvent$(IPC.IDLE_TIME).pipe(map(([ev, idleTimeInMs]) => idleTimeInMs as number)) : EMPTY; export const ipcAnyFileDownloaded$: Observable = IS_ELECTRON @@ -31,6 +29,6 @@ export const ipcShowAddTaskBar$: Observable = IS_ELECTRON export const ipcAddTaskFromAppUri$: Observable<{ title: string }> = IS_ELECTRON ? ipcEvent$(IPC.ADD_TASK_FROM_APP_URI).pipe( - map(([ev, data]: any) => data as { title: string }), + map(([ev, data]) => data as { title: string }), ) : EMPTY; diff --git a/src/app/features/issue/providers/caldav/caldav-client.service.ts b/src/app/features/issue/providers/caldav/caldav-client.service.ts index 6ad9a663d..3f346ee4f 100644 --- a/src/app/features/issue/providers/caldav/caldav-client.service.ts +++ b/src/app/features/issue/providers/caldav/caldav-client.service.ts @@ -23,6 +23,13 @@ interface ClientCache { calendars: Map; } +interface CalDavTaskData { + data: string; + url: string; + etag: string; + update?: () => Promise; +} + @Injectable({ providedIn: 'root', }) @@ -53,7 +60,10 @@ export class CaldavClientService { return url.substring(url.lastIndexOf('/') + 1); } - private static async _getAllTodos(calendar: any, filterOpen: boolean): Promise { + private static async _getAllTodos( + calendar: Calendar, + filterOpen: boolean, + ): Promise { const query = { name: [NS.IETF_CALDAV, 'comp-filter'], attributes: [['name', 'VCALENDAR']], @@ -83,7 +93,10 @@ export class CaldavClientService { return await calendar.calendarQuery([query]); } - private static async _findTaskByUid(calendar: any, taskUid: string): Promise { + private static async _findTaskByUid( + calendar: Calendar, + taskUid: string, + ): Promise { const query = { name: [NS.IETF_CALDAV, 'comp-filter'], attributes: [['name', 'VCALENDAR']], @@ -109,7 +122,7 @@ export class CaldavClientService { return await calendar.calendarQuery([query]); } - private static _mapTask(task: any): CaldavIssue { + private static _mapTask(task: CalDavTaskData): CaldavIssue { const jCal = ICAL.parse(task.data); const comp = new ICAL.Component(jCal); const todo = comp.getFirstSubcomponent('vtodo'); @@ -174,7 +187,7 @@ export class CaldavClientService { await client .connect({ enableCalDAV: true }) - .catch((err: any) => this._handleNetErr(err)); + .catch((err) => this._handleNetErr(err)); const cache = { client, @@ -186,7 +199,7 @@ export class CaldavClientService { } } - async _getCalendar(cfg: CaldavCfg): Promise { + async _getCalendar(cfg: CaldavCfg): Promise { const clientCache = await this._get_client(cfg); const resource = cfg.resourceName as string; @@ -196,7 +209,7 @@ export class CaldavClientService { const calendars = await clientCache.client.calendarHomes[0] .findAllCalendars() - .catch((err: any) => this._handleNetErr(err)); + .catch((err) => this._handleNetErr(err)); const calendar = calendars.find( (item: Calendar) => @@ -267,7 +280,7 @@ export class CaldavClientService { issueId: string, completed: boolean, summary: string, - ): Observable { + ): Observable { return from( this._updateTask(caldavCfg, issueId, { completed: completed, summary: summary }), ).pipe( @@ -275,7 +288,7 @@ export class CaldavClientService { ); } - private _getXhrProvider(cfg: CaldavCfg): any { + private _getXhrProvider(cfg: CaldavCfg): () => XMLHttpRequest { // eslint-disable-next-line prefer-arrow/prefer-arrow-functions function xhrProvider(): XMLHttpRequest { const xhr = new XMLHttpRequest(); @@ -301,7 +314,7 @@ export class CaldavClientService { return xhrProvider; } - private _handleNetErr(err: any): void { + private _handleNetErr(err: unknown): never { this._snackService.open({ type: 'ERROR', msg: T.F.ISSUE.S.ERR_NETWORK, @@ -331,11 +344,11 @@ export class CaldavClientService { filterCategory: boolean, ): Promise { const cal = await this._getCalendar(cfg); - const tasks = await CaldavClientService._getAllTodos(cal, filterOpen).catch( - (err: any) => this._handleNetErr(err), + const tasks = await CaldavClientService._getAllTodos(cal, filterOpen).catch((err) => + this._handleNetErr(err), ); return tasks - .map((t: any) => CaldavClientService._mapTask(t)) + .map((t) => CaldavClientService._mapTask(t)) .filter( (t: CaldavIssue) => !filterCategory || !cfg.categoryFilter || t.labels.includes(cfg.categoryFilter), @@ -344,7 +357,7 @@ export class CaldavClientService { private async _getTask(cfg: CaldavCfg, uid: string): Promise { const cal = await this._getCalendar(cfg); - const task = await CaldavClientService._findTaskByUid(cal, uid).catch((err: any) => + const task = await CaldavClientService._findTaskByUid(cal, uid).catch((err) => this._handleNetErr(err), ); @@ -363,7 +376,7 @@ export class CaldavClientService { cfg: CaldavCfg, uid: string, updates: { completed: boolean; summary: string }, - ): Promise { + ): Promise { const cal = await this._getCalendar(cfg); if (cal.readOnly) { @@ -377,7 +390,7 @@ export class CaldavClientService { throw new Error('CALENDAR READ ONLY: ' + cfg.resourceName); } - const tasks = await CaldavClientService._findTaskByUid(cal, uid).catch((err: any) => + const tasks = await CaldavClientService._findTaskByUid(cal, uid).catch((err) => this._handleNetErr(err), ); @@ -436,6 +449,8 @@ export class CaldavClientService { todo.updatePropertyWithValue('sequence', sequenceInt); task.data = ICAL.stringify(jCal); - await task.update().catch((err: any) => this._handleNetErr(err)); + if (task.update) { + await task.update().catch((err) => this._handleNetErr(err)); + } } } diff --git a/src/app/features/issue/providers/calendar/calendar-common-interfaces.service.ts b/src/app/features/issue/providers/calendar/calendar-common-interfaces.service.ts index 63afa32d5..2733a5f32 100644 --- a/src/app/features/issue/providers/calendar/calendar-common-interfaces.service.ts +++ b/src/app/features/issue/providers/calendar/calendar-common-interfaces.service.ts @@ -82,7 +82,7 @@ export class CalendarCommonInterfacesService implements IssueServiceInterface { async getFreshDataForIssueTask(task: Task): Promise<{ taskChanges: Partial; - issue: any; + issue: IssueData; issueTitle: string; } | null> { return null; @@ -92,7 +92,7 @@ export class CalendarCommonInterfacesService implements IssueServiceInterface { { task: Readonly; taskChanges: Partial>; - issue: any; + issue: IssueData; }[] > { return []; diff --git a/src/app/features/issue/providers/github/github-api.service.ts b/src/app/features/issue/providers/github/github-api.service.ts index 52153bf69..b48b4d3ef 100644 --- a/src/app/features/issue/providers/github/github-api.service.ts +++ b/src/app/features/issue/providers/github/github-api.service.ts @@ -113,9 +113,9 @@ export class GithubApiService { } getImportToBacklogIssuesFromGraphQL(cfg: GithubCfg): Observable { - const split: any = cfg.repo?.split('/'); - const owner = encodeURIComponent(split[0]); - const repo = encodeURIComponent(split[1]); + const split = cfg.repo?.split('/') || []; + const owner = encodeURIComponent(split[0] || ''); + const repo = encodeURIComponent(split[1] || ''); const assigneeFilter = cfg.backlogQuery ? `, assignee: "${cfg.filterUsernameForIssueUpdates}"` : ''; @@ -210,7 +210,9 @@ query Issues { return this._http.request(req).pipe( // Filter out HttpEventType.Sent (type: 0) events to only process actual responses filter((res) => !(res === Object(res) && res.type === 0)), - map((res: any) => (res && res.body ? res.body : res)), + map((res) => + res && (res as { body?: unknown }).body ? (res as { body: unknown }).body : res, + ), catchError(this._handleRequestError$.bind(this)), ); } diff --git a/src/app/features/reminder/reminder.service.ts b/src/app/features/reminder/reminder.service.ts index 171326d44..212d0a0b6 100644 --- a/src/app/features/reminder/reminder.service.ts +++ b/src/app/features/reminder/reminder.service.ts @@ -258,7 +258,7 @@ export class ReminderService { this._w.postMessage(reminders); } - private _handleError(err: any): void { + private _handleError(err: unknown): void { Log.err(err); this._snackService.open({ type: 'ERROR', msg: T.F.REMINDER.S_REMINDER_ERR }); } diff --git a/src/app/features/tasks/store/short-syntax.effects.ts b/src/app/features/tasks/store/short-syntax.effects.ts index 6e692bf99..30363bc1f 100644 --- a/src/app/features/tasks/store/short-syntax.effects.ts +++ b/src/app/features/tasks/store/short-syntax.effects.ts @@ -1,5 +1,6 @@ import { Injectable, inject } from '@angular/core'; import { Actions, createEffect, ofType } from '@ngrx/effects'; +import { Action } from '@ngrx/store'; import { addNewTagsFromShortSyntax } from './task.actions'; import { TaskSharedActions } from '../../../root-store/meta/task-shared.actions'; import { @@ -16,7 +17,7 @@ import { TaskReminderOptionId } from '../task.model'; import { GlobalConfigService } from '../../config/global-config.service'; import { unique } from '../../../util/unique'; import { TaskService } from '../task.service'; -import { EMPTY, Observable, of } from 'rxjs'; +import { EMPTY, of } from 'rxjs'; import { ProjectService } from '../../project/project.service'; import { TagService } from '../../tag/tag.service'; import { shortSyntax } from '../short-syntax'; @@ -48,7 +49,7 @@ export class ShortSyntaxEffects { private _layoutService = inject(LayoutService); private _workContextService = inject(WorkContextService); - shortSyntax$: any = createEffect(() => + shortSyntax$ = createEffect(() => this._actions$.pipe( ofType(TaskSharedActions.addTask, TaskSharedActions.updateTask), filter((action): boolean => { @@ -63,7 +64,7 @@ export class ShortSyntaxEffects { return changeProps.length === 1 && changeProps[0] === 'title'; }), // dirty fix to execute this after setDefaultProjectId$ effect - concatMap((originalAction): Observable => { + concatMap((originalAction) => { return this._taskService.getByIdOnce$(originalAction.task.id as string).pipe( map((task) => ({ task, @@ -123,7 +124,7 @@ export class ShortSyntaxEffects { if (isAddDefaultProjectIfNecessary) { return [ TaskSharedActions.moveToOtherProject({ - task, + task: { ...task, subTasks: [] }, targetProjectId: defaultProjectId as string, }), ]; @@ -131,7 +132,7 @@ export class ShortSyntaxEffects { return EMPTY; } - const actions: any[] = []; + const actions: Action[] = []; const tagIds: string[] = [...(r.taskChanges.tagIds || task.tagIds)]; const { taskChanges } = r; @@ -176,7 +177,7 @@ export class ShortSyntaxEffects { } else { actions.push( TaskSharedActions.moveToOtherProject({ - task, + task: { ...task, subTasks: [] }, targetProjectId: r.projectId, }), ); @@ -184,7 +185,7 @@ export class ShortSyntaxEffects { } else if (isAddDefaultProjectIfNecessary) { actions.push( TaskSharedActions.moveToOtherProject({ - task, + task: { ...task, subTasks: [] }, targetProjectId: defaultProjectId as string, }), ); @@ -220,7 +221,7 @@ export class ShortSyntaxEffects { ), ); - shortSyntaxAddNewTags$: any = createEffect(() => + shortSyntaxAddNewTags$ = createEffect(() => this._actions$.pipe( ofType(addNewTagsFromShortSyntax), // needed cause otherwise task gets the focus after blur & hide @@ -252,7 +253,7 @@ export class ShortSyntaxEffects { // NOTE: it is important to get a fresh task here, since otherwise we might run into #3728 withLatestFrom(this._taskService.getByIdOnce$(taskId)), mergeMap(([isConfirm, task]) => { - const actions: any[] = []; + const actions: Action[] = []; if (isConfirm) { const newTagIds = [...task.tagIds]; uniqueNewTitles.forEach((newTagTitle) => { diff --git a/src/app/features/tasks/store/task-electron.effects.ts b/src/app/features/tasks/store/task-electron.effects.ts index cee727b2f..dc24be2b3 100644 --- a/src/app/features/tasks/store/task-electron.effects.ts +++ b/src/app/features/tasks/store/task-electron.effects.ts @@ -72,7 +72,7 @@ export class TaskElectronEffects { }); } - taskChangeElectron$: any = createEffect( + taskChangeElectron$ = createEffect( () => this._actions$.pipe( ofType( @@ -133,7 +133,7 @@ export class TaskElectronEffects { { dispatch: false }, ); - setTaskBarProgress$: any = createEffect( + setTaskBarProgress$ = createEffect( () => this._actions$.pipe( ofType(TimeTrackingActions.addTimeSpent), diff --git a/src/app/features/tasks/store/task-internal.effects.ts b/src/app/features/tasks/store/task-internal.effects.ts index fcd513e95..b31866754 100644 --- a/src/app/features/tasks/store/task-internal.effects.ts +++ b/src/app/features/tasks/store/task-internal.effects.ts @@ -25,10 +25,10 @@ import { @Injectable() export class TaskInternalEffects { private _actions$ = inject(Actions); - private _store$ = inject>(Store); + private _store$ = inject(Store); private _workContextSession = inject(WorkContextService); - onAllSubTasksDone$: any = createEffect(() => + onAllSubTasksDone$ = createEffect(() => this._actions$.pipe( ofType(TaskSharedActions.updateTask), withLatestFrom( @@ -65,7 +65,7 @@ export class TaskInternalEffects { ), ); - setDefaultEstimateIfNonGiven$: any = createEffect(() => + setDefaultEstimateIfNonGiven$ = createEffect(() => this._actions$.pipe( ofType(TaskSharedActions.addTask, addSubTask), filter(({ task }) => !task.timeEstimate), @@ -91,7 +91,7 @@ export class TaskInternalEffects { ), ); - autoSetNextTask$: any = createEffect(() => + autoSetNextTask$ = createEffect(() => this._actions$.pipe( ofType( toggleStart, diff --git a/src/app/features/tasks/store/task-related-model.effects.ts b/src/app/features/tasks/store/task-related-model.effects.ts index e1dc2d1b2..3aad25a2c 100644 --- a/src/app/features/tasks/store/task-related-model.effects.ts +++ b/src/app/features/tasks/store/task-related-model.effects.ts @@ -24,7 +24,7 @@ export class TaskRelatedModelEffects { // EFFECTS ===> EXTERNAL // --------------------- - restoreTask$: any = createEffect( + restoreTask$ = createEffect( () => this._actions$.pipe( ofType(TaskSharedActions.restoreTask), @@ -38,7 +38,7 @@ export class TaskRelatedModelEffects { switchMap((misc) => (misc.isAutoAddWorkedOnToToday ? obs : EMPTY)), ); - autoAddTodayTagOnTracking: any = createEffect(() => + autoAddTodayTagOnTracking = createEffect(() => this.ifAutoAddTodayEnabled$( this._actions$.pipe( ofType(TimeTrackingActions.addTimeSpent), diff --git a/src/app/features/tasks/store/task-ui.effects.ts b/src/app/features/tasks/store/task-ui.effects.ts index 195d7831d..8ce9e9176 100644 --- a/src/app/features/tasks/store/task-ui.effects.ts +++ b/src/app/features/tasks/store/task-ui.effects.ts @@ -45,7 +45,7 @@ export class TaskUiEffects { private _globalConfigService = inject(GlobalConfigService); private _workContextService = inject(WorkContextService); - taskCreatedSnack$: any = createEffect( + taskCreatedSnack$ = createEffect( () => this._actions$.pipe( ofType(TaskSharedActions.addTask), @@ -63,7 +63,7 @@ export class TaskUiEffects { { dispatch: false }, ); - snackDelete$: any = createEffect( + snackDelete$ = createEffect( () => this._actions$.pipe( ofType(TaskSharedActions.deleteTask), @@ -82,7 +82,7 @@ export class TaskUiEffects { { dispatch: false }, ); - timeEstimateExceeded$: any = createEffect( + timeEstimateExceeded$ = createEffect( () => this._store$.pipe(select(selectConfigFeatureState)).pipe( switchMap((globalCfg) => @@ -113,7 +113,7 @@ export class TaskUiEffects { { dispatch: false }, ); - timeEstimateExceededDismissBanner$: any = createEffect( + timeEstimateExceededDismissBanner$ = createEffect( () => this._store$.pipe(select(selectConfigFeatureState)).pipe( switchMap((globalCfg) => @@ -138,7 +138,7 @@ export class TaskUiEffects { { dispatch: false }, ); - taskDoneSound$: any = createEffect( + taskDoneSound$ = createEffect( () => this._actions$.pipe( ofType(TaskSharedActions.updateTask), diff --git a/src/app/features/work-context/work-context.service.ts b/src/app/features/work-context/work-context.service.ts index a2d6be11b..380871099 100644 --- a/src/app/features/work-context/work-context.service.ts +++ b/src/app/features/work-context/work-context.service.ts @@ -624,7 +624,7 @@ export class WorkContextService { private _updateAdvancedCfgForCurrentContext( sectionKey: WorkContextAdvancedCfgKey, - data: any, + data: unknown, ): void { if (this.activeWorkContextType === WorkContextType.PROJECT) { this._store$.dispatch( diff --git a/src/app/imex/sync/sync-wrapper.service.ts b/src/app/imex/sync/sync-wrapper.service.ts index 1f60a7512..b2ea6aeae 100644 --- a/src/app/imex/sync/sync-wrapper.service.ts +++ b/src/app/imex/sync/sync-wrapper.service.ts @@ -162,7 +162,7 @@ export class SyncWrapperService { return r.status; } - } catch (error: any) { + } catch (error) { SyncLog.err(error); if (error instanceof PotentialCorsError) { @@ -236,7 +236,9 @@ export class SyncWrapperService { } else if (error instanceof CanNotMigrateMajorDownError) { alert(this._translateService.instant(T.F.SYNC.A.REMOTE_MODEL_VERSION_NEWER)); return 'HANDLED_ERROR'; - } else if (error?.message === 'Sync already in progress') { + } else if ( + (error as { message?: string })?.message === 'Sync already in progress' + ) { // Silently ignore concurrent sync attempts SyncLog.log('Sync already in progress, skipping concurrent sync attempt'); return 'HANDLED_ERROR'; diff --git a/src/app/imex/sync/sync.effects.ts b/src/app/imex/sync/sync.effects.ts index 14d224016..5c25cbac6 100644 --- a/src/app/imex/sync/sync.effects.ts +++ b/src/app/imex/sync/sync.effects.ts @@ -44,7 +44,7 @@ export class SyncEffects { private _execBeforeCloseService = inject(ExecBeforeCloseService); private readonly _initialPwaUpdateCheckService = inject(InitialPwaUpdateCheckService); - syncBeforeQuit$: any = createEffect( + syncBeforeQuit$ = createEffect( () => !IS_ELECTRON ? EMPTY @@ -97,7 +97,7 @@ export class SyncEffects { shareReplay(), ); - triggerSync$: any = createEffect( + triggerSync$ = createEffect( () => this._dataInitStateService.isAllDataLoadedInitially$.pipe( switchMap(() => diff --git a/src/app/pages/daily-summary/daily-summary.component.ts b/src/app/pages/daily-summary/daily-summary.component.ts index 1eadea3b4..1e02e9e8e 100644 --- a/src/app/pages/daily-summary/daily-summary.component.ts +++ b/src/app/pages/daily-summary/daily-summary.component.ts @@ -137,8 +137,8 @@ export class DailySummaryComponent implements OnInit, OnDestroy, AfterViewInit { startWith({ params: { dayStr: this._dateService.todayStr() }, }), - map((s: any) => { - if (s && s.params.dayStr) { + map((s) => { + if (s && 'params' in s && s.params.dayStr) { return s.params.dayStr; } else { return this._dateService.todayStr(); @@ -275,10 +275,11 @@ export class DailySummaryComponent implements OnInit, OnDestroy, AfterViewInit { this._activatedRoute.paramMap .pipe(takeUntil(this._onDestroy$)) - .subscribe((s: any) => { - if (s && s.params.dayStr) { + .subscribe((params) => { + const dayStr = params.get('dayStr'); + if (dayStr) { this.isForToday = false; - this.dayStr = s.params.dayStr; + this.dayStr = dayStr; } }); } @@ -390,7 +391,7 @@ export class DailySummaryComponent implements OnInit, OnDestroy, AfterViewInit { Log.log('[DailySummary] Archive operation completed'); } - private async _finishDayForGood(cb?: any): Promise { + private async _finishDayForGood(cb?: () => void): Promise { const cfg = this.configService.cfg(); const syncCfg = cfg?.sync; if (syncCfg?.isEnabled) { @@ -399,7 +400,7 @@ export class DailySummaryComponent implements OnInit, OnDestroy, AfterViewInit { this._initSuccessAnimation(cb); } - private _initSuccessAnimation(cb?: any): void { + private _initSuccessAnimation(cb?: () => void): void { this.showSuccessAnimation = true; this._cd.detectChanges(); this._successAnimationTimeout = window.setTimeout(() => { diff --git a/src/app/root-store/meta/action-logger.reducer.ts b/src/app/root-store/meta/action-logger.reducer.ts index 73791cd2c..821f6112d 100644 --- a/src/app/root-store/meta/action-logger.reducer.ts +++ b/src/app/root-store/meta/action-logger.reducer.ts @@ -1,15 +1,17 @@ -import { RootState } from '../root-state'; import { actionLogger } from '../../util/action-logger'; -import { ActionReducer } from '@ngrx/store/src/models'; +import { ActionReducer, Action } from '@ngrx/store'; import { Log } from '../../core/log'; -export const actionLoggerReducer = ( - reducer: ActionReducer, -): ActionReducer => { - return (state: RootState, action: any) => { +export const actionLoggerReducer = ( + reducer: ActionReducer, +): ActionReducer => { + return (state: S | undefined, action: A) => { // if (environment.production) { - Log.verbose('[a]' + action.type, (action as any)?.payload || action); - actionLogger(action); + Log.verbose( + '[a]' + action.type, + (action as Action & { payload?: unknown })?.payload || action, + ); + actionLogger(action as unknown as { type: string; [key: string]: unknown }); return reducer(state, action); }; }; diff --git a/src/app/root-store/shared/save-to-db.effects.ts b/src/app/root-store/shared/save-to-db.effects.ts index 2bfc5e9cd..8e658b4ad 100644 --- a/src/app/root-store/shared/save-to-db.effects.ts +++ b/src/app/root-store/shared/save-to-db.effects.ts @@ -128,7 +128,7 @@ export class SaveToDbEffects { [TimeTrackingActions.addTimeSpent.type], ); - updateTimeTrackingStorageAuditTime$: any = createEffect( + updateTimeTrackingStorageAuditTime$ = createEffect( () => this._actions.pipe( ofType(TimeTrackingActions.addTimeSpent), diff --git a/src/app/ui/formly-image-input/formly-image-input.component.ts b/src/app/ui/formly-image-input/formly-image-input.component.ts index abf8ef414..9ac5a7c6b 100644 --- a/src/app/ui/formly-image-input/formly-image-input.component.ts +++ b/src/app/ui/formly-image-input/formly-image-input.component.ts @@ -56,7 +56,7 @@ export class FormlyImageInputComponent extends FieldType { data: dialogData, }); - dialogRef.afterClosed().subscribe((result: any) => { + dialogRef.afterClosed().subscribe((result: string | { url: string } | null) => { if (result) { // Handle both string (legacy) and object (new) return formats const url = typeof result === 'string' ? result : result.url; diff --git a/src/app/ui/longpress/longpress-ios.directive.ts b/src/app/ui/longpress/longpress-ios.directive.ts index 8140fdc8a..ee2980d98 100644 --- a/src/app/ui/longpress/longpress-ios.directive.ts +++ b/src/app/ui/longpress/longpress-ios.directive.ts @@ -6,7 +6,7 @@ import { IS_IOS } from '../../util/is-ios'; export class LongPressIOSDirective implements OnDestroy { readonly longPressIOS = output(); - private longPressTimeout: any; + private longPressTimeout: number | undefined; constructor() { const el = inject(ElementRef); diff --git a/src/app/ui/longpress/longpress.directive.ts b/src/app/ui/longpress/longpress.directive.ts index 1cf3de969..efa605245 100644 --- a/src/app/ui/longpress/longpress.directive.ts +++ b/src/app/ui/longpress/longpress.directive.ts @@ -5,7 +5,7 @@ import { UI_LONG_PRESS_DURATION } from '../ui.const'; export class LongPressDirective implements OnDestroy { readonly longPress = output(); - private longPressTimeout: any; + private longPressTimeout: number | undefined; @HostListener('touchstart', ['$event']) @HostListener('mousedown', ['$event'])