PrivilegeAudit: Use the <details> tag

(cherry picked from commit 503f9b731602731455c77459216a5e9143af5c39)
This commit is contained in:
Johannes Meyer 2022-07-26 12:44:20 +02:00
parent 93bb9b69f3
commit 80c35f8571
2 changed files with 122 additions and 101 deletions

View File

@ -54,7 +54,7 @@ class PrivilegeAudit extends BaseHtmlElement
} }
} }
$header = new HtmlElement('div'); $header = new HtmlElement('summary');
if (! empty($refusedBy)) { if (! empty($refusedBy)) {
$header->add([ $header->add([
new Icon('times-circle', ['class' => 'refused']), new Icon('times-circle', ['class' => 'refused']),
@ -171,15 +171,24 @@ class PrivilegeAudit extends BaseHtmlElement
])); ]));
} }
if (empty($rolePaths)) {
return [
empty($refusedBy) ? (empty($grantedBy) ? null : true) : false,
new HtmlElement(
'div',
Attributes::create(['class' => 'inheritance-paths']),
$header->setTag('div')
)
];
}
return [ return [
empty($refusedBy) ? (empty($grantedBy) ? null : true) : false, empty($refusedBy) ? (empty($grantedBy) ? null : true) : false,
HtmlElement::create('div', [ HtmlElement::create('details', [
'class' => [empty($rolePaths) ? null : 'collapsible', 'inheritance-paths'], 'class' => ['collapsible', 'inheritance-paths'],
'data-toggle-element' => '.collapsible-control', 'data-no-persistence' => true
'data-no-persistence' => true,
'data-visible-height' => 0
], [ ], [
empty($rolePaths) ? $header : $header->addAttributes(['class' => 'collapsible-control']), $header->addAttributes(['class' => 'collapsible-control']),
$rolePaths $rolePaths
]) ])
]; ];
@ -202,7 +211,7 @@ class PrivilegeAudit extends BaseHtmlElement
} }
} }
$header = new HtmlElement('div'); $header = new HtmlElement('summary');
if (! empty($restrictedBy)) { if (! empty($restrictedBy)) {
$header->add([ $header->add([
new Icon('filter', ['class' => 'restricted']), new Icon('filter', ['class' => 'restricted']),
@ -277,17 +286,26 @@ class PrivilegeAudit extends BaseHtmlElement
]); ]);
} }
if (empty($roles)) {
return [
! empty($restrictedBy),
new HtmlElement(
'div',
Attributes::create(['class' => 'restrictions']),
$header->setTag('div')
)
];
}
return [ return [
! empty($restrictedBy), ! empty($restrictedBy),
new HtmlElement( new HtmlElement(
'div', 'details',
Attributes::create([ Attributes::create([
'class' => [empty($roles) ? null : 'collapsible', 'restrictions'], 'class' => ['collapsible', 'restrictions'],
'data-toggle-element' => '.collapsible-control', 'data-no-persistence' => true
'data-no-persistence' => true,
'data-visible-height' => 0
]), ]),
empty($roles) ? $header : $header->addAttributes(['class' => 'collapsible-control']), $header->addAttributes(['class' => 'collapsible-control']),
new HtmlElement('ul', null, ...$roles) new HtmlElement('ul', null, ...$roles)
) )
]; ];
@ -301,39 +319,45 @@ class PrivilegeAudit extends BaseHtmlElement
$this->addHtml(new HtmlElement( $this->addHtml(new HtmlElement(
'li', 'li',
Attributes::create([ null,
'class' => 'collapsible',
'data-toggle-element' => 'h3',
'data-visible-height' => 0
]),
new HtmlElement( new HtmlElement(
'h3', 'details',
null, Attributes::create([
new HtmlElement('span', null, Text::create(t('Administrative Privileges'))), 'class' => ['collapsible', 'privilege-section']
HtmlElement::create( ]),
'span',
['class' => 'audit-preview'],
$wildcardState || $unrestrictedState
? new Icon('check-circle', ['class' => 'granted'])
: null
)
),
new HtmlElement(
'ol',
Attributes::create(['class' => 'privilege-list']),
new HtmlElement( new HtmlElement(
'li', 'summary',
null, Attributes::create(['class' => [
HtmlElement::create('p', ['class' => 'privilege-label'], t('Administrative Access')), 'collapsible-control', // Helps JS, improves performance a bit
HtmlElement::create('div', ['class' => 'spacer']), ]]),
$wildcardAudit new HtmlElement('span', null, Text::create(t('Administrative Privileges'))),
HtmlElement::create(
'span',
['class' => 'audit-preview'],
$wildcardState || $unrestrictedState
? new Icon('check-circle', ['class' => 'granted'])
: null
),
new Icon('angles-down', ['class' => 'collapse-icon']),
new Icon('angles-left', ['class' => 'expand-icon'])
), ),
new HtmlElement( new HtmlElement(
'li', 'ol',
null, Attributes::create(['class' => 'privilege-list']),
HtmlElement::create('p', ['class' => 'privilege-label'], t('Unrestricted Access')), new HtmlElement(
HtmlElement::create('div', ['class' => 'spacer']), 'li',
$unrestrictedAudit null,
HtmlElement::create('p', ['class' => 'privilege-label'], t('Administrative Access')),
HtmlElement::create('div', ['class' => 'spacer']),
$wildcardAudit
),
new HtmlElement(
'li',
null,
HtmlElement::create('p', ['class' => 'privilege-label'], t('Unrestricted Access')),
HtmlElement::create('div', ['class' => 'spacer']),
$unrestrictedAudit
)
) )
) )
)); ));
@ -420,30 +444,36 @@ class PrivilegeAudit extends BaseHtmlElement
$label = [$source, ' ', HtmlElement::create('em', null, t('Module'))]; $label = [$source, ' ', HtmlElement::create('em', null, t('Module'))];
} }
$this->addHtml(HtmlElement::create('li', [ $this->addHtml(new HtmlElement(
'class' => 'collapsible', 'li',
'data-toggle-element' => 'h3', null,
'data-visible-height' => 0 HtmlElement::create('details', [
], [ 'class' => ['collapsible', 'privilege-section']
new HtmlElement( ], [
'h3', new HtmlElement(
null, 'summary',
HtmlElement::create('span', null, $label), Attributes::create(['class' => [
HtmlElement::create('span', ['class' => 'audit-preview'], [ 'collapsible-control', // Helps JS, improves performance a bit
$anythingGranted ? new Icon('check-circle', ['class' => 'granted']) : null, ]]),
$anythingRefused ? new Icon('times-circle', ['class' => 'refused']) : null, HtmlElement::create('span', null, $label),
$anythingRestricted ? new Icon('filter', ['class' => 'restricted']) : null HtmlElement::create('span', ['class' => 'audit-preview'], [
]) $anythingGranted ? new Icon('check-circle', ['class' => 'granted']) : null,
), $anythingRefused ? new Icon('times-circle', ['class' => 'refused']) : null,
$permissionList->isEmpty() ? null : [ $anythingRestricted ? new Icon('filter', ['class' => 'restricted']) : null
HtmlElement::create('h4', null, t('Permissions')), ]),
$permissionList new Icon('angles-down', ['class' => 'collapse-icon']),
], new Icon('angles-left', ['class' => 'expand-icon'])
$restrictionList->isEmpty() ? null : [ ),
HtmlElement::create('h4', null, t('Restrictions')), $permissionList->isEmpty() ? null : [
$restrictionList HtmlElement::create('h4', null, t('Permissions')),
] $permissionList
])); ],
$restrictionList->isEmpty() ? null : [
HtmlElement::create('h4', null, t('Restrictions')),
$restrictionList
]
])
));
} }
} }

