Merge branch 'develop' into ui-improvements
This commit is contained in:
commit
fa75e565cf
|
|
@ -7077,6 +7077,10 @@ body.display-side-panel #layout-side-panel {
|
|||
-webkit-box-shadow: 2px 0px 2px 0 rgba(0, 0, 0, 0.3);
|
||||
box-shadow: 2px 0px 2px 0 rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
body.side-panel-fix-shadow #layout-side-panel {
|
||||
-webkit-box-shadow: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
.touch #layout-side-panel .fix-button {
|
||||
display: none;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,16 @@
|
|||
(function($){
|
||||
function updateLayout() {
|
||||
var OctoberLayout = function() {}
|
||||
|
||||
OctoberLayout.prototype.setPageTitle = function(title) {
|
||||
var $title = $('title')
|
||||
|
||||
if (this.pageTitleTemplate === undefined)
|
||||
this.pageTitleTemplate = $title.data('titleTemplate')
|
||||
|
||||
$title.text(this.pageTitleTemplate.replace('%s', title))
|
||||
}
|
||||
|
||||
OctoberLayout.prototype.updateLayout = function(title) {
|
||||
$('.layout-cell.width-fix').each(function(){
|
||||
var $el = $(this).children();
|
||||
if ($el.length > 0) {
|
||||
|
|
@ -14,6 +25,13 @@
|
|||
})
|
||||
}
|
||||
|
||||
$(document).ready(updateLayout)
|
||||
$(window).on('resize', updateLayout)
|
||||
if ($.oc === undefined)
|
||||
$.oc = {}
|
||||
|
||||
$.oc.layout = new OctoberLayout()
|
||||
|
||||
$(document).ready($.oc.layout.updateLayout())
|
||||
$(window).on('resize', function() {
|
||||
$.oc.layout.updateLayout()
|
||||
})
|
||||
})(jQuery);
|
||||
|
|
@ -136,14 +136,22 @@
|
|||
SidePanelTab.prototype.fixPanel = function() {
|
||||
$(document.body).toggleClass('side-panel-not-fixed')
|
||||
|
||||
var fixed = this.panelFixed()
|
||||
var self = this
|
||||
|
||||
fixed
|
||||
? this.updateActiveTab()
|
||||
: this.hideSidePanel()
|
||||
window.setTimeout(function() {
|
||||
var fixed = self.panelFixed()
|
||||
|
||||
if (typeof(localStorage) !== 'undefined')
|
||||
localStorage.ocSidePanelFixed = fixed ? 1 : 0
|
||||
if (fixed) {
|
||||
self.updateActiveTab()
|
||||
$(document.body).addClass('side-panel-fix-shadow')
|
||||
} else {
|
||||
$(document.body).removeClass('side-panel-fix-shadow')
|
||||
self.hideSidePanel()
|
||||
}
|
||||
|
||||
if (typeof(localStorage) !== 'undefined')
|
||||
localStorage.ocSidePanelFixed = fixed ? 1 : 0
|
||||
}, 0)
|
||||
}
|
||||
|
||||
SidePanelTab.DEFAULTS = {
|
||||
|
|
|
|||
|
|
@ -131,7 +131,8 @@
|
|||
var
|
||||
$tabs = $('>li', this.$tabsContainer),
|
||||
tabIndex = $tabs.index(li),
|
||||
targetId = this.tabId + '-tab-' + tabIndex,
|
||||
time = new Date().getTime(),
|
||||
targetId = this.tabId + '-tab-' + tabIndex + time,
|
||||
$a = $('a', li)
|
||||
|
||||
$a.attr('data-target', '#'+targetId).attr('data-toggle', 'tab')
|
||||
|
|
|
|||
|
|
@ -42,7 +42,13 @@ body.display-side-panel {
|
|||
position: absolute;
|
||||
z-index: 500;
|
||||
width: 300px;
|
||||
.box-shadow(2px 0px 2px 0 rgba(0, 0, 0, 0.3))
|
||||
.box-shadow(2px 0px 2px 0 rgba(0, 0, 0, 0.3));
|
||||
}
|
||||
}
|
||||
|
||||
body.side-panel-fix-shadow {
|
||||
#layout-side-panel {
|
||||
.box-shadow(none);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -76,6 +76,11 @@ class Controller extends Extendable
|
|||
*/
|
||||
public $pageTitle;
|
||||
|
||||
/**
|
||||
* @var string Page title template
|
||||
*/
|
||||
public $pageTitleTemplate;
|
||||
|
||||
/**
|
||||
* @var string Body class property used for customising the layout on a controller basis.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1, user-scalable=0">
|
||||
<title><?= $this->pageTitle ?> | October CMS</title>
|
||||
<title data-title-template="<?= empty($this->pageTitleTemplate) ? '%s | October CMS' : e($this->pageTitleTemplate) ?>">
|
||||
<?= $this->pageTitle ?> | October CMS
|
||||
</title>
|
||||
|
||||
<link href="<?= URL::to('modules/backend/assets/vendor/select2/select2.css') ?>" rel="stylesheet">
|
||||
<link href="<?= URL::to('modules/backend/assets/css/october.css') ?>?v<?= System\Models\Parameters::get('system::core.build', 1) ?>" rel="stylesheet">
|
||||
|
|
|
|||
|
|
@ -118,6 +118,15 @@ div.control-componentlist.has-components {
|
|||
div.control-componentlist div.layout {
|
||||
width: auto;
|
||||
}
|
||||
div.control-componentlist div.components div.layout-cell.error-component {
|
||||
background: #ab2a1c;
|
||||
}
|
||||
div.control-componentlist div.components div.layout-cell.error-component > div {
|
||||
color: #ffffff;
|
||||
}
|
||||
div.control-componentlist div.components div.layout-cell.error-component > div:after {
|
||||
color: #ab2a1c;
|
||||
}
|
||||
div.control-componentlist div.components div.layout-cell:first-child {
|
||||
border-bottom-left-radius: 3px;
|
||||
border-top-left-radius: 3px;
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@
|
|||
success: function(data) {
|
||||
this.success(data).done(function(){
|
||||
$.oc.stripeLoadIndicator.hide()
|
||||
$('#cms-master-tabs').ocTab('addTab', data.title, data.tab, tabId, $form.data('type-icon'))
|
||||
$('#cms-master-tabs').ocTab('addTab', data.tabTitle, data.tab, tabId, $form.data('type-icon'))
|
||||
}).always(function(){
|
||||
$.oc.stripeLoadIndicator.hide()
|
||||
})
|
||||
|
|
@ -82,6 +82,21 @@
|
|||
*/
|
||||
$('#cms-master-tabs').on('closed.oc.tab', function(event){
|
||||
updateModifiedCounter()
|
||||
|
||||
if ($('> div.tab-content > div.tab-pane', '#cms-master-tabs').length == 0)
|
||||
setPageTitle('')
|
||||
})
|
||||
|
||||
/*
|
||||
* Listen for the onBeforeRequest event
|
||||
*/
|
||||
$('#cms-master-tabs').on('oc.beforeRequest', function(event) {
|
||||
var $form = $(event.target)
|
||||
|
||||
if ( $('.components .layout-cell.error-component', $form).length > 0) {
|
||||
if (!confirm('The form contains unknown components. Their properties will be lost on save. Do you want to save the form?'))
|
||||
event.preventDefault()
|
||||
}
|
||||
})
|
||||
|
||||
/*
|
||||
|
|
@ -92,6 +107,11 @@
|
|||
return
|
||||
|
||||
var dataId = $(event.target).closest('li').attr('data-tab-id')
|
||||
|
||||
var title = $(event.target).attr('title')
|
||||
if (title)
|
||||
setPageTitle(title)
|
||||
|
||||
$('#cms-side-panel [data-control=filelist]').fileList('markActive', dataId)
|
||||
$('#cms-side-panel form').trigger('oc.list.setActiveItem', [dataId])
|
||||
})
|
||||
|
|
@ -202,8 +222,10 @@
|
|||
$('[data-control=preview-button]', this).attr('href', data.pageUrl)
|
||||
}
|
||||
|
||||
if (data.title !== undefined)
|
||||
$('#cms-master-tabs').ocTab('updateTitle', $(this).closest('.tab-pane'), data.title)
|
||||
if (data.tabTitle !== undefined) {
|
||||
$('#cms-master-tabs').ocTab('updateTitle', $(this).closest('.tab-pane'), data.tabTitle)
|
||||
setPageTitle(data.tabTitle)
|
||||
}
|
||||
|
||||
var tabId = $('input[name=templateType]', this).val() + '-'
|
||||
+ $('input[name=theme]', this).val() + '-'
|
||||
|
|
@ -251,8 +273,9 @@
|
|||
},
|
||||
success: function(data) {
|
||||
this.success(data).done(function(){
|
||||
$('#cms-master-tabs').ocTab('addTab', data.title, data.tab, tabId, $form.data('type-icon') + ' new-template')
|
||||
$('#cms-master-tabs').ocTab('addTab', data.tabTitle, data.tab, tabId, $form.data('type-icon') + ' new-template')
|
||||
$('#layout-side-panel').trigger('close.oc.sidePanel')
|
||||
setPageTitle(data.tabTitle)
|
||||
}).always(function(){
|
||||
$.oc.stripeLoadIndicator.hide()
|
||||
})
|
||||
|
|
@ -446,7 +469,7 @@
|
|||
success: function(data) {
|
||||
this.success(data).done(function(){
|
||||
$.oc.stripeLoadIndicator.hide()
|
||||
$('#cms-master-tabs').ocTab('updateTab', tab, data.title, data.tab)
|
||||
$('#cms-master-tabs').ocTab('updateTab', tab, data.tabTitle, data.tab)
|
||||
$('#cms-master-tabs').ocTab('unmodifyTab', tab)
|
||||
updateModifiedCounter()
|
||||
}).always(function(){
|
||||
|
|
@ -460,6 +483,13 @@
|
|||
})
|
||||
}
|
||||
|
||||
function setPageTitle(title) {
|
||||
if (title.length)
|
||||
$.oc.layout.setPageTitle(title + ' | ')
|
||||
else
|
||||
$.oc.layout.setPageTitle(title)
|
||||
}
|
||||
|
||||
/*
|
||||
* Listen for the click event on the components' remove link
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@
|
|||
@color-component-hover-text: #ffffff;
|
||||
@color-component-placeholder: #e0e0e0;
|
||||
@color-group-bg: #f1f3f4;
|
||||
@color-error-component-bg: #ab2a1c;
|
||||
@color-error-component-text: #ffffff;
|
||||
|
||||
.component-lego-icon() {
|
||||
position: absolute;
|
||||
|
|
@ -117,6 +119,18 @@ div.control-componentlist {
|
|||
|
||||
div.components {
|
||||
div.layout-cell {
|
||||
&.error-component {
|
||||
background: @color-error-component-bg;
|
||||
|
||||
> div {
|
||||
color: @color-error-component-text;
|
||||
|
||||
&:after {
|
||||
color: @color-error-component-bg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:first-child {
|
||||
.border-left-radius(3px);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -133,8 +133,8 @@ class CmsCompoundObject extends CmsObject
|
|||
|
||||
$settingParts = explode(' ', $setting);
|
||||
$settingName = $settingParts[0];
|
||||
if (!$manager->hasComponent($settingName))
|
||||
continue;
|
||||
// if (!$manager->hasComponent($settingName))
|
||||
// continue;
|
||||
|
||||
$components[$setting] = $value;
|
||||
unset($this->settings[$setting]);
|
||||
|
|
|
|||
|
|
@ -39,6 +39,18 @@ abstract class ComponentBase extends Extendable
|
|||
*/
|
||||
public $pluginIcon;
|
||||
|
||||
/**
|
||||
* @var string Component CSS class name for the back-end page/layout component list.
|
||||
* This field is used by the CMS internally.
|
||||
*/
|
||||
public $componentCssClass;
|
||||
|
||||
/**
|
||||
* @var boolean Determines whether Inspector can be used with the component.
|
||||
* This field is used by the CMS internally.
|
||||
*/
|
||||
public $inspectorEnabled = true;
|
||||
|
||||
/**
|
||||
* @var string Specifies the component directory name.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
use Str;
|
||||
use Illuminate\Container\Container;
|
||||
use System\Classes\PluginManager;
|
||||
use System\Classes\SystemException;
|
||||
|
||||
/**
|
||||
* Component manager
|
||||
|
|
@ -179,10 +180,10 @@ class ComponentManager
|
|||
{
|
||||
$className = $this->resolve($name);
|
||||
if (!$className)
|
||||
return null;
|
||||
throw new SystemException(sprintf('Class name is not registered for the component %s. Check the component plugin.', $name));
|
||||
|
||||
if (!class_exists($className))
|
||||
throw new \Exception('Component class not found '.$className);
|
||||
throw new SystemException(sprintf('Component class not found %s.Check the component plugin.', $className));
|
||||
|
||||
$component = new $className($cmsObject, $properties);
|
||||
$component->name = $name;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,29 @@
|
|||
<?php namespace Cms\Classes;
|
||||
|
||||
use Cms\Classes\ComponentBase;
|
||||
use Cms\Classes\CodeBase;
|
||||
|
||||
class UnknownComponent extends ComponentBase
|
||||
{
|
||||
protected $errorMessage;
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function __construct($cmsObject, $properties, $errorMessage)
|
||||
{
|
||||
$this->errorMessage = $errorMessage;
|
||||
$this->componentCssClass = 'error-component';
|
||||
$this->inspectorEnabled = false;
|
||||
|
||||
parent::__construct($cmsObject, $properties);
|
||||
}
|
||||
|
||||
public function componentDetails()
|
||||
{
|
||||
return [
|
||||
'name' => 'Uknown component',
|
||||
'description' => $this->errorMessage
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -90,6 +90,7 @@ class Index extends Controller
|
|||
|
||||
$this->bodyClass = 'compact-container side-panel-not-fixed';
|
||||
$this->pageTitle = Lang::get('cms::lang.cms.menu_label');
|
||||
$this->pageTitleTemplate = '%s CMS | October';
|
||||
}
|
||||
|
||||
//
|
||||
|
|
@ -116,7 +117,7 @@ class Index extends Controller
|
|||
}
|
||||
|
||||
return [
|
||||
'title' => $this->getTabTitle($type, $template),
|
||||
'tabTitle' => $this->getTabTitle($type, $template),
|
||||
'tab' => $this->makePartial('form_page', [
|
||||
'form' => $widget,
|
||||
'templateType' => $type,
|
||||
|
|
@ -162,7 +163,7 @@ class Index extends Controller
|
|||
$result = [
|
||||
'templatePath' => $template->fileName,
|
||||
'templateMtime' => $template->mtime,
|
||||
'title' => $this->getTabTitle($type, $template)
|
||||
'tabTitle' => $this->getTabTitle($type, $template)
|
||||
];
|
||||
|
||||
if ($type == 'page') {
|
||||
|
|
@ -192,7 +193,7 @@ class Index extends Controller
|
|||
$this->vars['templatePath'] = '';
|
||||
|
||||
return [
|
||||
'title' => $this->getTabTitle($type, $template),
|
||||
'tabTitle' => $this->getTabTitle($type, $template),
|
||||
'tab' => $this->makePartial('form_page', [
|
||||
'form' => $widget,
|
||||
'templateType' => $type,
|
||||
|
|
|
|||
|
|
@ -3,7 +3,9 @@
|
|||
use Backend\Classes\FormWidgetBase;
|
||||
use Cms\Classes\ComponentManager;
|
||||
use Cms\Classes\ComponentHelpers;
|
||||
use Cms\Classes\UnknownComponent;
|
||||
use Lang;
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* Component Builder
|
||||
|
|
@ -36,15 +38,22 @@ class Components extends FormWidgetBase
|
|||
foreach ($this->model->settings['components'] as $name=>$properties) {
|
||||
list($name, $alias) = strpos($name, ' ') ? explode(' ', $name) : [$name, $name];
|
||||
|
||||
$componentObj = $manager->makeComponent($name, null, $properties);
|
||||
$componentObj->alias = $alias;
|
||||
$componentObj->pluginIcon = 'icon-puzzle-piece';
|
||||
try {
|
||||
$componentObj = $manager->makeComponent($name, null, $properties);
|
||||
|
||||
$plugin = $manager->findComponentPlugin($componentObj);
|
||||
if ($plugin) {
|
||||
$pluginDetails = $plugin->pluginDetails();
|
||||
if (isset($pluginDetails['icon']))
|
||||
$componentObj->pluginIcon = $pluginDetails['icon'];
|
||||
$componentObj->alias = $alias;
|
||||
$componentObj->pluginIcon = 'icon-puzzle-piece';
|
||||
|
||||
$plugin = $manager->findComponentPlugin($componentObj);
|
||||
if ($plugin) {
|
||||
$pluginDetails = $plugin->pluginDetails();
|
||||
if (isset($pluginDetails['icon']))
|
||||
$componentObj->pluginIcon = $pluginDetails['icon'];
|
||||
}
|
||||
} catch (Exception $ex) {
|
||||
$componentObj = new UnknownComponent(null, $properties, $ex->getMessage());
|
||||
$componentObj->alias = $alias;
|
||||
$componentObj->pluginIcon = 'icon-bug';
|
||||
}
|
||||
|
||||
$result[] = $componentObj;
|
||||
|
|
|
|||
|
|
@ -2,15 +2,21 @@
|
|||
<div class="components" data-control="toolbar">
|
||||
<div class="layout">
|
||||
<?php foreach ($components as $component): ?>
|
||||
<div class="layout-cell">
|
||||
<div class="<?= 'oc-'.$component->pluginIcon ?> layout-relative" data-inspectable data-inspector-title="<?= $name = e($this->getComponentName($component)) ?>" data-inspector-description="<?= $description = e($this->getComponentDescription($component)) ?>" data-inspector-config="<?= e($this->getComponentsPropertyConfig($component)) ?>" data-inspector-class="<?= get_class($component) ?>">
|
||||
<span class="name"><?= $name ?></span>
|
||||
<span class="description"><?= $description ?></span>
|
||||
<span class="alias oc-icon-code"><?= e($component->alias) ?></span>
|
||||
<input type="hidden" name="component_properties[]" data-inspector-values value="<?= e($this->getComponentPropertyValues($component)) ?>"/>
|
||||
<input type="hidden" name="component_names[]" value="<?= e($component->name) ?>"></input>
|
||||
<input type="hidden" name="component_aliases[]" value="<?= e($component->alias) ?>"></input>
|
||||
<a href="#" class="remove">×</a>
|
||||
<div class="layout-cell <?= e($component->componentCssClass) ?>">
|
||||
<div
|
||||
class="<?= 'oc-'.$component->pluginIcon ?> layout-relative"
|
||||
<?php if ($component->inspectorEnabled): ?>data-inspectable<?php endif ?>
|
||||
data-inspector-title="<?= $name = e($this->getComponentName($component)) ?>"
|
||||
data-inspector-description="<?= $description = e($this->getComponentDescription($component)) ?>"
|
||||
data-inspector-config="<?= e($this->getComponentsPropertyConfig($component)) ?>"
|
||||
data-inspector-class="<?= get_class($component) ?>">
|
||||
<span class="name"><?= $name ?></span>
|
||||
<span class="description"><?= $description ?></span>
|
||||
<span class="alias oc-icon-code"><?= e($component->alias) ?></span>
|
||||
<input type="hidden" name="component_properties[]" data-inspector-values value="<?= e($this->getComponentPropertyValues($component)) ?>"/>
|
||||
<input type="hidden" name="component_names[]" value="<?= e($component->name) ?>"></input>
|
||||
<input type="hidden" name="component_aliases[]" value="<?= e($component->alias) ?>"></input>
|
||||
<a href="#" class="remove">×</a>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach ?>
|
||||
|
|
|
|||
|
|
@ -45,7 +45,9 @@ if (window.jQuery === undefined)
|
|||
loading = options.loading !== undefined && options.loading.length ? $(options.loading) : null,
|
||||
isRedirect = options.redirect !== undefined && options.redirect.length
|
||||
|
||||
form.trigger('oc.beforeRequest', context)
|
||||
var _event = jQuery.Event('oc.beforeRequest')
|
||||
form.trigger(_event, context)
|
||||
if (_event.isDefaultPrevented()) return
|
||||
|
||||
var data = [form.serialize()]
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue