1
0
mirror of https://github.com/processwire/processwire.git synced 2025-08-13 02:04:35 +02:00

Version 3.0.78 has updates primarily specific to enabling more customization from admin themes. In this case, AdminThemeUikit, but applies to any admin theme.

This commit is contained in:
Ryan Cramer
2017-10-06 09:33:39 -04:00
parent 5a39c9efc9
commit df17b337fd
13 changed files with 177 additions and 51 deletions

View File

@@ -98,6 +98,8 @@ abstract class AdminTheme extends WireData implements Module {
* Initialize the admin theme systme and determine which admin theme should be used * Initialize the admin theme systme and determine which admin theme should be used
* *
* All admin themes must call this init() method to register themselves. * All admin themes must call this init() method to register themselves.
*
* Note: this should be called after API ready.
* *
*/ */
public function init() { public function init() {
@@ -116,6 +118,11 @@ abstract class AdminTheme extends WireData implements Module {
// if admin theme has already been set, then no need to continue // if admin theme has already been set, then no need to continue
if($this->wire('adminTheme')) return; if($this->wire('adminTheme')) return;
/** @var Config $config */
$config = $this->wire('config');
/** @var Session $session */
$session = $this->wire('session');
/** @var string $adminTheme */
$adminTheme = $this->wire('user')->admin_theme; $adminTheme = $this->wire('user')->admin_theme;
if($adminTheme) { if($adminTheme) {
@@ -129,19 +136,20 @@ abstract class AdminTheme extends WireData implements Module {
} }
// adjust $config adminThumbOptions[scale] for auto detect when requested // adjust $config adminThumbOptions[scale] for auto detect when requested
$o = $this->wire('config')->adminThumbOptions; $o = $config->adminThumbOptions;
if($o && isset($o['scale']) && $o['scale'] === 1) { if($o && isset($o['scale']) && $o['scale'] === 1) {
$o['scale'] = $this->wire('session')->hidpi ? 0.5 : 1.0; $o['scale'] = $session->hidpi ? 0.5 : 1.0;
$this->wire('config')->adminThumbOptions = $o; $config->adminThumbOptions = $o;
} }
$this->config->js('modals', $this->config->modals); $config->js('modals', $config->modals);
if($session->hidpi) $this->addBodyClass('hidpi-device');
if($session->touch) $this->addBodyClass('touch-device');
if($this->wire('session')->hidpi) $this->addBodyClass('hidpi-device');
if($this->wire('session')->touch) $this->addBodyClass('touch-device');
$this->addBodyClass($this->className()); $this->addBodyClass($this->className());
} }
public function get($key) { public function get($key) {
if($key == 'version') return $this->version; if($key == 'version') return $this->version;
return parent::get($key); return parent::get($key);

View File

@@ -84,6 +84,8 @@ abstract class AdminThemeFramework extends AdminTheme {
/** /**
* Initialize and attach hooks * Initialize and attach hooks
*
* Note: descending classes should call this after API ready
* *
*/ */
public function init() { public function init() {
@@ -98,13 +100,32 @@ abstract class AdminThemeFramework extends AdminTheme {
$this->isLoggedIn = $user->isLoggedin(); $this->isLoggedIn = $user->isLoggedin();
$this->isSuperuser = $this->isLoggedIn && $user->isSuperuser(); $this->isSuperuser = $this->isLoggedIn && $user->isSuperuser();
$this->isEditor = $this->isLoggedIn && ($this->isSuperuser || $user->hasPermission('page-edit')); $this->isEditor = $this->isLoggedIn && ($this->isSuperuser || $user->hasPermission('page-edit'));
$this->includeInitFile();
$modal = $this->wire('input')->get('modal'); $modal = $this->wire('input')->get('modal');
if($modal) $this->isModal = $modal == 'inline' ? 'inline' : true; if($modal) $this->isModal = $modal == 'inline' ? 'inline' : true;
// test notices when requested // test notices when requested
if($this->wire('input')->get('test_notices')) $this->testNotices(); if($this->wire('input')->get('test_notices') && $this->isLoggedIn) $this->testNotices();
} }
/**
* Include the admin theme init file
*
*/
public function includeInitFile() {
$config = $this->wire('config');
$initFile = $config->paths->adminTemplates . 'init.php';
if(file_exists($initFile)) {
if(strpos($initFile, $config->paths->site) === 0) {
// admin themes in /site/modules/ may be compiled
$initFile = $this->wire('files')->compile($initFile);
}
/** @noinspection PhpIncludeInspection */
include_once($initFile);
}
}
/** /**
* Perform a translation, based on text from shared admin file: /wire/templates-admin/default.php * Perform a translation, based on text from shared admin file: /wire/templates-admin/default.php
@@ -584,10 +605,12 @@ abstract class AdminThemeFramework extends AdminTheme {
// if(!count($notices)) return ''; // if(!count($notices)) return '';
/*
if($this->isLoggedIn && $this->wire('modules')->isInstalled('SystemNotifications')) { if($this->isLoggedIn && $this->wire('modules')->isInstalled('SystemNotifications')) {
$systemNotifications = $this->wire('modules')->get('SystemNotifications'); $systemNotifications = $this->wire('modules')->get('SystemNotifications');
if(!$systemNotifications->placement) return ''; if(!$systemNotifications->placement) return '';
} }
*/
$defaults = array( $defaults = array(
'messageClass' => 'NoticeMessage', // class for messages 'messageClass' => 'NoticeMessage', // class for messages

View File

@@ -742,8 +742,6 @@ class Modules extends WireArray {
/** /**
* Retrieve the installed module info as stored in the database * Retrieve the installed module info as stored in the database
* *
* @return array Indexed by module class name => array of module info
*
*/ */
protected function loadModulesTable() { protected function loadModulesTable() {
$database = $this->wire('database'); $database = $this->wire('database');
@@ -2648,8 +2646,11 @@ class Modules extends WireArray {
// if $info[requires] or $info[installs] isn't already an array, make it one // if $info[requires] or $info[installs] isn't already an array, make it one
if(!is_array($info['requires'])) { if(!is_array($info['requires'])) {
$info['requires'] = str_replace(' ', '', $info['requires']); // remove whitespace $info['requires'] = str_replace(' ', '', $info['requires']); // remove whitespace
if(strpos($info['requires'], ',') !== false) $info['requires'] = explode(',', $info['requires']); if(strpos($info['requires'], ',') !== false) {
else $info['requires'] = array($info['requires']); $info['requires'] = explode(',', $info['requires']);
} else {
$info['requires'] = array($info['requires']);
}
} }
// populate requiresVersions // populate requiresVersions
@@ -2669,8 +2670,11 @@ class Modules extends WireArray {
// what does it install? // what does it install?
if(!is_array($info['installs'])) { if(!is_array($info['installs'])) {
$info['installs'] = str_replace(' ', '', $info['installs']); // remove whitespace $info['installs'] = str_replace(' ', '', $info['installs']); // remove whitespace
if(strpos($info['installs'], ',') !== false) $info['installs'] = explode(',', $info['installs']); if(strpos($info['installs'], ',') !== false) {
else $info['installs'] = array($info['installs']); $info['installs'] = explode(',', $info['installs']);
} else {
$info['installs'] = array($info['installs']);
}
} }
// misc // misc

View File

@@ -45,7 +45,7 @@ class ProcessWire extends Wire {
* Reversion revision number * Reversion revision number
* *
*/ */
const versionRevision = 77; const versionRevision = 78;
/** /**
* Version suffix string (when applicable) * Version suffix string (when applicable)

View File

@@ -107,7 +107,7 @@ if($page->process && $page->process != 'ProcessPageView') {
$initFile = $wire->files->compile($initFile); $initFile = $wire->files->compile($initFile);
} }
/** @noinspection PhpIncludeInspection */ /** @noinspection PhpIncludeInspection */
include($initFile); include_once($initFile);
} }
if($input->get('modal')) $session->addHookBefore('redirect', null, '_hookSessionRedirectModal'); if($input->get('modal')) $session->addHookBefore('redirect', null, '_hookSessionRedirectModal');
$content = $controller->execute(); $content = $controller->execute();

View File

@@ -49,6 +49,9 @@
* @property string $subfieldIdentifier ... * @property string $subfieldIdentifier ...
* @property string $groupIdentifier (1) * @property string $groupIdentifier (1)
* @property int $maxUsers [20] Maximum number of users selectable. If more than regular text input used rather than select. * @property int $maxUsers [20] Maximum number of users selectable. If more than regular text input used rather than select.
* @property string $selectClass
* @property string $inputClass
* @property string $checkboxClass
* *
* *
*/ */
@@ -131,6 +134,13 @@ class InputfieldSelector extends Inputfield implements ConfigurableModule {
*/ */
protected $initTemplate = null; protected $initTemplate = null;
/**
* Has the ready method been called?
* @var bool
*
*/
protected $isReady = false;
/** /**
* Variable names that should be picked up through the session each time * Variable names that should be picked up through the session each time
* *
@@ -202,7 +212,7 @@ class InputfieldSelector extends Inputfield implements ConfigurableModule {
$this->setting('timeFormat', $this->_('H:i')); // time format $this->setting('timeFormat', $this->_('H:i')); // time format
$this->setting('timePlaceholder', $this->_('hh:mm')); // time format placeholder (what users see) $this->setting('timePlaceholder', $this->_('hh:mm')); // time format placeholder (what users see)
$this->setting('maxUsers', 20); // text input rather than select used when useres qty is greater than this $this->setting('maxUsers', 20); // text input rather than select used when useres qty is greater than this
parent::__construct(); parent::__construct();
} }
@@ -247,6 +257,21 @@ class InputfieldSelector extends Inputfield implements ConfigurableModule {
* *
*/ */
public function ready() { public function ready() {
if($this->isReady) return;
$this->isReady = true;
// settings specified in $config->InputfieldSelector
$configDefaults = array(
'selectClass' => '',
'inputClass' => '',
'checkboxClass' => '',
);
$configSettings = $this->wire('config')->InputfieldSelector;
$configSettings = is_array($configSettings) ? array_merge($configDefaults, $configSettings) : $configDefaults;
foreach($configSettings as $key => $value) {
$this->setting($key, $value);
}
$input = $this->wire('input'); $input = $this->wire('input');
$name = $input->get('name'); $name = $input->get('name');
@@ -902,7 +927,8 @@ class InputfieldSelector extends Inputfield implements ConfigurableModule {
$outSections['adjust'] = "<option data-labels='$dataLabels' data-names='$dataNames' value='toggle-names-labels'>$dataDefault</option>"; $outSections['adjust'] = "<option data-labels='$dataLabels' data-names='$dataNames' value='toggle-names-labels'>$dataDefault</option>";
$inputName = $this->attr('name') . "__" . $settings['name'] . "[]"; $inputName = $this->attr('name') . "__" . $settings['name'] . "[]";
$out = "<select class='select-$settings[name]' name='$inputName' data-type='$settings[type]' data-selected='$selectedValue'><option></option>"; $selectClass = trim("$this->selectClass select-$settings[name]");
$out = "<select class='$selectClass' name='$inputName' data-type='$settings[type]' data-selected='$selectedValue'><option></option>";
if(!$this->showOptgroups) { if(!$this->showOptgroups) {
ksort($outAll); ksort($outAll);
@@ -1051,7 +1077,8 @@ class InputfieldSelector extends Inputfield implements ConfigurableModule {
} }
$disabled = count($operators) ? "" : " disabled='disabled'"; $disabled = count($operators) ? "" : " disabled='disabled'";
$out = "<select$disabled class='select-operator' name='$inputName'>"; $selectClass = trim("$this->selectClass select-operator");
$out = "<select$disabled class='$selectClass' name='$inputName'>";
foreach($operators as $key => $label) { foreach($operators as $key => $label) {
if(isset($this->operators[$label])) { if(isset($this->operators[$label])) {
@@ -1270,7 +1297,8 @@ class InputfieldSelector extends Inputfield implements ConfigurableModule {
if(in_array($type, array('select', 'page', 'checkbox'))) { if(in_array($type, array('select', 'page', 'checkbox'))) {
// render a <select> box for the value // render a <select> box for the value
$out .= "<select class='select-value input-value' name='$inputName'>"; $selectClass = trim("$this->selectClass select-value input-value");
$out .= "<select class='$selectClass' name='$inputName'>";
$out .= "<option value=''></option>"; $out .= "<option value=''></option>";
if($type != 'checkbox' && !isset($this->systemFields[$fieldName]) && !isset($this->modifierFields[$fieldName])) { if($type != 'checkbox' && !isset($this->systemFields[$fieldName]) && !isset($this->modifierFields[$fieldName])) {
@@ -1313,7 +1341,8 @@ class InputfieldSelector extends Inputfield implements ConfigurableModule {
} }
} }
$out .= "<input value='$selectedValueEntities' class='input-value' name='$inputName' type='hidden' />"; $out .= "<input value='$selectedValueEntities' class='input-value' name='$inputName' type='hidden' />";
$out .= "<input value='$selectedValueTitle' class='input-value-autocomplete' name='autocomplete_$inputName' placeholder='$placeholder' type='text' />"; $inputClass = trim("$this->inputClass input-value-autocomplete");
$out .= "<input value='$selectedValueTitle' class='$inputClass' name='autocomplete_$inputName' placeholder='$placeholder' type='text' />";
} else if($type == 'datetime' || $type == 'date') { } else if($type == 'datetime' || $type == 'date') {
// render date/datetime input // render date/datetime input
@@ -1324,7 +1353,7 @@ class InputfieldSelector extends Inputfield implements ConfigurableModule {
} else { } else {
// render other input that uses an <input type='text'> whether text, number or selector // render other input that uses an <input type='text'> whether text, number or selector
$inputType = $type; $inputType = $type;
$inputClass = "input-value input-value-$type"; $inputClass = trim("$this->inputClass input-value input-value-$type");
if($type == 'number' || $type == 'selector' || $fieldName == 'id' || $subfield == 'id') { if($type == 'number' || $type == 'selector' || $fieldName == 'id' || $subfield == 'id') {
// adding this class tells InputfieldSelector.js that selector strings are allowed for this input // adding this class tells InputfieldSelector.js that selector strings are allowed for this input
@@ -1338,7 +1367,8 @@ class InputfieldSelector extends Inputfield implements ConfigurableModule {
// end the opval row by rendering a checkbox for the OR option // end the opval row by rendering a checkbox for the OR option
$orLabel = $this->_('Check box to make this row OR rather than AND'); $orLabel = $this->_('Check box to make this row OR rather than AND');
$orChecked = $orChecked ? ' checked' : ''; $orChecked = $orChecked ? ' checked' : '';
$out .= "<input$orChecked class='input-or' type='checkbox' name='or_$inputName' value='1' title='$orLabel' />"; $checkboxClass = trim("$this->checkboxClass input-or");
$out .= "<input$orChecked class='$checkboxClass' type='checkbox' name='or_$inputName' value='1' title='$orLabel' />";
return $out; return $out;
} }
@@ -1409,7 +1439,8 @@ class InputfieldSelector extends Inputfield implements ConfigurableModule {
$inputName = $this->attr('name') . "__" . $field->name . "[]"; $inputName = $this->attr('name') . "__" . $field->name . "[]";
$outSub = ''; // subselector optgroup output $outSub = ''; // subselector optgroup output
$out = "<select class='select-subfield' name='$inputName' data-type='$selectorInfo[input]'>"; $selectClass = trim("$this->selectClass select-subfield");
$out = "<select class='$selectClass' name='$inputName' data-type='$selectorInfo[input]'>";
$out .= "<option></option>"; $out .= "<option></option>";
// determine if there is a current value string and if it contains a selector string // determine if there is a current value string and if it contains a selector string
@@ -1705,6 +1736,7 @@ class InputfieldSelector extends Inputfield implements ConfigurableModule {
* *
*/ */
public function ___render() { public function ___render() {
$this->ready();
// tell jQuery UI we want it to load the modal component which makes a.modal open modal windows // tell jQuery UI we want it to load the modal component which makes a.modal open modal windows
$this->wire('modules')->get('JqueryUI')->use('modal'); $this->wire('modules')->get('JqueryUI')->use('modal');

View File

@@ -123,6 +123,9 @@ $(document).ready(function() {
// milliseconds in fade time to reveal or hide hover actions // milliseconds in fade time to reveal or hide hover actions
hoverActionFade: 150, hoverActionFade: 150,
// show only edit and view actions, and make everything else extra actions
useNarrowActions: $('body').hasClass('pw-narrow-width'),
// markup for the spinner used when ajax calls are made // markup for the spinner used when ajax calls are made
spinnerMarkup: "<span class='PageListLoading'><i class='ui-priority-secondary fa fa-fw fa-spin fa-spinner'></i></span>", spinnerMarkup: "<span class='PageListLoading'><i class='ui-priority-secondary fa fa-fw fa-spin fa-spinner'></i></span>",
@@ -622,7 +625,8 @@ $(document).ready(function() {
function addClickEvents($ul) { function addClickEvents($ul) {
$("a.PageListPage", $ul).click(clickChild); $("a.PageListPage", $ul).click(clickChild);
$(".PageListActionMove a", $ul).click(clickMove); $ul.on('click', '.PageListActionMove a', clickMove);
// $(".PageListActionMove a", $ul).click(clickMove);
$(".PageListActionSelect a", $ul).click(clickSelect); $(".PageListActionSelect a", $ul).click(clickSelect);
$(".PageListTriggerOpen:not(.PageListID1) > a.PageListPage", $ul).click(); $(".PageListTriggerOpen:not(.PageListID1) > a.PageListPage", $ul).click();
$(".PageListActionExtras > a:not(.clickExtras)", $ul).addClass('clickExtras').on('click', clickExtras); $(".PageListActionExtras > a:not(.clickExtras)", $ul).addClass('clickExtras').on('click', clickExtras);
@@ -644,8 +648,8 @@ $(document).ready(function() {
.attr('title', child.path) .attr('title', child.path)
.html(child.label) .html(child.label)
.addClass('PageListPage label'); .addClass('PageListPage label');
$li.addClass('PageListID' + child.id); $li.addClass(child.numChildren > 0 ? 'PageListHasChildren' : 'PageListNoChildren').addClass('PageListID' + child.id);
if(child.status == 0) $li.addClass('PageListStatusOff disabled'); if(child.status == 0) $li.addClass('PageListStatusOff disabled');
if(child.status & 2048) $li.addClass('PageListStatusUnpublished secondary'); if(child.status & 2048) $li.addClass('PageListStatusUnpublished secondary');
if(child.status & 1024) $li.addClass('PageListStatusHidden secondary'); if(child.status & 1024) $li.addClass('PageListStatusHidden secondary');
@@ -676,13 +680,26 @@ $(document).ready(function() {
} }
var $lastAction = null; var $lastAction = null;
var $extrasLink = null; // link that toggles extra actions
var extras = {}; // extra actions
$(links).each(function(n, action) { $(links).each(function(n, action) {
var actionName; var actionName;
if(action.name == options.selectSelectLabel) actionName = 'Select'; if(action.name == options.selectSelectLabel) {
else if(action.name == options.selectUnselectLabel) actionName = 'Select'; actionName = 'Select';
else actionName = action.cn; // cn = className } else if(action.name == options.selectUnselectLabel) {
actionName = 'Select';
} else {
actionName = action.cn; // cn = className
if(options.useNarrowActions && (actionName != 'Edit' && actionName != 'View' && actionName != 'Extras')) {
// move non-edit/view actions to extras when in narrow mode
extras[actionName] = action;
return;
}
}
var $a = $("<a></a>").html(action.name).attr('href', action.url); var $a = $("<a></a>").html(action.name).attr('href', action.url);
if(!isModal) { if(!isModal) {
if(action.cn == 'Edit') { if(action.cn == 'Edit') {
$a.addClass('pw-modal pw-modal-large pw-modal-longclick'); $a.addClass('pw-modal pw-modal-large pw-modal-longclick');
@@ -691,13 +708,20 @@ $(document).ready(function() {
$a.addClass('pw-modal pw-modal-large pw-modal-longclick'); $a.addClass('pw-modal pw-modal-large pw-modal-longclick');
} }
} }
if(typeof action.extras != "undefined") { if(typeof action.extras != "undefined") {
$a.data('extras', action.extras); for(var key in action.extras) {
extras[key] = action.extras[key];
}
$extrasLink = $a;
} }
var $action = $("<li></li>").addClass('PageListAction' + actionName).append($a); var $action = $("<li></li>").addClass('PageListAction' + actionName).append($a);
if(actionName == 'Extras') $lastAction = $action; if(actionName == 'Extras') $lastAction = $action;
else $actions.append($action); else $actions.append($action);
}); });
if($extrasLink) $extrasLink.data('extras', extras);
if($lastAction) { if($lastAction) {
$actions.append($lastAction); $actions.append($lastAction);
$lastAction.addClass('ui-priority-secondary'); $lastAction.addClass('ui-priority-secondary');

File diff suppressed because one or more lines are too long

View File

@@ -18,10 +18,15 @@ class ProcessPageListActions extends Wire {
'unlock' => 'Unlock', 'unlock' => 'Unlock',
'trash' => 'Trash', 'trash' => 'Trash',
'restore' => 'Restore', 'restore' => 'Restore',
'extras' => "<i class='fa fa-angle-right'></i>",
); );
public function __construct() { public function __construct() {
$this->superuser = $this->wire('user')->isSuperuser(); $this->superuser = $this->wire('user')->isSuperuser();
$settings = $this->wire('config')->ProcessPageList;
if(is_array($settings) && isset($settings['extrasLabel'])) {
$this->actionLabels['extras'] = $settings['extrasLabel'];
}
} }
public function setActionLabels(array $actionLabels) { public function setActionLabels(array $actionLabels) {
@@ -81,7 +86,7 @@ class ProcessPageListActions extends Wire {
if(count($extras)) { if(count($extras)) {
$actions['extras'] = array( $actions['extras'] = array(
'cn' => 'Extras', 'cn' => 'Extras',
'name' => "<i class='fa fa-angle-right'></i>", 'name' => $this->actionLabels['extras'],
'url' => '#', 'url' => '#',
'extras' => $extras, 'extras' => $extras,
); );

View File

@@ -5,6 +5,12 @@
background-color: #fff; background-color: #fff;
} }
.NotificationList {
margin: 0;
padding: 0;
list-style: none;
}
.NotificationList li { .NotificationList li {
opacity: 0.95; opacity: 0.95;
} }
@@ -18,10 +24,11 @@
display: block; display: block;
border-right: none !important; border-right: none !important;
border-left: none !important; border-left: none !important;
border-bottom: 1px dotted rgba(255,255,255,0.5); border-bottom: 1px solid rgba(255,255,255,0.5);
border-top: none; border-top: none;
padding-top: 0.25em; padding-top: 0.25em;
padding-bottom: 0.25em; padding-bottom: 0.25em;
margin: 0;
} }
.NotificationTitle { .NotificationTitle {

View File

@@ -17,6 +17,13 @@ var Notifications = {
iconMessage: 'smile-o', iconMessage: 'smile-o',
iconWarning: 'meh-o', iconWarning: 'meh-o',
iconError: 'frown-o', iconError: 'frown-o',
iconRemove: 'times-circle',
classCommon: 'NoticeItem',
classMessage: 'NoticeMessage',
classWarning: 'NoticeWarning',
classError: 'NoticeError',
classDebug: 'NoticeDebug',
classContainer: 'container',
ghostDelay: 2000, ghostDelay: 2000,
ghostDelayError: 4000, ghostDelayError: 4000,
ghostFadeSpeed: 'fast', ghostFadeSpeed: 'fast',
@@ -273,11 +280,11 @@ var Notifications = {
} }
if(qtyError > 0) { if(qtyError > 0) {
$bug.addClass('NoticeError', 'slow').removeClass('NoticeWarning', 'slow'); $bug.addClass(Notifications.options.classError, 'slow').removeClass(Notifications.options.classWarning, 'slow');
} else if(qtyWarning > 0) { } else if(qtyWarning > 0) {
$bug.addClass('NoticeWarning', 'slow').removeClass('NoticeError', 'slow'); $bug.addClass(Notifications.options.classWarning, 'slow').removeClass(Notifications.options.classError, 'slow');
} else { } else {
$bug.removeClass('NoticeWarning NoticeError', 'slow'); $bug.removeClass(Notifications.options.classWarning + ' ' + Notifications.options.classError, 'slow');
} }
}, },
@@ -389,7 +396,7 @@ var Notifications = {
$li = $("<li></li>"); $li = $("<li></li>");
} }
$li.attr('id', notification.id); $li.attr('id', notification.id).addClass(Notifications.options.classCommon);
if(notification.expires > 0) { if(notification.expires > 0) {
$li.attr('data-expires', notification.expires); $li.attr('data-expires', notification.expires);
} }
@@ -397,9 +404,9 @@ var Notifications = {
var $icon = $("<i></i>").addClass('fa fa-fw fa-' + notification.icon); var $icon = $("<i></i>").addClass('fa fa-fw fa-' + notification.icon);
var $title = $("<span></span>").addClass('NotificationTitle').html(notification.title); var $title = $("<span></span>").addClass('NotificationTitle').html(notification.title);
var $p = $("<p></p>").append($title).prepend('&nbsp;').prepend($icon); var $p = $("<p></p>").append($title).prepend('&nbsp;').prepend($icon);
var $div = $("<div></div>").addClass('container').append($p); var $div = $("<div></div>").addClass(Notifications.options.classContainer).append($p);
var $text = $("<div></div>").addClass('NotificationText'); var $text = $("<div></div>").addClass('NotificationText');
var $rm = $("<i class='NotificationRemove fa fa-times-circle'></i>"); var $rm = $("<i class='NotificationRemove fa fa-" + Notifications.options.iconRemove + "'></i>");
var addClass = ''; var addClass = '';
if(progressNext > 0) { if(progressNext > 0) {
@@ -422,10 +429,10 @@ var Notifications = {
$title.append(" <small data-created='" + notification.created + "' class='created'>" + notification.when + "</small>"); $title.append(" <small data-created='" + notification.created + "' class='created'>" + notification.when + "</small>");
} }
if(notification.flagNames.indexOf('debug') != -1) $li.addClass('NoticeDebug'); if(notification.flagNames.indexOf('debug') != -1) $li.addClass(Notifications.options.classDebug);
if(notification.flagNames.indexOf('error') != -1) $li.addClass('NoticeError'); if(notification.flagNames.indexOf('error') != -1) $li.addClass(Notifications.options.classError);
else if(notification.flagNames.indexOf('warning') != -1) $li.addClass('NoticeWarning'); else if(notification.flagNames.indexOf('warning') != -1) $li.addClass(Notifications.options.classWarning);
else if(notification.flagNames.indexOf('message') != -1) $li.addClass('NoticeMessage'); else if(notification.flagNames.indexOf('message') != -1) $li.addClass(Notifications.options.classMessage);
if(notification.html.length > 0) { if(notification.html.length > 0) {
@@ -586,15 +593,15 @@ var Notifications = {
var delay = Notifications.options.ghostDelay; var delay = Notifications.options.ghostDelay;
if(notification.flagNames.indexOf('error') > -1) { if(notification.flagNames.indexOf('error') > -1) {
$ghost.addClass('NoticeError'); $ghost.addClass(Notifications.options.classError);
delay = Notifications.options.ghostDelayError; delay = Notifications.options.ghostDelayError;
} else if(notification.flagNames.indexOf('warning') > -1) { } else if(notification.flagNames.indexOf('warning') > -1) {
$ghost.addClass('NoticeWarning'); $ghost.addClass(Notifications.options.classWarning);
delay = Notifications.options.ghostDelayError; delay = Notifications.options.ghostDelayError;
} else { } else {
$ghost.addClass('NoticeMessage'); $ghost.addClass(Notifications.options.classMessage);
} }
Notifications.$ghosts.append($li.hide()); Notifications.$ghosts.append($li.hide());
@@ -766,6 +773,8 @@ var Notifications = {
Notifications.$bug = $("#NotificationBug"); Notifications.$bug = $("#NotificationBug");
Notifications.$list = $("#NotificationList"); Notifications.$list = $("#NotificationList");
Notifications.$ghosts = $("#NotificationGhosts"); Notifications.$ghosts = $("#NotificationGhosts");
if(!Notifications.$bug.length) return;
Notifications.$menu.hide(); Notifications.$menu.hide();
Notifications.$bug.click(Notifications.clickBug); Notifications.$bug.click(Notifications.clickBug);

File diff suppressed because one or more lines are too long

View File

@@ -67,6 +67,7 @@ class SystemNotifications extends WireData implements Module {
// hook method to access notifications, in case field name ever needs to change for some reason // hook method to access notifications, in case field name ever needs to change for some reason
$this->addHook('User::notifications', $this, 'hookUserNotifications'); $this->addHook('User::notifications', $this, 'hookUserNotifications');
$this->set('disabled', false);
} }
/** /**
@@ -291,6 +292,8 @@ class SystemNotifications extends WireData implements Module {
* *
*/ */
public function hookAdminThemeGetExtraMarkup($event) { public function hookAdminThemeGetExtraMarkup($event) {
if($this->disabled) return;
$config = $this->wire('config'); $config = $this->wire('config');
$url = $config->urls->SystemNotifications . 'Notifications'; $url = $config->urls->SystemNotifications . 'Notifications';
@@ -326,6 +329,17 @@ class SystemNotifications extends WireData implements Module {
} }
$options['reverse'] = (bool) ((int) $options['reverse']); $options['reverse'] = (bool) ((int) $options['reverse']);
// options specified in $config->SystemNotifications
$configDefaults = array(
'classMessage' => 'NoticeMessage',
'classWarning' => 'NoticeWarning',
'classError' => 'NoticeError',
'classContainer' => 'container',
);
$configOptions = $this->wire('config')->SystemNotifications;
if(!is_array($configOptions)) $configOptions = array();
$options = array_merge($options, $configDefaults, $configOptions);
$textdomain = '/wire/core/Functions.php'; $textdomain = '/wire/core/Functions.php';
$options['i18n'] = array( $options['i18n'] = array(
'sec' => __('sec', $textdomain), 'sec' => __('sec', $textdomain),
@@ -436,7 +450,7 @@ class SystemNotifications extends WireData implements Module {
$extras = $event->return; $extras = $event->return;
$extras['body'] .= $out; $extras['body'] .= $out;
$extras['masthead'] .= $extras['masthead'] .=
"<div id='NotificationBug' class='NotificationBug qty$qty' data-qty='$qty'>" . "<div id='NotificationBug' class='NotificationBug qty$qty' data-qty='$qty'>" .
"<span class='qty fa fa-fw'>$qty</span>" . "<span class='qty fa fa-fw'>$qty</span>" .
"<i class='NotificationSpinner fa fa-fw fa-spin fa-spinner'></i>" . "<i class='NotificationSpinner fa fa-fw fa-spin fa-spinner'></i>" .