View File

@ -19,16 +19,17 @@
list-style-type: none; list-style-type: none;
} }
h3 { .privilege-section > summary {
font-weight: @font-weight-bold;
border-bottom: 1px solid @gray-light; border-bottom: 1px solid @gray-light;
} }
h3 em, .privilege-section > summary em,
.previews em, .previews em,
.privilege-label em { .privilege-label em {
color: @text-color-light; color: @text-color-light;
} }
h3 em { .privilege-section > summary em {
font-weight: normal; font-weight: normal;
} }
.privilege-label em { .privilege-label em {
@ -144,10 +145,6 @@
padding: 0; padding: 0;
} }
> li:not(.collapsed) {
margin-bottom: 2em;
}
.flex-overflow, .flex-overflow,
.privilege-list > li, .privilege-list > li,
.inheritance-paths > ol { .inheritance-paths > ol {
@ -165,15 +162,30 @@
// https://codepen.io/unthinkingly/pen/XMwJLG // https://codepen.io/unthinkingly/pen/XMwJLG
overflow: hidden; overflow: hidden;
} }
> details:last-child {
// The overflow above cuts off the outline of the summary otherwise
margin: -4px;
padding: 4px;
}
} }
h3 { .privilege-section {
&:not(.collapsed) {
margin-bottom: 2em;
}
}
.privilege-section > summary {
display: flex; display: flex;
align-items: baseline;
font-size: 1.167em;
margin: 0.556em 0 0.333em;
> :first-child { > :first-child {
flex: 3 1 auto; flex: 3 1 auto;
min-width: 20em; min-width: 20em;
max-width: 40em / 1.167em; // privilege label width + spacer width / h3 font-size max-width: 40em / 1.167em; // privilege label width + spacer width / summary font-size
} }
.audit-preview { .audit-preview {
@ -181,7 +193,7 @@
.icon:before { .icon:before {
width: 1.25em; width: 1.25em;
font-size: 1.25em / 1.167em; // privilege state icon font-size / h3 font-size font-size: 1.25em / 1.167em; // privilege state icon font-size / summary font-size
} }
} }
@ -213,7 +225,7 @@
.restrictions { .restrictions {
flex: 1 1 auto; flex: 1 1 auto;
> div { > summary {
line-height: 1; line-height: 1;
overflow: hidden; overflow: hidden;
@ -325,7 +337,7 @@
#layout.minimal-layout, #layout.minimal-layout,
#layout.poor-layout { #layout.poor-layout {
.privilege-audit { .privilege-audit {
h3 > :first-child { .privilege-section > summary > :first-child {
flex-grow: 99; flex-grow: 99;
} }
@ -346,27 +358,6 @@
.privilege-audit .collapsible { .privilege-audit .collapsible {
.collapsible-control { .collapsible-control {
cursor: pointer; cursor: pointer;
-webkit-touch-callout: none; .user-select(none);
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.collapsible-control:after {
content: "\f103";
display: inline-block;
font-family: 'ifont';
font-weight: normal;
padding: 0 .25em;
margin-right: .25em;
width: 1em;
opacity: .6;
float: right;
}
&.collapsed .collapsible-control:after {
content: "\e87a";
} }
} }