##// END OF EJS Templates
navigation: allow specifing more than one active element to set as one selecting current navlist entry.
marcink -
r2399:731e2343 default
parent child Browse files
Show More
@@ -1,135 +1,143 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2016-2017 RhodeCode GmbH
3 # Copyright (C) 2016-2017 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
7 # (only), as published by the Free Software Foundation.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU Affero General Public License
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
16 #
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21
21
22 import logging
22 import logging
23 import collections
23 import collections
24
24
25 from zope.interface import implementer
25 from zope.interface import implementer
26
26
27 from rhodecode.apps.admin.interfaces import IAdminNavigationRegistry
27 from rhodecode.apps.admin.interfaces import IAdminNavigationRegistry
28 from rhodecode.lib.utils2 import str2bool
28 from rhodecode.lib.utils2 import str2bool
29 from rhodecode.translation import _
29 from rhodecode.translation import _
30
30
31
31
32 log = logging.getLogger(__name__)
32 log = logging.getLogger(__name__)
33
33
34 NavListEntry = collections.namedtuple('NavListEntry', ['key', 'name', 'url'])
34 NavListEntry = collections.namedtuple(
35 'NavListEntry', ['key', 'name', 'url', 'active_list'])
35
36
36
37
37 class NavEntry(object):
38 class NavEntry(object):
38 """
39 """
39 Represents an entry in the admin navigation.
40 Represents an entry in the admin navigation.
40
41
41 :param key: Unique identifier used to store reference in an OrderedDict.
42 :param key: Unique identifier used to store reference in an OrderedDict.
42 :param name: Display name, usually a translation string.
43 :param name: Display name, usually a translation string.
43 :param view_name: Name of the view, used generate the URL.
44 :param view_name: Name of the view, used generate the URL.
44 :param pyramid: Indicator to use pyramid for URL generation. This should
45 :param active_list: list of urls that we select active for this element
45 be removed as soon as we are fully migrated to pyramid.
46 """
46 """
47
47
48 def __init__(self, key, name, view_name):
48 def __init__(self, key, name, view_name, active_list=None):
49 self.key = key
49 self.key = key
50 self.name = name
50 self.name = name
51 self.view_name = view_name
51 self.view_name = view_name
52 self._active_list = active_list or []
52
53
53 def generate_url(self, request):
54 def generate_url(self, request):
54 return request.route_path(self.view_name)
55 return request.route_path(self.view_name)
55
56
56 def get_localized_name(self, request):
57 def get_localized_name(self, request):
57 return request.translate(self.name)
58 return request.translate(self.name)
58
59
60 @property
61 def active_list(self):
62 active_list = [self.key]
63 if self._active_list:
64 active_list = self._active_list
65 return active_list
66
59
67
60 @implementer(IAdminNavigationRegistry)
68 @implementer(IAdminNavigationRegistry)
61 class NavigationRegistry(object):
69 class NavigationRegistry(object):
62
70
63 _base_entries = [
71 _base_entries = [
64 NavEntry('global', _('Global'),
72 NavEntry('global', _('Global'),
65 'admin_settings_global'),
73 'admin_settings_global'),
66 NavEntry('vcs', _('VCS'),
74 NavEntry('vcs', _('VCS'),
67 'admin_settings_vcs'),
75 'admin_settings_vcs'),
68 NavEntry('visual', _('Visual'),
76 NavEntry('visual', _('Visual'),
69 'admin_settings_visual'),
77 'admin_settings_visual'),
70 NavEntry('mapping', _('Remap and Rescan'),
78 NavEntry('mapping', _('Remap and Rescan'),
71 'admin_settings_mapping'),
79 'admin_settings_mapping'),
72 NavEntry('issuetracker', _('Issue Tracker'),
80 NavEntry('issuetracker', _('Issue Tracker'),
73 'admin_settings_issuetracker'),
81 'admin_settings_issuetracker'),
74 NavEntry('email', _('Email'),
82 NavEntry('email', _('Email'),
75 'admin_settings_email'),
83 'admin_settings_email'),
76 NavEntry('hooks', _('Hooks'),
84 NavEntry('hooks', _('Hooks'),
77 'admin_settings_hooks'),
85 'admin_settings_hooks'),
78 NavEntry('search', _('Full Text Search'),
86 NavEntry('search', _('Full Text Search'),
79 'admin_settings_search'),
87 'admin_settings_search'),
80 NavEntry('integrations', _('Integrations'),
88 NavEntry('integrations', _('Integrations'),
81 'global_integrations_home'),
89 'global_integrations_home'),
82 NavEntry('system', _('System Info'),
90 NavEntry('system', _('System Info'),
83 'admin_settings_system'),
91 'admin_settings_system'),
84 NavEntry('process_management', _('Processes'),
92 NavEntry('process_management', _('Processes'),
85 'admin_settings_process_management'),
93 'admin_settings_process_management'),
86 NavEntry('sessions', _('User Sessions'),
94 NavEntry('sessions', _('User Sessions'),
87 'admin_settings_sessions'),
95 'admin_settings_sessions'),
88 NavEntry('open_source', _('Open Source Licenses'),
96 NavEntry('open_source', _('Open Source Licenses'),
89 'admin_settings_open_source'),
97 'admin_settings_open_source'),
90
98
91 ]
99 ]
92
100
93 _labs_entry = NavEntry('labs', _('Labs'),
101 _labs_entry = NavEntry('labs', _('Labs'),
94 'admin_settings_labs')
102 'admin_settings_labs')
95
103
96 def __init__(self, labs_active=False):
104 def __init__(self, labs_active=False):
97 self._registered_entries = collections.OrderedDict()
105 self._registered_entries = collections.OrderedDict()
98 for item in self.__class__._base_entries:
106 for item in self.__class__._base_entries:
99 self._registered_entries[item.key] = item
107 self._registered_entries[item.key] = item
100
108
101 if labs_active:
109 if labs_active:
102 self.add_entry(self._labs_entry)
110 self.add_entry(self._labs_entry)
103
111
104 def add_entry(self, entry):
112 def add_entry(self, entry):
105 self._registered_entries[entry.key] = entry
113 self._registered_entries[entry.key] = entry
106
114
107 def get_navlist(self, request):
115 def get_navlist(self, request):
108 navlist = [NavListEntry(i.key, i.get_localized_name(request),
116 navlist = [NavListEntry(i.key, i.get_localized_name(request),
109 i.generate_url(request))
117 i.generate_url(request), i.active_list)
110 for i in self._registered_entries.values()]
118 for i in self._registered_entries.values()]
111 return navlist
119 return navlist
112
120
113
121
114 def navigation_registry(request, registry=None):
122 def navigation_registry(request, registry=None):
115 """
123 """
116 Helper that returns the admin navigation registry.
124 Helper that returns the admin navigation registry.
117 """
125 """
118 pyramid_registry = registry or request.registry
126 pyramid_registry = registry or request.registry
119 nav_registry = pyramid_registry.queryUtility(IAdminNavigationRegistry)
127 nav_registry = pyramid_registry.queryUtility(IAdminNavigationRegistry)
120 return nav_registry
128 return nav_registry
121
129
122
130
123 def navigation_list(request):
131 def navigation_list(request):
124 """
132 """
125 Helper that returns the admin navigation as list of NavListEntry objects.
133 Helper that returns the admin navigation as list of NavListEntry objects.
126 """
134 """
127 return navigation_registry(request).get_navlist(request)
135 return navigation_registry(request).get_navlist(request)
128
136
129
137
130 def includeme(config):
138 def includeme(config):
131 # Create admin navigation registry and add it to the pyramid registry.
139 # Create admin navigation registry and add it to the pyramid registry.
132 settings = config.get_settings()
140 settings = config.get_settings()
133 labs_active = str2bool(settings.get('labs_settings_active', False))
141 labs_active = str2bool(settings.get('labs_settings_active', False))
134 navigation_registry = NavigationRegistry(labs_active=labs_active)
142 navigation_registry = NavigationRegistry(labs_active=labs_active)
135 config.registry.registerUtility(navigation_registry) No newline at end of file
143 config.registry.registerUtility(navigation_registry)
@@ -1,53 +1,53 b''
1 ## -*- coding: utf-8 -*-
1 ## -*- coding: utf-8 -*-
2 <%inherit file="/base/base.mako"/>
2 <%inherit file="/base/base.mako"/>
3
3
4 <%def name="title()">
4 <%def name="title()">
5 ${_('Settings administration')}
5 ${_('Settings administration')}
6 %if c.rhodecode_name:
6 %if c.rhodecode_name:
7 &middot; ${h.branding(c.rhodecode_name)}
7 &middot; ${h.branding(c.rhodecode_name)}
8 %endif
8 %endif
9 </%def>
9 </%def>
10
10
11 <%def name="breadcrumbs_links()">
11 <%def name="breadcrumbs_links()">
12 ${h.link_to(_('Admin'),h.route_path('admin_home'))}
12 ${h.link_to(_('Admin'),h.route_path('admin_home'))}
13 &raquo;
13 &raquo;
14 ${_('Settings')}
14 ${_('Settings')}
15 </%def>
15 </%def>
16
16
17 <%def name="menu_bar_nav()">
17 <%def name="menu_bar_nav()">
18 ${self.menu_items(active='admin')}
18 ${self.menu_items(active='admin')}
19 </%def>
19 </%def>
20
20
21 <%def name="side_bar_nav()">
21 <%def name="side_bar_nav()">
22 % for navitem in c.navlist:
22 % for navitem in c.navlist:
23 <li class="${'active' if c.active==navitem.key else ''}">
23 <li class="${'active' if c.active in navitem.active_list else ''}">
24 <a href="${navitem.url}">${navitem.name}</a>
24 <a href="${navitem.url}">${navitem.name}</a>
25 </li>
25 </li>
26 % endfor
26 % endfor
27 </%def>
27 </%def>
28
28
29 <%def name="main_content()">
29 <%def name="main_content()">
30 <%include file="/admin/settings/settings_${c.active}.mako"/>
30 <%include file="/admin/settings/settings_${c.active}.mako"/>
31 </%def>
31 </%def>
32
32
33 <%def name="main()">
33 <%def name="main()">
34 <div class="box">
34 <div class="box">
35 <div class="title">
35 <div class="title">
36 ${self.breadcrumbs()}
36 ${self.breadcrumbs()}
37 </div>
37 </div>
38
38
39 ##main
39 ##main
40 <div class='sidebar-col-wrapper'>
40 <div class='sidebar-col-wrapper'>
41 <div class="sidebar">
41 <div class="sidebar">
42 <ul class="nav nav-pills nav-stacked">
42 <ul class="nav nav-pills nav-stacked">
43 ${self.side_bar_nav()}
43 ${self.side_bar_nav()}
44 </ul>
44 </ul>
45 </div>
45 </div>
46
46
47 <div class="main-content-full-width">
47 <div class="main-content-full-width">
48 ${self.main_content()}
48 ${self.main_content()}
49 </div>
49 </div>
50 </div>
50 </div>
51 </div>
51 </div>
52
52
53 </%def> No newline at end of file
53 </%def>
General Comments 0
You need to be logged in to leave comments. Login now