config: Add option to show advanced apps

Closes #1454.

Signed-off-by: James Valleroy <jvalleroy@mailbox.org>
Reviewed-by: Sunil Mohan Adapa <sunil@medhas.org>
This commit is contained in:
James Valleroy 2019-05-12 19:40:47 -04:00 committed by Sunil Mohan Adapa
parent 5fe7f4aaba
commit ff06c722bb
No known key found for this signature in database
GPG Key ID: 43EA1CFF0AA7C5F2
8 changed files with 89 additions and 33 deletions

View File

@ -27,7 +27,7 @@ class Menu(app.FollowerComponent):
def __init__(self, component_id, name=None, short_description=None,
icon=None, url_name=None, url_args=None, url_kwargs=None,
parent_url_name=None, order=50):
parent_url_name=None, order=50, advanced=False):
"""Initialize a new menu item with basic properties.
name is the label of the menu item.
@ -50,6 +50,8 @@ class Menu(app.FollowerComponent):
disregard that. If you need more granularity, don't bother renumbering
things. Feel free to use fractional orders.
advanced decides whether to show the menu item only in advanced mode.
"""
super().__init__(component_id)
if not url_name:
@ -62,6 +64,7 @@ class Menu(app.FollowerComponent):
self.icon = icon
self.url = url
self.order = order
self.advanced = advanced
self.items = []
# Add self to parent menu item

View File

@ -45,6 +45,7 @@ APACHE_HOMEPAGE_CONFIG = os.path.join(APACHE_CONF_ENABLED_DIR,
APACHE_HOMEPAGE_CONF_FILE_NAME)
FREEDOMBOX_APACHE_CONFIG = os.path.join(APACHE_CONF_ENABLED_DIR,
'freedombox.conf')
ADVANCED_MODE_KEY = 'advanced_mode'
app = None
@ -126,6 +127,18 @@ def change_home_page(shortcut_id):
actions.superuser_run('config', ['set-home-page', str(url)])
def get_advanced_mode():
"""Get whether option is enabled."""
from plinth import kvstore
return kvstore.get_default(ADVANCED_MODE_KEY, False)
def set_advanced_mode(advanced_mode):
"""Turn on/off advanced mode."""
from plinth import kvstore
kvstore.set(ADVANCED_MODE_KEY, advanced_mode)
def init():
"""Initialize the module"""
global app

View File

@ -100,3 +100,8 @@ class ConfigurationForm(forms.Form):
'/freedombox to reach {box_name} Service (Plinth).'),
box_name=ugettext_lazy(cfg.box_name)), required=False,
choices=get_homepage_choices)
advanced_mode = forms.BooleanField(
label=_('Show advanced apps and features'), required=False,
help_text=_('Show apps and features that require more technical '
'knowledge.'))

View File

@ -64,6 +64,7 @@ def get_status():
'hostname': config.get_hostname(),
'domainname': config.get_domainname(),
'homepage': config.get_home_page(),
'advanced_mode': config.get_advanced_mode(),
}
@ -102,6 +103,22 @@ def _apply_changes(request, old_status, new_status):
else:
messages.success(request, _('Webserver home page set'))
if old_status['advanced_mode'] != new_status['advanced_mode']:
try:
config.set_advanced_mode(new_status['advanced_mode'])
except Exception as exception:
messages.error(
request,
_('Error changing advanced mode: {exception}').format(
exception=exception))
else:
if new_status['advanced_mode']:
messages.success(request,
_('Showing advanced apps and features'))
else:
messages.success(request,
_('Hiding advanced apps and features'))
def set_hostname(hostname):
"""Sets machine hostname to hostname"""

View File

@ -0,0 +1,34 @@
{% comment %}
#
# This file is part of FreedomBox.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
{% endcomment %}
{% load static %}
<div class="card thumbnail">
<a href="{{ item.url }}" class="nav-link">
<div class="card-title">{{ item.name }}</div>
<div class="card-icon">
{% if 'fa-' in item.icon %}
<span class="fa {{ item.icon }}"></span>
{% else %}
<img src="{% static 'theme/icons/' %}{{ item.icon }}.svg"/>
{% endif %}
</div>
<div class="card-description">{{ item.short_description|default:'' }}</div>
</a>
</div>

