From c1062b997f7b84a73bf418df920e01b830bdd2d1 Mon Sep 17 00:00:00 2001 From: Thorsten Rinne Date: Mon, 20 Jan 2025 11:59:15 +0100 Subject: [PATCH] refactor: migrated from JavaScript to TypeScript (Part 3) WIP, not done yet, build is currently broken --- .../user/{autocomplete.js => autocomplete.ts} | 29 +-- .../assets/src/user/{index.js => index.ts} | 0 .../src/user/{user-list.js => user-list.ts} | 41 ++-- .../assets/src/user/{users.js => users.ts} | 179 +++++++++--------- .../assets/src/utils/{index.js => index.ts} | 0 .../src/utils/{session.js => session.ts} | 25 +-- .../src/utils/{sidebar.js => sidebar.ts} | 11 +- .../assets/src/utils/{utils.js => utils.ts} | 30 +-- 8 files changed, 167 insertions(+), 148 deletions(-) rename phpmyfaq/admin/assets/src/user/{autocomplete.js => autocomplete.ts} (63%) rename phpmyfaq/admin/assets/src/user/{index.js => index.ts} (100%) rename phpmyfaq/admin/assets/src/user/{user-list.js => user-list.ts} (65%) rename phpmyfaq/admin/assets/src/user/{users.js => users.ts} (59%) rename phpmyfaq/admin/assets/src/utils/{index.js => index.ts} (100%) rename phpmyfaq/admin/assets/src/utils/{session.js => session.ts} (58%) rename phpmyfaq/admin/assets/src/utils/{sidebar.js => sidebar.ts} (72%) rename phpmyfaq/admin/assets/src/utils/{utils.js => utils.ts} (50%) diff --git a/phpmyfaq/admin/assets/src/user/autocomplete.js b/phpmyfaq/admin/assets/src/user/autocomplete.ts similarity index 63% rename from phpmyfaq/admin/assets/src/user/autocomplete.js rename to phpmyfaq/admin/assets/src/user/autocomplete.ts index edd3e6c048..7cf8f877d0 100644 --- a/phpmyfaq/admin/assets/src/user/autocomplete.js +++ b/phpmyfaq/admin/assets/src/user/autocomplete.ts @@ -13,39 +13,44 @@ * @since 2022-03-23 */ -import autocomplete from 'autocompleter'; +import autocomplete, { AutocompleteItem } from 'autocompleter'; import { updateUser } from './users'; import { fetchUsers } from '../api'; import { addElement } from '../../../../assets/src/utils'; +interface User { + label: string; + value: string; +} + +type UserSuggestion = User & AutocompleteItem; + document.addEventListener('DOMContentLoaded', () => { - const autoComplete = document.getElementById('pmf-user-list-autocomplete'); + const autoComplete = document.getElementById('pmf-user-list-autocomplete') as HTMLInputElement; if (autoComplete) { - autocomplete({ + autocomplete({ input: autoComplete, minLength: 1, - onSelect: async (item, input) => { + onSelect: async (item: UserSuggestion, input: HTMLInputElement | HTMLTextAreaElement) => { input.value = item.label; await updateUser(item.value); }, - fetch: async (text, callback) => { + fetch: async (text: string, callback: (items: UserSuggestion[]) => void) => { const match = text.toLowerCase(); const users = await fetchUsers(match); callback( - users.filter((n) => { + users?.filter((n: UserSuggestion) => { return n.label.toLowerCase().indexOf(match) !== -1; }) ); }, - render: (item, value) => { - const regex = new RegExp(value, 'gi'); + render: (item: UserSuggestion, currentValue: string): HTMLDivElement => { + const regex = new RegExp(currentValue, 'gi'); return addElement('div', { classList: 'pmf-user-list-result border', - innerHTML: item.label.replace(regex, function (match) { - return `${match}`; - }), - }); + innerHTML: item.label.replace(regex, (match) => `${match}`), + }) as HTMLDivElement; }, emptyMsg: 'No users found', }); diff --git a/phpmyfaq/admin/assets/src/user/index.js b/phpmyfaq/admin/assets/src/user/index.ts similarity index 100% rename from phpmyfaq/admin/assets/src/user/index.js rename to phpmyfaq/admin/assets/src/user/index.ts diff --git a/phpmyfaq/admin/assets/src/user/user-list.js b/phpmyfaq/admin/assets/src/user/user-list.ts similarity index 65% rename from phpmyfaq/admin/assets/src/user/user-list.js rename to phpmyfaq/admin/assets/src/user/user-list.ts index 79386cb7d8..ac6f9cdc6a 100644 --- a/phpmyfaq/admin/assets/src/user/user-list.js +++ b/phpmyfaq/admin/assets/src/user/user-list.ts @@ -1,7 +1,7 @@ /** * Functions for handling user management * - * @todo move fetch() functionality to api.js + * @todo move fetch() functionality to api functions * * This Source Code Form is subject to the terms of the Mozilla Public License, * v. 2.0. If a copy of the MPL was not distributed with this file, You can @@ -15,12 +15,11 @@ * @since 2022-03-23 */ -import { addElement } from '../../../../assets/src/utils'; -import { pushErrorNotification, pushNotification } from '../utils'; +import { addElement, pushErrorNotification, pushNotification } from '../../../../assets/src/utils'; import { deleteUser } from '../api'; import { Modal } from 'bootstrap'; -const activateUser = async (userId, csrfToken) => { +const activateUser = async (userId: string, csrfToken: string): Promise => { try { const response = await fetch('./api/user/activate', { method: 'POST', @@ -36,24 +35,24 @@ const activateUser = async (userId, csrfToken) => { if (response.status === 200) { await response.json(); - const icon = document.querySelector(`.icon_user_id_${userId}`); + const icon = document.querySelector(`.icon_user_id_${userId}`) as HTMLElement; icon.classList.remove('bi-ban'); icon.classList.add('bi-check-circle-o'); - const button = document.getElementById(`btn_activate_user_id_${userId}`); + const button = document.getElementById(`btn_activate_user_id_${userId}`) as HTMLElement; button.remove(); } else { throw new Error('Network response was not ok.'); } } catch (error) { - const message = document.getElementById('pmf-user-message'); + const message = document.getElementById('pmf-user-message') as HTMLElement; message.insertAdjacentElement( 'afterend', - addElement('div', { classList: 'alert alert-danger', innerText: error.message }) + addElement('div', { classList: 'alert alert-danger', innerText: (error as Error).message }) ); } }; -export const handleUserList = () => { +export const handleUserList = (): void => { const activateButtons = document.querySelectorAll('.btn-activate-user'); const deleteButtons = document.querySelectorAll('.btn-delete-user'); @@ -62,8 +61,9 @@ export const handleUserList = () => { button.addEventListener('click', async (event) => { event.preventDefault(); - const csrfToken = event.target.getAttribute('data-csrf-token'); - const userId = event.target.getAttribute('data-user-id'); + const target = event.target as HTMLElement; + const csrfToken = target.getAttribute('data-csrf-token')!; + const userId = target.getAttribute('data-user-id')!; await activateUser(userId, csrfToken); }); @@ -75,11 +75,14 @@ export const handleUserList = () => { button.addEventListener('click', (event) => { event.preventDefault(); - const deleteModal = new Modal(document.getElementById('pmf-modal-user-confirm-delete')); + const deleteModal = new Modal(document.getElementById('pmf-modal-user-confirm-delete') as HTMLElement); deleteModal.show(); - document.getElementById('pmf-username-delete').innerText = button.getAttribute('data-username'); - document.getElementById('pmf-user-id-delete').value = button.getAttribute('data-user-id'); - document.getElementById('source_page').value = 'user-list'; + const usernameDelete = document.getElementById('pmf-username-delete') as HTMLElement; + usernameDelete.innerText = button.getAttribute('data-username')!; + const userIdDelete = document.getElementById('pmf-user-id-delete') as HTMLInputElement; + userIdDelete.value = button.getAttribute('data-user-id')!; + const sourcePage = document.getElementById('source_page') as HTMLInputElement; + sourcePage.value = 'user-list'; }); }); @@ -87,15 +90,15 @@ export const handleUserList = () => { if (deleteUserConfirm) { deleteUserConfirm.addEventListener('click', async (event) => { event.preventDefault(); - const source = document.getElementById('source_page'); + const source = document.getElementById('source_page') as HTMLInputElement; if (source.value === 'user-list') { - const userId = document.getElementById('pmf-user-id-delete').value; - const csrfToken = document.getElementById('csrf-token-delete-user').value; + const userId = (document.getElementById('pmf-user-id-delete') as HTMLInputElement).value; + const csrfToken = (document.getElementById('csrf-token-delete-user') as HTMLInputElement).value; const response = await deleteUser(userId, csrfToken); const json = await response.json(); if (json.success) { pushNotification(json.success); - const row = document.getElementById('row_user_id_' + userId); + const row = document.getElementById('row_user_id_' + userId) as HTMLElement; row.remove(); } if (json.error) { diff --git a/phpmyfaq/admin/assets/src/user/users.js b/phpmyfaq/admin/assets/src/user/users.ts similarity index 59% rename from phpmyfaq/admin/assets/src/user/users.js rename to phpmyfaq/admin/assets/src/user/users.ts index 978f3f2a92..d3e2e10d88 100644 --- a/phpmyfaq/admin/assets/src/user/users.js +++ b/phpmyfaq/admin/assets/src/user/users.ts @@ -1,7 +1,7 @@ /** * JavaScript functions for user frontend * - * @todo move fetch() functionality to api.js + * @todo move fetch() functionality to api functions * * This Source Code Form is subject to the terms of the Mozilla Public License, * v. 2.0. If a copy of the MPL was not distributed with this file, You can @@ -16,15 +16,14 @@ */ import { Modal } from 'bootstrap'; -import { fetchAllUsers, fetchUserData, fetchUserRights, deleteUser, postUserData } from '../api'; -import { addElement, capitalize } from '../../../../assets/src/utils'; -import { pushErrorNotification, pushNotification } from '../utils'; +import { fetchUserData, fetchUserRights, deleteUser, postUserData } from '../api'; +import { capitalize, pushErrorNotification, pushNotification } from '../../../../assets/src/utils'; /** * Updates the current loaded user * @param userId */ -export const updateUser = async (userId) => { +export const updateUser = async (userId: string): Promise => { await setUserData(userId); await setUserRights(userId); }; @@ -33,7 +32,7 @@ export const updateUser = async (userId) => { * Sets the user data * @param {string} userId */ -const setUserData = async (userId) => { +const setUserData = async (userId: string): Promise => { const userData = await fetchUserData(userId); updateInput('current_user_id', userData.user_id); @@ -48,49 +47,49 @@ const setUserData = async (userId) => { updateInput('overwrite_twofactor', userData.twofactor_enabled); if (userData.is_superadmin) { - const superAdmin = document.getElementById('is_superadmin'); + const superAdmin = document.getElementById('is_superadmin') as HTMLInputElement; superAdmin.setAttribute('checked', 'checked'); document.querySelectorAll('.permission').forEach((checkbox) => { - checkbox.removeAttribute('disabled'); + (checkbox as HTMLInputElement).removeAttribute('disabled'); }); document.querySelectorAll('#pmf-user-rights-save').forEach((element) => { - element.removeAttribute('disabled'); + (element as HTMLButtonElement).removeAttribute('disabled'); }); - document.getElementById('checkAll').removeAttribute('disabled'); - document.getElementById('uncheckAll').setAttribute('disabled', ''); + (document.getElementById('checkAll') as HTMLInputElement).removeAttribute('disabled'); + (document.getElementById('uncheckAll') as HTMLInputElement).setAttribute('disabled', ''); } else { - const superAdmin = document.getElementById('is_superadmin'); + const superAdmin = document.getElementById('is_superadmin') as HTMLInputElement; superAdmin.removeAttribute('checked'); } if (userData.twofactor_enabled === '1') { - const twoFactorEnabled = document.getElementById('overwrite_twofactor'); + const twoFactorEnabled = document.getElementById('overwrite_twofactor') as HTMLInputElement; twoFactorEnabled.setAttribute('checked', 'checked'); twoFactorEnabled.removeAttribute('disabled'); } if (userData.status !== 'protected') { - const deleteUser = document.getElementById('pmf-delete-user'); + const deleteUser = document.getElementById('pmf-delete-user') as HTMLButtonElement; deleteUser.classList.remove('disabled'); } - const saveUser = document.getElementById('pmf-user-save'); + const saveUser = document.getElementById('pmf-user-save') as HTMLButtonElement; saveUser.classList.remove('disabled'); window.history.pushState({}, '', `./user/edit/${userId}`); }; -const setUserRights = async (userId) => { +const setUserRights = async (userId: string): Promise => { clearUserRights(); const userRights = await fetchUserRights(userId); userRights.forEach((right) => { - const checkbox = document.getElementById(`user_right_${right}`); + const checkbox = document.getElementById(`user_right_${right}`) as HTMLInputElement; checkbox.setAttribute('checked', 'checked'); }); - document.getElementById('rights_user_id').value = userId; + (document.getElementById('rights_user_id') as HTMLInputElement).value = userId; }; -const clearUserForm = async () => { +const clearUserForm = async (): Promise => { updateInput('current_user_id', ''); updateInput('pmf-user-list-autocomplete', ''); updateInput('last_modified', ''); @@ -104,64 +103,64 @@ const clearUserForm = async () => { clearUserRights(); - document.getElementById('pmf-user-save').classList.add('disabled'); - document.getElementById('pmf-delete-user').classList.add('disabled'); + (document.getElementById('pmf-user-save') as HTMLButtonElement).classList.add('disabled'); + (document.getElementById('pmf-delete-user') as HTMLButtonElement).classList.add('disabled'); }; -const clearUserRights = () => { +const clearUserRights = (): void => { document.querySelectorAll('.permission').forEach((item) => { - if (item.checked) { - item.removeAttribute('checked'); + if ((item as HTMLInputElement).checked) { + (item as HTMLInputElement).removeAttribute('checked'); } }); }; -const updateInput = (id, value) => { - const input = document.getElementById(id); +const updateInput = (id: string, value: string): void => { + const input = document.getElementById(id) as HTMLInputElement; if (input) { input.value = value; input.removeAttribute('disabled'); } }; -export const handleUsers = async () => { - const currentUserId = document.getElementById('current_user_id'); +export const handleUsers = async (): Promise => { + const currentUserId = document.getElementById('current_user_id') as HTMLInputElement; if (currentUserId?.value) { await updateUser(currentUserId.value); } - const toggleCheckAll = document.getElementById('checkAll'); - const toggleUncheckAll = document.getElementById('uncheckAll'); - const modal = document.getElementById('addUserModal'); - const modalBackdrop = document.getElementsByClassName('modal-backdrop fade show'); - const addUser = document.getElementById('pmf-add-user-action'); - const addUserForm = document.getElementById('pmf-add-user-form'); - const addUserError = document.getElementById('pmf-add-user-error-message'); - const passwordToggle = document.getElementById('add_user_automatic_password'); - const passwordInputs = document.getElementById('add_user_show_password_inputs'); - const isSuperAdmin = document.getElementById('is_superadmin'); + const toggleCheckAll = document.getElementById('checkAll') as HTMLInputElement; + const toggleUncheckAll = document.getElementById('uncheckAll') as HTMLInputElement; + const modal = document.getElementById('addUserModal') as HTMLElement; + const modalBackdrop = document.getElementsByClassName('modal-backdrop fade show') as HTMLCollectionOf; + const addUser = document.getElementById('pmf-add-user-action') as HTMLButtonElement; + const addUserForm = document.getElementById('pmf-add-user-form') as HTMLFormElement; + const addUserError = document.getElementById('pmf-add-user-error-message') as HTMLElement; + const passwordToggle = document.getElementById('add_user_automatic_password') as HTMLInputElement; + const passwordInputs = document.getElementById('add_user_show_password_inputs') as HTMLElement; + const isSuperAdmin = document.getElementById('is_superadmin') as HTMLInputElement; if (isSuperAdmin) { isSuperAdmin.addEventListener('click', () => { if (isSuperAdmin.checked) { document.querySelectorAll('.permission').forEach((checkbox) => { - checkbox.removeAttribute('disabled'); + (checkbox as HTMLInputElement).removeAttribute('disabled'); }); document.querySelectorAll('#pmf-user-rights-save').forEach((element) => { - element.removeAttribute('disabled'); + (element as HTMLButtonElement).removeAttribute('disabled'); }); - document.getElementById('checkAll').setAttribute('disabled', ''); - document.getElementById('uncheckAll').setAttribute('disabled', ''); + (document.getElementById('checkAll') as HTMLInputElement).setAttribute('disabled', ''); + (document.getElementById('uncheckAll') as HTMLInputElement).setAttribute('disabled', ''); } else { document.querySelectorAll('.permission').forEach((checkbox) => { - checkbox.removeAttribute('disabled'); + (checkbox as HTMLInputElement).removeAttribute('disabled'); }); document.querySelectorAll('#pmf-user-rights-save').forEach((element) => { - element.removeAttribute('disabled'); + (element as HTMLButtonElement).removeAttribute('disabled'); }); - document.getElementById('checkAll').removeAttribute('disabled'); - document.getElementById('uncheckAll').removeAttribute('disabled'); + (document.getElementById('checkAll') as HTMLInputElement).removeAttribute('disabled'); + (document.getElementById('uncheckAll') as HTMLInputElement).removeAttribute('disabled'); } }); } @@ -175,12 +174,12 @@ export const handleUsers = async () => { if (toggleCheckAll && toggleUncheckAll) { toggleCheckAll.addEventListener('click', () => { document.querySelectorAll('.permission').forEach((checkbox) => { - checkbox.checked = true; + (checkbox as HTMLInputElement).checked = true; }); }); toggleUncheckAll.addEventListener('click', () => { document.querySelectorAll('.permission').forEach((checkbox) => { - checkbox.checked = false; + (checkbox as HTMLInputElement).checked = false; }); }); } @@ -188,14 +187,14 @@ export const handleUsers = async () => { if (addUser) { addUser.addEventListener('click', (event) => { event.preventDefault(); - const csrf = document.getElementById('add_user_csrf').value; - const userName = document.getElementById('add_user_name').value; - const realName = document.getElementById('add_user_realname').value; - const automaticPassword = document.getElementById('add_user_automatic_password')?.checked; - const email = document.getElementById('add_user_email').value; - const password = document.getElementById('add_user_password').value; - const passwordConfirm = document.getElementById('add_user_password_confirm').value; - let isSuperAdmin = document.querySelector('#add_user_is_superadmin'); + const csrf = (document.getElementById('add_user_csrf') as HTMLInputElement).value; + const userName = (document.getElementById('add_user_name') as HTMLInputElement).value; + const realName = (document.getElementById('add_user_realname') as HTMLInputElement).value; + const automaticPassword = (document.getElementById('add_user_automatic_password') as HTMLInputElement)?.checked; + const email = (document.getElementById('add_user_email') as HTMLInputElement).value; + const password = (document.getElementById('add_user_password') as HTMLInputElement).value; + const passwordConfirm = (document.getElementById('add_user_password_confirm') as HTMLInputElement).value; + let isSuperAdmin = document.querySelector('#add_user_is_superadmin') as HTMLInputElement; if (isSuperAdmin) { isSuperAdmin = isSuperAdmin.checked; @@ -223,7 +222,7 @@ export const handleUsers = async () => { } if (response.status === 400) { const json = await response.json(); - json.forEach((item) => { + json.forEach((item: string) => { pushErrorNotification(item); }); } @@ -245,7 +244,7 @@ export const handleUsers = async () => { }); } - const buttonExportAllUsers = document.getElementById('pmf-button-export-users'); + const buttonExportAllUsers = document.getElementById('pmf-button-export-users') as HTMLButtonElement; if (buttonExportAllUsers) { buttonExportAllUsers.addEventListener('click', (event) => { @@ -254,8 +253,8 @@ export const handleUsers = async () => { }); } - const buttonOverwritePassword = document.getElementById('pmf-user-password-overwrite-action'); - const container = document.getElementById('pmf-modal-user-password-overwrite'); + const buttonOverwritePassword = document.getElementById('pmf-user-password-overwrite-action') as HTMLButtonElement; + const container = document.getElementById('pmf-modal-user-password-overwrite') as HTMLElement; if (buttonOverwritePassword) { const modal = new Modal(container); @@ -263,10 +262,10 @@ export const handleUsers = async () => { buttonOverwritePassword.addEventListener('click', async (event) => { event.preventDefault(); - const csrf = document.getElementById('modal_csrf').value; - const userId = document.getElementById('modal_user_id').value; - const newPassword = document.getElementById('npass').value; - const passwordRepeat = document.getElementById('bpass').value; + const csrf = (document.getElementById('modal_csrf') as HTMLInputElement).value; + const userId = (document.getElementById('modal_user_id') as HTMLInputElement).value; + const newPassword = (document.getElementById('npass') as HTMLInputElement).value; + const passwordRepeat = (document.getElementById('bpass') as HTMLInputElement).value; const response = await overwritePassword(csrf, userId, newPassword, passwordRepeat); if (response.success) { @@ -280,26 +279,28 @@ export const handleUsers = async () => { } // Delete user - const deleteUserButton = document.getElementById('pmf-delete-user'); - const deleteUserConfirmed = document.getElementById('pmf-delete-user-yes'); + const deleteUserButton = document.getElementById('pmf-delete-user') as HTMLButtonElement; + const deleteUserConfirmed = document.getElementById('pmf-delete-user-yes') as HTMLButtonElement; if (deleteUserButton) { deleteUserButton.addEventListener('click', (event) => { event.preventDefault(); - const modalDeleteConfirmation = new Modal(document.getElementById('pmf-modal-user-confirm-delete')); + const modalDeleteConfirmation = new Modal( + document.getElementById('pmf-modal-user-confirm-delete') as HTMLElement + ); modalDeleteConfirmation.show(); - const username = document.getElementById('pmf-username-delete'); - const userid = document.getElementById('pmf-user-id-delete'); - username.innerText = document.getElementById('display_name').value; - userid.value = document.getElementById('current_user_id').value; - document.getElementById('source_page').value = 'users'; + const username = document.getElementById('pmf-username-delete') as HTMLElement; + const userid = document.getElementById('pmf-user-id-delete') as HTMLInputElement; + username.innerText = (document.getElementById('display_name') as HTMLInputElement).value; + userid.value = (document.getElementById('current_user_id') as HTMLInputElement).value; + (document.getElementById('source_page') as HTMLInputElement).value = 'users'; }); deleteUserConfirmed.addEventListener('click', async (event) => { event.preventDefault(); - const source = document.getElementById('source_page'); + const source = document.getElementById('source_page') as HTMLInputElement; if (source.value === 'users') { - const userId = document.getElementById('pmf-user-id-delete').value; - const csrfToken = document.getElementById('csrf-token-delete-user').value; + const userId = (document.getElementById('pmf-user-id-delete') as HTMLInputElement).value; + const csrfToken = (document.getElementById('csrf-token-delete-user') as HTMLInputElement).value; const response = await deleteUser(userId, csrfToken); const json = await response.json(); if (json.success) { @@ -314,19 +315,19 @@ export const handleUsers = async () => { } // Edit user - const editUserButton = document.getElementById('pmf-user-save'); + const editUserButton = document.getElementById('pmf-user-save') as HTMLButtonElement; if (editUserButton) { editUserButton.addEventListener('click', async (event) => { event.preventDefault(); - const userId = document.getElementById('update_user_id').value; + const userId = (document.getElementById('update_user_id') as HTMLInputElement).value; let userData = { - csrfToken: document.getElementById('pmf-csrf-token').value, - display_name: document.getElementById('display_name').value, - email: document.getElementById('email').value, - last_modified: document.getElementById('last_modified').value, - user_status: document.getElementById('user_status').value, - is_superadmin: document.getElementById('is_superadmin').checked, - overwrite_twofactor: document.getElementById('overwrite_twofactor').checked, + csrfToken: (document.getElementById('pmf-csrf-token') as HTMLInputElement).value, + display_name: (document.getElementById('display_name') as HTMLInputElement).value, + email: (document.getElementById('email') as HTMLInputElement).value, + last_modified: (document.getElementById('last_modified') as HTMLInputElement).value, + user_status: (document.getElementById('user_status') as HTMLInputElement).value, + is_superadmin: (document.getElementById('is_superadmin') as HTMLInputElement).checked, + overwrite_twofactor: (document.getElementById('overwrite_twofactor') as HTMLInputElement).checked, userId: userId, }; @@ -346,15 +347,15 @@ export const handleUsers = async () => { document.querySelectorAll('#pmf-user-rights-save').forEach((item) => { item.addEventListener('click', async (event) => { event.preventDefault(); - let rightData = []; + let rightData: string[] = []; document.querySelectorAll('.permission').forEach(async (checkbox) => { - if (checkbox.checked) { - rightData.push(checkbox.value); + if ((checkbox as HTMLInputElement).checked) { + rightData.push((checkbox as HTMLInputElement).value); } }); - const userId = document.getElementById('rights_user_id').value; + const userId = (document.getElementById('rights_user_id') as HTMLInputElement).value; let data = { - csrfToken: document.getElementById('pmf-csrf-token-rights').value, + csrfToken: (document.getElementById('pmf-csrf-token-rights') as HTMLInputElement).value, userId: userId, userRights: rightData, }; diff --git a/phpmyfaq/admin/assets/src/utils/index.js b/phpmyfaq/admin/assets/src/utils/index.ts similarity index 100% rename from phpmyfaq/admin/assets/src/utils/index.js rename to phpmyfaq/admin/assets/src/utils/index.ts diff --git a/phpmyfaq/admin/assets/src/utils/session.js b/phpmyfaq/admin/assets/src/utils/session.ts similarity index 58% rename from phpmyfaq/admin/assets/src/utils/session.js rename to phpmyfaq/admin/assets/src/utils/session.ts index cf09ab29f2..b4381cddc7 100644 --- a/phpmyfaq/admin/assets/src/utils/session.js +++ b/phpmyfaq/admin/assets/src/utils/session.ts @@ -14,9 +14,9 @@ */ import { Modal } from 'bootstrap'; -export const handleSessionTimeout = () => { - const showWarning = top.document.getElementById('pmf-show-session-warning'); - const config = { attributes: true }; +export const handleSessionTimeout = (): void => { + const showWarning = top?.document.getElementById('pmf-show-session-warning'); + const config: MutationObserverInit = { attributes: true }; if (showWarning) { const observer = new MutationObserver(onAttributeChange); observer.observe(showWarning, config); @@ -24,24 +24,25 @@ export const handleSessionTimeout = () => { } }; -const onAttributeChange = (mutationsList) => { - for (let mutation of mutationsList) { +const onAttributeChange = (mutationsList: MutationRecord[]): void => { + for (const mutation of mutationsList) { if (mutation.type === 'attributes' && mutation.attributeName === 'data-value') { - const value = mutation.target.getAttribute('data-value'); - toggleSessionWarnungModal(value); + const value = (mutation.target as HTMLElement).getAttribute('data-value'); + toggleSessionWarningModal(value); } } }; -const toggleSessionWarnungModal = (toggle) => { - const sessionWarnungModal = new Modal(top.document.getElementById('sessionWarningModal')); + +const toggleSessionWarningModal = (toggle: string | null): void => { + const sessionWarningModal = new Modal(top?.document.getElementById('sessionWarningModal') as HTMLElement); if (toggle === 'show') { - sessionWarnungModal.show(); + sessionWarningModal.show(); } else { - sessionWarnungModal.hide(); + sessionWarningModal.hide(); } }; -const reloadCurrentPage = () => { +const reloadCurrentPage = (): void => { const reloadButton = document.getElementById('pmf-button-reload-page'); if (reloadButton) { reloadButton.addEventListener('click', () => { diff --git a/phpmyfaq/admin/assets/src/utils/sidebar.js b/phpmyfaq/admin/assets/src/utils/sidebar.ts similarity index 72% rename from phpmyfaq/admin/assets/src/utils/sidebar.js rename to phpmyfaq/admin/assets/src/utils/sidebar.ts index 42e91a62e1..216a8189d1 100644 --- a/phpmyfaq/admin/assets/src/utils/sidebar.js +++ b/phpmyfaq/admin/assets/src/utils/sidebar.ts @@ -14,14 +14,17 @@ * @since 2014-03-22 */ -export const sidebarToggle = () => { - const sidebarToggle = document.body.querySelector('#sidebarToggle'); +export const sidebarToggle = (): void => { + const sidebarToggle = document.body.querySelector('#sidebarToggle') as HTMLElement | null; if (sidebarToggle) { - sidebarToggle.addEventListener('click', (event) => { + sidebarToggle.addEventListener('click', (event: Event) => { event.preventDefault(); document.body.classList.toggle('pmf-admin-sidenav-toggled'); - localStorage.setItem('sb|sidebar-toggle', document.body.classList.contains('pmf-admin-sidenav-toggled')); + localStorage.setItem( + 'sb|sidebar-toggle', + document.body.classList.contains('pmf-admin-sidenav-toggled').toString() + ); }); } }; diff --git a/phpmyfaq/admin/assets/src/utils/utils.js b/phpmyfaq/admin/assets/src/utils/utils.ts similarity index 50% rename from phpmyfaq/admin/assets/src/utils/utils.js rename to phpmyfaq/admin/assets/src/utils/utils.ts index a7c22970be..85871df8a7 100644 --- a/phpmyfaq/admin/assets/src/utils/utils.js +++ b/phpmyfaq/admin/assets/src/utils/utils.ts @@ -15,20 +15,26 @@ import { Tooltip } from 'bootstrap'; -export const selectAll = (selectId) => { - for (const options of [...document.querySelector(`#${selectId}`).options]) { - options.selected = true; +export const selectAll = (selectId: string): void => { + const selectElement = document.querySelector(`#${selectId}`) as HTMLSelectElement; + if (selectElement) { + for (const option of selectElement.options) { + option.selected = true; + } } }; -export const unSelectAll = (selectId) => { - for (const options of [...document.querySelector(`#${selectId}`).options]) { - options.selected = false; +export const unSelectAll = (selectId: string): void => { + const selectElement = document.querySelector(`#${selectId}`) as HTMLSelectElement; + if (selectElement) { + for (const option of selectElement.options) { + option.selected = false; + } } }; -export const formatBytes = (bytes, decimals = 2) => { - if (!+bytes) { +export const formatBytes = (bytes: number, decimals: number = 2): string => { + if (bytes === 0) { return '0 Bytes'; } @@ -41,9 +47,9 @@ export const formatBytes = (bytes, decimals = 2) => { return `${parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`; }; -export const initializeTooltips = () => { - const tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]')); - const tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) { - return new Tooltip(tooltipTriggerEl); +export const initializeTooltips = (): void => { + const tooltipTriggerList = Array.from(document.querySelectorAll('[data-bs-toggle="tooltip"]')); + tooltipTriggerList.forEach((tooltipTriggerEl) => { + new Tooltip(tooltipTriggerEl); }); };