Author SHA1 Message Date
Michal Kváček 8098288139 FIX: fix path to admin routes 2018-09-20 00:14:53 +02:00
Michal Kváček cf90d1b91e FEATURE: make nested margin on subpages 2018-04-11 23:04:16 +02:00
Michal Kváček 8acfcabb3c FEATURE: add infinite content pages depth into overview 2018-04-11 22:48:00 +02:00
Michal Kváček b91b80debb FEATURE: allow infinite subpages depth 2018-04-11 22:36:25 +02:00
Michal Kváček ae29c49acf Merge branch 'master' of binarity.cz:/opt/git/internal/cms/minicms 2018-03-25 11:23:38 +02:00
Michal Kváček 7e4507e9e4 FEATURE: add template to menu widget 2018-03-25 11:23:12 +02:00
Peter Hrdlica f0bb159efb Merge branch 'master' of binarity.cz:/opt/git/internal/cms/minicms 2017-10-15 15:54:57 +02:00
Peter Hrdlica ddae98d233 multiselect component 2017-10-15 15:54:21 +02:00
Michal Kváček b1ca6e4cfb FEATURE: allow multiple ckEditor instances 2017-10-09 00:14:48 +02:00
Michal Kváček c69bd9bcf7 FEATURE: add bootstrap datepicker. All elements with .date class are now datepicker holders 2017-09-25 23:22:25 +02:00
Michal Kváček 271e7f5170 FIX: fix insanely low file previews 2017-09-25 15:29:54 +02:00
Michal Kváček 1ecef555ef FIX: fix minor bug in content overview and module installation 2017-09-25 14:37:30 +02:00
Michal Kváček 4ef5e3e3cd FEATURE: make top menu extendable 2017-09-25 11:20:57 +02:00
Michal Kváček 1388383bb6 FEATURE: update Font Awesome and add bottom border and margin to submenus in admin 2017-09-24 16:44:36 +02:00
Michal Kváček f1ff45cfb1 FIX: do not fire error when module service provider is not found. Log it and let it go 2017-09-24 13:57:03 +02:00
Michal Kváček 6d723f026d FIX: remove template service provider from core repository 2017-09-23 00:52:35 +02:00
31 changed files with 430 additions and 379 deletions
+21 -1
View File
@@ -3,7 +3,6 @@
namespace App\CMS\Handlers; namespace App\CMS\Handlers;
use App\CMS\Contracts\Modules\BaseModuleHandler; use App\CMS\Contracts\Modules\BaseModuleHandler;
use App\CMS\Enumerations\TemplatePathsHumanReadableRootOnly;
use App\CMS\Enumerations\WidgetTypes; use App\CMS\Enumerations\WidgetTypes;
use App\CMS\Repositories\Module; use App\CMS\Repositories\Module;
use App\Models\ActionLog\ActionLog; use App\Models\ActionLog\ActionLog;
@@ -14,6 +13,7 @@ use App\Models\Templates\Template;
use App\Models\User; use App\Models\User;
use App\Models\Widgets\Widget; use App\Models\Widgets\Widget;
use App\Models\Widgets\WidgetArea; use App\Models\Widgets\WidgetArea;
use Mcamara\LaravelLocalization\Facades\LaravelLocalization;
abstract class BaseHandler implements BaseModuleHandler abstract class BaseHandler implements BaseModuleHandler
{ {
@@ -125,6 +125,26 @@ abstract class BaseHandler implements BaseModuleHandler
}, 10000, ['icon' => 'fa fa-fw fa-gears']); }, 10000, ['icon' => 'fa fa-fw fa-gears']);
}); });
\Menu::create('topMenu', function ($menu) use ($user) {
if (count(LaravelLocalization::getSupportedLocales()) > 1) {
$menu->dropdown(trans(LaravelLocalization::getCurrentLocaleName()), function ($menu) use ($user) {
foreach (LaravelLocalization::getSupportedLocales() as $localeCode => $properties) {
$menu->url(LaravelLocalization::getLocalizedURL($localeCode), $properties['native']);
}
});
}
if ($user->can('manage', Content::class)) {
$menu->route('page.index', '', [], 10, [
'icon' => 'fa fa-fw fa-globe',
'title' => trans('common.goToWeb'),
'target' => '_blank',
'data-toggle' => 'tooltip',
'data-placement' => 'left'
]);
}
});
// create menu with user profile // create menu with user profile
\Menu::create('profileMenu', function ($menu) use ($user) { \Menu::create('profileMenu', function ($menu) use ($user) {
$menu->route('users.detail', trans('admin/userManagement.profile'), ['user' => $user], 10, ['icon' => 'fa fa-fw fa-user icon']); $menu->route('users.detail', trans('admin/userManagement.profile'), ['user' => $user], 10, ['icon' => 'fa fa-fw fa-user icon']);
+1 -1
View File
@@ -17,7 +17,7 @@ trait Nullable {
* @return null|string * @return null|string
*/ */
public function nullableDate($date) { public function nullableDate($date) {
return empty($date) ? null : Carbon::parse($date)->toDateTimeString(); return empty($date) ? null : Carbon::createFromFormat(config('app.date_format'), $date)->toDateTimeString();
} }
/** /**
@@ -1,83 +0,0 @@
<?php
namespace App\CMS\MenuPresenters;
use Nwidart\Menus\MenuItem;
use Nwidart\Menus\Presenters\Presenter;
class FoundationDrilldownMenuPresenter extends Presenter
{
/**
* {@inheritdoc }
*/
public function getOpenTagWrapper()
{
return PHP_EOL . '<ul class="vertical menu" data-drilldown>' . PHP_EOL;
}
/**
* {@inheritdoc }
*/
public function getCloseTagWrapper()
{
return PHP_EOL . '</ul>' . PHP_EOL;
}
/**
* {@inheritdoc }
*/
public function getMenuWithoutDropdownWrapper($item)
{
return '<li' . $this->getActiveState($item) . '><a href="' . $item->getUrl() . '">' . $item->getIcon() . ' ' . $item->title . '</a></li>' . PHP_EOL;
}
/**
* {@inheritdoc }
*/
public function getActiveState(MenuItem $item)
{
$active = ' class="active"';
if (empty($item->getChilds())) {
// for direct menu input return if page is active
return \Request::is($item->getRequest()) ? $active : null;
} else {
// on nested menu inputs loop over children and in case any of them is active, mark active also root level
foreach ($item->getChilds() as $child) {
if ($this->getActiveState($child)) {
return $active;
}
}
}
return null;
}
/**
* {@inheritdoc }
*/
public function getDividerWrapper()
{
return '<li class="divider"></li>' . PHP_EOL;
}
public function getMultiLevelDropdownWrapper($item)
{
return $this->getMenuWithDropDownWrapper($item);
}
/**
* {@inheritdoc }
*/
public function getMenuWithDropDownWrapper($item)
{
$active = $this->getActiveState($item);
return '<li>
<a ' . $active . ' href="#">' . $item->getIcon() . ' ' . $item->title . '</a>
<ul class="vertical menu">
' . $this->getChildMenuItems($item) . '
</ul>
</li>' . PHP_EOL;
}
}
@@ -1,62 +0,0 @@
<?php
namespace App\CMS\MenuPresenters;
use Nwidart\Menus\Presenters\Presenter;
class FoundationDropdownMenuPresenter extends Presenter
{
/**
* {@inheritdoc }
*/
public function getOpenTagWrapper()
{
return PHP_EOL . '<ul class="vertical dropdown menu" data-dropdown-menu>' . PHP_EOL;
}
/**
* {@inheritdoc }
*/
public function getCloseTagWrapper()
{
return PHP_EOL . '</ul>' . PHP_EOL;
}
/**
* {@inheritdoc }
*/
public function getMenuWithoutDropdownWrapper($item)
{
$link = '<a href="' . $item->getUrl() . '">' . $item->getIcon() . ' ' . $item->title . '</a>';
return '<li' . $this->getActiveState($item) . '>' . $link . '</li>' . PHP_EOL;
}
/**
* {@inheritdoc }
*/
public function getActiveState($item)
{
return \Request::is($item->getRequest()) || $item->hasActiveOnChild ? ' class="active"' : null;
}
/**
* {@inheritdoc }
*/
public function getDividerWrapper()
{
return '<li class="divider"></li>' . PHP_EOL;
}
/**
* {@inheritdoc }
*/
public function getMenuWithDropDownWrapper($item)
{
return '<li>
<a href="#">' . $item->getIcon() . ' ' . $item->title . '</a>
<ul class="vertical menu">
' . $this->getChildMenuItems($item) . '
</ul>
</li>' . PHP_EOL;
}
}
@@ -1,10 +0,0 @@
<?php
namespace App\CMS\MenuPresenters;
class FoundationInitializedDropdownMenuPresenter extends FoundationDropdownMenuPresenter
{
public function getOpenTagWrapper()
{
return PHP_EOL . '<ul class="menu">' . PHP_EOL;
}
}
@@ -0,0 +1,16 @@
<?php
namespace App\CMS\MenuPresenters;
use Nwidart\Menus\Presenters\Bootstrap\NavbarPresenter;
class TopMenuPresenter extends NavbarPresenter {
public function getOpenTagWrapper()
{
return '';
}
public function getCloseTagWrapper()
{
return '';
}
}
@@ -4,6 +4,7 @@ namespace App\CMS\ModuleManager\Providers;
use App\CMS\Repositories\Module as ModuleRepository; use App\CMS\Repositories\Module as ModuleRepository;
use Illuminate\Database\QueryException; use Illuminate\Database\QueryException;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\ServiceProvider; use Illuminate\Support\ServiceProvider;
class ModuleManager extends ServiceProvider class ModuleManager extends ServiceProvider
@@ -25,6 +26,12 @@ class ModuleManager extends ServiceProvider
foreach ($modules as $module) { foreach ($modules as $module) {
if (isset($module->module_settings['providers']) && !empty($module->module_settings['providers'])) { if (isset($module->module_settings['providers']) && !empty($module->module_settings['providers'])) {
foreach ($module->module_settings['providers'] as $provider) { foreach ($module->module_settings['providers'] as $provider) {
if (!class_exists($provider)) {
Log::warning($provider.' does not exists. Skipping');
continue;
}
$this->app->register($provider); $this->app->register($provider);
} }
} }
+27 -14
View File
@@ -12,9 +12,10 @@ use Illuminate\Support\Facades\Route;
class Menu implements WidgetRenderer class Menu implements WidgetRenderer
{ {
public static $template = null;
/** /**
* Method used for displaying widget. * Method used for displaying widget.
*
* This method renders some HTML code for displaying. * This method renders some HTML code for displaying.
* *
* @param Widget $widget * @param Widget $widget
@@ -27,6 +28,11 @@ class Menu implements WidgetRenderer
$links = (array)$settings->links; $links = (array)$settings->links;
$pageIds = array_keys($links); $pageIds = array_keys($links);
if (!self::$template) {
throw new \Exception('neni nastavena sablona');
return;
}
// get pages // get pages
$pages = WidgetMenu::selectContentPages($pageIds); $pages = WidgetMenu::selectContentPages($pageIds);
@@ -40,14 +46,15 @@ class Menu implements WidgetRenderer
$parameters = Route::current() $parameters = Route::current()
->parameters(); ->parameters();
$code = '<ul class="menu ' . $widget->container_class . '"'; // $code = '<ul class="menu ' . $widget->container_class . '"';
if ($widget->container_id) { // if ($widget->container_id) {
$code .= ' id="' . e($widget->container_id) . '"'; // $code .= ' id="' . e($widget->container_id) . '"';
} // }
$code .= '>'; // $code .= '>';
$menuItems = [];
foreach ($links as $pageId => $link) { foreach ($links as $pageId => $link) {
if (!isset($pages[$pageId])) { if (!isset($pages[$pageId])) {
continue; continue;
@@ -57,16 +64,22 @@ class Menu implements WidgetRenderer
$active = ($page->isHomepage && $routeName == 'page.index') || ($routeName == 'page.content' && isset($parameters['url']) && $parameters['url'] == $page->url); $active = ($page->isHomepage && $routeName == 'page.index') || ($routeName == 'page.content' && isset($parameters['url']) && $parameters['url'] == $page->url);
$route = $page->isHomepage ? route('page.index') : route('page.content', ['url' => $page->url]); $route = $page->isHomepage ? route('page.index') : route('page.content', ['url' => $page->url]);
$code .= '<li'; $menuItems[] = compact('page', 'active', 'route');
if ($active) {
$code .= ' class="is-active active"';
}
$code .= '><a href="' . $route . '">' . e($page->title) . '</a></li>';
}
$code .= "</ul>"; // $code .= '<li';
// if ($active) {
// $code .= ' class="is-active active"';
}
// $code .= '><a href="' . $route . '">' . e($page->title) . '</a></li>';
// }
return $code; // $code .= "</ul>";
return view(self::$template, [
'containerClass' => $widget->container_class,
'containerId' => $widget->container_id,
'menuItems' => $menuItems
]);
} }
/** /**
@@ -67,6 +67,8 @@ class InstallModule extends Command
Cache::forget('enabled-modules'); Cache::forget('enabled-modules');
Cache::forget('module-handler-to-id-enumeration'); Cache::forget('module-handler-to-id-enumeration');
exec('php artisan module:enable '.$name);
exec('php artisan cache:clear');
exec('composer dump-autoload'); exec('composer dump-autoload');
// inform user // inform user
+1 -1
View File
@@ -74,7 +74,7 @@ class SetTemplate extends Command
// run again artisan for publishing resources // run again artisan for publishing resources
// it cannot be done using $this->call, because we need to load different template into service providers // it cannot be done using $this->call, because we need to load different template into service providers
if ($publish) { if ($publish) {
exec('php artisan vendor:publish'); exec('php artisan template:publish');
} }
} }
} }
@@ -35,7 +35,7 @@ class UploadedFilesOverview extends Controller
// include hidden directories? // include hidden directories?
$subdirectories = $this->directoryRepository->getAllSubdirectories($directory); $subdirectories = $this->directoryRepository->getAllSubdirectories($directory);
if (!Input::get('hidden', true)) { if (!Input::get('hidden', false)) {
$subdirectories = $subdirectories->where('hidden', false); $subdirectories = $subdirectories->where('hidden', false);
} }
+1 -1
View File
@@ -5,7 +5,7 @@
"dependencies": { "dependencies": {
"animate.css": "~3.4.0", "animate.css": "~3.4.0",
"bootstrap": "v4.0.0-alpha.5", "bootstrap": "v4.0.0-alpha.5",
"font-awesome": "~4.5.0", "font-awesome": "~4.7.0",
"jquery": "~3.2.1", "jquery": "~3.2.1",
"metisMenu": "~2.0.3", "metisMenu": "~2.0.3",
"nprogress": "~0.2.0", "nprogress": "~0.2.0",
+1 -3
View File
@@ -3,11 +3,9 @@
return [ return [
'styles' => [ 'styles' => [
'foundation-drilldown' => App\CMS\MenuPresenters\FoundationDrilldownMenuPresenter::class,
'foundation-dropdown' => App\CMS\MenuPresenters\FoundationDropdownMenuPresenter::class,
'foundation-dropdown-initialized' => App\CMS\MenuPresenters\FoundationInitializedDropdownMenuPresenter::class,
'metismenu' => App\CMS\MenuPresenters\MetismenuPresenter::class, 'metismenu' => App\CMS\MenuPresenters\MetismenuPresenter::class,
'profile-menu' => App\CMS\MenuPresenters\ProfileMenuPresenter::class, 'profile-menu' => App\CMS\MenuPresenters\ProfileMenuPresenter::class,
'top-menu' => \App\CMS\MenuPresenters\TopMenuPresenter::class
], ],
'ordering' => true, 'ordering' => true,
+3
View File
@@ -26,13 +26,16 @@ elixir (function (mix) {
'tinycolor/dist/tinycolor-min.js', 'tinycolor/dist/tinycolor-min.js',
'chart.js/dist/Chart.bundle.min.js', 'chart.js/dist/Chart.bundle.min.js',
'jquery.are-you-sure/jquery.are-you-sure.js', 'jquery.are-you-sure/jquery.are-you-sure.js',
'../node_modules/bootstrap-datepicker/dist/js/bootstrap-datepicker.js',
'../resources/assets/admin/js/*.js', '../resources/assets/admin/js/*.js',
], 'public/js/vendor.js', 'bower_components') ], 'public/js/vendor.js', 'bower_components')
.copy ('bower_components/font-awesome/css/font-awesome.min.css', 'public/css') .copy ('bower_components/font-awesome/css/font-awesome.min.css', 'public/css')
.copy ('node_modules/bootstrap-datepicker/dist/css/bootstrap-datepicker.css', 'public/css')
.copy ('bower_components/font-awesome/fonts', 'public/fonts') .copy ('bower_components/font-awesome/fonts', 'public/fonts')
.sass (['bootstrap/bootstrap.scss'], 'public/css/admin/bootstrap.css') .sass (['bootstrap/bootstrap.scss'], 'public/css/admin/bootstrap.css')
.styles ([ .styles ([
'../../../public/css/admin/bootstrap.css', '../../../public/css/admin/bootstrap.css',
'../../../public/css/bootstrap-datepicker.css',
'../../../bower_components/animate.css/animate.css', '../../../bower_components/animate.css/animate.css',
], 'public/css/admin/style.css') ], 'public/css/admin/style.css')
.remove ('public/css/admin/theme.scss'); .remove ('public/css/admin/theme.scss');
+15 -8
View File
@@ -152,6 +152,14 @@
"inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz" "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz"
} }
}, },
"bootstrap-datepicker": {
"version": "1.7.1",
"resolved": "https://registry.npmjs.org/bootstrap-datepicker/-/bootstrap-datepicker-1.7.1.tgz",
"integrity": "sha1-Tuf680iI2+x4NPv52+fEJ34B3a8=",
"requires": {
"jquery": "3.2.1"
}
},
"bower": { "bower": {
"version": "1.8.0", "version": "1.8.0",
"resolved": "https://registry.npmjs.org/bower/-/bower-1.8.0.tgz", "resolved": "https://registry.npmjs.org/bower/-/bower-1.8.0.tgz",
@@ -1761,8 +1769,7 @@
"jquery": { "jquery": {
"version": "3.2.1", "version": "3.2.1",
"resolved": "https://registry.npmjs.org/jquery/-/jquery-3.2.1.tgz", "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.2.1.tgz",
"integrity": "sha1-XE2d5lKvbNCncBVKYxu6ErAVx4c=", "integrity": "sha1-XE2d5lKvbNCncBVKYxu6ErAVx4c="
"dev": true
}, },
"json-stable-stringify": { "json-stable-stringify": {
"version": "1.0.1", "version": "1.0.1",
@@ -5129,12 +5136,6 @@
"integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=", "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=",
"dev": true "dev": true
}, },
"string_decoder": {
"version": "0.10.31",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
"integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
"dev": true
},
"string-width": { "string-width": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
@@ -5146,6 +5147,12 @@
"strip-ansi": "3.0.1" "strip-ansi": "3.0.1"
} }
}, },
"string_decoder": {
"version": "0.10.31",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
"integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
"dev": true
},
"stringstream": { "stringstream": {
"version": "0.0.5", "version": "0.0.5",
"resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz",
+1
View File
@@ -12,6 +12,7 @@
"lodash": "^4.16.2" "lodash": "^4.16.2"
}, },
"dependencies": { "dependencies": {
"bootstrap-datepicker": "^1.7.1",
"laravel-elixir-remove": "^0.2.1" "laravel-elixir-remove": "^0.2.1"
} }
} }
@@ -0,0 +1,46 @@
<html>
<head>
<meta charset="utf-8">
<script src="multiselectcomponent.js"></script>
</head>
<body>
<div style="width: 50%; float: left;" id="left"></div>
<div style="width: 50%; float: right;" id="right"></div>
<script type="application/javascript">
// Sample data.
var data1 = [
{id: 1, name: 'Peter', surname: 'Hrdlica'},
{id: 6, name: 'Vojtěch', surname: 'Hrdlica'},
{id: 2, name: 'Michal', surname: 'Kváček'},
{id: 19, name: 'Miček', surname: 'Je kokot!'},
{id: 13, name: 'Mirek', surname: 'Mráček'},
{id: 11, name: 'Naděžda', surname: 'Zímová'}
];
var data2 = [
{id: 2, name: 'wanna', surname: 'know'},
{id: 6, name: 'Batman', surname: 'insulted'},
{id: 58, name: 'scream', surname: 'pushed'},
{id: 19, name: 'Mob', surname: 'why'},
{id: 63, name: 'eight', surname: 'begin'},
{id: 4, name: 'you', surname: 'emotions'}
];
data1.sort(function(a, b) { return a.id > b.id; }); // Sort by ID, lowest first.
data2.sort(function(a, b) { return a.id > b.id; }); // Sort by ID, lowest first.
// Js component instance
var mscL = new MultiSelectComponent('contacts', data1, 'id', function(item) { return item.name + ' ' + item.surname; });
var mscR = new MultiSelectComponent('users', data2, 'id', function(item) { return item.name + ' ' + item.surname; });
// Generated data added to template
var left = document.getElementById('left');
var right = document.getElementById('right');
left.innerHTML = mscL.createTemplate();
right.innerHTML = mscR.createTemplate();
// Initialization. May be done in more elegant way if the template is created ie. on server.
mscL.init();
mscR.init();
</script>
</body>
</html>
@@ -0,0 +1,121 @@
/**
* Multi-select component
*
* @param identifier Identifier parameter that makes each instance unique and is used in DOM datasets used by this component.
* @param data Data (array of objects)
* @param field Field parameter that will be send as list with form
* @param itemString String that should be shown as selector in select and a item label in item list
*/
function MultiSelectComponent(identifier, data, field, itemString) {
// Private variables
var selectBox, addButton, itemHolder;
/**
* This is the method that generates template for multiselect component.
* This method is easily rewriteable into PHP.
* It is necessary to keep html datasets with prefix data-ms- intact for the javascript component to work.
* ECMAScript 5 version, does not need any compilers, nor jQuery or other framework.
* This method is not required to stay inside the MultiSelectComponent and may be rendered in any way;
*
* identifier is inherited from the instance creation.
* data is inherited from the instance creation.
* field is inherited from the instance creation.
* itemString is inherited from the instance creation.
*
*/
function createTemplate () {
var html = '<select data-ms-select="'+identifier+'">';
for(var idx in data) {
if(data.hasOwnProperty(idx)) {
html += '<option value="'+data[idx][field]+'">'+itemString(data[idx])+'</value>' //createSelectOption(data[idx]);
}
}
return html += '</select><input type="button" data-ms-add="'+identifier+'" value="add"><div data-ms-list="'+identifier+'"></div>';
}
/**
* This method creates an item list item that works as visual representation of selected values.
*/
function createItemListItem (value) {
return html = '<span>'+itemString(getDataItem(value))+
' <span data-ms-remove="'+identifier+'" data-ms-value="'+value+'">x</span>'+
'<input style="display: none" type="checkbox" value="'+value+'" name="'+identifier+'[]" checked>'+
'</span>';
}
/**
* Returns a requested data item that matches <field> (class instance variable field) value of passed value.
*/
function getDataItem (value) {
for(var idx in data) {
if(data.hasOwnProperty(idx)){
if(data[idx][field] == value){
return data[idx];
}
}
}
}
/**
* By selecting an item, that item is removed from list of available items and is added to list of selected items.
* If no more items are available for adding, add button and selectbox are disabled and list gets an informative item.
*/
function selectItem (value) {
selectBox.removeChild(selectBox.querySelector('option[value="' + value + '"]'));
itemHolder.innerHTML += createItemListItem(value);
if(selectBox.children.length === 0) {
selectBox.options.add(new Option('no more items to add', 0));
addButton.setAttribute('disabled', 'disabled');
selectBox.setAttribute('disabled', 'disabled');
}
}
/**
* By deselecting (removing) an item, that item is removed from selected list and added again into select box of available items;
* If add button was disabled (mostly because of no selectable items in list) it and the selectbox are now re-enabled and informative item is removed.
*/
function deselectItem (element) {
var id = element.getAttribute('data-ms-value');
selectBox.options.add(new Option(itemString(getDataItem(id)), id));
itemHolder.removeChild(element.parentNode);
if(addButton.getAttribute('disabled')) {
selectBox.options.remove(0);
addButton.removeAttribute('disabled');
selectBox.removeAttribute('disabled');
}
}
/**
* Initializes javascript part of the component.
*/
function init () {
// Cached elements only for JS to be a little more optimized.
selectBox = document.querySelector('[data-ms-select="'+identifier+'"]');
addButton = document.querySelector('[data-ms-add="'+identifier+'"]');
itemHolder = document.querySelector('[data-ms-list="'+identifier+'"]');
// Add button
addButton.addEventListener('click', function() {
selectItem(selectBox.value);
});
// Remove item button
itemHolder.addEventListener('click', function(e) {
if(e.target.getAttribute('data-ms-remove')) {
deselectItem(e.target);
}
})
}
// Publicly exposed static methods and variables.
return {
init: init,
createTemplate: createTemplate
};
}
+17 -1
View File
@@ -18,6 +18,11 @@ a:focus {
opacity: .7; opacity: .7;
} }
.collapse.in {
margin-bottom: 20px !important;
border-bottom: solid 2px !important;
}
.nav.nav-tabs-bordered + .tab-content { .nav.nav-tabs-bordered + .tab-content {
padding-bottom: 20px !important; padding-bottom: 20px !important;
} }
@@ -324,7 +329,7 @@ img {
.card.file-preview .card-block { .card.file-preview .card-block {
padding: 0; padding: 0;
height: 6em; height: 9em;
overflow: hidden; overflow: hidden;
} }
@@ -422,3 +427,14 @@ img {
padding-left: 35px; padding-left: 35px;
} }
.nav-profile .dropdown-menu > li {
width: 100%;
padding: 3px 1.5rem;
clear: both;
font-weight: normal;
color: #373a3c;
text-align: inherit;
white-space: nowrap;
background: none;
border: 0;
}
+4
View File
@@ -20,6 +20,10 @@ $ (document).ready (function () {
$ ('form').areYouSure (); $ ('form').areYouSure ();
}); });
$ ('.date').datepicker ({
format: 'dd. mm. yyyy'
});
$ ('.checkbox').change (function () { $ ('.checkbox').change (function () {
var e = $ (this); var e = $ (this);
var checked = e.is (':checked'); var checked = e.is (':checked');
@@ -49,11 +49,6 @@
********************************************** */ ********************************************** */
.item-list { .item-list {
.subpage {
padding-left: 35px;
}
.thumbnail { .thumbnail {
width: 100%; width: 100%;
height: 80px; height: 80px;
+4
View File
@@ -16,6 +16,10 @@ body {
overflow-x: hidden; overflow-x: hidden;
} }
.p-l-25 {
padding-left: 25px;
}
.main-wrapper { .main-wrapper {
width: 100%; width: 100%;
position: absolute; position: absolute;
@@ -1,24 +1,21 @@
<div class="{{$page->parentId ? 'p-l-25' : ''}}">
<div data-id="{{$page->id}}" class="row p-tb-15 parent-page-{{$page->parentId or 'none'}} {{$extraClass or ''}}"> <div data-id="{{$page->id}}" class="row p-tb-15 parent-page-{{$page->parentId or 'none'}} {{$extraClass or ''}}">
<div class="col-md-1 hidden-sm-down text-center with-placeholder"> <div class="col-md-1 hidden-sm-down text-center with-placeholder">
@can('update', $page) @can('update', $page)
<a href="{{route('content.edit', ['page' => $page])}}"> <a href="{{route('content.edit', ['page' => $page])}}">
@if(!view()->exists(template_name($page->template, false))) @if(!view()->exists(template_name($page->template, false)))
<i class="fa fa-2x text-warning fa-warning" data-toggle="tooltip" <i class="fa fa-2x text-warning fa-warning" data-toggle="tooltip" title="@lang('admin/contents.invalidTemplateSelected')"></i>
title="@lang('admin/contents.invalidTemplateSelected')"></i>
@else @else
@if(!empty($page->titlePhoto)) @if(!empty($page->titlePhoto))
<div class="thumbnail" style="background-image: url(@thumbnail($page->titlePhoto))"></div> <div class="thumbnail" style="background-image: url(@thumbnail($page->titlePhoto))"></div>
@else @else
<img src="{{asset('resources/assets/admin/img/placeholder.png')}}" <img src="{{asset('resources/assets/admin/img/placeholder.png')}}" class="placeholder" alt="{{$page->title}}" />
class="placeholder"
alt="{{$page->title}}" />
@endif @endif
@endif @endif
</a> </a>
@else @else
@if(!empty($page->titlePhoto)) @if(!empty($page->titlePhoto))
<img src="@thumbnail($page->titlePhoto)" class="placeholder" <img src="@thumbnail($page->titlePhoto)" class="placeholder" alt="{{$page->title}}" />
alt="{{$page->title}}" />
@endif @endif
@endcan @endcan
</div> </div>
@@ -31,9 +28,11 @@
{{$page->title}} {{$page->title}}
@endcan @endcan
@if ($page->subpages->count() > 0)
&nbsp;({{$page->subpages->count()}})
@endif
@if($page->isHomepage) <span @if($page->isHomepage) <span class="m-l-10 tag tag-primary">@lang('admin/contents.homepage')</span> @endif
class="m-l-10 tag tag-primary">@lang('admin/contents.homepage')</span> @endif
</div> </div>
<div class="col-lg-2 col-md-3 hidden-sm-down"> <div class="col-lg-2 col-md-3 hidden-sm-down">
<span class="tag @if($page->isPublic()) tag-success <span class="tag @if($page->isPublic()) tag-success
@@ -45,7 +44,9 @@
@lang($page->module->name) @lang($page->module->name)
</a> </a>
<br> <br>
@if(!is_null($page->templateModel))
<small>({{$page->templateModel->name}})</small> <small>({{$page->templateModel->name}})</small>
@endif
</div> </div>
<div class="col-lg-2 hidden-md-down">@date($page->created_at)</div> <div class="col-lg-2 hidden-md-down">@date($page->created_at)</div>
<div class="col-xs-2 col-lg-1 text-center"> <div class="col-xs-2 col-lg-1 text-center">
@@ -64,9 +65,7 @@
@if(!$page->isHomepage) @if(!$page->isHomepage)
@can('set-homepage', $page) @can('set-homepage', $page)
<li> <li>
<a href="{{route('content.setHomepage', ['page' => $page])}}" <a href="{{route('content.setHomepage', ['page' => $page])}}" data-toggle="tooltip" title="@lang('admin/contents.setHomepage')">
data-toggle="tooltip"
title="@lang('admin/contents.setHomepage')">
<i class="fa fa-home"></i> <i class="fa fa-home"></i>
</a> </a>
</li> </li>
@@ -75,8 +74,7 @@
@can('update', $page) @can('update', $page)
<li> <li>
<a class="edit" href="{{route('content.edit', ['page' => $page])}}" <a class="edit" href="{{route('content.edit', ['page' => $page])}}" data-toggle="tooltip" title="@lang('admin/contents.editPlain')">
data-toggle="tooltip" title="@lang('admin/contents.editPlain')">
<i class="fa fa-pencil"></i> <i class="fa fa-pencil"></i>
</a> </a>
</li> </li>
@@ -85,35 +83,26 @@
@if($page->isDraft()) @if($page->isDraft())
@can('publish', $page) @can('publish', $page)
<li> <li>
<a href="{{route('content.changeStatus', ['page' => $page, 'status' => 'public'])}}" <a href="{{route('content.changeStatus', ['page' => $page, 'status' => 'public'])}}" class="confirm" data-toggle="tooltip" title="@lang('admin/contents.makePublic')">
class="confirm" data-toggle="tooltip"
title="@lang('admin/contents.makePublic')">
<i class="fa fa-eye"></i> <i class="fa fa-eye"></i>
</a> </a>
</li> </li>
@endcan @endcan
@can('protect', $page) @can('protect', $page)
<li> <li>
<a href="{{route('content.changeStatus', ['page' => $page, 'status' => 'protected'])}}" <a href="{{route('content.changeStatus', ['page' => $page, 'status' => 'protected'])}}" class="confirm" data-toggle="tooltip" title="@lang('admin/contents.makeProtected')">
class="confirm" data-toggle="tooltip"
title="@lang('admin/contents.makeProtected')">
<i class="fa fa-lock"></i> <i class="fa fa-lock"></i>
</a> </a>
</li> </li>
@endcan @endcan
@else @else
<li> <li>
<a href="{{route('page.content', ['url' => $page->url])}}" <a href="{{route('page.content', ['url' => $page->url])}}" target="_blank" data-toggle="tooltip" title="@lang('admin/contents.viewPage')" class="button tiny secondary"><i class="fa fa-globe"></i>
target="_blank"
data-toggle="tooltip" title="@lang('admin/contents.viewPage')"
class="button tiny secondary"><i class="fa fa-globe"></i>
</a> </a>
</li> </li>
@can('draft', $page) @can('draft', $page)
<li> <li>
<a href="{{route('content.changeStatus', ['page' => $page, 'status' => 'draft'])}}" <a href="{{route('content.changeStatus', ['page' => $page, 'status' => 'draft'])}}" class="button tiny warning confirm" data-toggle="tooltip" title="@lang('admin/contents.makeDraft')">
class="button tiny warning confirm" data-toggle="tooltip"
title="@lang('admin/contents.makeDraft')">
<i class="fa fa-eye-slash"></i> <i class="fa fa-eye-slash"></i>
</a> </a>
</li> </li>
@@ -122,10 +111,7 @@
@can('delete', $page) @can('delete', $page)
<li> <li>
<a href="{{route('content.delete', ['page' => $page])}}" <a href="{{route('content.delete', ['page' => $page])}}" class="button tiny alert remove confirm" data-toggle="tooltip" title="@lang('admin/contents.deletePage')"><i class="fa fa-trash-o"></i>
class="button tiny alert remove confirm" data-toggle="tooltip"
title="@lang('admin/contents.deletePage')"><i
class="fa fa-trash-o"></i>
</a> </a>
</li> </li>
@endcan @endcan
@@ -135,3 +121,9 @@
</div> </div>
</div> </div>
</div> </div>
@foreach($page->subpages as $s)
@include('admin.content._partials.overviewRow', ['page' => $s, 'extraClass' => $s->subpages->isEmpty() ? 'subpage hidden-xs-up' : 'subpage hidden-xs-up has-subpages'])
@endforeach
</div>
@@ -0,0 +1,8 @@
<option value="{{$optionPage->id}}"
@if(old('parentId', $page->parentId) == $optionPage->id) selected @endif>
{{$prefix}} {{$optionPage->title}}
</option>
@foreach($optionPage->subpages as $subpage)
@include('admin.content._partials.subpages', ['optionPage' => $subpage, 'prefix' => $prefix.' - '])
@endforeach
@@ -43,10 +43,7 @@
<option value="">@lang('admin/contents.noParentPage')</option> <option value="">@lang('admin/contents.noParentPage')</option>
@foreach($rootPages as $rootPage) @foreach($rootPages as $rootPage)
<option value="{{$rootPage->id}}" @include('admin.content._partials.subpages', ['optionPage' => $rootPage, 'prefix' => ''])
@if(old('parentId', $page->parentId) == $rootPage->id) selected @endif>
{{$rootPage->title}}
</option>
@endforeach @endforeach
</select> </select>
@@ -51,10 +51,6 @@
</div> </div>
@foreach($pages as $page) @foreach($pages as $page)
@include('admin.content._partials.overviewRow', ['extraClass' => $page->subpages->isEmpty() ?: 'has-subpages']) @include('admin.content._partials.overviewRow', ['extraClass' => $page->subpages->isEmpty() ?: 'has-subpages'])
@foreach($page->subpages as $subpage)
@include('admin.content._partials.overviewRow', ['page' => $subpage, 'extraClass' => 'subpage hidden-xs-up'])
@endforeach
@endforeach @endforeach
</div> </div>
</div> </div>
@@ -1,5 +1,5 @@
@forelse($files as $file) @forelse($files as $file)
<div class="col-sm-4 col-md-3 text-center"> <div class="{{$responsiveClass or 'col-sm-4 col-md-3'}} text-center">
@include('admin.snippets.card', [ @include('admin.snippets.card', [
'body' => '<a href="'.route('upload.detail', ['id' => $file->id]).'">'.\App\CMS\Helpers\FileManager::getPreview($file).'</a>', 'body' => '<a href="'.route('upload.detail', ['id' => $file->id]).'">'.\App\CMS\Helpers\FileManager::getPreview($file).'</a>',
'footerClass' => 'text-right', 'footerClass' => 'text-right',
@@ -22,29 +22,11 @@
</div> </div>
<div class="header-block header-block-nav"> <div class="header-block header-block-nav">
<ul class="nav-profile">
@if(count(LaravelLocalization::getSupportedLocales()) > 1)
<li class="profile dropdown">
<a class="nav-link dropdown-toggle" data-toggle="dropdown" href="#" role="button"
aria-haspopup="true" aria-expanded="false">
@lang(LaravelLocalization::getCurrentLocaleName())
</a>
<div class="dropdown-menu">
@foreach(LaravelLocalization::getSupportedLocales() as $localeCode => $properties)
<a hreflang="{{$localeCode}}"
href="{{LaravelLocalization::getLocalizedURL($localeCode) }}"
class="dropdown-item">
{{ $properties['native'] }}
</a>
@endforeach
</div>
</li>
@endif
<li class="profile">
<a href="{{route('page.index')}}" target="_blank" class="nav-link" data-toggle="tooltip" <ul class="nav-profile">
data-placement="bottom" title="@lang('common.goToWeb')"><i class="fa fa-fw fa-globe"></i></a>
</li> {!! Menu::render('topMenu', 'top-menu') !!}
<li class="profile dropdown"> <li class="profile dropdown">
@@ -1,4 +1,7 @@
@if (!defined('CK_EDITOR_INITIALIZED'))
<script src="{{asset('/resources/assets/js/vendor/ckeditor/ckeditor.js')}}"></script> <script src="{{asset('/resources/assets/js/vendor/ckeditor/ckeditor.js')}}"></script>
@php define('CK_EDITOR_INITIALIZED', true) @endphp
@endif
<script type="application/javascript"> <script type="application/javascript">
CKEDITOR.on ('instanceCreated', function (e) { CKEDITOR.on ('instanceCreated', function (e) {
@@ -19,10 +22,11 @@
basicEntities: false, basicEntities: false,
entities_greek: false, entities_greek: false,
entities_latin: false, entities_latin: false,
height: 550, height: {{$height or 550}},
removePlugins: 'about,scayt', //elementspath removePlugins: 'about,scayt', //elementspath
extraPlugins: 'justify', extraPlugins: 'justify',
enterMode: CKEDITOR.ENTER_P, enterMode: CKEDITOR.ENTER_P,
@if (!isset($simpleEditor))
toolbarGroups: [ toolbarGroups: [
{name: 'undo', groups: ['undo']}, {name: 'undo', groups: ['undo']},
{name: 'styles'}, {name: 'styles'},
@@ -35,5 +39,11 @@
{name: 'document', groups: ['mode', 'document', 'doctools']}, {name: 'document', groups: ['mode', 'document', 'doctools']},
{name: 'tools'} {name: 'tools'}
] ]
@else
toolbarGroups: [
{name: 'undo', groups: ['undo']},
{name: 'basicstyles', groups: ['basicstyles', 'cleanup']},
]
@endif
}); });
</script> </script>
+2 -2
View File
@@ -17,9 +17,9 @@ Route::group([
], function () { ], function () {
// include all routes in routes/admin subfolder // include all routes in routes/admin subfolder
$files = File::allFiles('routes/admin'); $files = File::allFiles(base_path('routes/admin'));
foreach ($files as $file) { foreach ($files as $file) {
require_once base_path($file); require_once $file;
} }
// display dashboard with some usefull information // display dashboard with some usefull information
@@ -1,32 +0,0 @@
<?php
namespace Templates\PragueTennisCamp\Providers;
use App\CMS\Helpers\Template;
use Modules\ContactForm\Widgets\Form\Presenter;
use Templates\PragueTennisCamp\Pipeline\AddHotelsCategory;
use Templates\PragueTennisCamp\Pipeline\AddTraineeTeamCategory;
class ServiceProvider extends \Illuminate\Support\ServiceProvider
{
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
}
public function boot()
{
if (\App::runningInConsole()) {
return;
}
Presenter::$template = Template::name('widgets.contact.form');
$pipeline = app('displayPipeline');
$pipeline->add(AddTraineeTeamCategory::class);
$pipeline->add(AddHotelsCategory::class);
}
}