system: Organize items into sections

Closes: #2161.

- Sections are ordered by importance on which administrator must act after
setting up the system.

- Consistent order across all the languages.

- Update the styling for the section hearers.

  - For system section, make them compact.

  - Make them look like a header text (with underline) rather than a
    divider (like in a menu).

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: Veiko Aasa <veiko17@disroot.org>
This commit is contained in:
Sunil Mohan Adapa 2024-03-13 22:59:04 -07:00 committed by Veiko Aasa
parent 1b09d01575
commit 6e557dd1e9
No known key found for this signature in database
GPG Key ID: 478539CAE680674E
27 changed files with 105 additions and 35 deletions

View File

@ -3,6 +3,7 @@
from typing import ClassVar
from django.urls import reverse_lazy
from django.utils.translation import gettext_lazy as _
from plinth import app
@ -101,3 +102,14 @@ def init():
parent_url_name='index')
Menu('menu-system', icon='fa-cog', url_name='system',
parent_url_name='index')
Menu('menu-system-visibility', name=_('Visibility'), icon='fa-cog',
url_name='system:visibility', parent_url_name='system', order=10)
Menu('menu-system-data', name=_('Data'), icon='fa-cog',
url_name='system:data', parent_url_name='system', order=20)
Menu('menu-system-system', name=_('System'), icon='fa-cog',
url_name='system:system', parent_url_name='system', order=30)
Menu('menu-system-security', name=_('Security'), icon='fa-cog',
url_name='system:security', parent_url_name='system', order=40)
Menu('menu-system-administration', name=_('Administration'), icon='fa-cog',
url_name='system:administration', parent_url_name='system', order=50)

View File

@ -50,7 +50,8 @@ class AvahiApp(app_module.App):
self.add(info)
menu_item = menu.Menu('menu-avahi', info.name, None, info.icon,
'avahi:index', parent_url_name='system')
'avahi:index',
parent_url_name='system:visibility', order=50)
self.add(menu_item)
packages = Packages('packages-avahi', ['avahi-daemon', 'avahi-utils'])

View File

@ -47,7 +47,8 @@ class BackupsApp(app_module.App):
self.add(info)
menu_item = menu.Menu('menu-backups', info.name, None, info.icon,
'backups:index', parent_url_name='system')
'backups:index', parent_url_name='system:data',
order=20)
self.add(menu_item)
packages = Packages('packages-backups', ['borgbackup', 'sshfs'])

View File

@ -44,7 +44,7 @@ class BindApp(app_module.App):
menu_item = menu.Menu('menu-bind', info.name, info.short_description,
info.icon, 'bind:index',
parent_url_name='system')
parent_url_name='system:visibility', order=30)
self.add(menu_item)
packages = Packages('packages-bind', ['bind9'])

View File

@ -59,7 +59,9 @@ class CockpitApp(app_module.App):
menu_item = menu.Menu('menu-cockpit', info.name,
info.short_description, info.icon,
'cockpit:index', parent_url_name='system')
'cockpit:index',
parent_url_name='system:administration',
order=20)
self.add(menu_item)
shortcut = frontpage.Shortcut('shortcut-cockpit', info.name,

View File

@ -47,7 +47,8 @@ class ConfigApp(app_module.App):
self.add(info)
menu_item = menu.Menu('menu-config', _('Configure'), None, info.icon,
'config:index', parent_url_name='system')
'config:index', parent_url_name='system:system',
order=30)
self.add(menu_item)
packages = Packages('packages-config', ['zram-tools'])

View File

@ -71,7 +71,8 @@ class DateTimeApp(app_module.App):
self.add(info)
menu_item = menu.Menu('menu-datetime', info.name, None, info.icon,
'datetime:index', parent_url_name='system')
'datetime:index',
parent_url_name='system:system', order=40)
self.add(menu_item)
packages = Packages('packages-datetime', ['systemd-timesyncd'])

View File

@ -55,7 +55,9 @@ class DiagnosticsApp(app_module.App):
self.add(info)
menu_item = menu.Menu('menu-diagnostics', info.name, None, info.icon,
'diagnostics:index', parent_url_name='system')
'diagnostics:index',
parent_url_name='system:administration',
order=30)
self.add(menu_item)
backup_restore = BackupRestore('backup-restore-diagnostics',

View File

@ -64,7 +64,8 @@ class DynamicDNSApp(app_module.App):
self.add(info)
menu_item = menu.Menu('menu-dynamicdns', info.name, None, info.icon,
'dynamicdns:index', parent_url_name='system')
'dynamicdns:index',
parent_url_name='system:visibility', order=20)
self.add(menu_item)
enable_state = app_module.EnableState('enable-state-dynamicdns')

