From 0e26556d1c10e00ec23dd5a25b8c9b9e47e7e9f6 Mon Sep 17 00:00:00 2001 From: Andreas Kienast <a.fernandez@scripting-base.de> Date: Fri, 9 Feb 2024 10:15:43 +0100 Subject: [PATCH] [BUGFIX] Install Tool: Re-enable modal actions after execution In some cases it was missed to enable modal actions again after their execution in the Install Tool. This patch adds the necessary statements to enable said buttons again. Resolves: #101224 Releases: main, 12.4 Change-Id: I793f157302df15912f0506c376d9db2d6041ebcc Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/82871 Tested-by: Andreas Kienast <a.fernandez@scripting-base.de> Reviewed-by: Andreas Kienast <a.fernandez@scripting-base.de> Tested-by: core-ci <typo3@b13.com> --- .../module/environment/environment-check.ts | 4 +- .../module/environment/folder-structure.ts | 7 +- .../module/environment/image-processing.ts | 3 +- .../module/maintenance/clear-tables.ts | 4 +- .../maintenance/clear-typo3temp-files.ts | 4 +- .../module/maintenance/database-analyzer.ts | 9 +- .../module/upgrade/extension-compat-tester.ts | 4 +- .../module/upgrade/extension-scanner.ts | 325 +++++++++--------- .../module/upgrade/tca-ext-tables-check.ts | 4 +- .../module/upgrade/tca-migrations-check.ts | 5 +- .../module/environment/environment-check.js | 2 +- .../module/environment/folder-structure.js | 2 +- .../module/environment/image-processing.js | 2 +- .../module/maintenance/clear-tables.js | 2 +- .../maintenance/clear-typo3temp-files.js | 2 +- .../module/maintenance/database-analyzer.js | 2 +- .../module/upgrade/extension-compat-tester.js | 2 +- .../module/upgrade/extension-scanner.js | 2 +- .../module/upgrade/tca-ext-tables-check.js | 2 +- .../module/upgrade/tca-migrations-check.js | 2 +- 20 files changed, 206 insertions(+), 183 deletions(-) diff --git a/Build/Sources/TypeScript/install/module/environment/environment-check.ts b/Build/Sources/TypeScript/install/module/environment/environment-check.ts index ea9f97b34cf7..08ae603d472a 100644 --- a/Build/Sources/TypeScript/install/module/environment/environment-check.ts +++ b/Build/Sources/TypeScript/install/module/environment/environment-check.ts @@ -97,7 +97,9 @@ class EnvironmentCheck extends AbstractInteractableModule { (error: AjaxResponse): void => { Router.handleAjaxError(error, modalContent); } - ); + ).finally((): void => { + this.setModalButtonsState(true); + }); } } diff --git a/Build/Sources/TypeScript/install/module/environment/folder-structure.ts b/Build/Sources/TypeScript/install/module/environment/folder-structure.ts index e189b92fefdf..ea92389ca50e 100644 --- a/Build/Sources/TypeScript/install/module/environment/folder-structure.ts +++ b/Build/Sources/TypeScript/install/module/environment/folder-structure.ts @@ -64,9 +64,6 @@ class FolderStructure extends AbstractInteractableModule { const modalContent = this.getModalBody(); const $errorBadge = $(this.selectorGridderBadge); $errorBadge.text('').hide(); - modalContent.find(this.selectorOutputContainer).empty().append( - ProgressBar.render(Severity.loading, 'Loading...', ''), - ); (new AjaxRequest(Router.getUrl('folderStructureGetStatus'))) .get({ cache: 'no-cache' }) .then( @@ -113,7 +110,9 @@ class FolderStructure extends AbstractInteractableModule { (error: AjaxResponse): void => { Router.handleAjaxError(error, modalContent); } - ); + ).finally((): void => { + this.setModalButtonsState(true); + }); } private fix(): void { diff --git a/Build/Sources/TypeScript/install/module/environment/image-processing.ts b/Build/Sources/TypeScript/install/module/environment/image-processing.ts index 19294f862e43..ae9fb1136bb3 100644 --- a/Build/Sources/TypeScript/install/module/environment/image-processing.ts +++ b/Build/Sources/TypeScript/install/module/environment/image-processing.ts @@ -76,7 +76,6 @@ class ImageProcessing extends AbstractInteractableModule { private runTests(): void { const modalContent = this.getModalBody(); - const $triggerButton = this.findInModal(this.selectorExecuteTrigger); this.setModalButtonsState(false); const $twinImageTemplate = this.findInModal(this.selectorTwinImageTemplate); @@ -128,7 +127,7 @@ class ImageProcessing extends AbstractInteractableModule { }); Promise.all(promises).then((): void => { - $triggerButton.removeClass('disabled').prop('disabled', false); + this.setModalButtonsState(true); }); } } diff --git a/Build/Sources/TypeScript/install/module/maintenance/clear-tables.ts b/Build/Sources/TypeScript/install/module/maintenance/clear-tables.ts index 23b3598a6636..6c97b3aa3b82 100644 --- a/Build/Sources/TypeScript/install/module/maintenance/clear-tables.ts +++ b/Build/Sources/TypeScript/install/module/maintenance/clear-tables.ts @@ -94,7 +94,9 @@ class ClearTables extends AbstractInteractableModule { (error: AjaxResponse): void => { Router.handleAjaxError(error, modalContent); } - ); + ).finally((): void => { + this.setModalButtonsState(true); + }); } private clear(table: string): void { diff --git a/Build/Sources/TypeScript/install/module/maintenance/clear-typo3temp-files.ts b/Build/Sources/TypeScript/install/module/maintenance/clear-typo3temp-files.ts index a2a00c982099..fadaedbf5e56 100644 --- a/Build/Sources/TypeScript/install/module/maintenance/clear-typo3temp-files.ts +++ b/Build/Sources/TypeScript/install/module/maintenance/clear-typo3temp-files.ts @@ -123,7 +123,9 @@ class ClearTypo3tempFiles extends AbstractInteractableModule { (error: AjaxResponse): void => { Router.handleAjaxError(error, modalContent); } - ); + ).finally((): void => { + this.setModalButtonsState(true); + }); } } diff --git a/Build/Sources/TypeScript/install/module/maintenance/database-analyzer.ts b/Build/Sources/TypeScript/install/module/maintenance/database-analyzer.ts index 25fe3d2faef4..135b727ac8fd 100644 --- a/Build/Sources/TypeScript/install/module/maintenance/database-analyzer.ts +++ b/Build/Sources/TypeScript/install/module/maintenance/database-analyzer.ts @@ -163,10 +163,14 @@ class DatabaseAnalyzer extends AbstractInteractableModule { } } else { Notification.error('Something went wrong', 'The request was not processed successfully. Please check the browser\'s console and TYPO3\'s log.'); + this.setModalButtonState(analyzeTrigger, true); + this.setModalButtonState(executeTrigger, false); } }, (error: AjaxResponse): void => { Router.handleAjaxError(error, modalContent); + this.setModalButtonState(analyzeTrigger, true); + this.setModalButtonState(executeTrigger, false); } ); } @@ -205,7 +209,10 @@ class DatabaseAnalyzer extends AbstractInteractableModule { (error: AjaxResponse): void => { Router.handleAjaxError(error, modalContent); } - ); + ).finally((): void => { + this.setModalButtonState(this.getModalFooter().find(this.selectorAnalyzeTrigger), true); + this.setModalButtonState(this.getModalFooter().find(this.selectorExecuteTrigger), false); + }); } } diff --git a/Build/Sources/TypeScript/install/module/upgrade/extension-compat-tester.ts b/Build/Sources/TypeScript/install/module/upgrade/extension-compat-tester.ts index 0bcdc7b98f58..45ee70f50b27 100644 --- a/Build/Sources/TypeScript/install/module/upgrade/extension-compat-tester.ts +++ b/Build/Sources/TypeScript/install/module/upgrade/extension-compat-tester.ts @@ -94,17 +94,19 @@ class ExtensionCompatTester extends AbstractInteractableModule { }); } else { Notification.error('Something went wrong', 'The request was not processed successfully. Please check the browser\'s console and TYPO3\'s log.'); + this.unlockModal(); } }, (error: AjaxResponse): void => { Router.handleAjaxError(error, modalContent); + this.unlockModal(); } ); } private unlockModal(): void { this.findInModal(this.selectorOutputContainer).find('.alert-loading').remove(); - this.findInModal(this.selectorCheckTrigger).removeClass('disabled').prop('disabled', false); + this.setModalButtonsState(true); } private renderFailureMessages(scope: string, brokenExtensions: Array<BrokenExtension>, $outputContainer: JQuery): void { diff --git a/Build/Sources/TypeScript/install/module/upgrade/extension-scanner.ts b/Build/Sources/TypeScript/install/module/upgrade/extension-scanner.ts index 8ad149cd4ccd..86aed8c44f2b 100644 --- a/Build/Sources/TypeScript/install/module/upgrade/extension-scanner.ts +++ b/Build/Sources/TypeScript/install/module/upgrade/extension-scanner.ts @@ -110,7 +110,7 @@ class ExtensionScanner extends AbstractInteractableModule { return this.selectorExtensionContainer + '-' + extension; } - private scanAll($extensions: JQuery): void { + private async scanAll($extensions: JQuery): Promise<void> { this.findInModal(this.selectorExtensionContainer) .removeClass('panel-danger panel-warning panel-success') .find('.panel-progress-bar') @@ -119,12 +119,40 @@ class ExtensionScanner extends AbstractInteractableModule { .find('span') .text('0%'); this.setProgressForAll(); - $extensions.each((index: number, element: Element): void => { - const $me: JQuery = $(element); - const extension = $me.data('extension'); - this.scanSingleExtension(extension); - $me.data('scanned', true); + + const scannerPromises = $.map($extensions, async (element: HTMLElement) => { + const $extension = $(element); + const extension = $extension.data('extension'); + try { + await this.scanSingleExtension(extension); + } finally { + $extension.data('scanned', true); + } }); + + try { + await Promise.allSettled(scannerPromises); + } finally { + this.setModalButtonsState(true); + + Notification.success('Scan finished', 'All extensions have been scanned.'); + + try { + const response = await new AjaxRequest(Router.getUrl()).post({ + install: { + action: 'extensionScannerMarkFullyScannedRestFiles', + token: this.getModuleContent().data('extension-scanner-mark-fully-scanned-rest-files-token'), + hashes: Array.from(new Set(this.listOfAffectedRestFileHashes)), + }, + }); + const data = await response.resolve(); + if (data.success === true) { + Notification.success('Marked not affected files', 'Marked ' + data.markedAsNotAffected + ' ReST files as not affected.'); + } + } catch (error: unknown) { + Router.handleAjaxError(error as AjaxResponse, this.getModalBody()); + } + } } private setStatusMessageForScan(extension: string, doneFiles: number, numberOfFiles: number): void { @@ -153,41 +181,17 @@ class ExtensionScanner extends AbstractInteractableModule { + '.t3js-extensionscan-finished.panel-danger').length; const numberOfScannedExtensions: number = numberOfSuccess + numberOfWarning + numberOfError; const percent: number = (numberOfScannedExtensions / numberOfExtensions) * 100; - const modalContent: JQuery = this.getModalBody(); this.findInModal('.t3js-extensionScanner-progress-all-extension .progress-bar') .css('width', percent + '%') .attr('aria-valuenow', percent) .find('span') .text(numberOfScannedExtensions + ' of ' + numberOfExtensions + ' scanned'); - - if (numberOfScannedExtensions === numberOfExtensions) { - this.findInModal(this.selectorExtensionScanButton).removeClass('disabled').prop('disabled', false); - Notification.success('Scan finished', 'All extensions have been scanned.'); - - (new AjaxRequest(Router.getUrl())).post({ - install: { - action: 'extensionScannerMarkFullyScannedRestFiles', - token: this.getModuleContent().data('extension-scanner-mark-fully-scanned-rest-files-token'), - hashes: Array.from(new Set(this.listOfAffectedRestFileHashes)), - }, - }).then( - async (response: AjaxResponse): Promise<void> => { - const data = await response.resolve(); - if (data.success === true) { - Notification.success('Marked not affected files', 'Marked ' + data.markedAsNotAffected + ' ReST files as not affected.'); - } - }, - (error: AjaxResponse): void => { - Router.handleAjaxError(error, modalContent); - } - ); - } } /** * Handle a single extension scan */ - private scanSingleExtension(extension: string): void { + private async scanSingleExtension(extension: string): Promise<void> { const executeToken = this.getModuleContent().data('extension-scanner-files-token'); const modalContent = this.getModalBody(); const $extensionContainer = this.findInModal(this.getExtensionSelector(extension)); @@ -202,143 +206,146 @@ class ExtensionScanner extends AbstractInteractableModule { $extensionContainer.find('.t3js-extensionScanner-extension-body-ignored-files').empty().text('0'); $extensionContainer.find('.t3js-extensionScanner-extension-body-ignored-lines').empty().text('0'); this.setProgressForAll(); - (new AjaxRequest(Router.getUrl())).post({ - install: { - action: 'extensionScannerFiles', - token: executeToken, - extension: extension, - }, - }).then( - async (response: AjaxResponse): Promise<void> => { - const data: ExtensionScannerFilesResponse = await response.resolve(); - if (data.success === true && Array.isArray(data.files)) { - const numberOfFiles = data.files.length; - if (numberOfFiles <= 0) { - Notification.warning('No files found', 'The extension ' + extension + ' contains no scannable files'); - return; - } - this.setStatusMessageForScan(extension, 0, numberOfFiles); - $extensionContainer.find('.t3js-extensionScanner-extension-body').text(''); - $extensionContainer.addClass('panel-has-progress'); - let doneFiles = 0; - data.files.forEach((file: string): void => { - AjaxQueue.add({ - method: 'POST', - data: { - install: { - action: 'extensionScannerScanFile', - token: this.getModuleContent().data('extension-scanner-scan-file-token'), - extension: extension, - file: file, - }, + try { + const response = await (new AjaxRequest(Router.getUrl())).post({ + install: { + action: 'extensionScannerFiles', + token: executeToken, + extension: extension, + }, + }); + const data: ExtensionScannerFilesResponse = await response.resolve(); + if (data.success === true && Array.isArray(data.files)) { + const numberOfFiles = data.files.length; + if (numberOfFiles <= 0) { + Notification.warning('No files found', 'The extension ' + extension + ' contains no scannable files'); + return; + } + + this.setStatusMessageForScan(extension, 0, numberOfFiles); + $extensionContainer.find('.t3js-extensionScanner-extension-body').text(''); + $extensionContainer.addClass('panel-has-progress'); + let doneFiles = 0; + const filePromises = data.files.map((file: string): Promise<void> => new Promise<void>((resolve, reject): void => { + AjaxQueue.add({ + method: 'POST', + data: { + install: { + action: 'extensionScannerScanFile', + token: this.getModuleContent().data('extension-scanner-scan-file-token'), + extension: extension, + file: file, }, - url: Router.getUrl(), - onfulfilled: async (response: AjaxResponse): Promise<void> => { - const fileData: ExtensionScannerScanFileResponse = await response.resolve(); - doneFiles++; - this.setStatusMessageForScan(extension, doneFiles, numberOfFiles); - this.setProgressForScan(extension, doneFiles, numberOfFiles); - if (fileData.success && Array.isArray(fileData.matches)) { - fileData.matches.forEach((match: Match): void => { - hitFound = true; - const aMatch: JQuery = modalContent.find(hitTemplate).find('.panel').clone(); - aMatch.find('.t3js-extensionScanner-hit-file-panel-head').attr('href', '#collapse' + match.uniqueId); - aMatch.find('.t3js-extensionScanner-hit-file-panel-body').attr('id', 'collapse' + match.uniqueId); - aMatch.find('.t3js-extensionScanner-hit-filename').text(file); - aMatch.find('.t3js-extensionScanner-hit-message').text(match.message); - if (match.indicator === 'strong') { - aMatch.find('.t3js-extensionScanner-hit-file-panel-head .badges') - .append('<span class="badge badge-danger" title="Reliable match, false positive unlikely">strong</span>'); - } else { - aMatch.find('.t3js-extensionScanner-hit-file-panel-head .badges') - .append('<span class="badge badge-warning" title="Probable match, but can be a false positive">weak</span>'); - } - if (match.silenced === true) { - aMatch.find('.t3js-extensionScanner-hit-file-panel-head .badges') - .append('<span class="badge badge-info" title="Match has been annotated by extension author' + - ' as false positive match">silenced</span>'); - } - aMatch.find('.t3js-extensionScanner-hit-file-lineContent').empty().text(match.lineContent); - aMatch.find('.t3js-extensionScanner-hit-file-line').empty().text(match.line + ': '); - if (Array.isArray(match.restFiles)) { - match.restFiles.forEach((restFile: RestFile): void => { - const aRest = modalContent.find(restTemplate).find('.panel').clone(); - aRest.find('.t3js-extensionScanner-hit-rest-panel-head').attr('href', '#collapse' + restFile.uniqueId); - aRest.find('.t3js-extensionScanner-hit-rest-panel-head .badge').empty().text(restFile.version); - aRest.find('.t3js-extensionScanner-hit-rest-panel-body').attr('id', 'collapse' + restFile.uniqueId); - aRest.find('.t3js-extensionScanner-hit-rest-headline').text(restFile.headline); - aRest.find('.t3js-extensionScanner-hit-rest-body').text(restFile.content); - aRest.addClass('panel-' + restFile.class); - aMatch.find('.t3js-extensionScanner-hit-file-rest-container').append(aRest); - this.listOfAffectedRestFileHashes.push(restFile.file_hash); - }); - } - const panelClass = - aMatch.find('.panel-breaking, .t3js-extensionScanner-hit-file-rest-container').length > 0 - ? 'panel-danger' - : 'panel-warning'; - aMatch.addClass(panelClass); - aMatch.removeClass('panel-default'); - $extensionContainer.find('.t3js-extensionScanner-extension-body').removeClass('hide').append(aMatch); - $extensionContainer.removeClass('panel-default'); - if (panelClass === 'panel-danger') { - $extensionContainer.removeClass('panel-warning'); - $extensionContainer.addClass(panelClass); - } - if (panelClass === 'panel-warning' && !$extensionContainer.hasClass('panel-danger')) { - $extensionContainer.addClass(panelClass); - } - }); - } - if (fileData.success) { - const currentLinesOfCode = parseInt($extensionContainer.find('.t3js-extensionScanner-extension-body-loc').text(), 10); - $extensionContainer.find('.t3js-extensionScanner-extension-body-loc').empty() - .text(currentLinesOfCode + fileData.effectiveCodeLines); - if (fileData.isFileIgnored) { - const currentIgnoredFiles = parseInt( - $extensionContainer.find('.t3js-extensionScanner-extension-body-ignored-files').text(), - 10, - ); - $extensionContainer.find('.t3js-extensionScanner-extension-body-ignored-files').empty().text(currentIgnoredFiles + 1); + }, + url: Router.getUrl(), + onfulfilled: async (response: AjaxResponse): Promise<void> => { + const fileData: ExtensionScannerScanFileResponse = await response.resolve(); + doneFiles++; + this.setStatusMessageForScan(extension, doneFiles, numberOfFiles); + this.setProgressForScan(extension, doneFiles, numberOfFiles); + if (fileData.success && Array.isArray(fileData.matches)) { + fileData.matches.forEach((match: Match): void => { + hitFound = true; + const aMatch: JQuery = modalContent.find(hitTemplate).find('.panel').clone(); + aMatch.find('.t3js-extensionScanner-hit-file-panel-head').attr('href', '#collapse' + match.uniqueId); + aMatch.find('.t3js-extensionScanner-hit-file-panel-body').attr('id', 'collapse' + match.uniqueId); + aMatch.find('.t3js-extensionScanner-hit-filename').text(file); + aMatch.find('.t3js-extensionScanner-hit-message').text(match.message); + if (match.indicator === 'strong') { + aMatch.find('.t3js-extensionScanner-hit-file-panel-head .badges') + .append('<span class="badge badge-danger" title="Reliable match, false positive unlikely">strong</span>'); + } else { + aMatch.find('.t3js-extensionScanner-hit-file-panel-head .badges') + .append('<span class="badge badge-warning" title="Probable match, but can be a false positive">weak</span>'); + } + if (match.silenced === true) { + aMatch.find('.t3js-extensionScanner-hit-file-panel-head .badges') + .append('<span class="badge badge-info" title="Match has been annotated by extension author' + + ' as false positive match">silenced</span>'); + } + aMatch.find('.t3js-extensionScanner-hit-file-lineContent').empty().text(match.lineContent); + aMatch.find('.t3js-extensionScanner-hit-file-line').empty().text(match.line + ': '); + if (Array.isArray(match.restFiles)) { + match.restFiles.forEach((restFile: RestFile): void => { + const aRest = modalContent.find(restTemplate).find('.panel').clone(); + aRest.find('.t3js-extensionScanner-hit-rest-panel-head').attr('href', '#collapse' + restFile.uniqueId); + aRest.find('.t3js-extensionScanner-hit-rest-panel-head .badge').empty().text(restFile.version); + aRest.find('.t3js-extensionScanner-hit-rest-panel-body').attr('id', 'collapse' + restFile.uniqueId); + aRest.find('.t3js-extensionScanner-hit-rest-headline').text(restFile.headline); + aRest.find('.t3js-extensionScanner-hit-rest-body').text(restFile.content); + aRest.addClass('panel-' + restFile.class); + aMatch.find('.t3js-extensionScanner-hit-file-rest-container').append(aRest); + this.listOfAffectedRestFileHashes.push(restFile.file_hash); + }); } - const currentIgnoredLines = parseInt( - $extensionContainer.find('.t3js-extensionScanner-extension-body-ignored-lines').text(), + const panelClass = + aMatch.find('.panel-breaking, .t3js-extensionScanner-hit-file-rest-container').length > 0 + ? 'panel-danger' + : 'panel-warning'; + aMatch.addClass(panelClass); + aMatch.removeClass('panel-default'); + $extensionContainer.find('.t3js-extensionScanner-extension-body').removeClass('hide').append(aMatch); + $extensionContainer.removeClass('panel-default'); + if (panelClass === 'panel-danger') { + $extensionContainer.removeClass('panel-warning'); + $extensionContainer.addClass(panelClass); + } + if (panelClass === 'panel-warning' && !$extensionContainer.hasClass('panel-danger')) { + $extensionContainer.addClass(panelClass); + } + }); + } + if (fileData.success) { + const currentLinesOfCode = parseInt($extensionContainer.find('.t3js-extensionScanner-extension-body-loc').text(), 10); + $extensionContainer.find('.t3js-extensionScanner-extension-body-loc').empty() + .text(currentLinesOfCode + fileData.effectiveCodeLines); + if (fileData.isFileIgnored) { + const currentIgnoredFiles = parseInt( + $extensionContainer.find('.t3js-extensionScanner-extension-body-ignored-files').text(), 10, ); - $extensionContainer.find('.t3js-extensionScanner-extension-body-ignored-lines').empty() - .text(currentIgnoredLines + fileData.ignoredLines); + $extensionContainer.find('.t3js-extensionScanner-extension-body-ignored-files').empty().text(currentIgnoredFiles + 1); } - if (doneFiles === numberOfFiles) { - if (!hitFound) { - $extensionContainer.removeClass('panel-default'); - $extensionContainer.addClass('panel-success'); - } - $extensionContainer.addClass('t3js-extensionscan-finished'); - $extensionContainer.removeClass('panel-has-progress'); - this.setProgressForAll(); - $extensionContainer.find('.t3js-extensionScanner-scan-single').text('Rescan').attr('disabled', null); - } - }, - onrejected: (reason: string): void => { - doneFiles = doneFiles + 1; - this.setStatusMessageForScan(extension, doneFiles, numberOfFiles); - this.setProgressForScan(extension, doneFiles, numberOfFiles); - $extensionContainer.removeClass('panel-has-progress'); - this.setProgressForAll(); - console.error(reason); - }, - }); + const currentIgnoredLines = parseInt( + $extensionContainer.find('.t3js-extensionScanner-extension-body-ignored-lines').text(), + 10, + ); + $extensionContainer.find('.t3js-extensionScanner-extension-body-ignored-lines').empty() + .text(currentIgnoredLines + fileData.ignoredLines); + } + resolve(); + }, + onrejected: (reason: string): void => { + reject(); + doneFiles = doneFiles + 1; + this.setStatusMessageForScan(extension, doneFiles, numberOfFiles); + this.setProgressForScan(extension, doneFiles, numberOfFiles); + $extensionContainer.removeClass('panel-has-progress'); + this.setProgressForAll(); + console.error(reason); + }, }); - } else { - Notification.error('Oops, an error occurred', 'Please look at the browser console output for details'); - console.error(data); + })); + + await Promise.allSettled(filePromises); + + if (!hitFound) { + $extensionContainer.removeClass('panel-default'); + $extensionContainer.addClass('panel-success'); } - }, - (error: AjaxResponse): void => { - Router.handleAjaxError(error, modalContent); + $extensionContainer.addClass('t3js-extensionscan-finished'); + $extensionContainer.removeClass('panel-has-progress'); + this.setProgressForAll(); + $extensionContainer.find('.t3js-extensionScanner-scan-single').text('Rescan').attr('disabled', null); + + } else { + Notification.error('Oops, an error occurred', 'Please look at the browser console output for details'); + console.error(data); } - ); + } catch (error: unknown) { + Router.handleAjaxError(error as AjaxResponse, modalContent); + } } } diff --git a/Build/Sources/TypeScript/install/module/upgrade/tca-ext-tables-check.ts b/Build/Sources/TypeScript/install/module/upgrade/tca-ext-tables-check.ts index 2b45ae87ed6b..8bda7ddd73e3 100644 --- a/Build/Sources/TypeScript/install/module/upgrade/tca-ext-tables-check.ts +++ b/Build/Sources/TypeScript/install/module/upgrade/tca-ext-tables-check.ts @@ -81,7 +81,9 @@ class TcaExtTablesCheck extends AbstractInteractableModule { (error: AjaxResponse): void => { Router.handleAjaxError(error, modalContent); } - ); + ).finally((): void => { + this.setModalButtonsState(true); + }); } } diff --git a/Build/Sources/TypeScript/install/module/upgrade/tca-migrations-check.ts b/Build/Sources/TypeScript/install/module/upgrade/tca-migrations-check.ts index b49930e3d18e..c7f9ad902737 100644 --- a/Build/Sources/TypeScript/install/module/upgrade/tca-migrations-check.ts +++ b/Build/Sources/TypeScript/install/module/upgrade/tca-migrations-check.ts @@ -78,12 +78,13 @@ class TcaMigrationsCheck extends AbstractInteractableModule { const m4 = FlashMessage.render(Severity.error, 'Something went wrong', 'Use "Check for broken extensions"'); modalContent.find(this.selectorOutputContainer).append(m4); } - this.setModalButtonsState(true); }, (error: AjaxResponse): void => { Router.handleAjaxError(error, modalContent); } - ); + ).finally((): void => { + this.setModalButtonsState(true); + }); } } diff --git a/typo3/sysext/install/Resources/Public/JavaScript/module/environment/environment-check.js b/typo3/sysext/install/Resources/Public/JavaScript/module/environment/environment-check.js index 9c8548ad3e14..c16d59f56f1a 100644 --- a/typo3/sysext/install/Resources/Public/JavaScript/module/environment/environment-check.js +++ b/typo3/sysext/install/Resources/Public/JavaScript/module/environment/environment-check.js @@ -10,4 +10,4 @@ * * The TYPO3 project - inspiring people to share! */ -import"bootstrap";import $ from"jquery";import{AbstractInteractableModule}from"@typo3/install/module/abstract-interactable-module.js";import Modal from"@typo3/backend/modal.js";import Notification from"@typo3/backend/notification.js";import AjaxRequest from"@typo3/core/ajax/ajax-request.js";import InfoBox from"@typo3/install/renderable/info-box.js";import ProgressBar from"@typo3/install/renderable/progress-bar.js";import Severity from"@typo3/install/renderable/severity.js";import Router from"@typo3/install/router.js";class EnvironmentCheck extends AbstractInteractableModule{constructor(){super(...arguments),this.selectorGridderBadge=".t3js-environmentCheck-badge",this.selectorExecuteTrigger=".t3js-environmentCheck-execute",this.selectorOutputContainer=".t3js-environmentCheck-output"}initialize(e){this.currentModal=e,this.runTests(),e.on("click",this.selectorExecuteTrigger,(e=>{e.preventDefault(),this.runTests()}))}runTests(){this.setModalButtonsState(!1);const e=this.getModalBody(),t=$(this.selectorGridderBadge);t.text("").hide();const r=ProgressBar.render(Severity.loading,"Loading...","");e.find(this.selectorOutputContainer).empty().append(r),new AjaxRequest(Router.getUrl("environmentCheckGetStatus")).get({cache:"no-cache"}).then((async r=>{const o=await r.resolve();e.empty().append(o.html),Modal.setButtons(o.buttons);let s=0,n=0;if(!0===o.success&&"object"==typeof o.status){for(const t of Object.values(o.status))for(const r of t){1===r.severity&&s++,2===r.severity&&n++;const t=InfoBox.render(r.severity,r.title,r.message);e.find(this.selectorOutputContainer).append(t)}n>0?t.removeClass("badge-warning").addClass("badge-danger").text(n).show():s>0&&t.removeClass("badge-error").addClass("badge-warning").text(s).show()}else Notification.error("Something went wrong","The request was not processed successfully. Please check the browser's console and TYPO3's log.")}),(t=>{Router.handleAjaxError(t,e)}))}}export default new EnvironmentCheck; \ No newline at end of file +import"bootstrap";import $ from"jquery";import{AbstractInteractableModule}from"@typo3/install/module/abstract-interactable-module.js";import Modal from"@typo3/backend/modal.js";import Notification from"@typo3/backend/notification.js";import AjaxRequest from"@typo3/core/ajax/ajax-request.js";import InfoBox from"@typo3/install/renderable/info-box.js";import ProgressBar from"@typo3/install/renderable/progress-bar.js";import Severity from"@typo3/install/renderable/severity.js";import Router from"@typo3/install/router.js";class EnvironmentCheck extends AbstractInteractableModule{constructor(){super(...arguments),this.selectorGridderBadge=".t3js-environmentCheck-badge",this.selectorExecuteTrigger=".t3js-environmentCheck-execute",this.selectorOutputContainer=".t3js-environmentCheck-output"}initialize(e){this.currentModal=e,this.runTests(),e.on("click",this.selectorExecuteTrigger,(e=>{e.preventDefault(),this.runTests()}))}runTests(){this.setModalButtonsState(!1);const e=this.getModalBody(),t=$(this.selectorGridderBadge);t.text("").hide();const r=ProgressBar.render(Severity.loading,"Loading...","");e.find(this.selectorOutputContainer).empty().append(r),new AjaxRequest(Router.getUrl("environmentCheckGetStatus")).get({cache:"no-cache"}).then((async r=>{const o=await r.resolve();e.empty().append(o.html),Modal.setButtons(o.buttons);let s=0,n=0;if(!0===o.success&&"object"==typeof o.status){for(const t of Object.values(o.status))for(const r of t){1===r.severity&&s++,2===r.severity&&n++;const t=InfoBox.render(r.severity,r.title,r.message);e.find(this.selectorOutputContainer).append(t)}n>0?t.removeClass("badge-warning").addClass("badge-danger").text(n).show():s>0&&t.removeClass("badge-error").addClass("badge-warning").text(s).show()}else Notification.error("Something went wrong","The request was not processed successfully. Please check the browser's console and TYPO3's log.")}),(t=>{Router.handleAjaxError(t,e)})).finally((()=>{this.setModalButtonsState(!0)}))}}export default new EnvironmentCheck; \ No newline at end of file diff --git a/typo3/sysext/install/Resources/Public/JavaScript/module/environment/folder-structure.js b/typo3/sysext/install/Resources/Public/JavaScript/module/environment/folder-structure.js index f9c551129b8a..7268398d45c9 100644 --- a/typo3/sysext/install/Resources/Public/JavaScript/module/environment/folder-structure.js +++ b/typo3/sysext/install/Resources/Public/JavaScript/module/environment/folder-structure.js @@ -10,4 +10,4 @@ * * The TYPO3 project - inspiring people to share! */ -import"bootstrap";import $ from"jquery";import{AbstractInteractableModule}from"@typo3/install/module/abstract-interactable-module.js";import Modal from"@typo3/backend/modal.js";import Notification from"@typo3/backend/notification.js";import AjaxRequest from"@typo3/core/ajax/ajax-request.js";import InfoBox from"@typo3/install/renderable/info-box.js";import ProgressBar from"@typo3/install/renderable/progress-bar.js";import Severity from"@typo3/install/renderable/severity.js";import Router from"@typo3/install/router.js";class FolderStructure extends AbstractInteractableModule{constructor(){super(...arguments),this.selectorGridderBadge=".t3js-folderStructure-badge",this.selectorOutputContainer=".t3js-folderStructure-output",this.selectorErrorContainer=".t3js-folderStructure-errors",this.selectorErrorList=".t3js-folderStructure-errors-list",this.selectorErrorFixTrigger=".t3js-folderStructure-errors-fix",this.selectorOkContainer=".t3js-folderStructure-ok",this.selectorOkList=".t3js-folderStructure-ok-list",this.selectorPermissionContainer=".t3js-folderStructure-permissions"}static removeLoadingMessage(e){e.find(".alert-loading").remove()}initialize(e){this.currentModal=e,this.getStatus(),e.on("click",this.selectorErrorFixTrigger,(e=>{e.preventDefault(),this.fix()}))}getStatus(){const e=this.getModalBody(),t=$(this.selectorGridderBadge);t.text("").hide(),e.find(this.selectorOutputContainer).empty().append(ProgressBar.render(Severity.loading,"Loading...","")),new AjaxRequest(Router.getUrl("folderStructureGetStatus")).get({cache:"no-cache"}).then((async r=>{const o=await r.resolve();if(e.empty().append(o.html),Modal.setButtons(o.buttons),!0===o.success&&Array.isArray(o.errorStatus)){let r=0;o.errorStatus.length>0?(e.find(this.selectorErrorContainer).show(),e.find(this.selectorErrorList).empty(),o.errorStatus.forEach((o=>{r++,t.text(r).show();const s=InfoBox.render(o.severity,o.title,o.message);e.find(this.selectorErrorList).append(s)}))):e.find(this.selectorErrorContainer).hide()}!0===o.success&&Array.isArray(o.okStatus)&&(o.okStatus.length>0?(e.find(this.selectorOkContainer).show(),e.find(this.selectorOkList).empty(),o.okStatus.forEach((t=>{const r=InfoBox.render(t.severity,t.title,t.message);e.find(this.selectorOkList).append(r)}))):e.find(this.selectorOkContainer).hide());let s=o.folderStructureFilePermissionStatus;e.find(this.selectorPermissionContainer).empty().append(InfoBox.render(s.severity,s.title,s.message)),s=o.folderStructureDirectoryPermissionStatus,e.find(this.selectorPermissionContainer).append(InfoBox.render(s.severity,s.title,s.message))}),(t=>{Router.handleAjaxError(t,e)}))}fix(){this.setModalButtonsState(!1);const e=this.getModalBody(),t=this.findInModal(this.selectorOutputContainer),r=ProgressBar.render(Severity.loading,"Loading...","");t.empty().append(r),new AjaxRequest(Router.getUrl("folderStructureFix")).get({cache:"no-cache"}).then((async e=>{const r=await e.resolve();FolderStructure.removeLoadingMessage(t),!0===r.success&&Array.isArray(r.fixedStatus)?(r.fixedStatus.length>0?r.fixedStatus.forEach((e=>{t.append(InfoBox.render(e.severity,e.title,e.message))})):t.append(InfoBox.render(Severity.warning,"Nothing fixed","")),this.getStatus()):Notification.error("Something went wrong","The request was not processed successfully. Please check the browser's console and TYPO3's log.")}),(t=>{Router.handleAjaxError(t,e)}))}}export default new FolderStructure; \ No newline at end of file +import"bootstrap";import $ from"jquery";import{AbstractInteractableModule}from"@typo3/install/module/abstract-interactable-module.js";import Modal from"@typo3/backend/modal.js";import Notification from"@typo3/backend/notification.js";import AjaxRequest from"@typo3/core/ajax/ajax-request.js";import InfoBox from"@typo3/install/renderable/info-box.js";import ProgressBar from"@typo3/install/renderable/progress-bar.js";import Severity from"@typo3/install/renderable/severity.js";import Router from"@typo3/install/router.js";class FolderStructure extends AbstractInteractableModule{constructor(){super(...arguments),this.selectorGridderBadge=".t3js-folderStructure-badge",this.selectorOutputContainer=".t3js-folderStructure-output",this.selectorErrorContainer=".t3js-folderStructure-errors",this.selectorErrorList=".t3js-folderStructure-errors-list",this.selectorErrorFixTrigger=".t3js-folderStructure-errors-fix",this.selectorOkContainer=".t3js-folderStructure-ok",this.selectorOkList=".t3js-folderStructure-ok-list",this.selectorPermissionContainer=".t3js-folderStructure-permissions"}static removeLoadingMessage(e){e.find(".alert-loading").remove()}initialize(e){this.currentModal=e,this.getStatus(),e.on("click",this.selectorErrorFixTrigger,(e=>{e.preventDefault(),this.fix()}))}getStatus(){const e=this.getModalBody(),t=$(this.selectorGridderBadge);t.text("").hide(),new AjaxRequest(Router.getUrl("folderStructureGetStatus")).get({cache:"no-cache"}).then((async r=>{const o=await r.resolve();if(e.empty().append(o.html),Modal.setButtons(o.buttons),!0===o.success&&Array.isArray(o.errorStatus)){let r=0;o.errorStatus.length>0?(e.find(this.selectorErrorContainer).show(),e.find(this.selectorErrorList).empty(),o.errorStatus.forEach((o=>{r++,t.text(r).show();const s=InfoBox.render(o.severity,o.title,o.message);e.find(this.selectorErrorList).append(s)}))):e.find(this.selectorErrorContainer).hide()}!0===o.success&&Array.isArray(o.okStatus)&&(o.okStatus.length>0?(e.find(this.selectorOkContainer).show(),e.find(this.selectorOkList).empty(),o.okStatus.forEach((t=>{const r=InfoBox.render(t.severity,t.title,t.message);e.find(this.selectorOkList).append(r)}))):e.find(this.selectorOkContainer).hide());let s=o.folderStructureFilePermissionStatus;e.find(this.selectorPermissionContainer).empty().append(InfoBox.render(s.severity,s.title,s.message)),s=o.folderStructureDirectoryPermissionStatus,e.find(this.selectorPermissionContainer).append(InfoBox.render(s.severity,s.title,s.message))}),(t=>{Router.handleAjaxError(t,e)})).finally((()=>{this.setModalButtonsState(!0)}))}fix(){this.setModalButtonsState(!1);const e=this.getModalBody(),t=this.findInModal(this.selectorOutputContainer),r=ProgressBar.render(Severity.loading,"Loading...","");t.empty().append(r),new AjaxRequest(Router.getUrl("folderStructureFix")).get({cache:"no-cache"}).then((async e=>{const r=await e.resolve();FolderStructure.removeLoadingMessage(t),!0===r.success&&Array.isArray(r.fixedStatus)?(r.fixedStatus.length>0?r.fixedStatus.forEach((e=>{t.append(InfoBox.render(e.severity,e.title,e.message))})):t.append(InfoBox.render(Severity.warning,"Nothing fixed","")),this.getStatus()):Notification.error("Something went wrong","The request was not processed successfully. Please check the browser's console and TYPO3's log.")}),(t=>{Router.handleAjaxError(t,e)}))}}export default new FolderStructure; \ No newline at end of file diff --git a/typo3/sysext/install/Resources/Public/JavaScript/module/environment/image-processing.js b/typo3/sysext/install/Resources/Public/JavaScript/module/environment/image-processing.js index 1a319bc58dec..6ddbb78900e6 100644 --- a/typo3/sysext/install/Resources/Public/JavaScript/module/environment/image-processing.js +++ b/typo3/sysext/install/Resources/Public/JavaScript/module/environment/image-processing.js @@ -10,4 +10,4 @@ * * The TYPO3 project - inspiring people to share! */ -import"bootstrap";import $ from"jquery";import{AbstractInteractableModule}from"@typo3/install/module/abstract-interactable-module.js";import Modal from"@typo3/backend/modal.js";import Notification from"@typo3/backend/notification.js";import AjaxRequest from"@typo3/core/ajax/ajax-request.js";import InfoBox from"@typo3/install/renderable/info-box.js";import Severity from"@typo3/install/renderable/severity.js";import Router from"@typo3/install/router.js";class ImageProcessing extends AbstractInteractableModule{constructor(){super(...arguments),this.selectorExecuteTrigger=".t3js-imageProcessing-execute",this.selectorTestContainer=".t3js-imageProcessing-twinContainer",this.selectorTwinImageTemplate=".t3js-imageProcessing-twinImage-template",this.selectorCommandContainer=".t3js-imageProcessing-command",this.selectorCommandText=".t3js-imageProcessing-command-text",this.selectorTwinImages=".t3js-imageProcessing-images"}initialize(e){this.currentModal=e,this.getData(),e.on("click",this.selectorExecuteTrigger,(e=>{e.preventDefault(),this.runTests()}))}getData(){const e=this.getModalBody();new AjaxRequest(Router.getUrl("imageProcessingGetData")).get({cache:"no-cache"}).then((async t=>{const s=await t.resolve();!0===s.success?(e.empty().append(s.html),Modal.setButtons(s.buttons),this.runTests()):Notification.error("Something went wrong","The request was not processed successfully. Please check the browser's console and TYPO3's log.")}),(t=>{Router.handleAjaxError(t,e)}))}runTests(){const e=this.getModalBody(),t=this.findInModal(this.selectorExecuteTrigger);this.setModalButtonsState(!1);const s=this.findInModal(this.selectorTwinImageTemplate),o=[];e.find(this.selectorTestContainer).each(((t,r)=>{const a=$(r),n=a.data("test"),i=InfoBox.render(Severity.loading,"Loading...","");a.empty().append(i);const c=new AjaxRequest(Router.getUrl(n)).get({cache:"no-cache"}).then((async e=>{const t=await e.resolve();if(!0===t.success){a.empty(),Array.isArray(t.status)&&t.status.forEach((e=>{const t=InfoBox.render(e.severity,e.title,e.message);a.append(t)}));const e=s.clone();if(e.removeClass("t3js-imageProcessing-twinImage-template"),!0===t.fileExists&&(e.find("img.reference").attr("src",t.referenceFile),e.find("img.result").attr("src",t.outputFile),e.find(this.selectorTwinImages).show()),Array.isArray(t.command)&&t.command.length>0){e.find(this.selectorCommandContainer).show();const s=[];t.command.forEach((e=>{s.push("<strong>Command:</strong>\n"+e[1]),3===e.length&&s.push("<strong>Result:</strong>\n"+e[2])})),e.find(this.selectorCommandText).html(s.join("\n"))}a.append(e)}}),(t=>{Router.handleAjaxError(t,e)}));o.push(c)})),Promise.all(o).then((()=>{t.removeClass("disabled").prop("disabled",!1)}))}}export default new ImageProcessing; \ No newline at end of file +import"bootstrap";import $ from"jquery";import{AbstractInteractableModule}from"@typo3/install/module/abstract-interactable-module.js";import Modal from"@typo3/backend/modal.js";import Notification from"@typo3/backend/notification.js";import AjaxRequest from"@typo3/core/ajax/ajax-request.js";import InfoBox from"@typo3/install/renderable/info-box.js";import Severity from"@typo3/install/renderable/severity.js";import Router from"@typo3/install/router.js";class ImageProcessing extends AbstractInteractableModule{constructor(){super(...arguments),this.selectorExecuteTrigger=".t3js-imageProcessing-execute",this.selectorTestContainer=".t3js-imageProcessing-twinContainer",this.selectorTwinImageTemplate=".t3js-imageProcessing-twinImage-template",this.selectorCommandContainer=".t3js-imageProcessing-command",this.selectorCommandText=".t3js-imageProcessing-command-text",this.selectorTwinImages=".t3js-imageProcessing-images"}initialize(e){this.currentModal=e,this.getData(),e.on("click",this.selectorExecuteTrigger,(e=>{e.preventDefault(),this.runTests()}))}getData(){const e=this.getModalBody();new AjaxRequest(Router.getUrl("imageProcessingGetData")).get({cache:"no-cache"}).then((async t=>{const s=await t.resolve();!0===s.success?(e.empty().append(s.html),Modal.setButtons(s.buttons),this.runTests()):Notification.error("Something went wrong","The request was not processed successfully. Please check the browser's console and TYPO3's log.")}),(t=>{Router.handleAjaxError(t,e)}))}runTests(){const e=this.getModalBody();this.setModalButtonsState(!1);const t=this.findInModal(this.selectorTwinImageTemplate),s=[];e.find(this.selectorTestContainer).each(((o,r)=>{const n=$(r),a=n.data("test"),i=InfoBox.render(Severity.loading,"Loading...","");n.empty().append(i);const c=new AjaxRequest(Router.getUrl(a)).get({cache:"no-cache"}).then((async e=>{const s=await e.resolve();if(!0===s.success){n.empty(),Array.isArray(s.status)&&s.status.forEach((e=>{const t=InfoBox.render(e.severity,e.title,e.message);n.append(t)}));const e=t.clone();if(e.removeClass("t3js-imageProcessing-twinImage-template"),!0===s.fileExists&&(e.find("img.reference").attr("src",s.referenceFile),e.find("img.result").attr("src",s.outputFile),e.find(this.selectorTwinImages).show()),Array.isArray(s.command)&&s.command.length>0){e.find(this.selectorCommandContainer).show();const t=[];s.command.forEach((e=>{t.push("<strong>Command:</strong>\n"+e[1]),3===e.length&&t.push("<strong>Result:</strong>\n"+e[2])})),e.find(this.selectorCommandText).html(t.join("\n"))}n.append(e)}}),(t=>{Router.handleAjaxError(t,e)}));s.push(c)})),Promise.all(s).then((()=>{this.setModalButtonsState(!0)}))}}export default new ImageProcessing; \ No newline at end of file diff --git a/typo3/sysext/install/Resources/Public/JavaScript/module/maintenance/clear-tables.js b/typo3/sysext/install/Resources/Public/JavaScript/module/maintenance/clear-tables.js index ae7a7b00d75b..436470d5a4b1 100644 --- a/typo3/sysext/install/Resources/Public/JavaScript/module/maintenance/clear-tables.js +++ b/typo3/sysext/install/Resources/Public/JavaScript/module/maintenance/clear-tables.js @@ -10,4 +10,4 @@ * * The TYPO3 project - inspiring people to share! */ -import $ from"jquery";import{AbstractInteractableModule}from"@typo3/install/module/abstract-interactable-module.js";import Modal from"@typo3/backend/modal.js";import Notification from"@typo3/backend/notification.js";import AjaxRequest from"@typo3/core/ajax/ajax-request.js";import Router from"@typo3/install/router.js";class ClearTables extends AbstractInteractableModule{constructor(){super(...arguments),this.selectorClearTrigger=".t3js-clearTables-clear",this.selectorStatsTrigger=".t3js-clearTables-stats",this.selectorOutputContainer=".t3js-clearTables-output",this.selectorStatContainer=".t3js-clearTables-stat-container",this.selectorStatTemplate=".t3js-clearTables-stat-template",this.selectorStatDescription=".t3js-clearTables-stat-description",this.selectorStatRows=".t3js-clearTables-stat-rows",this.selectorStatName=".t3js-clearTables-stat-name"}initialize(t){this.currentModal=t,this.getStats(),t.on("click",this.selectorStatsTrigger,(t=>{t.preventDefault(),$(this.selectorOutputContainer).empty(),this.getStats()})),t.on("click",this.selectorClearTrigger,(t=>{const e=$(t.target).closest(this.selectorClearTrigger).data("table");t.preventDefault(),this.clear(e)}))}getStats(){this.setModalButtonsState(!1);const t=this.getModalBody();new AjaxRequest(Router.getUrl("clearTablesStats")).get({cache:"no-cache"}).then((async e=>{const s=await e.resolve();!0===s.success?(t.empty().append(s.html),Modal.setButtons(s.buttons),Array.isArray(s.stats)&&s.stats.length>0&&s.stats.forEach((e=>{if(e.rowCount>0){const s=t.find(this.selectorStatTemplate).clone();s.find(this.selectorStatDescription).text(e.description),s.find(this.selectorStatName).text(e.name),s.find(this.selectorStatRows).text(e.rowCount),s.find(this.selectorClearTrigger).attr("data-table",e.name),t.find(this.selectorStatContainer).append(s.html())}}))):Notification.error("Something went wrong","The request was not processed successfully. Please check the browser's console and TYPO3's log.")}),(e=>{Router.handleAjaxError(e,t)}))}clear(t){const e=this.getModalBody(),s=this.getModuleContent().data("clear-tables-clear-token");new AjaxRequest(Router.getUrl()).post({install:{action:"clearTablesClear",token:s,table:t}}).then((async t=>{const e=await t.resolve();!0===e.success&&Array.isArray(e.status)?e.status.forEach((t=>{Notification.success(t.title,t.message)})):Notification.error("Something went wrong","The request was not processed successfully. Please check the browser's console and TYPO3's log."),this.getStats()}),(t=>{Router.handleAjaxError(t,e)}))}}export default new ClearTables; \ No newline at end of file +import $ from"jquery";import{AbstractInteractableModule}from"@typo3/install/module/abstract-interactable-module.js";import Modal from"@typo3/backend/modal.js";import Notification from"@typo3/backend/notification.js";import AjaxRequest from"@typo3/core/ajax/ajax-request.js";import Router from"@typo3/install/router.js";class ClearTables extends AbstractInteractableModule{constructor(){super(...arguments),this.selectorClearTrigger=".t3js-clearTables-clear",this.selectorStatsTrigger=".t3js-clearTables-stats",this.selectorOutputContainer=".t3js-clearTables-output",this.selectorStatContainer=".t3js-clearTables-stat-container",this.selectorStatTemplate=".t3js-clearTables-stat-template",this.selectorStatDescription=".t3js-clearTables-stat-description",this.selectorStatRows=".t3js-clearTables-stat-rows",this.selectorStatName=".t3js-clearTables-stat-name"}initialize(t){this.currentModal=t,this.getStats(),t.on("click",this.selectorStatsTrigger,(t=>{t.preventDefault(),$(this.selectorOutputContainer).empty(),this.getStats()})),t.on("click",this.selectorClearTrigger,(t=>{const e=$(t.target).closest(this.selectorClearTrigger).data("table");t.preventDefault(),this.clear(e)}))}getStats(){this.setModalButtonsState(!1);const t=this.getModalBody();new AjaxRequest(Router.getUrl("clearTablesStats")).get({cache:"no-cache"}).then((async e=>{const s=await e.resolve();!0===s.success?(t.empty().append(s.html),Modal.setButtons(s.buttons),Array.isArray(s.stats)&&s.stats.length>0&&s.stats.forEach((e=>{if(e.rowCount>0){const s=t.find(this.selectorStatTemplate).clone();s.find(this.selectorStatDescription).text(e.description),s.find(this.selectorStatName).text(e.name),s.find(this.selectorStatRows).text(e.rowCount),s.find(this.selectorClearTrigger).attr("data-table",e.name),t.find(this.selectorStatContainer).append(s.html())}}))):Notification.error("Something went wrong","The request was not processed successfully. Please check the browser's console and TYPO3's log.")}),(e=>{Router.handleAjaxError(e,t)})).finally((()=>{this.setModalButtonsState(!0)}))}clear(t){const e=this.getModalBody(),s=this.getModuleContent().data("clear-tables-clear-token");new AjaxRequest(Router.getUrl()).post({install:{action:"clearTablesClear",token:s,table:t}}).then((async t=>{const e=await t.resolve();!0===e.success&&Array.isArray(e.status)?e.status.forEach((t=>{Notification.success(t.title,t.message)})):Notification.error("Something went wrong","The request was not processed successfully. Please check the browser's console and TYPO3's log."),this.getStats()}),(t=>{Router.handleAjaxError(t,e)}))}}export default new ClearTables; \ No newline at end of file diff --git a/typo3/sysext/install/Resources/Public/JavaScript/module/maintenance/clear-typo3temp-files.js b/typo3/sysext/install/Resources/Public/JavaScript/module/maintenance/clear-typo3temp-files.js index d49a7f4aff39..3b6d38738826 100644 --- a/typo3/sysext/install/Resources/Public/JavaScript/module/maintenance/clear-typo3temp-files.js +++ b/typo3/sysext/install/Resources/Public/JavaScript/module/maintenance/clear-typo3temp-files.js @@ -10,4 +10,4 @@ * * The TYPO3 project - inspiring people to share! */ -import $ from"jquery";import{AbstractInteractableModule}from"@typo3/install/module/abstract-interactable-module.js";import Modal from"@typo3/backend/modal.js";import Notification from"@typo3/backend/notification.js";import AjaxRequest from"@typo3/core/ajax/ajax-request.js";import Router from"@typo3/install/router.js";class ClearTypo3tempFiles extends AbstractInteractableModule{constructor(){super(...arguments),this.selectorDeleteTrigger=".t3js-clearTypo3temp-delete",this.selectorOutputContainer=".t3js-clearTypo3temp-output",this.selectorStatContainer=".t3js-clearTypo3temp-stat-container",this.selectorStatsTrigger=".t3js-clearTypo3temp-stats",this.selectorStatTemplate=".t3js-clearTypo3temp-stat-template",this.selectorStatNumberOfFiles=".t3js-clearTypo3temp-stat-numberOfFiles",this.selectorStatDirectory=".t3js-clearTypo3temp-stat-directory"}initialize(t){this.currentModal=t,this.getStats(),t.on("click",this.selectorStatsTrigger,(t=>{t.preventDefault(),$(this.selectorOutputContainer).empty(),this.getStats()})),t.on("click",this.selectorDeleteTrigger,(t=>{const e=$(t.currentTarget).data("folder"),s=$(t.currentTarget).data("storage-uid");t.preventDefault(),this.delete(e,s)}))}getStats(){this.setModalButtonsState(!1);const t=this.getModalBody();new AjaxRequest(Router.getUrl("clearTypo3tempFilesStats")).get({cache:"no-cache"}).then((async e=>{const s=await e.resolve();!0===s.success?(t.empty().append(s.html),Modal.setButtons(s.buttons),Array.isArray(s.stats)&&s.stats.length>0&&s.stats.forEach((e=>{if(e.numberOfFiles>0){const s=t.find(this.selectorStatTemplate).clone();s.find(this.selectorStatNumberOfFiles).text(e.numberOfFiles),s.find(this.selectorStatDirectory).text(e.directory),s.find(this.selectorDeleteTrigger).attr("data-folder",e.directory),s.find(this.selectorDeleteTrigger).attr("data-storage-uid",e.storageUid),t.find(this.selectorStatContainer).append(s.html())}}))):Notification.error("Something went wrong","The request was not processed successfully. Please check the browser's console and TYPO3's log.")}),(e=>{Router.handleAjaxError(e,t)}))}delete(t,e){const s=this.getModalBody(),r=this.getModuleContent().data("clear-typo3temp-delete-token");new AjaxRequest(Router.getUrl()).post({install:{action:"clearTypo3tempFiles",token:r,folder:t,storageUid:e}}).then((async t=>{const e=await t.resolve();!0===e.success&&Array.isArray(e.status)?(e.status.forEach((t=>{Notification.success(t.title,t.message)})),this.getStats()):Notification.error("Something went wrong","The request was not processed successfully. Please check the browser's console and TYPO3's log.")}),(t=>{Router.handleAjaxError(t,s)}))}}export default new ClearTypo3tempFiles; \ No newline at end of file +import $ from"jquery";import{AbstractInteractableModule}from"@typo3/install/module/abstract-interactable-module.js";import Modal from"@typo3/backend/modal.js";import Notification from"@typo3/backend/notification.js";import AjaxRequest from"@typo3/core/ajax/ajax-request.js";import Router from"@typo3/install/router.js";class ClearTypo3tempFiles extends AbstractInteractableModule{constructor(){super(...arguments),this.selectorDeleteTrigger=".t3js-clearTypo3temp-delete",this.selectorOutputContainer=".t3js-clearTypo3temp-output",this.selectorStatContainer=".t3js-clearTypo3temp-stat-container",this.selectorStatsTrigger=".t3js-clearTypo3temp-stats",this.selectorStatTemplate=".t3js-clearTypo3temp-stat-template",this.selectorStatNumberOfFiles=".t3js-clearTypo3temp-stat-numberOfFiles",this.selectorStatDirectory=".t3js-clearTypo3temp-stat-directory"}initialize(t){this.currentModal=t,this.getStats(),t.on("click",this.selectorStatsTrigger,(t=>{t.preventDefault(),$(this.selectorOutputContainer).empty(),this.getStats()})),t.on("click",this.selectorDeleteTrigger,(t=>{const e=$(t.currentTarget).data("folder"),s=$(t.currentTarget).data("storage-uid");t.preventDefault(),this.delete(e,s)}))}getStats(){this.setModalButtonsState(!1);const t=this.getModalBody();new AjaxRequest(Router.getUrl("clearTypo3tempFilesStats")).get({cache:"no-cache"}).then((async e=>{const s=await e.resolve();!0===s.success?(t.empty().append(s.html),Modal.setButtons(s.buttons),Array.isArray(s.stats)&&s.stats.length>0&&s.stats.forEach((e=>{if(e.numberOfFiles>0){const s=t.find(this.selectorStatTemplate).clone();s.find(this.selectorStatNumberOfFiles).text(e.numberOfFiles),s.find(this.selectorStatDirectory).text(e.directory),s.find(this.selectorDeleteTrigger).attr("data-folder",e.directory),s.find(this.selectorDeleteTrigger).attr("data-storage-uid",e.storageUid),t.find(this.selectorStatContainer).append(s.html())}}))):Notification.error("Something went wrong","The request was not processed successfully. Please check the browser's console and TYPO3's log.")}),(e=>{Router.handleAjaxError(e,t)}))}delete(t,e){const s=this.getModalBody(),r=this.getModuleContent().data("clear-typo3temp-delete-token");new AjaxRequest(Router.getUrl()).post({install:{action:"clearTypo3tempFiles",token:r,folder:t,storageUid:e}}).then((async t=>{const e=await t.resolve();!0===e.success&&Array.isArray(e.status)?(e.status.forEach((t=>{Notification.success(t.title,t.message)})),this.getStats()):Notification.error("Something went wrong","The request was not processed successfully. Please check the browser's console and TYPO3's log.")}),(t=>{Router.handleAjaxError(t,s)})).finally((()=>{this.setModalButtonsState(!0)}))}}export default new ClearTypo3tempFiles; \ No newline at end of file diff --git a/typo3/sysext/install/Resources/Public/JavaScript/module/maintenance/database-analyzer.js b/typo3/sysext/install/Resources/Public/JavaScript/module/maintenance/database-analyzer.js index e72cc865be5a..263ee8ee4501 100644 --- a/typo3/sysext/install/Resources/Public/JavaScript/module/maintenance/database-analyzer.js +++ b/typo3/sysext/install/Resources/Public/JavaScript/module/maintenance/database-analyzer.js @@ -10,4 +10,4 @@ * * The TYPO3 project - inspiring people to share! */ -import $ from"jquery";import{AbstractInteractableModule}from"@typo3/install/module/abstract-interactable-module.js";import Modal from"@typo3/backend/modal.js";import Notification from"@typo3/backend/notification.js";import AjaxRequest from"@typo3/core/ajax/ajax-request.js";import InfoBox from"@typo3/install/renderable/info-box.js";import ProgressBar from"@typo3/install/renderable/progress-bar.js";import Severity from"@typo3/install/renderable/severity.js";import Router from"@typo3/install/router.js";class DatabaseAnalyzer extends AbstractInteractableModule{constructor(){super(...arguments),this.selectorAnalyzeTrigger=".t3js-databaseAnalyzer-analyze",this.selectorExecuteTrigger=".t3js-databaseAnalyzer-execute",this.selectorOutputContainer=".t3js-databaseAnalyzer-output",this.selectorSuggestionBlock=".t3js-databaseAnalyzer-suggestion-block",this.selectorSuggestionList=".t3js-databaseAnalyzer-suggestion-list",this.selectorSuggestionLineTemplate=".t3js-databaseAnalyzer-suggestion-line-template"}initialize(e){this.currentModal=e,this.getData(),e.on("click",".t3js-databaseAnalyzer-suggestion-block-checkbox",(e=>{const t=$(e.currentTarget);t.closest("fieldset").find(":checkbox").prop("checked",t.get(0).checked)})),e.on("click",this.selectorAnalyzeTrigger,(e=>{e.preventDefault(),this.analyze()})),e.on("click",this.selectorExecuteTrigger,(e=>{e.preventDefault(),this.execute()}))}getData(){const e=this.getModalBody();new AjaxRequest(Router.getUrl("databaseAnalyzer")).get({cache:"no-cache"}).then((async t=>{const a=await t.resolve();!0===a.success?(e.empty().append(a.html),Modal.setButtons(a.buttons),this.analyze()):Notification.error("Something went wrong","The request was not processed successfully. Please check the browser's console and TYPO3's log.")}),(t=>{Router.handleAjaxError(t,e)}))}analyze(){this.setModalButtonsState(!1);const e=this.getModalBody(),t=this.getModalFooter(),a=e.find(this.selectorOutputContainer),s=t.find(this.selectorExecuteTrigger),n=t.find(this.selectorAnalyzeTrigger);a.empty().append(ProgressBar.render(Severity.loading,"Analyzing current database schema...","")),a.on("change",'input[type="checkbox"]',(()=>{const e=a.find(":checked").length>0;this.setModalButtonState(s,e)})),new AjaxRequest(Router.getUrl("databaseAnalyzerAnalyze")).get({cache:"no-cache"}).then((async t=>{const o=await t.resolve();!0===o.success?(Array.isArray(o.status)&&(a.find(".alert-loading").remove(),o.status.forEach((e=>{const t=InfoBox.render(e.severity,e.title,e.message);a.append(t)}))),Array.isArray(o.suggestions)&&(o.suggestions.forEach((t=>{const s=e.find(this.selectorSuggestionBlock).clone();s.removeClass(this.selectorSuggestionBlock.substr(1));const n=t.key;s.find(".t3js-databaseAnalyzer-suggestion-block-legend").text(t.label),s.find(".t3js-databaseAnalyzer-suggestion-block-checkbox").attr("id","t3-install-"+n+"-checkbox"),t.enabled&&s.find(".t3js-databaseAnalyzer-suggestion-block-checkbox").attr("checked","checked"),s.find(".t3js-databaseAnalyzer-suggestion-block-label").attr("for","t3-install-"+n+"-checkbox"),t.children.forEach((a=>{const n=e.find(this.selectorSuggestionLineTemplate).children().clone(),o=a.hash,r=n.find(".t3js-databaseAnalyzer-suggestion-line-checkbox");r.attr("id","t3-install-db-"+o).attr("data-hash",o),t.enabled&&r.attr("checked","checked"),n.find(".t3js-databaseAnalyzer-suggestion-line-label").attr("for","t3-install-db-"+o),n.find(".t3js-databaseAnalyzer-suggestion-line-statement").text(a.statement),void 0!==a.current&&(n.find(".t3js-databaseAnalyzer-suggestion-line-current-value").text(a.current),n.find(".t3js-databaseAnalyzer-suggestion-line-current").show()),void 0!==a.rowCount&&(n.find(".t3js-databaseAnalyzer-suggestion-line-count-value").text(a.rowCount),n.find(".t3js-databaseAnalyzer-suggestion-line-count").show()),s.find(this.selectorSuggestionList).append(n)})),a.append(s.html())})),this.setModalButtonState(n,!0),this.setModalButtonState(s,a.find(":checked").length>0)),0===o.suggestions.length&&0===o.status.length&&a.append(InfoBox.render(Severity.ok,"Database schema is up to date. Good job!",""))):Notification.error("Something went wrong","The request was not processed successfully. Please check the browser's console and TYPO3's log.")}),(t=>{Router.handleAjaxError(t,e)}))}execute(){this.setModalButtonsState(!1);const e=this.getModalBody(),t=this.getModuleContent().data("database-analyzer-execute-token"),a=e.find(this.selectorOutputContainer),s=[];a.find(".t3js-databaseAnalyzer-suggestion-line input:checked").each(((e,t)=>{s.push($(t).data("hash"))})),a.empty().append(ProgressBar.render(Severity.loading,"Executing database updates...","")),new AjaxRequest(Router.getUrl()).post({install:{action:"databaseAnalyzerExecute",token:t,hashes:s}}).then((async e=>{const t=await e.resolve();Array.isArray(t.status)&&t.status.forEach((e=>{Notification.showMessage(e.title,e.message,e.severity)})),this.analyze()}),(t=>{Router.handleAjaxError(t,e)}))}}export default new DatabaseAnalyzer; \ No newline at end of file +import $ from"jquery";import{AbstractInteractableModule}from"@typo3/install/module/abstract-interactable-module.js";import Modal from"@typo3/backend/modal.js";import Notification from"@typo3/backend/notification.js";import AjaxRequest from"@typo3/core/ajax/ajax-request.js";import InfoBox from"@typo3/install/renderable/info-box.js";import ProgressBar from"@typo3/install/renderable/progress-bar.js";import Severity from"@typo3/install/renderable/severity.js";import Router from"@typo3/install/router.js";class DatabaseAnalyzer extends AbstractInteractableModule{constructor(){super(...arguments),this.selectorAnalyzeTrigger=".t3js-databaseAnalyzer-analyze",this.selectorExecuteTrigger=".t3js-databaseAnalyzer-execute",this.selectorOutputContainer=".t3js-databaseAnalyzer-output",this.selectorSuggestionBlock=".t3js-databaseAnalyzer-suggestion-block",this.selectorSuggestionList=".t3js-databaseAnalyzer-suggestion-list",this.selectorSuggestionLineTemplate=".t3js-databaseAnalyzer-suggestion-line-template"}initialize(e){this.currentModal=e,this.getData(),e.on("click",".t3js-databaseAnalyzer-suggestion-block-checkbox",(e=>{const t=$(e.currentTarget);t.closest("fieldset").find(":checkbox").prop("checked",t.get(0).checked)})),e.on("click",this.selectorAnalyzeTrigger,(e=>{e.preventDefault(),this.analyze()})),e.on("click",this.selectorExecuteTrigger,(e=>{e.preventDefault(),this.execute()}))}getData(){const e=this.getModalBody();new AjaxRequest(Router.getUrl("databaseAnalyzer")).get({cache:"no-cache"}).then((async t=>{const a=await t.resolve();!0===a.success?(e.empty().append(a.html),Modal.setButtons(a.buttons),this.analyze()):Notification.error("Something went wrong","The request was not processed successfully. Please check the browser's console and TYPO3's log.")}),(t=>{Router.handleAjaxError(t,e)}))}analyze(){this.setModalButtonsState(!1);const e=this.getModalBody(),t=this.getModalFooter(),a=e.find(this.selectorOutputContainer),s=t.find(this.selectorExecuteTrigger),o=t.find(this.selectorAnalyzeTrigger);a.empty().append(ProgressBar.render(Severity.loading,"Analyzing current database schema...","")),a.on("change",'input[type="checkbox"]',(()=>{const e=a.find(":checked").length>0;this.setModalButtonState(s,e)})),new AjaxRequest(Router.getUrl("databaseAnalyzerAnalyze")).get({cache:"no-cache"}).then((async t=>{const n=await t.resolve();!0===n.success?(Array.isArray(n.status)&&(a.find(".alert-loading").remove(),n.status.forEach((e=>{const t=InfoBox.render(e.severity,e.title,e.message);a.append(t)}))),Array.isArray(n.suggestions)&&(n.suggestions.forEach((t=>{const s=e.find(this.selectorSuggestionBlock).clone();s.removeClass(this.selectorSuggestionBlock.substr(1));const o=t.key;s.find(".t3js-databaseAnalyzer-suggestion-block-legend").text(t.label),s.find(".t3js-databaseAnalyzer-suggestion-block-checkbox").attr("id","t3-install-"+o+"-checkbox"),t.enabled&&s.find(".t3js-databaseAnalyzer-suggestion-block-checkbox").attr("checked","checked"),s.find(".t3js-databaseAnalyzer-suggestion-block-label").attr("for","t3-install-"+o+"-checkbox"),t.children.forEach((a=>{const o=e.find(this.selectorSuggestionLineTemplate).children().clone(),n=a.hash,r=o.find(".t3js-databaseAnalyzer-suggestion-line-checkbox");r.attr("id","t3-install-db-"+n).attr("data-hash",n),t.enabled&&r.attr("checked","checked"),o.find(".t3js-databaseAnalyzer-suggestion-line-label").attr("for","t3-install-db-"+n),o.find(".t3js-databaseAnalyzer-suggestion-line-statement").text(a.statement),void 0!==a.current&&(o.find(".t3js-databaseAnalyzer-suggestion-line-current-value").text(a.current),o.find(".t3js-databaseAnalyzer-suggestion-line-current").show()),void 0!==a.rowCount&&(o.find(".t3js-databaseAnalyzer-suggestion-line-count-value").text(a.rowCount),o.find(".t3js-databaseAnalyzer-suggestion-line-count").show()),s.find(this.selectorSuggestionList).append(o)})),a.append(s.html())})),this.setModalButtonState(o,!0),this.setModalButtonState(s,a.find(":checked").length>0)),0===n.suggestions.length&&0===n.status.length&&a.append(InfoBox.render(Severity.ok,"Database schema is up to date. Good job!",""))):(Notification.error("Something went wrong","The request was not processed successfully. Please check the browser's console and TYPO3's log."),this.setModalButtonState(o,!0),this.setModalButtonState(s,!1))}),(t=>{Router.handleAjaxError(t,e),this.setModalButtonState(o,!0),this.setModalButtonState(s,!1)}))}execute(){this.setModalButtonsState(!1);const e=this.getModalBody(),t=this.getModuleContent().data("database-analyzer-execute-token"),a=e.find(this.selectorOutputContainer),s=[];a.find(".t3js-databaseAnalyzer-suggestion-line input:checked").each(((e,t)=>{s.push($(t).data("hash"))})),a.empty().append(ProgressBar.render(Severity.loading,"Executing database updates...","")),new AjaxRequest(Router.getUrl()).post({install:{action:"databaseAnalyzerExecute",token:t,hashes:s}}).then((async e=>{const t=await e.resolve();Array.isArray(t.status)&&t.status.forEach((e=>{Notification.showMessage(e.title,e.message,e.severity)})),this.analyze()}),(t=>{Router.handleAjaxError(t,e)})).finally((()=>{this.setModalButtonState(this.getModalFooter().find(this.selectorAnalyzeTrigger),!0),this.setModalButtonState(this.getModalFooter().find(this.selectorExecuteTrigger),!1)}))}}export default new DatabaseAnalyzer; \ No newline at end of file diff --git a/typo3/sysext/install/Resources/Public/JavaScript/module/upgrade/extension-compat-tester.js b/typo3/sysext/install/Resources/Public/JavaScript/module/upgrade/extension-compat-tester.js index 8a88cc331be6..3416f111b52a 100644 --- a/typo3/sysext/install/Resources/Public/JavaScript/module/upgrade/extension-compat-tester.js +++ b/typo3/sysext/install/Resources/Public/JavaScript/module/upgrade/extension-compat-tester.js @@ -10,4 +10,4 @@ * * The TYPO3 project - inspiring people to share! */ -import"bootstrap";import $ from"jquery";import{AbstractInteractableModule}from"@typo3/install/module/abstract-interactable-module.js";import Modal from"@typo3/backend/modal.js";import Notification from"@typo3/backend/notification.js";import AjaxRequest from"@typo3/core/ajax/ajax-request.js";import InfoBox from"@typo3/install/renderable/info-box.js";import ProgressBar from"@typo3/install/renderable/progress-bar.js";import Severity from"@typo3/install/renderable/severity.js";import Router from"@typo3/install/router.js";class ExtensionCompatTester extends AbstractInteractableModule{constructor(){super(...arguments),this.selectorCheckTrigger=".t3js-extensionCompatTester-check",this.selectorUninstallTrigger=".t3js-extensionCompatTester-uninstall",this.selectorOutputContainer=".t3js-extensionCompatTester-output"}initialize(e){this.currentModal=e,this.getLoadedExtensionList(),e.on("click",this.selectorCheckTrigger,(()=>{this.findInModal(this.selectorUninstallTrigger).addClass("hidden"),this.findInModal(this.selectorOutputContainer).empty(),this.getLoadedExtensionList()})),e.on("click",this.selectorUninstallTrigger,(e=>{this.uninstallExtension($(e.target).data("extension"))}))}getLoadedExtensionList(){this.setModalButtonsState(!1);const e=this.getModalBody(),t=this.findInModal(this.selectorOutputContainer);if(t.length){const e=ProgressBar.render(Severity.loading,"Loading...","");t.append(e)}new AjaxRequest(Router.getUrl("extensionCompatTesterLoadedExtensionList")).get({cache:"no-cache"}).then((async t=>{const o=await t.resolve();e.empty().append(o.html),Modal.setButtons(o.buttons);const n=this.findInModal(this.selectorOutputContainer),s=ProgressBar.render(Severity.loading,"Loading...","");n.append(s),!0===o.success?this.loadExtLocalconf().then((()=>{n.append(InfoBox.render(Severity.ok,"ext_localconf.php of all loaded extensions successfully loaded","")),this.loadExtTables().then((()=>{n.append(InfoBox.render(Severity.ok,"ext_tables.php of all loaded extensions successfully loaded",""))}),(async e=>{this.renderFailureMessages("ext_tables.php",(await e.response.json()).brokenExtensions,n)})).finally((()=>{this.unlockModal()}))}),(async e=>{this.renderFailureMessages("ext_localconf.php",(await e.response.json()).brokenExtensions,n),n.append(InfoBox.render(Severity.notice,"Skipped scanning ext_tables.php files due to previous errors","")),this.unlockModal()})):Notification.error("Something went wrong","The request was not processed successfully. Please check the browser's console and TYPO3's log.")}),(t=>{Router.handleAjaxError(t,e)}))}unlockModal(){this.findInModal(this.selectorOutputContainer).find(".alert-loading").remove(),this.findInModal(this.selectorCheckTrigger).removeClass("disabled").prop("disabled",!1)}renderFailureMessages(e,t,o){for(const n of t){let t;n.isProtected||(t=$("<button />",{class:"btn btn-danger t3js-extensionCompatTester-uninstall"}).attr("data-extension",n.name).text('Uninstall extension "'+n.name+'"')),o.append(InfoBox.render(Severity.error,"Loading "+e+' of extension "'+n.name+'" failed',n.isProtected?"Extension is mandatory and cannot be uninstalled.":""),t)}this.unlockModal()}loadExtLocalconf(){const e=this.getModuleContent().data("extension-compat-tester-load-ext_localconf-token");return new AjaxRequest(Router.getUrl()).post({install:{action:"extensionCompatTesterLoadExtLocalconf",token:e}})}loadExtTables(){const e=this.getModuleContent().data("extension-compat-tester-load-ext_tables-token");return new AjaxRequest(Router.getUrl()).post({install:{action:"extensionCompatTesterLoadExtTables",token:e}})}uninstallExtension(e){const t=this.getModuleContent().data("extension-compat-tester-uninstall-extension-token"),o=this.getModalBody(),n=$(this.selectorOutputContainer),s=ProgressBar.render(Severity.loading,"Loading...","");n.append(s),new AjaxRequest(Router.getUrl()).post({install:{action:"extensionCompatTesterUninstallExtension",token:t,extension:e}}).then((async e=>{const t=await e.resolve();t.success?(Array.isArray(t.status)&&t.status.forEach((e=>{const t=InfoBox.render(e.severity,e.title,e.message);o.find(this.selectorOutputContainer).empty().append(t)})),this.findInModal(this.selectorUninstallTrigger).addClass("hidden"),this.getLoadedExtensionList()):Notification.error("Something went wrong","The request was not processed successfully. Please check the browser's console and TYPO3's log.")}),(e=>{Router.handleAjaxError(e,o)}))}}export default new ExtensionCompatTester; \ No newline at end of file +import"bootstrap";import $ from"jquery";import{AbstractInteractableModule}from"@typo3/install/module/abstract-interactable-module.js";import Modal from"@typo3/backend/modal.js";import Notification from"@typo3/backend/notification.js";import AjaxRequest from"@typo3/core/ajax/ajax-request.js";import InfoBox from"@typo3/install/renderable/info-box.js";import ProgressBar from"@typo3/install/renderable/progress-bar.js";import Severity from"@typo3/install/renderable/severity.js";import Router from"@typo3/install/router.js";class ExtensionCompatTester extends AbstractInteractableModule{constructor(){super(...arguments),this.selectorCheckTrigger=".t3js-extensionCompatTester-check",this.selectorUninstallTrigger=".t3js-extensionCompatTester-uninstall",this.selectorOutputContainer=".t3js-extensionCompatTester-output"}initialize(e){this.currentModal=e,this.getLoadedExtensionList(),e.on("click",this.selectorCheckTrigger,(()=>{this.findInModal(this.selectorUninstallTrigger).addClass("hidden"),this.findInModal(this.selectorOutputContainer).empty(),this.getLoadedExtensionList()})),e.on("click",this.selectorUninstallTrigger,(e=>{this.uninstallExtension($(e.target).data("extension"))}))}getLoadedExtensionList(){this.setModalButtonsState(!1);const e=this.getModalBody(),t=this.findInModal(this.selectorOutputContainer);if(t.length){const e=ProgressBar.render(Severity.loading,"Loading...","");t.append(e)}new AjaxRequest(Router.getUrl("extensionCompatTesterLoadedExtensionList")).get({cache:"no-cache"}).then((async t=>{const o=await t.resolve();e.empty().append(o.html),Modal.setButtons(o.buttons);const n=this.findInModal(this.selectorOutputContainer),s=ProgressBar.render(Severity.loading,"Loading...","");n.append(s),!0===o.success?this.loadExtLocalconf().then((()=>{n.append(InfoBox.render(Severity.ok,"ext_localconf.php of all loaded extensions successfully loaded","")),this.loadExtTables().then((()=>{n.append(InfoBox.render(Severity.ok,"ext_tables.php of all loaded extensions successfully loaded",""))}),(async e=>{this.renderFailureMessages("ext_tables.php",(await e.response.json()).brokenExtensions,n)})).finally((()=>{this.unlockModal()}))}),(async e=>{this.renderFailureMessages("ext_localconf.php",(await e.response.json()).brokenExtensions,n),n.append(InfoBox.render(Severity.notice,"Skipped scanning ext_tables.php files due to previous errors","")),this.unlockModal()})):(Notification.error("Something went wrong","The request was not processed successfully. Please check the browser's console and TYPO3's log."),this.unlockModal())}),(t=>{Router.handleAjaxError(t,e),this.unlockModal()}))}unlockModal(){this.findInModal(this.selectorOutputContainer).find(".alert-loading").remove(),this.setModalButtonsState(!0)}renderFailureMessages(e,t,o){for(const n of t){let t;n.isProtected||(t=$("<button />",{class:"btn btn-danger t3js-extensionCompatTester-uninstall"}).attr("data-extension",n.name).text('Uninstall extension "'+n.name+'"')),o.append(InfoBox.render(Severity.error,"Loading "+e+' of extension "'+n.name+'" failed',n.isProtected?"Extension is mandatory and cannot be uninstalled.":""),t)}this.unlockModal()}loadExtLocalconf(){const e=this.getModuleContent().data("extension-compat-tester-load-ext_localconf-token");return new AjaxRequest(Router.getUrl()).post({install:{action:"extensionCompatTesterLoadExtLocalconf",token:e}})}loadExtTables(){const e=this.getModuleContent().data("extension-compat-tester-load-ext_tables-token");return new AjaxRequest(Router.getUrl()).post({install:{action:"extensionCompatTesterLoadExtTables",token:e}})}uninstallExtension(e){const t=this.getModuleContent().data("extension-compat-tester-uninstall-extension-token"),o=this.getModalBody(),n=$(this.selectorOutputContainer),s=ProgressBar.render(Severity.loading,"Loading...","");n.append(s),new AjaxRequest(Router.getUrl()).post({install:{action:"extensionCompatTesterUninstallExtension",token:t,extension:e}}).then((async e=>{const t=await e.resolve();t.success?(Array.isArray(t.status)&&t.status.forEach((e=>{const t=InfoBox.render(e.severity,e.title,e.message);o.find(this.selectorOutputContainer).empty().append(t)})),this.findInModal(this.selectorUninstallTrigger).addClass("hidden"),this.getLoadedExtensionList()):Notification.error("Something went wrong","The request was not processed successfully. Please check the browser's console and TYPO3's log.")}),(e=>{Router.handleAjaxError(e,o)}))}}export default new ExtensionCompatTester; \ No newline at end of file diff --git a/typo3/sysext/install/Resources/Public/JavaScript/module/upgrade/extension-scanner.js b/typo3/sysext/install/Resources/Public/JavaScript/module/upgrade/extension-scanner.js index f7f59bba8e34..8e6268ccb84e 100644 --- a/typo3/sysext/install/Resources/Public/JavaScript/module/upgrade/extension-scanner.js +++ b/typo3/sysext/install/Resources/Public/JavaScript/module/upgrade/extension-scanner.js @@ -10,4 +10,4 @@ * * The TYPO3 project - inspiring people to share! */ -import"bootstrap";import $ from"jquery";import AjaxRequest from"@typo3/core/ajax/ajax-request.js";import{AbstractInteractableModule}from"@typo3/install/module/abstract-interactable-module.js";import Modal from"@typo3/backend/modal.js";import Notification from"@typo3/backend/notification.js";import AjaxQueue from"@typo3/install/ajax/ajax-queue.js";import Router from"@typo3/install/router.js";class ExtensionScanner extends AbstractInteractableModule{constructor(){super(...arguments),this.listOfAffectedRestFileHashes=[],this.selectorExtensionContainer=".t3js-extensionScanner-extension",this.selectorNumberOfFiles=".t3js-extensionScanner-number-of-files",this.selectorScanSingleTrigger=".t3js-extensionScanner-scan-single",this.selectorExtensionScanButton=".t3js-extensionScanner-scan-all"}initialize(e){this.currentModal=e,this.getData(),e.on("show.bs.collapse",this.selectorExtensionContainer,(e=>{const n=$(e.currentTarget);if(void 0===n.data("scanned")){const e=n.data("extension");this.scanSingleExtension(e),n.data("scanned",!0)}})).on("typo3-modal-hide",(()=>{AjaxQueue.flush()})).on("click",this.selectorScanSingleTrigger,(e=>{e.preventDefault();const n=$(e.currentTarget).closest(this.selectorExtensionContainer).data("extension");this.scanSingleExtension(n)})).on("click",this.selectorExtensionScanButton,(n=>{n.preventDefault(),this.setModalButtonsState(!1);const t=e.find(this.selectorExtensionContainer);this.scanAll(t)}))}getData(){const e=this.getModalBody();new AjaxRequest(Router.getUrl("extensionScannerGetData")).get().then((async n=>{const t=await n.resolve();!0===t.success?(e.empty().append(t.html),Modal.setButtons(t.buttons)):Notification.error("Something went wrong","The request was not processed successfully. Please check the browser's console and TYPO3's log.")}),(n=>{Router.handleAjaxError(n,e)}))}getExtensionSelector(e){return this.selectorExtensionContainer+"-"+e}scanAll(e){this.findInModal(this.selectorExtensionContainer).removeClass("panel-danger panel-warning panel-success").find(".panel-progress-bar").css("width",0).attr("aria-valuenow",0).find("span").text("0%"),this.setProgressForAll(),e.each(((e,n)=>{const t=$(n),s=t.data("extension");this.scanSingleExtension(s),t.data("scanned",!0)}))}setStatusMessageForScan(e,n,t){this.findInModal(this.getExtensionSelector(e)).find(this.selectorNumberOfFiles).text("Checked "+n+" of "+t+" files")}setProgressForScan(e,n,t){const s=n/t*100;this.findInModal(this.getExtensionSelector(e)).find(".panel-progress-bar").css("width",s+"%").attr("aria-valuenow",s).find("span").text(s+"%")}setProgressForAll(){const e=this.findInModal(this.selectorExtensionContainer).length,n=this.findInModal(this.selectorExtensionContainer+".t3js-extensionscan-finished.panel-success").length+this.findInModal(this.selectorExtensionContainer+".t3js-extensionscan-finished.panel-warning").length+this.findInModal(this.selectorExtensionContainer+".t3js-extensionscan-finished.panel-danger").length,t=n/e*100,s=this.getModalBody();this.findInModal(".t3js-extensionScanner-progress-all-extension .progress-bar").css("width",t+"%").attr("aria-valuenow",t).find("span").text(n+" of "+e+" scanned"),n===e&&(this.findInModal(this.selectorExtensionScanButton).removeClass("disabled").prop("disabled",!1),Notification.success("Scan finished","All extensions have been scanned."),new AjaxRequest(Router.getUrl()).post({install:{action:"extensionScannerMarkFullyScannedRestFiles",token:this.getModuleContent().data("extension-scanner-mark-fully-scanned-rest-files-token"),hashes:Array.from(new Set(this.listOfAffectedRestFileHashes))}}).then((async e=>{const n=await e.resolve();!0===n.success&&Notification.success("Marked not affected files","Marked "+n.markedAsNotAffected+" ReST files as not affected.")}),(e=>{Router.handleAjaxError(e,s)})))}scanSingleExtension(e){const n=this.getModuleContent().data("extension-scanner-files-token"),t=this.getModalBody(),s=this.findInModal(this.getExtensionSelector(e));let a=!1;s.addClass("panel-default"),s.removeClass("panel-danger panel-warning panel-success t3js-extensionscan-finished"),s.data("hasRun","true"),s.find(".t3js-extensionScanner-scan-single").text("Scanning...").attr("disabled","disabled"),s.find(".t3js-extensionScanner-extension-body-loc").empty().text("0"),s.find(".t3js-extensionScanner-extension-body-ignored-files").empty().text("0"),s.find(".t3js-extensionScanner-extension-body-ignored-lines").empty().text("0"),this.setProgressForAll(),new AjaxRequest(Router.getUrl()).post({install:{action:"extensionScannerFiles",token:n,extension:e}}).then((async n=>{const i=await n.resolve();if(!0===i.success&&Array.isArray(i.files)){const n=i.files.length;if(n<=0)return void Notification.warning("No files found","The extension "+e+" contains no scannable files");this.setStatusMessageForScan(e,0,n),s.find(".t3js-extensionScanner-extension-body").text(""),s.addClass("panel-has-progress");let o=0;i.files.forEach((i=>{AjaxQueue.add({method:"POST",data:{install:{action:"extensionScannerScanFile",token:this.getModuleContent().data("extension-scanner-scan-file-token"),extension:e,file:i}},url:Router.getUrl(),onfulfilled:async r=>{const l=await r.resolve();if(o++,this.setStatusMessageForScan(e,o,n),this.setProgressForScan(e,o,n),l.success&&Array.isArray(l.matches)&&l.matches.forEach((e=>{a=!0;const n=t.find("#t3js-extensionScanner-file-hit-template").find(".panel").clone();n.find(".t3js-extensionScanner-hit-file-panel-head").attr("href","#collapse"+e.uniqueId),n.find(".t3js-extensionScanner-hit-file-panel-body").attr("id","collapse"+e.uniqueId),n.find(".t3js-extensionScanner-hit-filename").text(i),n.find(".t3js-extensionScanner-hit-message").text(e.message),"strong"===e.indicator?n.find(".t3js-extensionScanner-hit-file-panel-head .badges").append('<span class="badge badge-danger" title="Reliable match, false positive unlikely">strong</span>'):n.find(".t3js-extensionScanner-hit-file-panel-head .badges").append('<span class="badge badge-warning" title="Probable match, but can be a false positive">weak</span>'),!0===e.silenced&&n.find(".t3js-extensionScanner-hit-file-panel-head .badges").append('<span class="badge badge-info" title="Match has been annotated by extension author as false positive match">silenced</span>'),n.find(".t3js-extensionScanner-hit-file-lineContent").empty().text(e.lineContent),n.find(".t3js-extensionScanner-hit-file-line").empty().text(e.line+": "),Array.isArray(e.restFiles)&&e.restFiles.forEach((e=>{const s=t.find("#t3js-extensionScanner-file-hit-rest-template").find(".panel").clone();s.find(".t3js-extensionScanner-hit-rest-panel-head").attr("href","#collapse"+e.uniqueId),s.find(".t3js-extensionScanner-hit-rest-panel-head .badge").empty().text(e.version),s.find(".t3js-extensionScanner-hit-rest-panel-body").attr("id","collapse"+e.uniqueId),s.find(".t3js-extensionScanner-hit-rest-headline").text(e.headline),s.find(".t3js-extensionScanner-hit-rest-body").text(e.content),s.addClass("panel-"+e.class),n.find(".t3js-extensionScanner-hit-file-rest-container").append(s),this.listOfAffectedRestFileHashes.push(e.file_hash)}));const o=n.find(".panel-breaking, .t3js-extensionScanner-hit-file-rest-container").length>0?"panel-danger":"panel-warning";n.addClass(o),n.removeClass("panel-default"),s.find(".t3js-extensionScanner-extension-body").removeClass("hide").append(n),s.removeClass("panel-default"),"panel-danger"===o&&(s.removeClass("panel-warning"),s.addClass(o)),"panel-warning"!==o||s.hasClass("panel-danger")||s.addClass(o)})),l.success){const e=parseInt(s.find(".t3js-extensionScanner-extension-body-loc").text(),10);if(s.find(".t3js-extensionScanner-extension-body-loc").empty().text(e+l.effectiveCodeLines),l.isFileIgnored){const e=parseInt(s.find(".t3js-extensionScanner-extension-body-ignored-files").text(),10);s.find(".t3js-extensionScanner-extension-body-ignored-files").empty().text(e+1)}const n=parseInt(s.find(".t3js-extensionScanner-extension-body-ignored-lines").text(),10);s.find(".t3js-extensionScanner-extension-body-ignored-lines").empty().text(n+l.ignoredLines)}o===n&&(a||(s.removeClass("panel-default"),s.addClass("panel-success")),s.addClass("t3js-extensionscan-finished"),s.removeClass("panel-has-progress"),this.setProgressForAll(),s.find(".t3js-extensionScanner-scan-single").text("Rescan").attr("disabled",null))},onrejected:t=>{o+=1,this.setStatusMessageForScan(e,o,n),this.setProgressForScan(e,o,n),s.removeClass("panel-has-progress"),this.setProgressForAll(),console.error(t)}})}))}else Notification.error("Oops, an error occurred","Please look at the browser console output for details"),console.error(i)}),(e=>{Router.handleAjaxError(e,t)}))}}export default new ExtensionScanner; \ No newline at end of file +import"bootstrap";import $ from"jquery";import AjaxRequest from"@typo3/core/ajax/ajax-request.js";import{AbstractInteractableModule}from"@typo3/install/module/abstract-interactable-module.js";import Modal from"@typo3/backend/modal.js";import Notification from"@typo3/backend/notification.js";import AjaxQueue from"@typo3/install/ajax/ajax-queue.js";import Router from"@typo3/install/router.js";class ExtensionScanner extends AbstractInteractableModule{constructor(){super(...arguments),this.listOfAffectedRestFileHashes=[],this.selectorExtensionContainer=".t3js-extensionScanner-extension",this.selectorNumberOfFiles=".t3js-extensionScanner-number-of-files",this.selectorScanSingleTrigger=".t3js-extensionScanner-scan-single",this.selectorExtensionScanButton=".t3js-extensionScanner-scan-all"}initialize(e){this.currentModal=e,this.getData(),e.on("show.bs.collapse",this.selectorExtensionContainer,(e=>{const n=$(e.currentTarget);if(void 0===n.data("scanned")){const e=n.data("extension");this.scanSingleExtension(e),n.data("scanned",!0)}})).on("typo3-modal-hide",(()=>{AjaxQueue.flush()})).on("click",this.selectorScanSingleTrigger,(e=>{e.preventDefault();const n=$(e.currentTarget).closest(this.selectorExtensionContainer).data("extension");this.scanSingleExtension(n)})).on("click",this.selectorExtensionScanButton,(n=>{n.preventDefault(),this.setModalButtonsState(!1);const t=e.find(this.selectorExtensionContainer);this.scanAll(t)}))}getData(){const e=this.getModalBody();new AjaxRequest(Router.getUrl("extensionScannerGetData")).get().then((async n=>{const t=await n.resolve();!0===t.success?(e.empty().append(t.html),Modal.setButtons(t.buttons)):Notification.error("Something went wrong","The request was not processed successfully. Please check the browser's console and TYPO3's log.")}),(n=>{Router.handleAjaxError(n,e)}))}getExtensionSelector(e){return this.selectorExtensionContainer+"-"+e}async scanAll(e){this.findInModal(this.selectorExtensionContainer).removeClass("panel-danger panel-warning panel-success").find(".panel-progress-bar").css("width",0).attr("aria-valuenow",0).find("span").text("0%"),this.setProgressForAll();const n=$.map(e,(async e=>{const n=$(e),t=n.data("extension");try{await this.scanSingleExtension(t)}finally{n.data("scanned",!0)}}));try{await Promise.allSettled(n)}finally{this.setModalButtonsState(!0),Notification.success("Scan finished","All extensions have been scanned.");try{const e=await new AjaxRequest(Router.getUrl()).post({install:{action:"extensionScannerMarkFullyScannedRestFiles",token:this.getModuleContent().data("extension-scanner-mark-fully-scanned-rest-files-token"),hashes:Array.from(new Set(this.listOfAffectedRestFileHashes))}}),n=await e.resolve();!0===n.success&&Notification.success("Marked not affected files","Marked "+n.markedAsNotAffected+" ReST files as not affected.")}catch(e){Router.handleAjaxError(e,this.getModalBody())}}}setStatusMessageForScan(e,n,t){this.findInModal(this.getExtensionSelector(e)).find(this.selectorNumberOfFiles).text("Checked "+n+" of "+t+" files")}setProgressForScan(e,n,t){const s=n/t*100;this.findInModal(this.getExtensionSelector(e)).find(".panel-progress-bar").css("width",s+"%").attr("aria-valuenow",s).find("span").text(s+"%")}setProgressForAll(){const e=this.findInModal(this.selectorExtensionContainer).length,n=this.findInModal(this.selectorExtensionContainer+".t3js-extensionscan-finished.panel-success").length+this.findInModal(this.selectorExtensionContainer+".t3js-extensionscan-finished.panel-warning").length+this.findInModal(this.selectorExtensionContainer+".t3js-extensionscan-finished.panel-danger").length,t=n/e*100;this.findInModal(".t3js-extensionScanner-progress-all-extension .progress-bar").css("width",t+"%").attr("aria-valuenow",t).find("span").text(n+" of "+e+" scanned")}async scanSingleExtension(e){const n=this.getModuleContent().data("extension-scanner-files-token"),t=this.getModalBody(),s=this.findInModal(this.getExtensionSelector(e));let a=!1;s.addClass("panel-default"),s.removeClass("panel-danger panel-warning panel-success t3js-extensionscan-finished"),s.data("hasRun","true"),s.find(".t3js-extensionScanner-scan-single").text("Scanning...").attr("disabled","disabled"),s.find(".t3js-extensionScanner-extension-body-loc").empty().text("0"),s.find(".t3js-extensionScanner-extension-body-ignored-files").empty().text("0"),s.find(".t3js-extensionScanner-extension-body-ignored-lines").empty().text("0"),this.setProgressForAll();try{const i=await new AjaxRequest(Router.getUrl()).post({install:{action:"extensionScannerFiles",token:n,extension:e}}),o=await i.resolve();if(!0===o.success&&Array.isArray(o.files)){const n=o.files.length;if(n<=0)return void Notification.warning("No files found","The extension "+e+" contains no scannable files");this.setStatusMessageForScan(e,0,n),s.find(".t3js-extensionScanner-extension-body").text(""),s.addClass("panel-has-progress");let i=0;const r=o.files.map((o=>new Promise(((r,l)=>{AjaxQueue.add({method:"POST",data:{install:{action:"extensionScannerScanFile",token:this.getModuleContent().data("extension-scanner-scan-file-token"),extension:e,file:o}},url:Router.getUrl(),onfulfilled:async l=>{const c=await l.resolve();if(i++,this.setStatusMessageForScan(e,i,n),this.setProgressForScan(e,i,n),c.success&&Array.isArray(c.matches)&&c.matches.forEach((e=>{a=!0;const n=t.find("#t3js-extensionScanner-file-hit-template").find(".panel").clone();n.find(".t3js-extensionScanner-hit-file-panel-head").attr("href","#collapse"+e.uniqueId),n.find(".t3js-extensionScanner-hit-file-panel-body").attr("id","collapse"+e.uniqueId),n.find(".t3js-extensionScanner-hit-filename").text(o),n.find(".t3js-extensionScanner-hit-message").text(e.message),"strong"===e.indicator?n.find(".t3js-extensionScanner-hit-file-panel-head .badges").append('<span class="badge badge-danger" title="Reliable match, false positive unlikely">strong</span>'):n.find(".t3js-extensionScanner-hit-file-panel-head .badges").append('<span class="badge badge-warning" title="Probable match, but can be a false positive">weak</span>'),!0===e.silenced&&n.find(".t3js-extensionScanner-hit-file-panel-head .badges").append('<span class="badge badge-info" title="Match has been annotated by extension author as false positive match">silenced</span>'),n.find(".t3js-extensionScanner-hit-file-lineContent").empty().text(e.lineContent),n.find(".t3js-extensionScanner-hit-file-line").empty().text(e.line+": "),Array.isArray(e.restFiles)&&e.restFiles.forEach((e=>{const s=t.find("#t3js-extensionScanner-file-hit-rest-template").find(".panel").clone();s.find(".t3js-extensionScanner-hit-rest-panel-head").attr("href","#collapse"+e.uniqueId),s.find(".t3js-extensionScanner-hit-rest-panel-head .badge").empty().text(e.version),s.find(".t3js-extensionScanner-hit-rest-panel-body").attr("id","collapse"+e.uniqueId),s.find(".t3js-extensionScanner-hit-rest-headline").text(e.headline),s.find(".t3js-extensionScanner-hit-rest-body").text(e.content),s.addClass("panel-"+e.class),n.find(".t3js-extensionScanner-hit-file-rest-container").append(s),this.listOfAffectedRestFileHashes.push(e.file_hash)}));const i=n.find(".panel-breaking, .t3js-extensionScanner-hit-file-rest-container").length>0?"panel-danger":"panel-warning";n.addClass(i),n.removeClass("panel-default"),s.find(".t3js-extensionScanner-extension-body").removeClass("hide").append(n),s.removeClass("panel-default"),"panel-danger"===i&&(s.removeClass("panel-warning"),s.addClass(i)),"panel-warning"!==i||s.hasClass("panel-danger")||s.addClass(i)})),c.success){const e=parseInt(s.find(".t3js-extensionScanner-extension-body-loc").text(),10);if(s.find(".t3js-extensionScanner-extension-body-loc").empty().text(e+c.effectiveCodeLines),c.isFileIgnored){const e=parseInt(s.find(".t3js-extensionScanner-extension-body-ignored-files").text(),10);s.find(".t3js-extensionScanner-extension-body-ignored-files").empty().text(e+1)}const n=parseInt(s.find(".t3js-extensionScanner-extension-body-ignored-lines").text(),10);s.find(".t3js-extensionScanner-extension-body-ignored-lines").empty().text(n+c.ignoredLines)}r()},onrejected:t=>{l(),i+=1,this.setStatusMessageForScan(e,i,n),this.setProgressForScan(e,i,n),s.removeClass("panel-has-progress"),this.setProgressForAll(),console.error(t)}})}))));await Promise.allSettled(r),a||(s.removeClass("panel-default"),s.addClass("panel-success")),s.addClass("t3js-extensionscan-finished"),s.removeClass("panel-has-progress"),this.setProgressForAll(),s.find(".t3js-extensionScanner-scan-single").text("Rescan").attr("disabled",null)}else Notification.error("Oops, an error occurred","Please look at the browser console output for details"),console.error(o)}catch(e){Router.handleAjaxError(e,t)}}}export default new ExtensionScanner; \ No newline at end of file diff --git a/typo3/sysext/install/Resources/Public/JavaScript/module/upgrade/tca-ext-tables-check.js b/typo3/sysext/install/Resources/Public/JavaScript/module/upgrade/tca-ext-tables-check.js index a1def5de7ed5..2fa1a9d48f10 100644 --- a/typo3/sysext/install/Resources/Public/JavaScript/module/upgrade/tca-ext-tables-check.js +++ b/typo3/sysext/install/Resources/Public/JavaScript/module/upgrade/tca-ext-tables-check.js @@ -10,4 +10,4 @@ * * The TYPO3 project - inspiring people to share! */ -import $ from"jquery";import{AbstractInteractableModule}from"@typo3/install/module/abstract-interactable-module.js";import Modal from"@typo3/backend/modal.js";import Notification from"@typo3/backend/notification.js";import AjaxRequest from"@typo3/core/ajax/ajax-request.js";import InfoBox from"@typo3/install/renderable/info-box.js";import ProgressBar from"@typo3/install/renderable/progress-bar.js";import Severity from"@typo3/install/renderable/severity.js";import Router from"@typo3/install/router.js";class TcaExtTablesCheck extends AbstractInteractableModule{constructor(){super(...arguments),this.selectorCheckTrigger=".t3js-tcaExtTablesCheck-check",this.selectorOutputContainer=".t3js-tcaExtTablesCheck-output"}initialize(e){this.currentModal=e,this.check(),e.on("click",this.selectorCheckTrigger,(e=>{e.preventDefault(),this.check()}))}check(){this.setModalButtonsState(!1);const e=this.getModalBody(),t=$(this.selectorOutputContainer),o=ProgressBar.render(Severity.loading,"Loading...","");t.empty().append(o),new AjaxRequest(Router.getUrl("tcaExtTablesCheck")).get({cache:"no-cache"}).then((async o=>{const r=await o.resolve();if(e.empty().append(r.html),Modal.setButtons(r.buttons),!0===r.success&&Array.isArray(r.status))if(r.status.length>0){const o=InfoBox.render(Severity.warning,"Following extensions change TCA in ext_tables.php","Check ext_tables.php files, look for ExtensionManagementUtility calls and $GLOBALS['TCA'] modifications");e.find(this.selectorOutputContainer).append(o),r.status.forEach((o=>{const r=InfoBox.render(o.severity,o.title,o.message);t.append(r),e.append(r)}))}else{const t=InfoBox.render(Severity.ok,"No TCA changes in ext_tables.php files. Good job!","");e.find(this.selectorOutputContainer).append(t)}else Notification.error("Something went wrong",'Please use the module "Check for broken extensions" to find a possible extension causing this issue.')}),(t=>{Router.handleAjaxError(t,e)}))}}export default new TcaExtTablesCheck; \ No newline at end of file +import $ from"jquery";import{AbstractInteractableModule}from"@typo3/install/module/abstract-interactable-module.js";import Modal from"@typo3/backend/modal.js";import Notification from"@typo3/backend/notification.js";import AjaxRequest from"@typo3/core/ajax/ajax-request.js";import InfoBox from"@typo3/install/renderable/info-box.js";import ProgressBar from"@typo3/install/renderable/progress-bar.js";import Severity from"@typo3/install/renderable/severity.js";import Router from"@typo3/install/router.js";class TcaExtTablesCheck extends AbstractInteractableModule{constructor(){super(...arguments),this.selectorCheckTrigger=".t3js-tcaExtTablesCheck-check",this.selectorOutputContainer=".t3js-tcaExtTablesCheck-output"}initialize(e){this.currentModal=e,this.check(),e.on("click",this.selectorCheckTrigger,(e=>{e.preventDefault(),this.check()}))}check(){this.setModalButtonsState(!1);const e=this.getModalBody(),t=$(this.selectorOutputContainer),o=ProgressBar.render(Severity.loading,"Loading...","");t.empty().append(o),new AjaxRequest(Router.getUrl("tcaExtTablesCheck")).get({cache:"no-cache"}).then((async o=>{const r=await o.resolve();if(e.empty().append(r.html),Modal.setButtons(r.buttons),!0===r.success&&Array.isArray(r.status))if(r.status.length>0){const o=InfoBox.render(Severity.warning,"Following extensions change TCA in ext_tables.php","Check ext_tables.php files, look for ExtensionManagementUtility calls and $GLOBALS['TCA'] modifications");e.find(this.selectorOutputContainer).append(o),r.status.forEach((o=>{const r=InfoBox.render(o.severity,o.title,o.message);t.append(r),e.append(r)}))}else{const t=InfoBox.render(Severity.ok,"No TCA changes in ext_tables.php files. Good job!","");e.find(this.selectorOutputContainer).append(t)}else Notification.error("Something went wrong",'Please use the module "Check for broken extensions" to find a possible extension causing this issue.')}),(t=>{Router.handleAjaxError(t,e)})).finally((()=>{this.setModalButtonsState(!0)}))}}export default new TcaExtTablesCheck; \ No newline at end of file diff --git a/typo3/sysext/install/Resources/Public/JavaScript/module/upgrade/tca-migrations-check.js b/typo3/sysext/install/Resources/Public/JavaScript/module/upgrade/tca-migrations-check.js index 63008b32e7d9..8770aff87bbd 100644 --- a/typo3/sysext/install/Resources/Public/JavaScript/module/upgrade/tca-migrations-check.js +++ b/typo3/sysext/install/Resources/Public/JavaScript/module/upgrade/tca-migrations-check.js @@ -10,4 +10,4 @@ * * The TYPO3 project - inspiring people to share! */ -import $ from"jquery";import{AbstractInteractableModule}from"@typo3/install/module/abstract-interactable-module.js";import Modal from"@typo3/backend/modal.js";import AjaxRequest from"@typo3/core/ajax/ajax-request.js";import FlashMessage from"@typo3/install/renderable/flash-message.js";import InfoBox from"@typo3/install/renderable/info-box.js";import ProgressBar from"@typo3/install/renderable/progress-bar.js";import Severity from"@typo3/install/renderable/severity.js";import Router from"@typo3/install/router.js";class TcaMigrationsCheck extends AbstractInteractableModule{constructor(){super(...arguments),this.selectorCheckTrigger=".t3js-tcaMigrationsCheck-check",this.selectorOutputContainer=".t3js-tcaMigrationsCheck-output"}initialize(e){this.currentModal=e,this.check(),e.on("click",this.selectorCheckTrigger,(e=>{e.preventDefault(),this.check()}))}check(){this.setModalButtonsState(!1);const e=$(this.selectorOutputContainer),t=this.getModalBody(),r=ProgressBar.render(Severity.loading,"Loading...","");e.empty().append(r),new AjaxRequest(Router.getUrl("tcaMigrationsCheck")).get({cache:"no-cache"}).then((async e=>{const r=await e.resolve();if(t.empty().append(r.html),Modal.setButtons(r.buttons),!0===r.success&&Array.isArray(r.status))if(r.status.length>0){const e=InfoBox.render(Severity.warning,"TCA migrations need to be applied","Check the following list and apply needed changes.");t.find(this.selectorOutputContainer).empty(),t.find(this.selectorOutputContainer).append(e),r.status.forEach((e=>{const r=InfoBox.render(e.severity,e.title,e.message);t.find(this.selectorOutputContainer).append(r)}))}else{const e=InfoBox.render(Severity.ok,"No TCA migrations need to be applied","Your TCA looks good.");t.find(this.selectorOutputContainer).append(e)}else{const e=FlashMessage.render(Severity.error,"Something went wrong",'Use "Check for broken extensions"');t.find(this.selectorOutputContainer).append(e)}this.setModalButtonsState(!0)}),(e=>{Router.handleAjaxError(e,t)}))}}export default new TcaMigrationsCheck; \ No newline at end of file +import $ from"jquery";import{AbstractInteractableModule}from"@typo3/install/module/abstract-interactable-module.js";import Modal from"@typo3/backend/modal.js";import AjaxRequest from"@typo3/core/ajax/ajax-request.js";import FlashMessage from"@typo3/install/renderable/flash-message.js";import InfoBox from"@typo3/install/renderable/info-box.js";import ProgressBar from"@typo3/install/renderable/progress-bar.js";import Severity from"@typo3/install/renderable/severity.js";import Router from"@typo3/install/router.js";class TcaMigrationsCheck extends AbstractInteractableModule{constructor(){super(...arguments),this.selectorCheckTrigger=".t3js-tcaMigrationsCheck-check",this.selectorOutputContainer=".t3js-tcaMigrationsCheck-output"}initialize(e){this.currentModal=e,this.check(),e.on("click",this.selectorCheckTrigger,(e=>{e.preventDefault(),this.check()}))}check(){this.setModalButtonsState(!1);const e=$(this.selectorOutputContainer),t=this.getModalBody(),r=ProgressBar.render(Severity.loading,"Loading...","");e.empty().append(r),new AjaxRequest(Router.getUrl("tcaMigrationsCheck")).get({cache:"no-cache"}).then((async e=>{const r=await e.resolve();if(t.empty().append(r.html),Modal.setButtons(r.buttons),!0===r.success&&Array.isArray(r.status))if(r.status.length>0){const e=InfoBox.render(Severity.warning,"TCA migrations need to be applied","Check the following list and apply needed changes.");t.find(this.selectorOutputContainer).empty(),t.find(this.selectorOutputContainer).append(e),r.status.forEach((e=>{const r=InfoBox.render(e.severity,e.title,e.message);t.find(this.selectorOutputContainer).append(r)}))}else{const e=InfoBox.render(Severity.ok,"No TCA migrations need to be applied","Your TCA looks good.");t.find(this.selectorOutputContainer).append(e)}else{const e=FlashMessage.render(Severity.error,"Something went wrong",'Use "Check for broken extensions"');t.find(this.selectorOutputContainer).append(e)}}),(e=>{Router.handleAjaxError(e,t)})).finally((()=>{this.setModalButtonsState(!0)}))}}export default new TcaMigrationsCheck; \ No newline at end of file -- GitLab