feat(help-center): add help panel to sidebar icon bar
New help-center module adds a question-mark icon to the sidebar with an aside panel containing three sections: Documentation (permission- gated links to docs viewer and API docs), Keyboard Shortcuts (inline reference from HotkeyService with Mac/Win variants), and About (application info). Visible to all logged-in users — individual resource links respect existing permissions. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -12,5 +12,5 @@
|
||||
* Each entry must match a directory name under modules/ containing a module.php manifest.
|
||||
*/
|
||||
return [
|
||||
'enabled_modules' => ['audit', 'addressbook', 'bookmarks', 'notifications', 'api-docs'],
|
||||
'enabled_modules' => ['audit', 'addressbook', 'bookmarks', 'notifications', 'api-docs', 'help-center'],
|
||||
];
|
||||
|
||||
16
modules/help-center/i18n/default_de.json
Normal file
16
modules/help-center/i18n/default_de.json
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"Help": "Hilfe",
|
||||
"Documentation": "Dokumentation",
|
||||
"Keyboard shortcuts": "Tastenkuerzel",
|
||||
"Action": "Aktion",
|
||||
"Shortcut": "Kuerzel",
|
||||
"About": "Info",
|
||||
"Application": "Anwendung",
|
||||
"CoreCore Admin": "CoreCore Admin",
|
||||
"Open search": "Suche oeffnen",
|
||||
"Save in edit pages": "Speichern auf Bearbeitungsseiten",
|
||||
"Toggle sidebar": "Seitenleiste umschalten",
|
||||
"Switch sidebar section": "Seitenleisten-Bereich wechseln",
|
||||
"Back": "Zurueck",
|
||||
"Forward": "Vorwaerts"
|
||||
}
|
||||
16
modules/help-center/i18n/default_en.json
Normal file
16
modules/help-center/i18n/default_en.json
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"Help": "Help",
|
||||
"Documentation": "Documentation",
|
||||
"Keyboard shortcuts": "Keyboard shortcuts",
|
||||
"Action": "Action",
|
||||
"Shortcut": "Shortcut",
|
||||
"About": "About",
|
||||
"Application": "Application",
|
||||
"CoreCore Admin": "CoreCore Admin",
|
||||
"Open search": "Open search",
|
||||
"Save in edit pages": "Save in edit pages",
|
||||
"Toggle sidebar": "Toggle sidebar",
|
||||
"Switch sidebar section": "Switch sidebar section",
|
||||
"Back": "Back",
|
||||
"Forward": "Forward"
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace MintyPHP\Module\HelpCenter;
|
||||
|
||||
use MintyPHP\App\AppContainer;
|
||||
use MintyPHP\App\Container\ContainerRegistrar;
|
||||
|
||||
final class HelpCenterContainerRegistrar implements ContainerRegistrar
|
||||
{
|
||||
public function register(AppContainer $container): void
|
||||
{
|
||||
// No services to register — help panel uses static utility classes only.
|
||||
}
|
||||
}
|
||||
54
modules/help-center/module.php
Normal file
54
modules/help-center/module.php
Normal file
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Help Center module manifest.
|
||||
*
|
||||
* Adds a help icon to the sidebar with documentation links,
|
||||
* keyboard shortcuts reference, and system information.
|
||||
*/
|
||||
return [
|
||||
'id' => 'help-center',
|
||||
'version' => '1.0.0',
|
||||
'enabled_by_default' => true,
|
||||
'load_order' => 30,
|
||||
'requires' => [],
|
||||
|
||||
'routes' => [],
|
||||
'public_paths' => [],
|
||||
'container_registrars' => [
|
||||
\MintyPHP\Module\HelpCenter\HelpCenterContainerRegistrar::class,
|
||||
],
|
||||
|
||||
'ui_slots' => [
|
||||
'aside.tab_panel' => [
|
||||
[
|
||||
'key' => 'help',
|
||||
'label' => 'Help',
|
||||
'icon' => 'bi-question-circle',
|
||||
'href' => '',
|
||||
'permission' => '',
|
||||
'panel_template' => 'templates/aside-help-panel.phtml',
|
||||
'order' => 900,
|
||||
],
|
||||
],
|
||||
'layout.head_style' => [
|
||||
[
|
||||
'key' => 'help-center-style',
|
||||
'path' => 'modules/help-center/css/components/app-help-panel.css',
|
||||
'order' => 200,
|
||||
],
|
||||
],
|
||||
],
|
||||
|
||||
'authorization_policies' => [],
|
||||
'search_resources' => [],
|
||||
'asset_groups' => [],
|
||||
'scheduler_jobs' => [],
|
||||
'layout_context_providers' => [],
|
||||
'session_providers' => [],
|
||||
'permissions' => [],
|
||||
'event_listeners' => [],
|
||||
'deactivation_handler' => null,
|
||||
'migrations_path' => null,
|
||||
'i18n_path' => 'i18n',
|
||||
];
|
||||
65
modules/help-center/templates/aside-help-panel.phtml
Normal file
65
modules/help-center/templates/aside-help-panel.phtml
Normal file
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
use MintyPHP\Service\Docs\DocsCatalogService;
|
||||
use MintyPHP\Service\Ui\HotkeyService;
|
||||
|
||||
$layoutAuth = is_array($viewAuth['layout'] ?? null) ? $viewAuth['layout'] : [];
|
||||
$canViewDocs = !empty($layoutAuth['can_view_docs']);
|
||||
$canViewApiDocs = !empty($layoutAuth['api_docs.view']);
|
||||
$hasDocumentation = $canViewDocs || $canViewApiDocs;
|
||||
|
||||
$docsDefaultSlug = $canViewDocs ? DocsCatalogService::defaultSlug() : '';
|
||||
$docsUrl = $docsDefaultSlug !== '' ? lurl('admin/docs/' . $docsDefaultSlug) : '';
|
||||
$apiDocsUrl = $canViewApiDocs ? lurl('admin/api-docs') : '';
|
||||
|
||||
$isMac = str_contains(strtolower((string) ($_SERVER['HTTP_USER_AGENT'] ?? '')), 'mac');
|
||||
$hotkeys = HotkeyService::list();
|
||||
?>
|
||||
<div class="app-help-panel">
|
||||
<?php if ($hasDocumentation): ?>
|
||||
<div class="app-sidebar-group">
|
||||
<h3 class="app-sidebar-title"><?php e(t('Documentation')); ?></h3>
|
||||
<ul>
|
||||
<?php if ($canViewDocs && $docsUrl !== ''): ?>
|
||||
<li><a href="<?php e($docsUrl); ?>"><i class="bi bi-book"></i> <?php e(t('Documentation')); ?></a></li>
|
||||
<?php endif; ?>
|
||||
<?php if ($canViewApiDocs): ?>
|
||||
<li><a href="<?php e($apiDocsUrl); ?>"><i class="bi bi-braces"></i> <?php e(t('API docs')); ?></a></li>
|
||||
<?php endif; ?>
|
||||
</ul>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="app-sidebar-group">
|
||||
<h3 class="app-sidebar-title"><?php e(t('Keyboard shortcuts')); ?></h3>
|
||||
<table class="app-help-shortcuts-table" role="grid">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col"><?php e(t('Action')); ?></th>
|
||||
<th scope="col"><?php e(t('Shortcut')); ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($hotkeys as $hotkey):
|
||||
$shortcut = $isMac ? ($hotkey['mac'] ?? '') : ($hotkey['win'] ?? '');
|
||||
$action = t($hotkey['action_key'] ?? '');
|
||||
?>
|
||||
<tr>
|
||||
<td><?php e($action); ?></td>
|
||||
<td><kbd><?php e($shortcut); ?></kbd></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="app-sidebar-group">
|
||||
<h3 class="app-sidebar-title"><?php e(t('About')); ?></h3>
|
||||
<ul>
|
||||
<li class="app-help-about-item">
|
||||
<span class="app-help-about-label"><?php e(t('Application')); ?></span>
|
||||
<span class="app-help-about-value"><?php e(t('CoreCore Admin')); ?></span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
103
modules/help-center/web/css/components/app-help-panel.css
Normal file
103
modules/help-center/web/css/components/app-help-panel.css
Normal file
@@ -0,0 +1,103 @@
|
||||
@layer components {
|
||||
.app-help-panel {
|
||||
padding: var(--app-spacing);
|
||||
}
|
||||
|
||||
.app-help-panel .app-sidebar-title {
|
||||
text-transform: uppercase;
|
||||
font-size: var(--app-text-2xs);
|
||||
font-weight: 600;
|
||||
color: var(--app-muted-color);
|
||||
margin: 0 0 0.5rem;
|
||||
letter-spacing: 0.03em;
|
||||
}
|
||||
|
||||
.app-help-panel .app-sidebar-group {
|
||||
margin-bottom: calc(var(--app-spacing) * 1.5);
|
||||
}
|
||||
|
||||
.app-help-panel .app-sidebar-group ul {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.app-help-panel .app-sidebar-group ul li a {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
padding: 0.35rem 0.5rem;
|
||||
border-radius: var(--app-border-radius);
|
||||
color: var(--app-color);
|
||||
text-decoration: none;
|
||||
font-size: var(--app-text-sm);
|
||||
transition: background-color 0.15s;
|
||||
}
|
||||
|
||||
.app-help-panel .app-sidebar-group ul li a:hover {
|
||||
background-color: var(--app-accordion-border-color);
|
||||
}
|
||||
|
||||
.app-help-panel .app-sidebar-group ul li a i {
|
||||
font-size: 1rem;
|
||||
opacity: 0.65;
|
||||
}
|
||||
|
||||
.app-help-shortcuts-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
font-size: var(--app-text-sm);
|
||||
}
|
||||
|
||||
.app-help-shortcuts-table th,
|
||||
.app-help-shortcuts-table td {
|
||||
padding: 0.3rem 0.5rem;
|
||||
text-align: left;
|
||||
border: none;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.app-help-shortcuts-table th {
|
||||
font-weight: 600;
|
||||
color: var(--app-muted-color);
|
||||
font-size: var(--app-text-2xs);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.03em;
|
||||
border-bottom: 1px solid var(--app-border);
|
||||
}
|
||||
|
||||
.app-help-shortcuts-table td {
|
||||
border-bottom: 1px solid var(--app-border);
|
||||
}
|
||||
|
||||
.app-help-shortcuts-table tr:last-child td {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.app-help-shortcuts-table kbd {
|
||||
display: inline-block;
|
||||
padding: 0.1rem 0.35rem;
|
||||
font-size: var(--app-text-xs);
|
||||
font-family: var(--app-font-family-mono, monospace);
|
||||
background: var(--app-card-background-color);
|
||||
border: 1px solid var(--app-border);
|
||||
border-radius: 3px;
|
||||
box-shadow: 0 1px 0 var(--app-border);
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.app-help-about-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 0.35rem 0.5rem;
|
||||
font-size: var(--app-text-sm);
|
||||
}
|
||||
|
||||
.app-help-about-label {
|
||||
color: var(--app-muted-color);
|
||||
}
|
||||
|
||||
.app-help-about-value {
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user