View File

@ -64,7 +64,8 @@ class FirewallApp(app_module.App):
self.add(info)
menu_item = menu.Menu('menu-firewall', info.name, None, info.icon,
'firewall:index', parent_url_name='system')
'firewall:index',
parent_url_name='system:security', order=30)
self.add(menu_item)
packages = Packages('packages-firewall', ['firewalld', 'nftables'])

View File

@ -66,7 +66,8 @@ class LetsEncryptApp(app_module.App):
menu_item = menu.Menu('menu-letsencrypt', info.name,
info.short_description, info.icon,
'letsencrypt:index', parent_url_name='system')
'letsencrypt:index',
parent_url_name='system:security', order=20)
self.add(menu_item)
packages = Packages('packages-letsencrypt', ['certbot'])

View File

@ -46,7 +46,8 @@ class NamesApp(app_module.App):
self.add(info)
menu_item = menu.Menu('menu-names', info.name, None, info.icon,
'names:index', parent_url_name='system')
'names:index',
parent_url_name='system:visibility', order=10)
self.add(menu_item)
backup_restore = BackupRestore('backup-restore-names',

View File

@ -62,7 +62,8 @@ class NetworksApp(app_module.App):
self.add(info)
menu_item = menu.Menu('menu-networks', info.name, None, info.icon,
'networks:index', parent_url_name='system')
'networks:index',
parent_url_name='system:system', order=20)
self.add(menu_item)
packages = Packages('packages-networks', ['network-manager', 'batctl'])

View File

@ -64,7 +64,8 @@ class PagekiteApp(app_module.App):
menu_item = menu.Menu('menu-pagekite', info.name,
info.short_description, info.icon,
'pagekite:index', parent_url_name='system')
'pagekite:index',
parent_url_name='system:visibility', order=40)
self.add(menu_item)
packages = Packages('packages-pagekite', ['pagekite'])

View File

@ -46,7 +46,9 @@ class PerformanceApp(app_module.App):
menu_item = menu.Menu('menu-performance', info.name,
info.short_description, info.icon,
'performance:index', parent_url_name='system')
'performance:index',
parent_url_name='system:administration',
order=40)
self.add(menu_item)
packages = Packages('packages-performance', ['cockpit-pcp'])

View File

@ -34,7 +34,9 @@ class PowerApp(app_module.App):
self.add(info)
menu_item = menu.Menu('menu-power', info.name, None, info.icon,
'power:index', parent_url_name='system')
'power:index',
parent_url_name='system:administration',
order=50)
self.add(menu_item)
backup_restore = BackupRestore('backup-restore-power',

View File

@ -36,7 +36,8 @@ class PrivacyApp(app_module.App):
menu_item = menu.Menu('menu-privacy', info.name,
info.short_description, info.icon,
'privacy:index', parent_url_name='system')
'privacy:index', parent_url_name='system:data',
order=10)
self.add(menu_item)
packages = Packages('packages-privacy', ['popularity-contest', 'gpg'])

View File

@ -37,7 +37,8 @@ class SecurityApp(app_module.App):
self.add(info)
menu_item = menu.Menu('menu-security', info.name, None, info.icon,
'security:index', parent_url_name='system')
'security:index',
parent_url_name='system:security', order=10)
self.add(menu_item)
packages = Packages('packages-security', ['fail2ban', 'debsecan'])

View File

@ -53,7 +53,8 @@ class SnapshotApp(app_module.App):
self.add(info)
menu_item = menu.Menu('menu-snapshot', info.name, None, info.icon,
'snapshot:index', parent_url_name='system')
'snapshot:index', parent_url_name='system:data',
order=40)
self.add(menu_item)
packages = Packages('packages-snapshot', ['snapper'])

View File

@ -45,7 +45,9 @@ class SSHApp(app_module.App):
self.add(info)
menu_item = menu.Menu('menu-ssh', info.name, None, info.icon,
'ssh:index', parent_url_name='system')
'ssh:index',
parent_url_name='system:administration',
order=10)
self.add(menu_item)
packages = Packages('packages-ssh', ['openssh-server'])

View File

