diff --git a/src/frontend/components/button/lib/create-report-button.test.ts b/src/frontend/components/button/lib/create-report-button.test.ts index 88f9fc910..03b262e0f 100644 --- a/src/frontend/components/button/lib/create-report-button.test.ts +++ b/src/frontend/components/button/lib/create-report-button.test.ts @@ -1,6 +1,8 @@ +/* eslint-disable */ import "../../../testing/globals.definitions"; import {validateRequiredFields} from 'validation'; import CreateReportButtonComponent from "./create-report-button"; +import { describe, it, expect, jest } from '@jest/globals'; describe('create-report-button', () => { it('does not submit form if no checkboxes are checked', () => { diff --git a/src/frontend/components/button/lib/rename-button.ts b/src/frontend/components/button/lib/rename-button.ts index 4e66e6f31..9db4f1110 100644 --- a/src/frontend/components/button/lib/rename-button.ts +++ b/src/frontend/components/button/lib/rename-button.ts @@ -39,13 +39,14 @@ declare global { */ class RenameButton { private readonly dataClass = 'rename-button'; - private value: string; + private value!: string; /** * Attach event to button * @param {HTMLButtonElement} button Button to attach the event to */ constructor(button: HTMLButtonElement) { + if(!button) return; const $button = $(button); if ($button.data(this.dataClass) === 'true') return; const data = $button.data('fieldId'); @@ -126,8 +127,8 @@ class RenameButton { $(`#rename-confirm-${id}`) .removeClass('hidden') .attr('aria-hidden', null) - .on('click', (e) => { - this.triggerRename(id, ev.target, e) + .on('click', () => { + this.triggerRename(id, ev.target) }); $(`#rename-cancel-${id}`) .removeClass('hidden') @@ -158,7 +159,7 @@ class RenameButton { * @param {JQuery} button The button that was clicked * @param {JQuery.BlurEvent} e The blur event */ - private triggerRename(id: number, button: JQuery, e: JQuery.Event) { + private triggerRename(id: number, button: JQuery) { const previousValue = $(`#current-${id}`).text(); const extension = '.' + previousValue.split('.').pop(); const newName = this.value.endsWith(extension) ? this.value : this.value + extension; @@ -190,8 +191,8 @@ class RenameButton { if(typeof jQuery !== 'undefined') { (function ($) { $.fn.renameButton = function () { - return this.each(function (_: unknown, el: HTMLButtonElement) { - new RenameButton(el); + return this.each((_, el) => { + new RenameButton(el as HTMLButtonElement); }); }; })(jQuery); diff --git a/src/frontend/components/form-group/autosave/lib/component.js b/src/frontend/components/form-group/autosave/lib/component.js index ae8a114a0..9906c0b6e 100644 --- a/src/frontend/components/form-group/autosave/lib/component.js +++ b/src/frontend/components/form-group/autosave/lib/component.js @@ -11,6 +11,7 @@ class AutosaveComponent extends AutosaveBase { */ async initAutosave() { const $field = $(this.element); + /* eslint-disable-next-line @typescript-eslint/no-this-alias */ const self = this; if ($field.data('is-readonly')) return; diff --git a/src/frontend/components/form-group/input/lib/documentComponent.ts b/src/frontend/components/form-group/input/lib/documentComponent.ts index 7c47c4bee..3bd5b306d 100644 --- a/src/frontend/components/form-group/input/lib/documentComponent.ts +++ b/src/frontend/components/form-group/input/lib/documentComponent.ts @@ -70,6 +70,7 @@ class DocumentComponent { if(JSON.parse(e as string)?.message) e = JSON.parse(e as string).message; this.handler.addError(e); + logging.error("Failed to upload file:", e); }); }); } @@ -126,6 +127,7 @@ class DocumentComponent { .hide(); }); } catch (e) { + logging.error("Failed to upload file:", e); this.showException(e instanceof Error || "message" in e ? e.message : e as string ?? e.toString()); } } @@ -191,6 +193,7 @@ class DocumentComponent { this.showException(e); const current = $(`#current-${fileId}`); current.text(oldName); + logging.error("Failed to rename file:", e); } } diff --git a/src/frontend/js/lib/logging.js b/src/frontend/js/lib/logging.js index 4799b610a..da8faa25f 100644 --- a/src/frontend/js/lib/logging.js +++ b/src/frontend/js/lib/logging.js @@ -1,53 +1,57 @@ import { uploadMessage } from "util/scriptErrorHandler"; class Logging { + /** + * Create a new Logging instance. + */ constructor() { this.allowLogging = window.test || location.hostname === 'localhost' || location.hostname === '127.0.0.1' || - location.hostname.endsWith('.peek.digitpaint.nl') + location.hostname.endsWith('.peek.digitpaint.nl'); } log(...message) { if (this.allowLogging) { - console.log(message) + console.log(...message) } else { - const message = this.formatMessage('log', ...message) - uploadMessage(message) + const msg = this.formatMessage('log', ...message) + uploadMessage(msg) } } info(...message) { if (this.allowLogging) { - console.info(message) + console.info(...message) } else { - const message = this.formatMessage('info', ...message) - uploadMessage(message) + const msg = this.formatMessage('info', ...message) + uploadMessage(msg) } } warn(...message) { if (this.allowLogging) { - console.warn(message) + console.warn(...message) } else { - const message = this.formatMessage('warn', ...message) - uploadMessage(message) + const msg = this.formatMessage('warn', ...message) + uploadMessage(msg) } } error(...message) { if (this.allowLogging) { - console.error(message) + console.error(...message) } else { - const message = this.formatMessage('error', ...message) - uploadMessage(message) + const msg = this.formatMessage('error', ...message) + uploadMessage(msg) } } formatMessage(type, ...message) { let output = type + ': '; for (let i = 0; i < message.length; i++) { + if(!message[i]) continue; if (typeof message[i] === 'object') { output += JSON.stringify(message[i]); } else { @@ -60,5 +64,5 @@ class Logging { } } -const logging = new Logging +const logging = new Logging(); export { logging } diff --git a/src/frontend/js/lib/util/scriptErrorHandler/lib/MessageUploader.test.ts b/src/frontend/js/lib/util/scriptErrorHandler/lib/MessageUploader.test.ts deleted file mode 100644 index b7725c100..000000000 --- a/src/frontend/js/lib/util/scriptErrorHandler/lib/MessageUploader.test.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { describe, it, expect, jest } from '@jest/globals'; -import { MessageUploader } from './MessageUploader'; - -describe('MessageUploader', () => { - class MockUploader { - upload = jest.fn(); - } - - it('should upload messages correctly', async () => { - const uploader = new MockUploader(); - const messageUploader = new MessageUploader(uploader); - - const messages = { id: 1, content: 'Test message 1' }; - - await messageUploader.uploadMessage(JSON.stringify(messages)); - - expect(uploader.upload).toHaveBeenCalledTimes(1); - expect(uploader.upload).toHaveBeenCalledWith({ - description: JSON.stringify(messages), - url: 'http://localhost/' - }); - }); -}); diff --git a/src/frontend/js/lib/util/scriptErrorHandler/lib/MessageUploader.ts b/src/frontend/js/lib/util/scriptErrorHandler/lib/MessageUploader.ts index b362cfeb7..a89539db0 100644 --- a/src/frontend/js/lib/util/scriptErrorHandler/lib/MessageUploader.ts +++ b/src/frontend/js/lib/util/scriptErrorHandler/lib/MessageUploader.ts @@ -5,15 +5,23 @@ export const uploadMessage = async (message: string) => { description: message, url: window.location.href }; - const uploader = new Uploader('/api/script_error', 'POST'); - const messageUploader = new MessageUploader(uploader); + const messageUploader = MessageUploader.instance; return await messageUploader.uploadMessage(body.description); }; -export class MessageUploader { +class MessageUploader { + private static _instance: MessageUploader; + constructor(private uploader: Uploader) { } + static get instance(): MessageUploader { + if (!this._instance) { + this._instance = new MessageUploader(new Uploader('/api/script_error', 'POST')); + } + return this._instance; + } + async uploadMessage(description: string): Promise { const csrf_token = document.body.dataset.csrf; const body = {