ENHANCEMENT Changed AssetAdmin interface 'delete' action to behave same as main CMS interface: Show 'batch actions' with dropdown. Added AssetAdmin_DeleteBatchAction class.

ENHANCEMENT Moved 'Sync files' action in AssetAdmin from toplevel tab to the bottom of the tree and hooked up to AssetAdmin->SyncForm to avoid hardcoding the URL.
ENHANCEMENT Changed AssetAdmin interface 'create' button to show dialog and 'go' button, and behave similar to the main CMS interface

git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/trunk@92802 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
Ingo Schommer 2009-11-21 03:19:05 +00:00
parent e47ce88853
commit 067b7bcaeb
4 changed files with 247 additions and 179 deletions

View File

@ -36,8 +36,8 @@ class AssetAdmin extends LeftAndMain {
public static $apply_restrictions_to_admin = false; public static $apply_restrictions_to_admin = false;
static $allowed_actions = array( static $allowed_actions = array(
'addfolder', 'doAdd',
'deletefolder', 'AddForm',
'deletemarked', 'deletemarked',
'DeleteItemsForm', 'DeleteItemsForm',
'deleteUnusedThumbnails', 'deleteUnusedThumbnails',
@ -50,7 +50,9 @@ class AssetAdmin extends LeftAndMain {
'savefile', 'savefile',
'uploadiframe', 'uploadiframe',
'UploadForm', 'UploadForm',
'deleteUnusedThumbnails' => 'ADMIN' 'deleteUnusedThumbnails' => 'ADMIN',
'batchactions',
'BatchActionsForm'
); );
/** /**
@ -105,6 +107,8 @@ class AssetAdmin extends LeftAndMain {
}; };
JS JS
); );
CMSBatchActionHandler::register('delete', 'AssetAdmin_DeleteBatchAction', 'Folder');
} }
/** /**
@ -506,10 +510,33 @@ JS;
// Data saving handlers // Data saving handlers
/**
* @return Form
*/
function AddForm() {
$typeMap = array('Folder' => singleton('Folder')->i18n_singular_name());
$typeField = new DropdownField('Type', false, $typeMap, 'Folder');
$form = new Form(
$this,
'AddForm',
new FieldSet(
new HiddenField('ParentID'),
$typeField->performReadonlyTransformation()
),
new FieldSet(
new FormAction('doAdd', _t('AssetAdmin_left.ss.GO','Go'))
)
);
$form->setValidator(null);
$form->addExtraClass('actionparams');
return $form;
}
/** /**
* Add a new folder and return its details suitable for ajax. * Add a new folder and return its details suitable for ajax.
*/ */
public function addfolder() { public function doAdd() {
$parent = ($_REQUEST['ParentID'] && is_numeric($_REQUEST['ParentID'])) ? (int)$_REQUEST['ParentID'] : 0; $parent = ($_REQUEST['ParentID'] && is_numeric($_REQUEST['ParentID'])) ? (int)$_REQUEST['ParentID'] : 0;
$name = (isset($_REQUEST['Name'])) ? basename($_REQUEST['Name']) : _t('AssetAdmin.NEWFOLDER',"NewFolder"); $name = (isset($_REQUEST['Name'])) ? basename($_REQUEST['Name']) : _t('AssetAdmin.NEWFOLDER',"NewFolder");
@ -552,61 +579,49 @@ JS;
} }
/** /**
* @return Form * Batch Actions Handler
*/ */
function DeleteItemsForm() { function batchactions() {
$form = new Form( return new CMSBatchActionHandler($this, 'batchactions', 'Folder');
$this,
'DeleteItemsForm',
new FieldSet(
new LiteralField('SelectedPagesNote',
sprintf('<p>%s</p>', _t('AssetAdmin_left.ss.SELECTTODEL','Select the folders that you want to delete and then click the button below'))
),
new HiddenField('csvIDs')
),
new FieldSet(
new FormAction('deletefolder', _t('AssetAdmin_left.ss.DELFOLDERS','Delete the selected folders'))
)
);
$form->addExtraClass('actionparams');
return $form;
} }
/** /**
* Delete a folder * @return Form
*/ */
public function deletefolder() { function BatchActionsForm() {
$script = ''; $actions = $this->batchactions()->batchActionList();
$ids = split(' *, *', $_REQUEST['csvIDs']); $actionsMap = array();
$script = ''; foreach($actions as $action) $actionsMap[$action->Link] = $action->Title;
if(!$ids) return false; $form = new Form(
$this,
'BatchActionsForm',
new FieldSet(
new LiteralField(
'Intro',
sprintf('<p><small>%s</small></p>',
_t(
'CMSMain_left.ss.SELECTPAGESACTIONS',
'Select the pages that you want to change &amp; then click an action:'
)
)
),
new HiddenField('csvIDs'),
new DropdownField(
'Action',
false,
$actionsMap
)
),
new FieldSet(
// TODO i18n
new FormAction('submit', "Go")
)
);
$form->addExtraClass('actionparams');
$form->unsetValidator();
foreach($ids as $id) { return $form;
if(is_numeric($id)) {
$record = DataObject::get_by_id($this->stat('tree_class'), $id);
if($record) {
$record->delete();
$record->destroy();
}
}
}
$size = sizeof($ids);
if($size > 1) {
$message = $size.' '._t('AssetAdmin.FOLDERSDELETED', 'folders deleted.');
} else {
$message = $size.' '._t('AssetAdmin.FOLDERDELETED', 'folder deleted.');
}
if(isset($brokenPageList)) {
$message .= ' '._t('AssetAdmin.NOWBROKEN', 'The following pages now have broken links:').'<ul>'.addslashes($brokenPageList).'</ul>'.
_t('AssetAdmin.NOWBROKEN2', 'Their owners have been emailed and they will fix up those pages.');
}
$script .= "statusMessage('$message');";
echo $script;
} }
public function removefile(){ public function removefile(){
@ -754,4 +769,38 @@ JS;
} }
} }
/**
* Delete multiple {@link Folder} records (and the associated filesystem nodes).
* Usually used through the {@link AssetAdmin} interface.
*
* @package cms
* @subpackage batchactions
*/
class AssetAdmin_DeleteBatchAction extends CMSBatchAction {
function getActionTitle() {
// _t('AssetAdmin_left.ss.SELECTTODEL','Select the folders that you want to delete and then click the button below')
return _t('AssetAdmin_DeleteBatchAction.TITLE', 'Delete folders');
}
function run(DataObjectSet $records) {
$status = array(
'modified'=>array(),
'deleted'=>array()
);
foreach($records as $record) {
$id = $record->ID;
// Perform the action
if($record->canDelete()) $record->delete();
$status['deleted'][$id] = array();
$record->destroy();
unset($record);
}
return Convert::raw2json($status);
}
}
?> ?>

