Adds a hint system to the backend
This commit is contained in:
parent
d23f42c5e1
commit
223f3025f0
|
|
@ -9289,6 +9289,9 @@ table.table.data tr.list-tree-level-25 td.list-data-column-1 {
|
|||
font-weight: bold;
|
||||
}
|
||||
.control-simplelist.is-selectable li a {
|
||||
padding: 5px 10px;
|
||||
margin: -5px -10px;
|
||||
display: block;
|
||||
color: #333333;
|
||||
}
|
||||
.control-simplelist.is-selectable li:hover {
|
||||
|
|
@ -10412,6 +10415,9 @@ html.cssanimations .cursor-loading-indicator.hide {
|
|||
font-size: 14px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.callout > .close {
|
||||
margin: 15px 15px 0 0;
|
||||
}
|
||||
.callout.callout-danger > .header {
|
||||
background: #f6b5b2;
|
||||
}
|
||||
|
|
@ -10521,6 +10527,13 @@ html.cssanimations .cursor-loading-indicator.hide {
|
|||
.callout > .content .action-panel {
|
||||
padding: 10px 0 0 0;
|
||||
}
|
||||
.callout.no-icon > .header h3,
|
||||
.callout.no-icon > .header p {
|
||||
margin-left: 0;
|
||||
}
|
||||
.callout.no-subheader > .header i {
|
||||
margin-top: -5px;
|
||||
}
|
||||
.dropdown-menu {
|
||||
padding: 0;
|
||||
background: transparent;
|
||||
|
|
@ -11027,7 +11040,7 @@ body.dropdown-open .dropdown-overlay {
|
|||
}
|
||||
.control-tabs.content-tabs > ul.nav-tabs li {
|
||||
margin-right: 0;
|
||||
border-top: 1px solid transparent;
|
||||
border-top: 1px solid #e3e5e7;
|
||||
border-right: 1px solid #e3e5e7;
|
||||
}
|
||||
.control-tabs.content-tabs > ul.nav-tabs li a {
|
||||
|
|
@ -11039,24 +11052,17 @@ body.dropdown-open .dropdown-overlay {
|
|||
background: transparent;
|
||||
}
|
||||
.control-tabs.content-tabs > ul.nav-tabs li:first-child {
|
||||
border-left: 1px solid transparent;
|
||||
}
|
||||
.control-tabs.content-tabs > ul.nav-tabs li:first-child.active {
|
||||
border-left: 1px solid #e3e5e7;
|
||||
}
|
||||
.control-tabs.content-tabs > ul.nav-tabs li:last-child {
|
||||
border-right: none;
|
||||
border-right: 1px solid #e3e5e7;
|
||||
}
|
||||
.control-tabs.content-tabs > ul.nav-tabs li.active {
|
||||
border-top: 1px solid #e3e5e7;
|
||||
background: #ffffff;
|
||||
}
|
||||
.control-tabs.content-tabs > ul.nav-tabs li.active a {
|
||||
font-weight: 600;
|
||||
}
|
||||
.control-tabs.content-tabs > ul.nav-tabs li.active:last-child {
|
||||
border-right: 1px solid #e3e5e7;
|
||||
}
|
||||
.control-tabs.content-tabs > .tab-content > .tab-pane {
|
||||
padding-top: 0;
|
||||
}
|
||||
|
|
@ -11071,8 +11077,14 @@ body.dropdown-open .dropdown-overlay {
|
|||
.control-tabs.content-tabs.tabs-flush > ul.nav-tabs li {
|
||||
border-top: none;
|
||||
}
|
||||
.control-tabs.content-tabs.tabs-flush > ul.nav-tabs li:last-child {
|
||||
border-right: 1px solid transparent;
|
||||
}
|
||||
.control-tabs.content-tabs.tabs-flush > ul.nav-tabs li:first-child {
|
||||
border-left: none;
|
||||
border-left: 1px solid transparent;
|
||||
}
|
||||
.control-tabs.content-tabs.tabs-flush > ul.nav-tabs li.active:last-child {
|
||||
border-right: 1px solid #e3e5e7;
|
||||
}
|
||||
.hide-tabs .control-tabs ul.nav-tabs {
|
||||
display: none;
|
||||
|
|
|
|||
|
|
@ -128,7 +128,7 @@
|
|||
}
|
||||
|
||||
Tab.prototype.initTab = function(li) {
|
||||
var
|
||||
var
|
||||
$tabs = $('>li', this.$tabsContainer),
|
||||
tabIndex = $tabs.index(li),
|
||||
time = new Date().getTime(),
|
||||
|
|
|
|||
|
|
@ -41,6 +41,10 @@
|
|||
font-size: 14px;
|
||||
margin-bottom: @line-height-computed;
|
||||
|
||||
> .close {
|
||||
margin: 15px 15px 0 0;
|
||||
}
|
||||
|
||||
&.callout-danger {
|
||||
> .header {
|
||||
background: @callout-danger-header-bg;
|
||||
|
|
@ -136,4 +140,20 @@
|
|||
padding: 10px 0 0 0;
|
||||
}
|
||||
}
|
||||
|
||||
&.no-icon {
|
||||
> .header {
|
||||
h3, p {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.no-subheader {
|
||||
> .header {
|
||||
i {
|
||||
margin-top: -5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -261,7 +261,7 @@
|
|||
|
||||
li {
|
||||
margin-right: 0;
|
||||
border-top: 1px solid transparent;
|
||||
border-top: 1px solid @color-tab-content-border;
|
||||
border-right: 1px solid @color-tab-content-border;
|
||||
|
||||
a {
|
||||
|
|
@ -274,26 +274,18 @@
|
|||
}
|
||||
|
||||
&:first-child {
|
||||
border-left: 1px solid transparent;
|
||||
&.active {
|
||||
border-left: 1px solid @color-tab-content-border;
|
||||
}
|
||||
border-left: 1px solid @color-tab-content-border;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
border-right: none;
|
||||
border-right: 1px solid @color-tab-content-border;
|
||||
}
|
||||
|
||||
&.active {
|
||||
border-top: 1px solid @color-tab-content-border;
|
||||
background: @color-tab-content-active-bg;
|
||||
a {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
border-right: 1px solid @color-tab-content-border;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -323,8 +315,14 @@
|
|||
li {
|
||||
border-top: none;
|
||||
}
|
||||
li:last-child {
|
||||
border-right: 1px solid transparent;
|
||||
}
|
||||
li:first-child {
|
||||
border-left: none;
|
||||
border-left: 1px solid transparent;
|
||||
}
|
||||
li.active:last-child {
|
||||
border-right: 1px solid @color-tab-content-border;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,8 +13,10 @@ use Redirect;
|
|||
use Response;
|
||||
use Exception;
|
||||
use BackendAuth;
|
||||
use Backend\Models\UserPreferences;
|
||||
use Backend\Models\BackendPreferences;
|
||||
use System\Classes\SystemException;
|
||||
use System\Classes\ApplicationException;
|
||||
use October\Rain\Extension\Extendable;
|
||||
use October\Rain\Support\ValidationException;
|
||||
use Illuminate\Database\Eloquent\MassAssignmentException;
|
||||
|
|
@ -92,7 +94,7 @@ class Controller extends Extendable
|
|||
/**
|
||||
* @var array Default methods which cannot be called as actions.
|
||||
*/
|
||||
public $hiddenActions = ['run', 'actionExists', 'pageAction', 'getId', 'handleError'];
|
||||
public $hiddenActions = ['run', 'actionExists', 'pageAction', 'getId', 'setStatusCode', 'handleError', 'makeHintPartial'];
|
||||
|
||||
/**
|
||||
* @var array Controller specified methods which cannot be called as actions.
|
||||
|
|
@ -478,4 +480,54 @@ class Controller extends Extendable
|
|||
$this->fatalError = $exception->getMessage();
|
||||
$this->vars['fatalError'] = $exception->getMessage();
|
||||
}
|
||||
|
||||
//
|
||||
// Hints
|
||||
//
|
||||
|
||||
/**
|
||||
* Renders a hint partial, used for displaying informative information that
|
||||
* can be hidden by the user.
|
||||
* @param string $name Unique key name
|
||||
* @param string $partial Reference to content (partial name)
|
||||
* @param array $params Extra parameters
|
||||
* @return string
|
||||
*/
|
||||
public function makeHintPartial($name, $partial, array $params = [])
|
||||
{
|
||||
return $this->makeLayoutPartial('hint', [
|
||||
'hintName' => $name,
|
||||
'hintPartial' => $partial,
|
||||
'hintParams' => $params
|
||||
] + $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ajax handler to hide a backend hint, once hidden the partial
|
||||
* will no longer display for the user.
|
||||
* @return void
|
||||
*/
|
||||
public function onHideBackendHint()
|
||||
{
|
||||
if (!$name = post('name'))
|
||||
throw new ApplicationException('Missing a hint name.');
|
||||
|
||||
$preferences = UserPreferences::forUser();
|
||||
$hiddenHints = $preferences->get('backend::hints.hidden', []);
|
||||
$hiddenHints[$name] = 1;
|
||||
|
||||
$preferences->set('backend::hints.hidden', $hiddenHints);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a hint has been hidden by the user.
|
||||
* @param string $name Unique key name
|
||||
* @return boolean
|
||||
*/
|
||||
public function isBackendHintHidden($name)
|
||||
{
|
||||
$hiddenHints = UserPreferences::forUser()->get('backend::hints.hidden', []);
|
||||
return array_key_exists($name, $hiddenHints);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
$type = !empty($type) ? $type : 'info';
|
||||
?>
|
||||
<?php if (empty($hintName) || !$this->isBackendHintHidden($hintName)): ?>
|
||||
<div class="callout callout-<?= $type ?> <?=empty($icon)?'no-icon':''?> <?=empty($subtitle)?'no-subheader':''?>">
|
||||
<?php if (!empty($hintName)): ?>
|
||||
<button
|
||||
type="button"
|
||||
class="close"
|
||||
data-request="onHideBackendHint"
|
||||
data-request-data="name: '<?= $hintName ?>'"
|
||||
data-dismiss="callout"
|
||||
aria-hidden="true">×</button>
|
||||
<?php endif ?>
|
||||
<?php if (!empty($title)): ?>
|
||||
<div class="header">
|
||||
<?php if (!empty($icon)): ?><i class="<?= $icon ?>"></i><?php endif ?>
|
||||
<h3><?= $title ?></h3>
|
||||
<?php if (!empty($subtitle)): ?><p><?= $subtitle ?></p><?php endif ?>
|
||||
</div>
|
||||
<?php endif ?>
|
||||
<div class="content">
|
||||
<?= $this->makePartial($hintPartial, $hintParams) ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif ?>
|
||||
Loading…
Reference in New Issue