View File

@ -35,19 +35,9 @@
<div class="card-list card-list-primary">
{% for item in submenu.sorted_items %}
{% if not show_disabled or item.is_enabled %}
<div class="card thumbnail">
<a href="{{ item.url }}" class="nav-link">
<div class="card-title">{{ item.name }}</div>
<div class="card-icon">
{% if 'fa-' in item.icon %}
<span class="fa {{ item.icon }}"></span>
{% else %}
<img src="{% static 'theme/icons/' %}{{ item.icon }}.svg"/>
{% endif %}
</div>
<div class="card-description">{{ item.short_description|default:'' }}</div>
</a>
</div>
{% if advanced_mode or not item.advanced %}
{% include "card.html" %}
{% endif %}
{% endif %}
{% endfor %}
</div>
@ -61,19 +51,9 @@
<div class="card-list card-list-disabled">
{% for item in submenu.sorted_items %}
{% if not item.is_enabled %}
<div class="card thumbnail">
<a href="{{ item.url }}" class="nav-link">
<div class="card-title">{{ item.name }}</div>
<div class="card-icon">
{% if 'fa-' in item.icon %}
<span class="fa {{ item.icon }}"></span>
{% else %}
<img src="{% static 'theme/icons/' %}{{ item.icon }}.svg"/>
{% endif %}
</div>
<div class="card-description">{{ item.short_description|default:'' }}</div>
</a>
</div>
{% if advanced_mode or not item.advanced %}
{% include "card.html" %}
{% endif %}
{% endif %}
{% endfor %}
</div>

View File

@ -92,6 +92,7 @@ def test_menu_creation_without_arguments():
assert menu.icon is None
assert menu.url == '/'
assert menu.order == 50
assert not menu.advanced
assert not menu.items
@ -107,7 +108,7 @@ def test_menu_creation_with_arguments():
parent_menu = Menu('menu-index', url_name='index')
menu = Menu('menu-test', expected_name, expected_short_description,
expected_icon, url_name, url_kwargs=url_kwargs,
parent_url_name='index', order=expected_order)
parent_url_name='index', order=expected_order, advanced=True)
assert len(parent_menu.items) == 1
assert parent_menu.items[0] == menu
@ -116,6 +117,7 @@ def test_menu_creation_with_arguments():
assert expected_icon == menu.icon
assert expected_url == menu.url
assert expected_order == menu.order
assert menu.advanced
assert not menu.items
@ -129,7 +131,7 @@ def test_get():
reversed_url = reverse(url_name)
expected_order = 2
menu = Menu('menu-test', expected_name, expected_short_description,
expected_icon, url_name, order=expected_order)
expected_icon, url_name, order=expected_order, advanced=True)
actual_item = menu.get(expected_url)
assert actual_item is not None
@ -138,6 +140,7 @@ def test_get():
assert expected_icon == actual_item.icon
assert reversed_url == actual_item.url
assert expected_order == actual_item.order
assert actual_item.advanced
assert not actual_item.items

View File

@ -32,6 +32,7 @@ from stronghold.decorators import public
import plinth
from plinth import package
from plinth.modules.config import get_advanced_mode
from plinth.modules.storage import views as disk_views
from plinth.translation import get_language_from_request, set_language
@ -48,9 +49,7 @@ def index(request):
selected = request.GET.get('selected')
selected_shortcut = [
shortcut
for shortcut in shortcuts
if shortcut.component_id == selected
shortcut for shortcut in shortcuts if shortcut.component_id == selected
]
selected_shortcut = selected_shortcut[0] if selected_shortcut else None
@ -71,13 +70,15 @@ class AppsIndexView(TemplateView):
def get_context_data(self, *args, **kwargs):
context = super().get_context_data(*args, **kwargs)
context['show_disabled'] = True
context['advanced_mode'] = get_advanced_mode()
return context
def system_index(request):
"""Serve the system index page."""
disk_views.warn_about_low_disk_space(request)
return TemplateResponse(request, 'system.html')
return TemplateResponse(request, 'system.html',
{'advanced_mode': get_advanced_mode()})
class LanguageSelectionView(FormView):