@ -48,7 +48,8 @@ class StorageApp(app_module.App):
self.add(info)
menu_item = menu.Menu('menu-storage', info.name, None, info.icon,
'storage:index', parent_url_name='system')
'storage:index', parent_url_name='system:data',
order=30)
self.add(menu_item)
packages = Packages('packages-storage',

View File

@ -68,7 +68,8 @@ class UpgradesApp(app_module.App):
self.add(info)
menu_item = menu.Menu('menu-upgrades', info.name, None, info.icon,
'upgrades:index', parent_url_name='system')
'upgrades:index',
parent_url_name='system:system', order=50)
self.add(menu_item)
packages = Packages('packages-upgrades',

View File

@ -62,7 +62,8 @@ class UsersApp(app_module.App):
self.add(info)
menu_item = menu.Menu('menu-users', info.name, None, info.icon,
'users:index', parent_url_name='system')
'users:index', parent_url_name='system:system',
order=10)
self.add(menu_item)
packages = Packages('packages-users', [

View File

@ -31,7 +31,7 @@
{% if show_disabled %}
<div class="container card-container">
<div class="card-section-title text-center">{% trans "Disabled" %}</div>
<div class="card-section-title">{% trans "Disabled" %}</div>
<div class="row">
<div class="card-list card-list-disabled">
{% for item in submenu.sorted_items %}

View File

@ -7,3 +7,29 @@
{% load i18n %}
{% block body_class %}system-page{% endblock %}
{% block container %}
<div class="container">
<div class="row">
<div class="col-lg-8 offset-lg-2">
{% include 'messages.html' %}
</div>
</div>
</div>
<div class="container card-container">
{% for section_item in submenu.sorted_items %}
<div class="system-section-title">{{ section_item.name }}</div>
<div class="row">
<div class="card-list card-list-primary">
{% for item in section_item.sorted_items %}
{% if advanced_mode or not item.advanced %}
{% include "card.html" %}
{% endif %}
{% endfor %}
</div>
</div>
{% endfor %}
</div>
{% endblock %}

View File

@ -3,11 +3,20 @@
Django URLconf file containing all urls
"""
from captcha import views as cviews
from django.urls import re_path
from django.urls import include, re_path
from stronghold.decorators import public
from . import views
system_urlpatterns = [
re_path(r'^sys/#visibility$', views.system_index, name='visibility'),
re_path(r'^sys/#data$', views.system_index, name='data'),
re_path(r'^sys/#system$', views.system_index, name='system'),
re_path(r'^sys/#security$', views.system_index, name='security'),
re_path(r'^sys/#administration$', views.system_index,
name='administration'),
]
urlpatterns = [
re_path(r'^$', views.index, name='index'),
re_path(r'^language-selection/$',
@ -15,6 +24,7 @@ urlpatterns = [
name='language-selection'),
re_path(r'^apps/$', views.AppsIndexView.as_view(), name='apps'),
re_path(r'^sys/$', views.system_index, name='system'),
re_path(r'', include((system_urlpatterns, 'system'))),
re_path(r'^uninstall/(?P<app_id>[1-9a-z\-_]+)/$',
views.UninstallView.as_view(), name='uninstall'),
re_path(r'^rerun-setup/(?P<app_id>[1-9a-z\-_]+)/$', views.rerun_setup_view,

View File

@ -488,20 +488,16 @@ footer {
justify-content: left;
}
.card-section-title {
.card-section-title, .system-section-title {
display: flex;
font-weight: 800;
font-size: 1.25rem;
padding: 0 2.875rem;
margin: 1.25rem 0;
margin-bottom: 1.25rem;
border-bottom: var(--neutral-dark-color) solid 2px;
}
.card-section-title:before, .card-section-title:after {
color: white;
content: '';
flex: 1;
border-bottom: var(--neutral-dark-color) solid 2px;
margin: auto 1.125rem;
.card-section-title {
margin-top: 1.25rem;
}
a.menu_link {
@ -605,7 +601,7 @@ a.menu_link_active {
/* Button table - Tables with a list of actions as buttons on top */
.index-page .card-list:before,
.apps-page .card-list:before,
.system-page .card-list:before {
.system-page .system-section-title:first-child:before {
position: relative;
width: 25rem;
height: 25rem;
@ -627,7 +623,7 @@ a.menu_link_active {
background-image: url('../img/apps-background.svg');
}
.system-page .card-list:before {
.system-page .system-section-title:first-child:before {
background-image: url('../img/system-background.svg');
}