View File

@ -22,3 +22,20 @@
.DraggedHandle { .DraggedHandle {
width: 30em !important; width: 30em !important;
} }
form#Form_AddForm fieldset {
float: left;
margin-right: 1em;
}
form#Form_AddForm .field span.readonly {
background: none;
border: none;
margin: 0;
padding: 0;
width: auto;
}
#TreeActions-sync {
/* Same as .checkboxAboveTree */
border-top: 1px solid #CCCCCC;
padding: .5em;
}

View File

@ -10,132 +10,146 @@ SiteTreeHandlers.showRecord_url = 'admin/assets/show/';
SiteTreeHandlers.controller_url = 'admin/assets'; SiteTreeHandlers.controller_url = 'admin/assets';
var _HANDLER_FORMS = { var _HANDLER_FORMS = {
addpage : 'Form_AddPageOptionsForm', addpage : 'Form_AddForm',
deletepage : 'Form_DeleteItemsForm', deletepage : 'Form_DeleteItemsForm',
sortitems : 'sortitems_options' sortitems : 'sortitems_options'
}; };
(function($) { (function($) {
/** /**
* Overload the "Create" tab to execute action instead of * @class Simple form with a page type dropdown
* opening the tab content. * which creates a new page through #Form_EditForm and adds a new tree node.
* @name ss.Form_AddForm
* @requires ss.i18n
* @requires ss.Form_EditForm
*/ */
$('#TreeActions-create-btn').concrete('ss', function($) { $('#Form_AddForm').concrete(function($) {
return { return/** @lends ss.Form_AddForm */{
onmatch: function() { /**
this.bind('click', function(e) { * @type DOMElement
var form = $('form#addpage_options'); */
jQuery.post( Tree: null,
form.attr('action'),
form.serialize(),
function(data) {
} /**
); * @type Array Internal counter to create unique page identifiers prior to ajax saving
return false; */
}) _NewPages: [],
onmatch: function() {
var self = this;
this.bind('submit', function(e) {
return self._submit(e);
});
Observable.applyTo(this[0]);
var tree = jQuery('#sitetree')[0];
this.setTree(tree);
},
_submit: function(e) {
var newPages = this._NewPages();
var tree = this.Tree();
var parentID = (tree.firstSelected()) ? tree.getIdxOf(tree.firstSelected()) : 0;
// TODO: Remove 'new-' code http://open.silverstripe.com/ticket/875
if(parentID && parentID.substr(0,3) == 'new') {
alert(ss.i18n._t('CMSMAIN.WARNINGSAVEPAGESBEFOREADDING'));
}
if(tree.firstSelected() && jQuery(tree.firstSelected()).hasClass("nochildren")) {
alert(ss.i18n._t('CMSMAIN.CANTADDCHILDREN') );
}
// Optionally initalize the new pages tracker
if(!newPages[parentID] ) newPages[parentID] = 1;
// default to first button
var button = jQuery(this).find(':submit:first');
button.addClass('loading');
// collect data and submit the form
var data = jQuery(this).serializeArray();
data.push({name:'Suffix',value:newPages[parentID]++});
data.push({name:button.attr('name'),value:button.val()});
jQuery('#Form_EditForm').concrete('ss').loadForm(
jQuery(this).attr('action'),
function() {
button.removeClass('loading');
},
{type: 'POST', data: data}
);
this.set_NewPages(newPages);
return false;
} }
}; };
}); });
}(jQuery));
$('#Form_SyncForm').concrete('ss', function($) {
return {
onmatch: function() {
this.bind('submit', this._onsubmit);
this._super();
},
_onsubmit: function(e) {
var button = jQuery(this).find(':submit:first');
button.addClass('loading');
$.get(
jQuery(this).attr('action'),
function() {
button.removeClass('loading');
}
);
/** return false;
* Add File Action }
*/ };
addfolder = Class.create(); });
addfolder.applyTo('#addpage');
addfolder.prototype = {
initialize: function () {
Observable.applyTo($(this.id + '_options'));
this.getElementsByTagName('button')[0].onclick = returnFalse;
$(this.id + '_options').onsubmit = this.form_submit;
}, $('#Form_DeleteItemsForm').concrete('ss', function($) {
return {
onmatch: function() {
$('#TreeActions').bind('tabsselect', function(e, ui) {
if($(ui.tab).attr('id') == 'TreeActions-delete-btn') {
onclick : function() { }
statusMessage('Creating new folder...'); });
this.form_submit(); },
/* /**
if(treeactions.toggleSelection(this)) { * @param {Boolean}
var selectedNode = $('sitetree').firstSelected(); */
toggleTree: function(bool) {
if(bool) {
deletefolder.o1 = $('sitetree').observeMethod('SelectionChanged', deletefolder.treeSelectionChanged);
deletefolder.o2 = $('Form_DeleteItemsForm').observeMethod('Close', deletefolder.popupClosed);
if(selectedNode) { jQuery('#sitetree').addClass('multiselect');
while(selectedNode.parentTreeNode && !selectedNode.hints.defaultChild) {
$('sitetree').changeCurrentTo(selectedNode.parentTreeNode); deletefolder.selectedNodes = { };
selectedNode = selectedNode.parentTreeNode;
var sel = $('sitetree').firstSelected()
if(sel) {
var selIdx = $('sitetree').getIdxOf(sel);
deletefolder.selectedNodes[selIdx] = true;
sel.removeNodeClass('current');
sel.addNodeClass('selected');
}
} }
} }
}
*/
return false;
},
form_submit : function() { };
var st = $('sitetree'); });
}(jQuery));
$('Form_AddPageOptionsForm').elements.ParentID.value = st.getIdxOf(st.firstSelected());
Ajax.SubmitForm('Form_AddPageOptionsForm', null, {
onSuccess : this.onSuccess,
onFailure : this.showAddPageError
});
return false;
},
onSuccess: function(response) {
Ajax.Evaluator(response);
// Make it possible to drop files into the new folder
DropFileItem.applyTo('#sitetree li');
},
showAddPageError: function(response) {
errorMessage('Error adding folder', response);
}
}
/**
* Look for new files (FilesystemSync) action
*/
FilesystemSyncClass = Class.create();
FilesystemSyncClass.applyTo('#filesystemsync');
FilesystemSyncClass.prototype = {
initialize: function () {
this.getElementsByTagName('button')[0].onclick = returnFalse;
},
onclick : function() {
statusMessage('Looking for new files');
new Ajax.Request('dev/tasks/FilesystemSyncTask', {
onSuccess: function(t) {
statusMessage(t.responseText, "good");
},
onFailure: function(t) {
errorMessage("There was an error looking for new files");
}
});
return false;
}
}
/** /**
* Delete folder action * Delete folder action
*/ */
deletefolder = { deletefolder = {
button_onclick : function() { button_onclick : function() {
if(treeactions.toggleSelection(this)) {
deletefolder.o1 = $('sitetree').observeMethod('SelectionChanged', deletefolder.treeSelectionChanged);
deletefolder.o2 = $('Form_DeleteItemsForm').observeMethod('Close', deletefolder.popupClosed);
jQuery('#sitetree').addClass('multiselect');
deletefolder.selectedNodes = { };
var sel = $('sitetree').firstSelected()
if(sel) {
var selIdx = $('sitetree').getIdxOf(sel);
deletefolder.selectedNodes[selIdx] = true;
sel.removeNodeClass('current');
sel.addNodeClass('selected');
}
}
return false; return false;
}, },

View File

@ -13,34 +13,18 @@
</a> </a>
</li> </li>
<li> <li>
<a href="#TreeActions-delete" id="TreeActions-delete-btn"> <a href="#TreeActions-batchactions" id="batchactions">
<% _t('DELETE','Delete',PR_HIGH) %> <% _t('BATCHACTIONS','Batch Actions',PR_HIGH) %>
</a>
</li>
<li>
<a href="#" title="<% _t('FILESYSTEMSYNC_DESC', 'SilverStripe maintains its own database of the files &amp; images stored in your assets/ folder. Click this button to update that database, if files are added to the assets/ folder from outside SilverStripe, for example, if you have uploaded files via FTP.') %>">
<% _t('FILESYSTEMSYNC','Look for new files') %>
</a> </a>
</li> </li>
</ul> </ul>
<div id="TreeActions-create"> <div id="TreeActions-create">
<form class="actionparams" id="addpage_options" action="admin/assets/addfolder"> $AddForm
<div>
<input type="hidden" name="ParentID" />
<input class="action" type="submit" value="<% _t('GO','Go') %>" />
</div>
</form>
</div> </div>
<div id="TreeActions-delete"> <div id="TreeActions-batchactions">
<form class="actionparams" id="deletepage_options" style="display: none" action="admin/assets/deletefolder"> $BatchActionsForm
<p><% _t('SELECTTODEL','Select the folders that you want to delete and then click the button below') %></p>
<div>
<input type="hidden" name="csvIDs" />
<input type="submit" value="<% _t('DELFOLDERS','Delete the selected folders') %>" class="action delete" />
</div>
</form>
</div> </div>
</div> </div>
@ -56,6 +40,10 @@
$SiteTreeAsUL $SiteTreeAsUL
</div> </div>
<div id="TreeActions-sync">
$SyncForm
</div>
</div> </div>
</div> </div>