Commit 97206015 authored by Frank Nägler's avatar Frank Nägler Committed by Susanne Moog
Browse files

[TASK] Migrate TYPO3/CMS/Filelist/* to TypeScript

This commit also removes superfluous code and streamlines the search
template.

Resolves: #88333
Releases: master
Change-Id: Id6761796dd8e774497223fe7de6f811b4610e245
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/60730

Tested-by: Andreas Fernandez's avatarAndreas Fernandez <a.fernandez@scripting-base.de>
Tested-by: default avatarTYPO3com <noreply@typo3.com>
Tested-by: Susanne Moog's avatarSusanne Moog <look@susi.dev>
Reviewed-by: Andreas Fernandez's avatarAndreas Fernandez <a.fernandez@scripting-base.de>
Reviewed-by: Susanne Moog's avatarSusanne Moog <look@susi.dev>
parent 65bc70dc
......@@ -74,7 +74,7 @@ class ContentContainer extends AbstractContainer {
* @param {InteractionRequest} interactionRequest
* @returns {JQueryDeferred<{}>}
*/
public refresh(forceGet: boolean, interactionRequest: InteractionRequest): JQueryDeferred<{}> {
public refresh(forceGet: boolean, interactionRequest?: InteractionRequest): JQueryDeferred<{}> {
let deferred;
const iFrame = <HTMLIFrameElement>this.resolveIFrameElement();
// abort, if no IFRAME can be found
......
/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/
import {SeverityEnum} from 'TYPO3/CMS/Backend/Enum/Severity';
import * as $ from 'jquery';
import Modal = require('TYPO3/CMS/Backend/Modal');
/**
* Module: TYPO3/CMS/Filelist/ContextMenuActions
*
* JavaScript to handle filelist actions from context menu
* @exports TYPO3/CMS/Filelist/ContextMenuActions
*/
class ContextMenuActions {
public static getReturnUrl(): void {
return top.rawurlencode(top.list_frame.document.location.pathname + top.list_frame.document.location.search);
}
public static renameFile(table: string, uid: string): void {
top.TYPO3.Backend.ContentContainer.setUrl(
top.TYPO3.settings.FileRename.moduleUrl + '&target=' + top.rawurlencode(uid) + '&returnUrl=' + ContextMenuActions.getReturnUrl(),
);
}
public static editFile(table: string, uid: string): void {
top.TYPO3.Backend.ContentContainer.setUrl(
top.TYPO3.settings.FileEdit.moduleUrl + '&target=' + top.rawurlencode(uid) + '&returnUrl=' + ContextMenuActions.getReturnUrl(),
);
}
public static editFileStorage(table: string, uid: string): void {
top.TYPO3.Backend.ContentContainer.setUrl(
top.TYPO3.settings.FormEngine.moduleUrl
+ '&edit[sys_file_storage][' + parseInt(uid, 10) + ']=edit&returnUrl='
+ ContextMenuActions.getReturnUrl(),
);
}
public static openInfoPopUp(table: string, uid: string): void {
if (table === 'sys_file_storage') {
top.TYPO3.InfoWindow.showItem(table, uid);
} else {
// Files and folders
top.TYPO3.InfoWindow.showItem('_FILE', uid);
}
}
public static uploadFile(table: string, uid: string): void {
top.TYPO3.Backend.ContentContainer.setUrl(
top.TYPO3.settings.FileUpload.moduleUrl + '&target=' + top.rawurlencode(uid) + '&returnUrl=' + ContextMenuActions.getReturnUrl(),
);
}
public static createFile(table: string, uid: string): void {
top.TYPO3.Backend.ContentContainer.setUrl(
top.TYPO3.settings.FileCreate.moduleUrl + '&target=' + top.rawurlencode(uid) + '&returnUrl=' + ContextMenuActions.getReturnUrl(),
);
}
public static deleteFile(table: string, uid: string): void {
const $anchorElement = $(this);
const performDelete = () => {
top.TYPO3.Backend.ContentContainer.setUrl(
top.TYPO3.settings.FileCommit.moduleUrl
+ '&data[delete][0][data]=' + top.rawurlencode(uid)
+ '&data[delete][0][redirect]=' + ContextMenuActions.getReturnUrl(),
);
};
if (!$anchorElement.data('title')) {
performDelete();
return;
}
const $modal = Modal.confirm(
$anchorElement.data('title'),
$anchorElement.data('message'),
SeverityEnum.warning, [
{
text: $(this).data('button-close-text') || TYPO3.lang['button.cancel'] || 'Cancel',
active: true,
btnClass: 'btn-default',
name: 'cancel',
},
{
text: $(this).data('button-ok-text') || TYPO3.lang['button.delete'] || 'Delete',
btnClass: 'btn-warning',
name: 'delete',
},
]);
$modal.on('button.clicked', (e: JQueryEventObject): void => {
const $element: HTMLInputElement = <HTMLInputElement>e.currentTarget;
if ($element.name === 'delete') {
performDelete();
}
Modal.dismiss();
});
}
public static copyFile(table: string, uid: string): void {
const shortMD5 = top.MD5(uid).substring(0, 10);
let url = TYPO3.settings.ajaxUrls.contextmenu_clipboard;
url += '&CB[el][_FILE%7C' + shortMD5 + ']=' + top.rawurlencode(uid) + '&CB[setCopyMode]=1';
$.ajax(url).always((): void => {
top.TYPO3.Backend.ContentContainer.refresh(true);
});
}
public static copyReleaseFile(table: string, uid: string): void {
const shortMD5 = top.MD5(uid).substring(0, 10);
let url = TYPO3.settings.ajaxUrls.contextmenu_clipboard;
url += '&CB[el][_FILE%7C' + shortMD5 + ']=0&CB[setCopyMode]=1';
$.ajax(url).always((): void => {
top.TYPO3.Backend.ContentContainer.refresh(true);
});
}
public static cutFile(table: string, uid: string): void {
const shortMD5 = top.MD5(uid).substring(0, 10);
let url = TYPO3.settings.ajaxUrls.contextmenu_clipboard;
url += '&CB[el][_FILE%7C' + shortMD5 + ']=' + top.rawurlencode(uid);
$.ajax(url).always((): void => {
top.TYPO3.Backend.ContentContainer.refresh(true);
});
}
public static cutReleaseFile(table: string, uid: string): void {
const shortMD5 = top.MD5(uid).substring(0, 10);
let url = TYPO3.settings.ajaxUrls.contextmenu_clipboard;
url += '&CB[el][_FILE%7C' + shortMD5 + ']=0';
$.ajax(url).always((): void => {
top.TYPO3.Backend.ContentContainer.refresh(true);
});
}
public static pasteFileInto(table: string, uid: string): void {
const $anchorElement = $(this);
const title = $anchorElement.data('title');
const performPaste = (): void => {
top.TYPO3.Backend.ContentContainer.setUrl(
top.TYPO3.settings.FileCommit.moduleUrl
+ '&CB[paste]=FILE|' + top.rawurlencode(uid)
+ '&CB[pad]=normal&redirect=' + ContextMenuActions.getReturnUrl(),
);
};
if (!$anchorElement.data('title')) {
performPaste();
return;
}
const $modal = Modal.confirm(
$anchorElement.data('title'),
$anchorElement.data('message'),
SeverityEnum.warning, [
{
text: $(this).data('button-close-text') || TYPO3.lang['button.cancel'] || 'Cancel',
active: true,
btnClass: 'btn-default',
name: 'cancel',
},
{
text: $(this).data('button-ok-text') || TYPO3.lang['button.ok'] || 'OK',
btnClass: 'btn-warning',
name: 'ok',
},
]);
$modal.on('button.clicked', (e: JQueryEventObject): void => {
const $element: HTMLInputElement = <HTMLInputElement>e.target;
if ($element.name === 'ok') {
performPaste();
}
Modal.dismiss();
});
}
public static dropInto(table: string, uid: string, mode: string): void {
const target = $(this).data('drop-target');
top.TYPO3.Backend.ContentContainer.setUrl(
top.TYPO3.settings.FileCommit.moduleUrl
+ '&file[' + mode + '][0][data]=' + top.rawurlencode(uid)
+ '&file[' + mode + '][0][target]=' + top.rawurlencode(target)
+ '&redirect=' + ContextMenuActions.getReturnUrl(),
);
}
public static dropMoveInto(table: string, uid: string): void {
ContextMenuActions.dropInto.bind($(this))(table, uid, 'move');
}
public static dropCopyInto(table: string, uid: string): void {
ContextMenuActions.dropInto.bind($(this))(table, uid, 'copy');
}
}
export = ContextMenuActions;
/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/
import {SeverityEnum} from 'TYPO3/CMS/Backend/Enum/Severity';
import * as $ from 'jquery';
import Modal = require('TYPO3/CMS/Backend/Modal');
/**
* Module: TYPO3/CMS/Filelist/FileDelete
* @exports TYPO3/CMS/Filelist/FileDelete
*/
class FileDelete {
constructor() {
$((): void => {
$(document).on('click', '.t3js-filelist-delete', (e: JQueryEventObject): void => {
e.preventDefault();
const $anchorElement = $(e.currentTarget);
let redirectUrl = $anchorElement.data('redirectUrl');
redirectUrl = (redirectUrl)
? top.rawurlencode(redirectUrl)
: top.rawurlencode(top.list_frame.document.location.pathname + top.list_frame.document.location.search);
const identifier = $anchorElement.data('identifier');
const deleteType = $anchorElement.data('deleteType');
const deleteUrl = $anchorElement.data('deleteUrl') + '&data[delete][0][data]=' + encodeURIComponent(identifier);
const target = deleteUrl + '&data[delete][0][redirect]=' + redirectUrl;
if ($anchorElement.data('check')) {
const $modal = Modal.confirm($anchorElement.data('title'), $anchorElement.data('content'), SeverityEnum.warning, [
{
text: TYPO3.lang['buttons.confirm.delete_file.no'] || 'Cancel',
active: true,
btnClass: 'btn-default',
name: 'no',
},
{
text: TYPO3.lang['buttons.confirm.' + deleteType + '.yes'] || 'Yes, delete this file or folder',
btnClass: 'btn-warning',
name: 'yes',
},
]);
$modal.on('button.clicked', (evt: JQueryEventObject): void => {
const $element = <HTMLInputElement>evt.target;
const name = $element.name;
if (name === 'no') {
Modal.dismiss();
} else if (name === 'yes') {
Modal.dismiss();
top.list_frame.location.href = target;
}
});
} else {
top.list_frame.location.href = target;
}
});
});
}
}
export = new FileDelete();
/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/
import * as $ from 'jquery';
import InfoWindow = require('TYPO3/CMS/Backend/InfoWindow');
/**
* Module: TYPO3/CMS/Filelist/Filelist
* @exports TYPO3/CMS/Filelist/Filelist
*/
class Filelist {
/**
* @param identifier
*/
private static openFileInfoPopup(identifier: string): void {
InfoWindow.showItem('_FILE', identifier);
}
constructor() {
$((): void => {
$('a.btn.filelist-file-info').click((event: JQueryEventObject): void => {
event.preventDefault();
Filelist.openFileInfoPopup($(event.currentTarget).attr('data-identifier'));
});
$('a.filelist-file-references').click((event: JQueryEventObject): void => {
event.preventDefault();
Filelist.openFileInfoPopup($(event.currentTarget).attr('data-identifier'));
});
$('a.btn.filelist-file-copy').click((event: JQueryEventObject): void => {
event.preventDefault();
const $element = $(event.currentTarget);
const url = $element.attr('href');
let redirectUrl = (url)
? top.rawurlencode(url)
: top.rawurlencode(top.list_frame.document.location.pathname + top.list_frame.document.location.search);
top.list_frame.location.href = url + '&redirect=' + redirectUrl;
});
});
}
}
export = new Filelist();
/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/
import * as $ from 'jquery';
/**
* Module: TYPO3/CMS/Filelist/FileListLocalisation
* @exports TYPO3/CMS/Filelist/FileListLocalisation
*/
class FileListLocalisation {
constructor() {
$((): void => {
$('a.filelist-translationToggler').click((event: JQueryEventObject): void => {
const id = $(event.currentTarget).attr('data-fileid');
$('div[data-fileid="' + id + '"]').toggle();
});
});
}
}
export = new FileListLocalisation();
/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/
import * as $ from 'jquery';
import 'TYPO3/CMS/Backend/jquery.clearable';
/**
* Module: TYPO3/CMS/Filelist/RenameFile
* Modal to pick the required conflict strategy for colliding filenames
* @exports TYPO3/CMS/Filelist/RenameFile
*/
class FileSearch {
constructor() {
$((): void => {
const $searchFields = $('input[name="tx_filelist_file_filelistlist[searchWord]"]');
const searchResultShown = ('' !== $searchFields.first().val());
// make search field clearable
$searchFields.clearable({
onClear: (): void => {
if (searchResultShown) {
$searchFields.closest('form').submit();
}
},
});
});
}
}
export = new FileSearch();
......@@ -100,6 +100,7 @@ declare module 'TYPO3/CMS/Backend/Wizard' {
// type definition for global namespace object
interface Window {
TYPO3: any;
MD5: any;
$: any;
startInModule: Array<string>;
inline: {
......
......@@ -42,9 +42,9 @@
<td class="col-title col-responsive nowrap">
<f:if condition="{file.isMetadataEditable}">
<f:then>
<a href="#" class="filelist-file-title"
<a href="{be:uri.editRecord( uid:file.metadataUid, table:'sys_file_metadata', returnUrl:'{f:uri.action( action:\'search\', arguments:{ searchWord:\'{searchWord->f:format.htmlentities()}\' } ) -> f:format.raw()}' )}"
class="filelist-file-title"
title="{f:translate( key:'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:cm.editMetadata' )}"
data-url="{be:uri.editRecord( uid:file.metadataUid, table:'sys_file_metadata', returnUrl:'{f:uri.action( action:\'search\', arguments:{ searchWord:\'{searchWord->f:format.htmlentities()}\' } ) -> f:format.raw()}' )}"
>
{file.name}
</a>
......@@ -62,9 +62,9 @@
<div class="btn-group">
<f:if condition="{file.isEditable}">
<f:then>
<a href="#" class="btn btn-default filelist-file-edit"
<a href="{fl:uri.editFileContent( file:file.resource, returnUrl:'{f:uri.action( action:\'search\', arguments:{ searchWord:\'{searchWord->f:format.htmlentities()}\' } ) -> f:format.raw()}' )}"
class="btn btn-default filelist-file-edit"
title="{f:translate( key:'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:cm.editcontent' )}"
data-url="{fl:uri.editFileContent( file:file.resource, returnUrl:'{f:uri.action( action:\'search\', arguments:{ searchWord:\'{searchWord->f:format.htmlentities()}\' } ) -> f:format.raw()}' )}"
>
<core:icon identifier="actions-page-open" />
</a>
......@@ -76,9 +76,9 @@
<f:if condition="{file.IsMetadataEditable}">
<f:then>
<a href="#" class="btn btn-default filelist-file-edit"
title="{f:translate( key:'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:cm.editMetadata' )}"
data-url="{be:uri.editRecord(uid:file.metadataUid, table:'sys_file_metadata', returnUrl:'{f:uri.action( action:\'search\', arguments:{ searchWord:\'{searchWord->f:format.htmlentities()}\' } ) -> f:format.raw()}' )}"
<a href="{be:uri.editRecord(uid:file.metadataUid, table:'sys_file_metadata', returnUrl:'{f:uri.action( action:\'search\', arguments:{ searchWord:\'{searchWord->f:format.htmlentities()}\' } ) -> f:format.raw()}' )}"
class="btn btn-default filelist-file-edit"
title="{f:translate( key:'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:cm.editMetadata' )}"
>
<core:icon identifier="actions-open" />
</a>
......@@ -90,9 +90,8 @@
<f:if condition="{file.publicUrl}">
<f:then>
<a href="#" class="btn btn-default filelist-file-view"
<a href="{file.publicUrl}" target="_blank" class="btn btn-default filelist-file-view"
title="{f:translate( key:'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:cm.view' )}"
data-url="{file.publicUrl}"
>
<core:icon identifier="actions-document-view" />
</a>
......@@ -104,9 +103,9 @@
<f:if condition="{file.isReplaceable}">
<f:then>
<a href="#" class="btn btn-default filelist-file-replace"
<a href="{fl:uri.replaceFile( file:file.resource, returnUrl:'{f:uri.action( action:\'search\', arguments:{ searchWord:\'{searchWord->f:format.htmlentities()}\' } ) -> f:format.raw()}' )}"
class="btn btn-default filelist-file-replace"
title="{f:translate( key:'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:cm.replace' )}"
data-url="{fl:uri.replaceFile( file:file.resource, returnUrl:'{f:uri.action( action:\'search\', arguments:{ searchWord:\'{searchWord->f:format.htmlentities()}\' } ) -> f:format.raw()}' )}"
>
<core:icon identifier="actions-edit-replace" />
</a>
......@@ -118,9 +117,9 @@
<f:if condition="{file.isRenamable}">
<f:then>
<a href="#" class="btn btn-default filelist-file-rename"
<a href="{fl:uri.renameFile( file:file.resource, returnUrl:'{f:uri.action( action:\'search\', arguments:{ searchWord:\'{searchWord->f:format.htmlentities()}\' } ) -> f:format.raw()}' )}"
class="btn btn-default filelist-file-rename"
title="{f:translate( key:'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:cm.rename' )}"
data-url="{fl:uri.renameFile( file:file.resource, returnUrl:'{f:uri.action( action:\'search\', arguments:{ searchWord:\'{searchWord->f:format.htmlentities()}\' } ) -> f:format.raw()}' )}"
>
<core:icon identifier="actions-edit-rename" />
</a>
......@@ -146,10 +145,10 @@
<f:if condition="{file.copyable}">
<f:then>
<a href="#" class="btn btn-default filelist-file-copy"
title="{f:translate( key:'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:cm.copy' )}"
data-url="{fl:uri.copyCutFile( file:file.resource, copyOrCut: 'copy' )}"
data-redirect-url="{f:uri.action( action:'search', arguments:{ searchWord:'{searchWord->f:format.htmlentities()}' } )}"
<a href="{fl:uri.copyCutFile( file:file.resource, copyOrCut: 'copy' )}"
class="btn btn-default filelist-file-copy"
title="{f:translate( key:'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:cm.copy' )}"
data-redirect-url="{f:uri.action( action:'search', arguments:{ searchWord:'{searchWord->f:format.htmlentities()}' } )}"
>
<f:if condition="{file.selected} == 'copy'">
<f:then><core:icon identifier="actions-edit-copy-release" /></f:then>
......@@ -163,9 +162,9 @@
</f:if>
<f:if condition="{file.cuttable}">
<f:then>
<a href="#" class="btn btn-default filelist-file-cut"
title="{f:translate( key:'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:cm.cut' )}"
data-url="{fl:uri.copyCutFile( file:file.resource, copyOrCut: 'cut' )}"
<a href="{fl:uri.copyCutFile( file:file.resource, copyOrCut: 'cut' )}"
class="btn btn-default filelist-file-cut"
title="{f:translate( key:'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:cm.cut' )}"
>
<f:if condition="{file.selected} == 'cut'">
<f:then><core:icon identifier="actions-edit-cut-release" /></f:then>
......
......@@ -10,188 +10,4 @@
*
* The TYPO3 project - inspiring people to share!
*/
/**
* Module: TYPO3/CMS/Filelist/ContextMenuActions
*
* JavaScript to handle filelist actions from context menu
* @exports TYPO3/CMS/Filelist/ContextMenuActions
*/
define(['jquery', 'TYPO3/CMS/Backend/Modal', 'TYPO3/CMS/Backend/Severity'], function($, Modal, Severity) {
'use strict';
/**
* @exports TYPO3/CMS/Filelist/ContextMenuActions
*/
var ContextMenuActions = {};
ContextMenuActions.getReturnUrl = function() {
return top.rawurlencode(top.list_frame.document.location.pathname + top.list_frame.document.location.search);
};
ContextMenuActions.renameFile = function(table, uid) {
top.TYPO3.Backend.ContentContainer.setUrl(
top.TYPO3.settings.FileRename.moduleUrl + '&target=' + top.rawurlencode(uid) + '&returnUrl=' + ContextMenuActions.getReturnUrl()
);
};
ContextMenuActions.editFile = function(table, uid) {
top.TYPO3.Backend.ContentContainer.setUrl(
top.TYPO3.settings.FileEdit.moduleUrl + '&target=' + top.rawurlencode(uid) + '&returnUrl=' + ContextMenuActions.getReturnUrl()
);
};
ContextMenuActions.editFileStorage = function(table, uid) {
top.TYPO3.Backend.ContentContainer.setUrl(