From cb1895866ac0f86016d20c9378b61a73f14a812d Mon Sep 17 00:00:00 2001 From: Ingo Schommer Date: Sat, 21 Nov 2009 03:16:09 +0000 Subject: [PATCH] ENHANCEMENT Refactored versions panel in CMS: Removed "compare mode" checkbox in UI, and replaced with explicit checkboxes and a "compare versions" button. Added manual "refresh" button. Replaced custom markup with a form generated through CMSMain->VersionsForm(), and adjusted markup in CMSMain_versions.ss accordingly API CHANGE Removed CMSMain->sendFormToBrowser(), replaced with custom code git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/trunk@92731 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- code/CMSMain.php | 138 +++++++++++++------ code/LeftAndMain.php | 3 - css/cms_left.css | 3 + javascript/CMSMain.js | 127 ++++++++++++++++- javascript/SideTabs.js | 214 ----------------------------- templates/CMSMain_versions.ss | 16 ++- templates/Includes/CMSMain_left.ss | 14 +- 7 files changed, 238 insertions(+), 277 deletions(-) delete mode 100755 javascript/SideTabs.js diff --git a/code/CMSMain.php b/code/CMSMain.php index eb1bb5f7..7ca6ce9a 100755 --- a/code/CMSMain.php +++ b/code/CMSMain.php @@ -57,7 +57,9 @@ class CMSMain extends LeftAndMain implements CurrentPageIdentifier, PermissionPr 'getfilteredsubtree', 'batchactions', 'SearchTreeForm', - 'ReportForm' + 'ReportForm', + 'LangForm', + 'VersionsForm' ); public function init() { @@ -644,6 +646,7 @@ JS; ) ); $form->unsetValidator(); + $form->setFormMethod('GET'); return $form; } @@ -680,20 +683,71 @@ JS; $form = $this->ReportForm(); return (Director::is_ajax()) ? $form->forTemplate() : $form; } + + /** + * @return Form + */ + function VersionsForm() { + $pageID = ($this->request->requestVar('ID')) ? $this->request->requestVar('ID') : $this->currentPageID(); + $page = $this->getRecord($pageID); + if($page) { + $versions = $page->allVersions( + ($this->request->requestVar('ShowUnpublished')) ? + "" : "\"SiteTree\".\"WasPublished\" = 1" + ); + + // inject link to cms + if($versions) foreach($versions as $k => $version) { + $version->CMSLink = sprintf('%s/%s/%s', + $this->Link('getversion'), + $version->ID, + $version->Version + ); + } + $vd = new ViewableData(); + $versionsHtml = $vd->customise( + array('Versions'=>$versions) + )->renderWith('CMSMain_versions'); + } else { + $versionsHtml = ''; + } + + $form = new Form( + $this, + 'VersionsForm', + new FieldSet( + new CheckboxField( + 'ShowUnpublished', + _t('CMSMain_left.ss.SHOWUNPUB','Show unpublished versions') + ), + new LiteralField('VersionsHtml', $versionsHtml), + new HiddenField('ID', false, $pageID), + new HiddenField('Locale', false, $this->Locale) + ), + new FieldSet( + new FormAction( + 'versions', + _t('CMSMain.BTNREFRESH','Refresh') + ), + new FormAction( + 'compareversions', + _t('CMSMain.BTNCOMPAREVERSIONS','Compare Versions') + ) + ) + ); + $form->loadDataFrom($this->request->requestVars()); + $form->setFormMethod('GET'); + $form->unsetValidator(); + + return $form; + } + /** * Get the versions of the current page */ function versions() { - $pageID = $this->urlParams['ID']; - $page = $this->getRecord($pageID); - if($page) { - $versions = $page->allVersions($_REQUEST['unpublished'] ? "" : "\"SiteTree\".\"WasPublished\" = 1"); - return array( - 'Versions' => $versions, - ); - } else { - return sprintf(_t('CMSMain.VERSIONSNOPAGE',"Can't find page #%d",PR_LOW),$pageID); - } + $form = $this->VersionsForm(); + return (Director::is_ajax()) ? $form->forTemplate() : $form; } /** @@ -752,9 +806,17 @@ JS; return $record; } + /** + * Supports both direct URL links (format: admin/getversion//), + * and through GET parameters: admin/getversion/?ID=&Versions[]= + */ function getversion() { - $id = $this->urlParams['ID']; - $version = str_replace('&ajax=1','',$this->urlParams['OtherID']); + $id = ($this->request->param('ID')) ? + $this->request->param('ID') : $this->request->requestVar('ID'); + + $version = ($this->request->param('OtherID')) ? + $this->request->param('OtherID') : $this->request->requestVar('Versions'); + $record = Versioned::get_version("SiteTree", $id, $version); if($record) { @@ -817,28 +879,28 @@ JS; $readonlyFields = $form->Fields()->makeReadonly(); $form->setFields($readonlyFields); - $templateData = $this->customise(array( - "EditForm" => $form - )); - SSViewer::setOption('rewriteHashlinks', false); if(Director::is_ajax()) { - $result = $templateData->renderWith($this->class . '_right'); - $parts = split(']*>', $result); - return $parts[sizeof($parts)-2]; + return $form->formHtmlContent(); } else { + $templateData = $this->customise(array( + "EditForm" => $form + )); return $templateData->renderWith('LeftAndMain'); } - - } } function compareversions() { - $id = (int)$this->urlParams['ID']; - $version1 = (int)$_REQUEST['From']; - $version2 = (int)$_REQUEST['To']; + $id = ($this->request->param('ID')) ? + $this->request->param('ID') : $this->request->requestVar('ID'); + + $versions = $this->request->requestVar('Versions'); + $version1 = ($versions && isset($versions[0])) ? + $versions[0] : $this->request->getVar('From'); + $version2 = ($versions && isset($versions[1])) ? + $versions[1] : $this->request->getVar('To'); if( $version1 > $version2 ) { $toVersion = $version1; @@ -847,6 +909,8 @@ JS; $toVersion = $version2; $fromVersion = $version1; } + + if(!$toVersion || !$toVersion) return false; $page = DataObject::get_by_id("SiteTree", $id); if($page && !$page->canView()) return Security::permissionFailure($this); @@ -899,22 +963,14 @@ JS; $field->dontEscape = true; } - return $this->sendFormToBrowser(array( - "EditForm" => $form - )); - } - } - - function sendFormToBrowser($templateData) { - if(Director::is_ajax()) { - SSViewer::setOption('rewriteHashlinks', false); - $result = $this->customise($templateData)->renderWith($this->class . '_right'); - $parts = split(']*>', $result); - return $parts[sizeof($parts)-2]; - } else { - return array( - "Right" => $this->customise($templateData)->renderWith($this->class . '_right'), - ); + if(Director::is_ajax()) { + return $form->formHtmlContent(); + } else { + $templateData = $this->customise(array( + "EditForm" => $form + )); + return $templateData->renderWith('LeftAndMain'); + } } } diff --git a/code/LeftAndMain.php b/code/LeftAndMain.php index a2870de8..9a000282 100644 --- a/code/LeftAndMain.php +++ b/code/LeftAndMain.php @@ -230,8 +230,6 @@ class LeftAndMain extends Controller { Requirements::javascript(CMS_DIR . '/javascript/LeftAndMain.js'); Requirements::javascript(CMS_DIR . '/javascript/LeftAndMain.Tree.js'); Requirements::javascript(CMS_DIR . '/javascript/LeftAndMain.EditForm.js'); - - Requirements::javascript(CMS_DIR . '/javascript/SideTabs.js'); Requirements::themedCSS('typography'); @@ -289,7 +287,6 @@ class LeftAndMain extends Controller { array( 'cms/javascript/CMSMain_left.js', 'cms/javascript/CMSMain_right.js', - 'cms/javascript/SideTabs.js', ) ); diff --git a/css/cms_left.css b/css/cms_left.css index fe8ab2bd..40d81ac8 100644 --- a/css/cms_left.css +++ b/css/cms_left.css @@ -473,6 +473,9 @@ ul.tree span.untranslated a:visited { margin: 0 !important; padding: 4px 7px; } +#Form_VersionsForm td.checkbox { + +} form#SideReportForm label.left { margin-left: 0em; diff --git a/javascript/CMSMain.js b/javascript/CMSMain.js index 0b8a5722..a7aae49f 100644 --- a/javascript/CMSMain.js +++ b/javascript/CMSMain.js @@ -261,9 +261,7 @@ /** * @class Simple form with a page type dropdown * which creates a new page through #Form_EditForm and adds a new tree node. - * @name ss.Form_AddPageOptionsForm - * @requires ss.i18n - * @requires ss.reports_holder + * @name ss.reports_holder */ $('#Form_ReportForm').concrete(function($) { return/** @lends ss.reports_holder */{ @@ -320,6 +318,129 @@ } }); + return false; + } + }; + }); + + /** + * @class Simple form showing versions of a specific page. + * @name ss.Form_VersionsForm + * @requires ss.i18n + */ + $('#Form_VersionsForm').concrete(function($) { + return/** @lends ss.Form_VersionsForm */{ + onmatch: function() { + var self = this; + + this.bind('submit', function(e) { + return self._submit(e); + }); + + // set button to be available in form submit event later on + this.find(':submit').bind('click', function(e) { + self.data('_clickedButton', this); + }); + + // integrate with sitetree selection changes + jQuery('#sitetree').bind('selectionchanged', function(e, data) { + self.find(':input[name=ID]').val(data.node.getIdx()); + self.trigger('submit'); + }); + + // refresh when field is selected + // TODO coupling + $('#treepanes').bind('accordionchange', function(e, ui) { + if($(ui.newContent).attr('id') == 'Form_VersionsForm') self.trigger('submit'); + }); + + // submit when 'show unpublished versions' checkbox is changed + this.find(':input[name=ShowUnpublished]').bind('change', function(e) { + // force the refresh button, not 'compare versions' + self.data('_clickedButton', self.find(':submit[name=action_versions]')); + self.trigger('submit'); + }); + + // move submit button to the top + this.find('#ReportClass').after(this.find('.Actions')); + + // links in results + this.find('td').bind('click', function(e) { + var td = $(this); + + // exclude checkboxes + if($(e.target).is(':input')) return true; + + var link = $(this).siblings('.versionlink').find('a').attr('href'); + td.addClass('loading'); + jQuery('#Form_EditForm').concrete('ss').loadForm( + link, + function(e) { + td.removeClass('loading'); + } + ); + return false; + }); + + // compare versions action + this.find(':submit[name=action_compareversions]').bind('click', function(e) { + // validation: only allow selection of exactly two versions + var versions = self.find(':input[name=Versions[]]:checked'); + if(versions.length != 2) { + alert(ss.i18n._t( + 'CMSMain.VALIDATIONTWOVERSION', + 'Please select two versions' + )); + return false; + } + + // overloaded submission: refresh the right form instead + self.data('_clickedButton', this); + self._submit(e, true); + + return false; + }) + }, + + /** + * @param {boolean} loadEditForm Determines if responses should show in current panel, + * or in the edit form (in the case of 'compare versions'). + */ + _submit: function(e, loadEditForm) { + var self = this; + + // Don't submit with empty ID + if(!this.find(':input[name=ID]').val()) return false; + + var $button = (self.data('_clickedButton')) ? $(self.data('_clickedButton')) : this.find(':submit:first'); + $button.addClass('loading'); + + var data = this.serializeArray(); + data.push({name:$button.attr('name'), value: $button.val()}); + + if(loadEditForm) { + jQuery('#Form_EditForm').concrete('ss').loadForm( + this.attr('action'), + function(e) { + $button.removeClass('loading'); + }, + {data: data, type: 'POST'} + ); + } else { + jQuery.ajax({ + url: this.attr('action'), + data: data, + dataType: 'html', + success: function(data, status) { + self.replaceWith(data); + }, + complete: function(xmlhttp, status) { + $button.removeClass('loading'); + } + }); + } + + return false; } }; diff --git a/javascript/SideTabs.js b/javascript/SideTabs.js deleted file mode 100755 index 69052556..00000000 --- a/javascript/SideTabs.js +++ /dev/null @@ -1,214 +0,0 @@ -/** - * Generic base class for all side panels - */ -SidePanel = Class.create(); -SidePanel.prototype = { - initialize : function() { - this.body = this.getElementsByTagName('div')[0]; - }, - destroy: function() { - this.body = null; - }, - onshow : function() { - this.onresize(); - this.body.innerHTML = '

loading...

'; - this.ajaxGetPanel(this.afterPanelLoaded); - }, - ajaxGetPanel : function(onComplete) { - new Ajax.Updater(this.body, this.ajaxURL(), { - onComplete : onComplete ? onComplete.bind(this) : null, - onFailure : this.ajaxPanelError - }); - }, - - ajaxPanelError : function (response) { - errorMessage("error getting side panel", response); - }, - - ajaxURL : function() { - var srcName = this.id.replace('_holder',''); - var id = $('Form_EditForm').elements.ID; - if(id) id = id.value; else id = ""; - - // This assumes that admin/cms/ refers to CMSMain - var url = 'admin/cms/' + srcName + '/' + id + '?ajax=1'; - if($('Form_EditForm_Locale')) url += "&locale=" + $('Form_EditForm_Locale').value; - return url; - }, - - afterPanelLoaded : function() { - }, - onpagechanged : function() { - } -} - -SidePanelRecord = Class.create(); -SidePanelRecord.prototype = { - onclick : function(event) { - Event.stop(event); - $('Form_EditForm').getPageFromServer(this.getID()); - }, - destroy: function() { - this.onclick = null; - }, - getID : function() { - if(this.href.match(/\/([^\/]+)$/)) return parseInt(RegExp.$1); - } -} - - - - - -/** - * Version list - */ -VersionList = Class.extend('SidePanel'); -VersionList.prototype = { - initialize : function() { - this.mode = 'view'; - this.SidePanel.initialize(); - }, - destroy: function() { - this.SidePanel = null; - this.onclose = null; - }, - - ajaxURL : function() { - return this.SidePanel.ajaxURL() + '&unpublished=' + ($('versions_showall').checked ? 1 : 0); - }, - afterPanelLoaded : function() { - this.idLoaded = $('Form_EditForm').elements.ID.value; - VersionItem.applyTo('#' + this.id + ' tbody tr'); - }, - - select : function(pageID, versionID, sourceEl) { - if(this.mode == 'view') { - sourceEl.select(); - var url = 'admin/getversion/' + pageID + '/' + versionID; - if($('Form_EditForm_Locale')) url += "?locale=" + $('Form_EditForm_Locale').value; - $('Form_EditForm').loadURLFromServer(url); - $('viewArchivedSite').style.display = ''; - $('viewArchivedSite').getVars = '?archiveDate=' + sourceEl.getElementsByTagName('td')[1].className; - - } else { - $('viewArchivedSite').style.display = 'none'; - - if(this.otherVersionID) { - sourceEl.select(); - this.otherSourceEl.select(true); - statusMessage('Loading comparison...'); - var url = 'admin/compareversions/' + pageID + '/?From=' + this.otherVersionID + '&To=' + versionID; - if($('Form_EditForm_Locale')) url += "&locale=" + $('Form_EditForm_Locale').value; - $('Form_EditForm').loadURLFromServer(url); - } else { - sourceEl.select(); - } - } - this.otherVersionID = versionID; - this.otherSourceEl = sourceEl; - }, - onpagechanged : function() { - if(this.idLoaded != $('Form_EditForm').elements.ID.value) { - this.body.innerHTML = '

loading...

'; - this.ajaxGetPanel(this.afterPanelLoaded); - } - }, - refresh : function() { - this.ajaxGetPanel(this.afterPanelLoaded); - }, - onclose : function() { - if(this.idLoaded) { - $('Form_EditForm').getPageFromServer(this.idLoaded); - } - $('viewArchivedSite').style.display = 'none'; - } -} - -VersionItem = Class.create(); -VersionItem.prototype = { - initialize : function() { - this.holder = $('versions_holder'); - }, - - destroy: function() { - this.holder = null; - this.onclick = null; - }, - - onclick : function() { - this.holder.select(this.pageID(), this.versionID(), this); - }, - idPair : function() { - if(this.id.match(/page-([^-]+)-version-([^-]+)$/)) { - return RegExp.$1 + '/' + RegExp.$2; - } - }, - pageID : function() { - if(this.id.match(/page-([^-]+)-version-([^-]+)$/)) { - return RegExp.$1; - } - }, - versionID : function() { - if(this.id.match(/page-([^-]+)-version-([^-]+)$/)) { - return RegExp.$2; - } - } -} - -VersionAction = Class.create(); -VersionAction.prototype = { - initialize: function() { - this.holder = $('versions_holder'); - - this.showallCheckbox = $('versions_showall'); - this.showallCheckbox.holder = this; - this.showallCheckbox.onclick = this.showall_change; - - this.comparemodeCheckbox = $('versions_comparemode'); - this.comparemodeCheckbox.holder = this; - this.comparemodeCheckbox.onclick = function() { this.holder.comparemode_change(this.checked); } - }, - - showall_change: function() { - this.holder.holder.refresh(); - }, - - destroy: function() { - if(this.comparemodeCheckbox) { - this.comparemodeCheckbox.holder = null; - this.comparemodeCheckbox.onclick = null; - } - if(this.showallCheckbox) { - this.showallCheckbox.holder = null; - this.showallCheckbox.onchange = null; - } - this.holder = null; - this.comparemodeCheckbox = null; - }, - - /** - * Handler function when comparemode checkbox is clicked - */ - comparemode_change: function(isChecked) { - if (true == isChecked) { - return this.compare(); - } else { - return this.view(); - } - }, - - view: function() { - this.holder.mode = 'view'; - }, - - compare: function() { - this.holder.mode = 'compare'; - } -} - - -VersionItem.applyTo('#versions_holder tbody tr'); -VersionAction.applyTo('#versions_holder p.pane_actions'); -VersionList.applyTo('#versions_holder'); - diff --git a/templates/CMSMain_versions.ss b/templates/CMSMain_versions.ss index 2c829227..71a24ec9 100755 --- a/templates/CMSMain_versions.ss +++ b/templates/CMSMain_versions.ss @@ -1,6 +1,7 @@ + @@ -10,9 +11,18 @@ <% control Versions %> - - - + + + +
# <% _t('WHEN','When') %> <% _t('AUTHOR','Author') %>
$Version$LastEdited.Ago$Author.FirstName $Author.Surname.Initial + + + $LastEdited.Ago + + $Author.FirstName $Author.Surname.Initial + <% if Published %> <% if Publisher %> diff --git a/templates/Includes/CMSMain_left.ss b/templates/Includes/CMSMain_left.ss index 9f39414f..ed2a116c 100755 --- a/templates/Includes/CMSMain_left.ss +++ b/templates/Includes/CMSMain_left.ss @@ -25,19 +25,7 @@ <% _t('PAGEVERSIONH','Page Version History') %>
-

- - - - - - - - -

- -
-
+ $VersionsForm