Show More
@@ -0,0 +1,38 b'' | |||||
|
1 | # Copyright (C) 2016-2023 RhodeCode GmbH | |||
|
2 | # | |||
|
3 | # This program is free software: you can redistribute it and/or modify | |||
|
4 | # it under the terms of the GNU Affero General Public License, version 3 | |||
|
5 | # (only), as published by the Free Software Foundation. | |||
|
6 | # | |||
|
7 | # This program is distributed in the hope that it will be useful, | |||
|
8 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
|
9 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
|
10 | # GNU General Public License for more details. | |||
|
11 | # | |||
|
12 | # You should have received a copy of the GNU Affero General Public License | |||
|
13 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
|
14 | # | |||
|
15 | # This program is dual-licensed. If you wish to learn more about the | |||
|
16 | # RhodeCode Enterprise Edition, including its added features, Support services, | |||
|
17 | # and proprietary license terms, please see https://rhodecode.com/licenses/ | |||
|
18 | ||||
|
19 | import logging | |||
|
20 | ||||
|
21 | from rhodecode.apps._base import BaseAppView | |||
|
22 | from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator | |||
|
23 | ||||
|
24 | log = logging.getLogger(__name__) | |||
|
25 | ||||
|
26 | ||||
|
27 | class AdminAutomationView(BaseAppView): | |||
|
28 | ||||
|
29 | def load_default_context(self): | |||
|
30 | c = self._get_local_tmpl_context() | |||
|
31 | return c | |||
|
32 | ||||
|
33 | @LoginRequired() | |||
|
34 | @HasPermissionAllDecorator('hg.admin') | |||
|
35 | def automation(self): | |||
|
36 | c = self.load_default_context() | |||
|
37 | c.active = 'automation' | |||
|
38 | return self._get_template_context(c) |
@@ -0,0 +1,38 b'' | |||||
|
1 | # Copyright (C) 2016-2023 RhodeCode GmbH | |||
|
2 | # | |||
|
3 | # This program is free software: you can redistribute it and/or modify | |||
|
4 | # it under the terms of the GNU Affero General Public License, version 3 | |||
|
5 | # (only), as published by the Free Software Foundation. | |||
|
6 | # | |||
|
7 | # This program is distributed in the hope that it will be useful, | |||
|
8 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
|
9 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
|
10 | # GNU General Public License for more details. | |||
|
11 | # | |||
|
12 | # You should have received a copy of the GNU Affero General Public License | |||
|
13 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
|
14 | # | |||
|
15 | # This program is dual-licensed. If you wish to learn more about the | |||
|
16 | # RhodeCode Enterprise Edition, including its added features, Support services, | |||
|
17 | # and proprietary license terms, please see https://rhodecode.com/licenses/ | |||
|
18 | ||||
|
19 | import logging | |||
|
20 | ||||
|
21 | from rhodecode.apps._base import BaseAppView | |||
|
22 | from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator | |||
|
23 | ||||
|
24 | log = logging.getLogger(__name__) | |||
|
25 | ||||
|
26 | ||||
|
27 | class AdminSchedulerView(BaseAppView): | |||
|
28 | ||||
|
29 | def load_default_context(self): | |||
|
30 | c = self._get_local_tmpl_context() | |||
|
31 | return c | |||
|
32 | ||||
|
33 | @LoginRequired() | |||
|
34 | @HasPermissionAllDecorator('hg.admin') | |||
|
35 | def scheduler(self): | |||
|
36 | c = self.load_default_context() | |||
|
37 | c.active = 'scheduler' | |||
|
38 | return self._get_template_context(c) |
@@ -0,0 +1,39 b'' | |||||
|
1 | <%inherit file="/base/base.mako"/> | |||
|
2 | ||||
|
3 | <%def name="title()"> | |||
|
4 | ${_('Artifacts Admin')} | |||
|
5 | %if c.rhodecode_name: | |||
|
6 | · ${h.branding(c.rhodecode_name)} | |||
|
7 | %endif | |||
|
8 | </%def> | |||
|
9 | ||||
|
10 | <%def name="breadcrumbs_links()"></%def> | |||
|
11 | ||||
|
12 | <%def name="menu_bar_nav()"> | |||
|
13 | ${self.menu_items(active='admin')} | |||
|
14 | </%def> | |||
|
15 | ||||
|
16 | <%def name="menu_bar_subnav()"> | |||
|
17 | ${self.admin_menu(active='scheduler')} | |||
|
18 | </%def> | |||
|
19 | ||||
|
20 | <%def name="main()"> | |||
|
21 | ||||
|
22 | <div class="box"> | |||
|
23 | ||||
|
24 | <div class="panel panel-default"> | |||
|
25 | <div class="panel-heading"> | |||
|
26 | <h3 class="panel-title">${_('Scheduler Administration.')}</h3> | |||
|
27 | </div> | |||
|
28 | <div class="panel-body"> | |||
|
29 | <h4>${_('This feature is available in RhodeCode EE edition only. Contact {sales_email} to obtain a trial license.').format(sales_email='<a href="mailto:sales@rhodecode.com">sales@rhodecode.com</a>')|n}</h4> | |||
|
30 | <p> | |||
|
31 | Scheduler enables management of automation tasks, and defining new custom cron-like actions to be executed within RhodeCode system. | |||
|
32 | </p> | |||
|
33 | </div> | |||
|
34 | </div> | |||
|
35 | ||||
|
36 | </div> | |||
|
37 | ||||
|
38 | ||||
|
39 | </%def> |
@@ -0,0 +1,37 b'' | |||||
|
1 | <%inherit file="/base/base.mako"/> | |||
|
2 | ||||
|
3 | <%def name="title()"> | |||
|
4 | ${_('Artifacts Admin')} | |||
|
5 | %if c.rhodecode_name: | |||
|
6 | · ${h.branding(c.rhodecode_name)} | |||
|
7 | %endif | |||
|
8 | </%def> | |||
|
9 | ||||
|
10 | <%def name="breadcrumbs_links()"></%def> | |||
|
11 | ||||
|
12 | <%def name="menu_bar_nav()"> | |||
|
13 | ${self.menu_items(active='admin')} | |||
|
14 | </%def> | |||
|
15 | ||||
|
16 | <%def name="menu_bar_subnav()"> | |||
|
17 | ${self.admin_menu(active='automation')} | |||
|
18 | </%def> | |||
|
19 | ||||
|
20 | <%def name="main()"> | |||
|
21 | ||||
|
22 | <div class="box"> | |||
|
23 | ||||
|
24 | <div class="panel panel-default"> | |||
|
25 | <div class="panel-heading"> | |||
|
26 | <h3 class="panel-title">${_('Automation Administration.')}</h3> | |||
|
27 | </div> | |||
|
28 | <div class="panel-body"> | |||
|
29 | <h4>${_('This feature is available in RhodeCode EE edition only. Contact {sales_email} to obtain a trial license.').format(sales_email='<a href="mailto:sales@rhodecode.com">sales@rhodecode.com</a>')|n}</h4> | |||
|
30 | <img style="width: 100%; height: 100%" src="${h.asset('images/ee_features/admin_automation.png')}"/> | |||
|
31 | </div> | |||
|
32 | </div> | |||
|
33 | ||||
|
34 | </div> | |||
|
35 | ||||
|
36 | ||||
|
37 | </%def> |
@@ -42,8 +42,8 b' from rhodecode.model.repo import ReadmeF' | |||||
42 | log = logging.getLogger(__name__) |
|
42 | log = logging.getLogger(__name__) | |
43 |
|
43 | |||
44 |
|
44 | |||
45 | ADMIN_PREFIX = '/_admin' |
|
45 | ADMIN_PREFIX: str = '/_admin' | |
46 | STATIC_FILE_PREFIX = '/_static' |
|
46 | STATIC_FILE_PREFIX: str = '/_static' | |
47 |
|
47 | |||
48 | URL_NAME_REQUIREMENTS = { |
|
48 | URL_NAME_REQUIREMENTS = { | |
49 | # group name can have a slash in them, but they must not end with a slash |
|
49 | # group name can have a slash in them, but they must not end with a slash |
@@ -101,8 +101,6 b' class NavigationRegistry(object):' | |||||
101 | 'admin_settings_sessions'), |
|
101 | 'admin_settings_sessions'), | |
102 | NavEntry('open_source', _('Open Source Licenses'), |
|
102 | NavEntry('open_source', _('Open Source Licenses'), | |
103 | 'admin_settings_open_source'), |
|
103 | 'admin_settings_open_source'), | |
104 | NavEntry('automation', _('Automation'), |
|
|||
105 | 'admin_settings_automation') |
|
|||
106 | ] |
|
104 | ] | |
107 |
|
105 | |||
108 | _labs_entry = NavEntry('labs', _('Labs'), |
|
106 | _labs_entry = NavEntry('labs', _('Labs'), |
@@ -18,6 +18,8 b'' | |||||
18 |
|
18 | |||
19 |
|
19 | |||
20 | from rhodecode.apps._base import ADMIN_PREFIX |
|
20 | from rhodecode.apps._base import ADMIN_PREFIX | |
|
21 | from rhodecode.apps._base.navigation import includeme as nav_includeme | |||
|
22 | from rhodecode.apps.admin.views.main_views import AdminMainView | |||
21 |
|
23 | |||
22 |
|
24 | |||
23 | def admin_routes(config): |
|
25 | def admin_routes(config): | |
@@ -26,9 +28,10 b' def admin_routes(config):' | |||||
26 | """ |
|
28 | """ | |
27 | from rhodecode.apps.admin.views.audit_logs import AdminAuditLogsView |
|
29 | from rhodecode.apps.admin.views.audit_logs import AdminAuditLogsView | |
28 | from rhodecode.apps.admin.views.artifacts import AdminArtifactsView |
|
30 | from rhodecode.apps.admin.views.artifacts import AdminArtifactsView | |
|
31 | from rhodecode.apps.admin.views.automation import AdminAutomationView | |||
|
32 | from rhodecode.apps.admin.views.scheduler import AdminSchedulerView | |||
29 | from rhodecode.apps.admin.views.defaults import AdminDefaultSettingsView |
|
33 | from rhodecode.apps.admin.views.defaults import AdminDefaultSettingsView | |
30 | from rhodecode.apps.admin.views.exception_tracker import ExceptionsTrackerView |
|
34 | from rhodecode.apps.admin.views.exception_tracker import ExceptionsTrackerView | |
31 | from rhodecode.apps.admin.views.main_views import AdminMainView |
|
|||
32 | from rhodecode.apps.admin.views.open_source_licenses import OpenSourceLicensesAdminSettingsView |
|
35 | from rhodecode.apps.admin.views.open_source_licenses import OpenSourceLicensesAdminSettingsView | |
33 | from rhodecode.apps.admin.views.permissions import AdminPermissionsView |
|
36 | from rhodecode.apps.admin.views.permissions import AdminPermissionsView | |
34 | from rhodecode.apps.admin.views.process_management import AdminProcessManagementView |
|
37 | from rhodecode.apps.admin.views.process_management import AdminProcessManagementView | |
@@ -76,6 +79,7 b' def admin_routes(config):' | |||||
76 | attr='artifacts', |
|
79 | attr='artifacts', | |
77 | route_name='admin_artifacts_show_all', request_method='GET', |
|
80 | route_name='admin_artifacts_show_all', request_method='GET', | |
78 | renderer='rhodecode:templates/admin/artifacts/artifacts.mako') |
|
81 | renderer='rhodecode:templates/admin/artifacts/artifacts.mako') | |
|
82 | ||||
79 | # EE views |
|
83 | # EE views | |
80 | config.add_route( |
|
84 | config.add_route( | |
81 | name='admin_artifacts_show_info', |
|
85 | name='admin_artifacts_show_info', | |
@@ -87,6 +91,26 b' def admin_routes(config):' | |||||
87 | name='admin_artifacts_update', |
|
91 | name='admin_artifacts_update', | |
88 | pattern=ADMIN_PREFIX + '/artifacts/{uid}/update') |
|
92 | pattern=ADMIN_PREFIX + '/artifacts/{uid}/update') | |
89 |
|
93 | |||
|
94 | # Automation EE feature | |||
|
95 | config.add_route( | |||
|
96 | 'admin_automation', | |||
|
97 | pattern=ADMIN_PREFIX + '/automation') | |||
|
98 | config.add_view( | |||
|
99 | AdminAutomationView, | |||
|
100 | attr='automation', | |||
|
101 | route_name='admin_automation', request_method='GET', | |||
|
102 | renderer='rhodecode:templates/admin/automation/automation.mako') | |||
|
103 | ||||
|
104 | # Scheduler EE feature | |||
|
105 | config.add_route( | |||
|
106 | 'admin_scheduler', | |||
|
107 | pattern=ADMIN_PREFIX + '/scheduler') | |||
|
108 | config.add_view( | |||
|
109 | AdminSchedulerView, | |||
|
110 | attr='scheduler', | |||
|
111 | route_name='admin_scheduler', request_method='GET', | |||
|
112 | renderer='rhodecode:templates/admin/scheduler/scheduler.mako') | |||
|
113 | ||||
90 | config.add_route( |
|
114 | config.add_route( | |
91 | name='admin_settings_open_source', |
|
115 | name='admin_settings_open_source', | |
92 | pattern='/settings/open_source') |
|
116 | pattern='/settings/open_source') | |
@@ -440,16 +464,6 b' def admin_routes(config):' | |||||
440 | route_name='admin_settings_labs_update', request_method='POST', |
|
464 | route_name='admin_settings_labs_update', request_method='POST', | |
441 | renderer='rhodecode:templates/admin/settings/settings.mako') |
|
465 | renderer='rhodecode:templates/admin/settings/settings.mako') | |
442 |
|
466 | |||
443 | # Automation EE feature |
|
|||
444 | config.add_route( |
|
|||
445 | 'admin_settings_automation', |
|
|||
446 | pattern=ADMIN_PREFIX + '/settings/automation') |
|
|||
447 | config.add_view( |
|
|||
448 | AdminSettingsView, |
|
|||
449 | attr='settings_automation', |
|
|||
450 | route_name='admin_settings_automation', request_method='GET', |
|
|||
451 | renderer='rhodecode:templates/admin/settings/settings.mako') |
|
|||
452 |
|
||||
453 | # global permissions |
|
467 | # global permissions | |
454 |
|
468 | |||
455 | config.add_route( |
|
469 | config.add_route( | |
@@ -1039,9 +1053,6 b' def admin_routes(config):' | |||||
1039 |
|
1053 | |||
1040 |
|
1054 | |||
1041 | def includeme(config): |
|
1055 | def includeme(config): | |
1042 | from rhodecode.apps._base.navigation import includeme as nav_includeme |
|
|||
1043 | from rhodecode.apps.admin.views.main_views import AdminMainView |
|
|||
1044 |
|
||||
1045 | # Create admin navigation registry and add it to the pyramid registry. |
|
1056 | # Create admin navigation registry and add it to the pyramid registry. | |
1046 | nav_includeme(config) |
|
1057 | nav_includeme(config) | |
1047 |
|
1058 |
@@ -248,8 +248,9 b' class AdminSettingsView(BaseAppView):' | |||||
248 | added, removed = repo2db_mapper(filesystem_repos, rm_obsolete) |
|
248 | added, removed = repo2db_mapper(filesystem_repos, rm_obsolete) | |
249 | PermissionModel().trigger_permission_flush() |
|
249 | PermissionModel().trigger_permission_flush() | |
250 |
|
250 | |||
251 |
def _repr( |
|
251 | def _repr(rm_repo): | |
252 |
return ', '.join(map(safe_str, |
|
252 | return ', '.join(map(safe_str, rm_repo)) or '-' | |
|
253 | ||||
253 | h.flash(_('Repositories successfully ' |
|
254 | h.flash(_('Repositories successfully ' | |
254 | 'rescanned added: %s ; removed: %s') % |
|
255 | 'rescanned added: %s ; removed: %s') % | |
255 | (_repr(added), _repr(removed)), |
|
256 | (_repr(added), _repr(removed)), | |
@@ -623,14 +624,6 b' class AdminSettingsView(BaseAppView):' | |||||
623 |
|
624 | |||
624 | @LoginRequired() |
|
625 | @LoginRequired() | |
625 | @HasPermissionAllDecorator('hg.admin') |
|
626 | @HasPermissionAllDecorator('hg.admin') | |
626 | def settings_automation(self): |
|
|||
627 | c = self.load_default_context() |
|
|||
628 | c.active = 'automation' |
|
|||
629 |
|
||||
630 | return self._get_template_context(c) |
|
|||
631 |
|
||||
632 | @LoginRequired() |
|
|||
633 | @HasPermissionAllDecorator('hg.admin') |
|
|||
634 | def settings_labs(self): |
|
627 | def settings_labs(self): | |
635 | c = self.load_default_context() |
|
628 | c = self.load_default_context() | |
636 | if not c.labs_active: |
|
629 | if not c.labs_active: |
@@ -413,6 +413,7 b' class RepoFilesView(RepoAppView):' | |||||
413 | archive_cache_disable = self.request.GET.get('no_cache') |
|
413 | archive_cache_disable = self.request.GET.get('no_cache') | |
414 |
|
414 | |||
415 | d_cache = get_archival_cache_store(config=CONFIG) |
|
415 | d_cache = get_archival_cache_store(config=CONFIG) | |
|
416 | ||||
416 | # NOTE: we get the config to pass to a call to lazy-init the SAME type of cache on vcsserver |
|
417 | # NOTE: we get the config to pass to a call to lazy-init the SAME type of cache on vcsserver | |
417 | d_cache_conf = get_archival_config(config=CONFIG) |
|
418 | d_cache_conf = get_archival_config(config=CONFIG) | |
418 |
|
419 |
@@ -30,6 +30,9 b' class PullRequestEvent(RepoEvent):' | |||||
30 |
|
30 | |||
31 | :param pullrequest: a :class:`PullRequest` instance |
|
31 | :param pullrequest: a :class:`PullRequest` instance | |
32 | """ |
|
32 | """ | |
|
33 | name = 'pullrequest-event' | |||
|
34 | display_name = lazy_ugettext('pullrequest generic event') | |||
|
35 | description = lazy_ugettext('All events within a context of a pull request') | |||
33 |
|
36 | |||
34 | def __init__(self, pullrequest): |
|
37 | def __init__(self, pullrequest): | |
35 | super().__init__(pullrequest.target_repo) |
|
38 | super().__init__(pullrequest.target_repo) |
@@ -21,7 +21,7 b' import logging' | |||||
21 | import datetime |
|
21 | import datetime | |
22 |
|
22 | |||
23 | from rhodecode.translation import lazy_ugettext |
|
23 | from rhodecode.translation import lazy_ugettext | |
24 |
from rhodecode.model.db import User, Repository |
|
24 | from rhodecode.model.db import User, Repository | |
25 | from rhodecode.events.base import RhodeCodeIntegrationEvent |
|
25 | from rhodecode.events.base import RhodeCodeIntegrationEvent | |
26 | from rhodecode.lib.vcs.exceptions import CommitDoesNotExistError |
|
26 | from rhodecode.lib.vcs.exceptions import CommitDoesNotExistError | |
27 |
|
27 | |||
@@ -34,7 +34,7 b' def _commits_as_dict(event, commit_ids, ' | |||||
34 |
|
34 | |||
35 | :param event: class calling this method |
|
35 | :param event: class calling this method | |
36 | :param commit_ids: commits to get |
|
36 | :param commit_ids: commits to get | |
37 | :param repos: list of repos to check |
|
37 | :param repos: a list of repos to check | |
38 | """ |
|
38 | """ | |
39 | from rhodecode.lib.utils2 import extract_mentioned_users |
|
39 | from rhodecode.lib.utils2 import extract_mentioned_users | |
40 | from rhodecode.lib.helpers import ( |
|
40 | from rhodecode.lib.helpers import ( | |
@@ -154,11 +154,12 b' def _issues_as_dict(commits):' | |||||
154 | class RepoEvent(RhodeCodeIntegrationEvent): |
|
154 | class RepoEvent(RhodeCodeIntegrationEvent): | |
155 | """ |
|
155 | """ | |
156 | Base class for events acting on a repository. |
|
156 | Base class for events acting on a repository. | |
157 |
|
||||
158 | :param repo: a :class:`Repository` instance |
|
|||
159 | """ |
|
157 | """ | |
160 |
|
158 | |||
161 | def __init__(self, repo): |
|
159 | def __init__(self, repo): | |
|
160 | """ | |||
|
161 | :param repo: a :class:`Repository` instance | |||
|
162 | """ | |||
162 | super().__init__() |
|
163 | super().__init__() | |
163 | self.repo = repo |
|
164 | self.repo = repo | |
164 |
|
165 | |||
@@ -299,6 +300,9 b' class RepoVCSEvent(RepoEvent):' | |||||
299 | """ |
|
300 | """ | |
300 | Base class for events triggered by the VCS |
|
301 | Base class for events triggered by the VCS | |
301 | """ |
|
302 | """ | |
|
303 | name = '' | |||
|
304 | display_name = 'generic_vcs_event' | |||
|
305 | ||||
302 | def __init__(self, repo_name, extras): |
|
306 | def __init__(self, repo_name, extras): | |
303 | self.repo = Repository.get_by_repo_name(repo_name) |
|
307 | self.repo = Repository.get_by_repo_name(repo_name) | |
304 | if not self.repo: |
|
308 | if not self.repo: |
@@ -44,7 +44,7 b' def run_task(task, *args, **kwargs):' | |||||
44 | import celery |
|
44 | import celery | |
45 | log.debug('Got task `%s` for execution, celery mode enabled:%s', task, rhodecode.CELERY_ENABLED) |
|
45 | log.debug('Got task `%s` for execution, celery mode enabled:%s', task, rhodecode.CELERY_ENABLED) | |
46 | if task is None: |
|
46 | if task is None: | |
47 | raise ValueError('Got non-existing task for execution') |
|
47 | raise ValueError(f'Got non-existing task: {task} for execution') | |
48 |
|
48 | |||
49 | exec_mode = 'sync' |
|
49 | exec_mode = 'sync' | |
50 | allow_async = True |
|
50 | allow_async = True |
@@ -19,9 +19,7 b'' | |||||
19 |
|
19 | |||
20 | import sqlalchemy |
|
20 | import sqlalchemy | |
21 | from sqlalchemy import UnicodeText |
|
21 | from sqlalchemy import UnicodeText | |
22 |
from sqlalchemy.ext.mutable import Mutable, |
|
22 | from sqlalchemy.ext.mutable import Mutable, MutableList, MutableDict | |
23 | MutableList as MutationList, \ |
|
|||
24 | MutableDict as MutationDict |
|
|||
25 |
|
23 | |||
26 | from rhodecode.lib import ext_json |
|
24 | from rhodecode.lib import ext_json | |
27 |
|
25 | |||
@@ -30,7 +28,7 b' class JsonRaw(str):' | |||||
30 | """ |
|
28 | """ | |
31 | Allows interacting with a JSON types field using a raw string. |
|
29 | Allows interacting with a JSON types field using a raw string. | |
32 |
|
30 | |||
33 |
For example: |
|
31 | For example: | |
34 | db_instance = JsonTable() |
|
32 | db_instance = JsonTable() | |
35 | db_instance.enabled = True |
|
33 | db_instance.enabled = True | |
36 | db_instance.json_data = JsonRaw('{"a": 4}') |
|
34 | db_instance.json_data = JsonRaw('{"a": 4}') | |
@@ -100,7 +98,7 b' class MutationObj(Mutable):' | |||||
100 | return MutationList.coerce(key, value) |
|
98 | return MutationList.coerce(key, value) | |
101 | return value |
|
99 | return value | |
102 |
|
100 | |||
103 | def de_coerce(self): |
|
101 | def de_coerce(self) -> "MutationObj": | |
104 | return self |
|
102 | return self | |
105 |
|
103 | |||
106 | @classmethod |
|
104 | @classmethod | |
@@ -153,6 +151,16 b' class MutationObj(Mutable):' | |||||
153 | propagate=True) |
|
151 | propagate=True) | |
154 |
|
152 | |||
155 |
|
153 | |||
|
154 | class MutationList(MutableList): | |||
|
155 | def de_coerce(self): | |||
|
156 | return list(self) | |||
|
157 | ||||
|
158 | ||||
|
159 | class MutationDict(MutableDict): | |||
|
160 | def de_coerce(self): | |||
|
161 | return dict(self) | |||
|
162 | ||||
|
163 | ||||
156 | def JsonType(impl=None, **kwargs): |
|
164 | def JsonType(impl=None, **kwargs): | |
157 | """ |
|
165 | """ | |
158 | Helper for using a mutation obj, it allows to use .with_variant easily. |
|
166 | Helper for using a mutation obj, it allows to use .with_variant easily. |
@@ -5378,14 +5378,14 b' class ScheduleEntry(Base, BaseModel):' | |||||
5378 | except ValueError: |
|
5378 | except ValueError: | |
5379 | return dict() |
|
5379 | return dict() | |
5380 |
|
5380 | |||
5381 |
def _as_raw(self, val, indent= |
|
5381 | def _as_raw(self, val, indent=False): | |
5382 | if hasattr(val, 'de_coerce'): |
|
5382 | if hasattr(val, 'de_coerce'): | |
5383 | val = val.de_coerce() |
|
5383 | val = val.de_coerce() | |
5384 | if val: |
|
5384 | if val: | |
5385 | if indent: |
|
5385 | if indent: | |
5386 | ext_json.formatted_json(val) |
|
5386 | val = ext_json.formatted_str_json(val) | |
5387 | else: |
|
5387 | else: | |
5388 |
val = ext_json.json |
|
5388 | val = ext_json.str_json(val) | |
5389 |
|
5389 | |||
5390 | return val |
|
5390 | return val | |
5391 |
|
5391 | |||
@@ -5393,10 +5393,10 b' class ScheduleEntry(Base, BaseModel):' | |||||
5393 | def schedule_definition_raw(self): |
|
5393 | def schedule_definition_raw(self): | |
5394 | return self._as_raw(self.schedule_definition) |
|
5394 | return self._as_raw(self.schedule_definition) | |
5395 |
|
5395 | |||
5396 |
def args_raw(self, indent= |
|
5396 | def args_raw(self, indent=False): | |
5397 | return self._as_raw(self.task_args, indent) |
|
5397 | return self._as_raw(self.task_args, indent) | |
5398 |
|
5398 | |||
5399 |
def kwargs_raw(self, indent= |
|
5399 | def kwargs_raw(self, indent=False): | |
5400 | return self._as_raw(self.task_kwargs, indent) |
|
5400 | return self._as_raw(self.task_kwargs, indent) | |
5401 |
|
5401 | |||
5402 | def __repr__(self): |
|
5402 | def __repr__(self): | |
@@ -5610,6 +5610,19 b' class FileStore(Base, BaseModel):' | |||||
5610 | repo_group = relationship('RepoGroup', lazy='joined') |
|
5610 | repo_group = relationship('RepoGroup', lazy='joined') | |
5611 |
|
5611 | |||
5612 | @classmethod |
|
5612 | @classmethod | |
|
5613 | def get_scope(cls, scope_type, scope_id): | |||
|
5614 | if scope_type == 'repo': | |||
|
5615 | return f'repo:{scope_id}' | |||
|
5616 | elif scope_type == 'repo-group': | |||
|
5617 | return f'repo-group:{scope_id}' | |||
|
5618 | elif scope_type == 'user': | |||
|
5619 | return f'user:{scope_id}' | |||
|
5620 | elif scope_type == 'user-group': | |||
|
5621 | return f'user-group:{scope_id}' | |||
|
5622 | else: | |||
|
5623 | return scope_type | |||
|
5624 | ||||
|
5625 | @classmethod | |||
5613 | def get_by_store_uid(cls, file_store_uid, safe=False): |
|
5626 | def get_by_store_uid(cls, file_store_uid, safe=False): | |
5614 | if safe: |
|
5627 | if safe: | |
5615 | return FileStore.query().filter(FileStore.file_uid == file_store_uid).first() |
|
5628 | return FileStore.query().filter(FileStore.file_uid == file_store_uid).first() |
@@ -25,7 +25,7 b' import colander' | |||||
25 | from rhodecode.translation import _ |
|
25 | from rhodecode.translation import _ | |
26 | from rhodecode.lib.utils2 import glob2re |
|
26 | from rhodecode.lib.utils2 import glob2re | |
27 | from rhodecode.lib.str_utils import safe_str |
|
27 | from rhodecode.lib.str_utils import safe_str | |
28 | from rhodecode.lib.ext_json import json |
|
28 | from rhodecode.lib.ext_json import json, sjson | |
29 |
|
29 | |||
30 | log = logging.getLogger(__name__) |
|
30 | log = logging.getLogger(__name__) | |
31 |
|
31 | |||
@@ -152,8 +152,9 b' def json_validator(node, value):' | |||||
152 |
|
152 | |||
153 |
|
153 | |||
154 | def json_validator_with_exc(node, value): |
|
154 | def json_validator_with_exc(node, value): | |
|
155 | ||||
155 | try: |
|
156 | try: | |
156 | json.loads(value) |
|
157 | json.loads(value) | |
157 | except (Exception,) as e: |
|
158 | except (Exception,) as e: | |
158 | msg = _(f'Please enter a valid json object: `{e}`') |
|
159 | msg = _(f'Please enter a valid json object type={type(value)}: `{e}`') | |
159 | raise colander.Invalid(node, msg) |
|
160 | raise colander.Invalid(node, msg) |
@@ -20,6 +20,8 b' function registerRCRoutes() {' | |||||
20 | pyroutes.register('admin_artifacts_update', '/_admin/artifacts/%(uid)s/update', ['uid']); |
|
20 | pyroutes.register('admin_artifacts_update', '/_admin/artifacts/%(uid)s/update', ['uid']); | |
21 | pyroutes.register('admin_audit_log_entry', '/_admin/audit_logs/%(audit_log_id)s', ['audit_log_id']); |
|
21 | pyroutes.register('admin_audit_log_entry', '/_admin/audit_logs/%(audit_log_id)s', ['audit_log_id']); | |
22 | pyroutes.register('admin_audit_logs', '/_admin/audit_logs', []); |
|
22 | pyroutes.register('admin_audit_logs', '/_admin/audit_logs', []); | |
|
23 | pyroutes.register('admin_automation', '/_admin/automation', []); | |||
|
24 | pyroutes.register('admin_automation_update', '/_admin/automation/%(entry_id)s/update', ['entry_id']); | |||
23 | pyroutes.register('admin_defaults_repositories', '/_admin/defaults/repositories', []); |
|
25 | pyroutes.register('admin_defaults_repositories', '/_admin/defaults/repositories', []); | |
24 | pyroutes.register('admin_defaults_repositories_update', '/_admin/defaults/repositories/update', []); |
|
26 | pyroutes.register('admin_defaults_repositories_update', '/_admin/defaults/repositories/update', []); | |
25 | pyroutes.register('admin_home', '/_admin', []); |
|
27 | pyroutes.register('admin_home', '/_admin', []); | |
@@ -37,9 +39,9 b' function registerRCRoutes() {' | |||||
37 | pyroutes.register('admin_permissions_ssh_keys', '/_admin/permissions/ssh_keys', []); |
|
39 | pyroutes.register('admin_permissions_ssh_keys', '/_admin/permissions/ssh_keys', []); | |
38 | pyroutes.register('admin_permissions_ssh_keys_data', '/_admin/permissions/ssh_keys/data', []); |
|
40 | pyroutes.register('admin_permissions_ssh_keys_data', '/_admin/permissions/ssh_keys/data', []); | |
39 | pyroutes.register('admin_permissions_ssh_keys_update', '/_admin/permissions/ssh_keys/update', []); |
|
41 | pyroutes.register('admin_permissions_ssh_keys_update', '/_admin/permissions/ssh_keys/update', []); | |
|
42 | pyroutes.register('admin_scheduler', '/_admin/scheduler', []); | |||
|
43 | pyroutes.register('admin_scheduler_show_tasks', '/_admin/scheduler/_tasks', []); | |||
40 | pyroutes.register('admin_settings', '/_admin/settings', []); |
|
44 | pyroutes.register('admin_settings', '/_admin/settings', []); | |
41 | pyroutes.register('admin_settings_automation', '/_admin/settings/automation', []); |
|
|||
42 | pyroutes.register('admin_settings_automation_update', '/_admin/settings/automation/%(entry_id)s/update', ['entry_id']); |
|
|||
43 | pyroutes.register('admin_settings_email', '/_admin/settings/email', []); |
|
45 | pyroutes.register('admin_settings_email', '/_admin/settings/email', []); | |
44 | pyroutes.register('admin_settings_email_update', '/_admin/settings/email/update', []); |
|
46 | pyroutes.register('admin_settings_email_update', '/_admin/settings/email/update', []); | |
45 | pyroutes.register('admin_settings_exception_tracker', '/_admin/settings/exceptions', []); |
|
47 | pyroutes.register('admin_settings_exception_tracker', '/_admin/settings/exceptions', []); | |
@@ -66,14 +68,12 b' function registerRCRoutes() {' | |||||
66 | pyroutes.register('admin_settings_process_management_data', '/_admin/settings/process_management/data', []); |
|
68 | pyroutes.register('admin_settings_process_management_data', '/_admin/settings/process_management/data', []); | |
67 | pyroutes.register('admin_settings_process_management_master_signal', '/_admin/settings/process_management/master_signal', []); |
|
69 | pyroutes.register('admin_settings_process_management_master_signal', '/_admin/settings/process_management/master_signal', []); | |
68 | pyroutes.register('admin_settings_process_management_signal', '/_admin/settings/process_management/signal', []); |
|
70 | pyroutes.register('admin_settings_process_management_signal', '/_admin/settings/process_management/signal', []); | |
69 |
pyroutes.register('admin_settings_scheduler_create', '/_admin/s |
|
71 | pyroutes.register('admin_settings_scheduler_create', '/_admin/scheduler/create', []); | |
70 |
pyroutes.register('admin_settings_scheduler_delete', '/_admin/s |
|
72 | pyroutes.register('admin_settings_scheduler_delete', '/_admin/scheduler/%(schedule_id)s/delete', ['schedule_id']); | |
71 |
pyroutes.register('admin_settings_scheduler_edit', '/_admin/s |
|
73 | pyroutes.register('admin_settings_scheduler_edit', '/_admin/scheduler/%(schedule_id)s', ['schedule_id']); | |
72 |
pyroutes.register('admin_settings_scheduler_execute', '/_admin/s |
|
74 | pyroutes.register('admin_settings_scheduler_execute', '/_admin/scheduler/%(schedule_id)s/execute', ['schedule_id']); | |
73 |
pyroutes.register('admin_settings_scheduler_new', '/_admin/s |
|
75 | pyroutes.register('admin_settings_scheduler_new', '/_admin/scheduler/new', []); | |
74 |
pyroutes.register('admin_settings_scheduler_ |
|
76 | pyroutes.register('admin_settings_scheduler_update', '/_admin/scheduler/%(schedule_id)s/update', ['schedule_id']); | |
75 | pyroutes.register('admin_settings_scheduler_show_tasks', '/_admin/settings/scheduler/_tasks', []); |
|
|||
76 | pyroutes.register('admin_settings_scheduler_update', '/_admin/settings/scheduler/%(schedule_id)s/update', ['schedule_id']); |
|
|||
77 | pyroutes.register('admin_settings_search', '/_admin/settings/search', []); |
|
77 | pyroutes.register('admin_settings_search', '/_admin/settings/search', []); | |
78 | pyroutes.register('admin_settings_sessions', '/_admin/settings/sessions', []); |
|
78 | pyroutes.register('admin_settings_sessions', '/_admin/settings/sessions', []); | |
79 | pyroutes.register('admin_settings_sessions_cleanup', '/_admin/settings/sessions/cleanup', []); |
|
79 | pyroutes.register('admin_settings_sessions_cleanup', '/_admin/settings/sessions/cleanup', []); | |
@@ -308,7 +308,6 b' function registerRCRoutes() {' | |||||
308 | pyroutes.register('repo_creating', '/%(repo_name)s/repo_creating', ['repo_name']); |
|
308 | pyroutes.register('repo_creating', '/%(repo_name)s/repo_creating', ['repo_name']); | |
309 | pyroutes.register('repo_creating_check', '/%(repo_name)s/repo_creating_check', ['repo_name']); |
|
309 | pyroutes.register('repo_creating_check', '/%(repo_name)s/repo_creating_check', ['repo_name']); | |
310 | pyroutes.register('repo_default_reviewers_data', '/%(repo_name)s/settings/review/default-reviewers', ['repo_name']); |
|
310 | pyroutes.register('repo_default_reviewers_data', '/%(repo_name)s/settings/review/default-reviewers', ['repo_name']); | |
311 | pyroutes.register('repo_edit_toggle_locking', '/%(repo_name)s/settings/toggle_locking', ['repo_name']); |
|
|||
312 | pyroutes.register('repo_file_authors', '/%(repo_name)s/authors/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']); |
|
311 | pyroutes.register('repo_file_authors', '/%(repo_name)s/authors/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']); | |
313 | pyroutes.register('repo_file_download', '/%(repo_name)s/download/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']); |
|
312 | pyroutes.register('repo_file_download', '/%(repo_name)s/download/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']); | |
314 | pyroutes.register('repo_file_download:legacy', '/%(repo_name)s/rawfile/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']); |
|
313 | pyroutes.register('repo_file_download:legacy', '/%(repo_name)s/rawfile/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']); | |
@@ -362,6 +361,7 b' function registerRCRoutes() {' | |||||
362 | pyroutes.register('repo_reviewers_review_rule_delete', '/%(repo_name)s/settings/review/rules/%(rule_id)s/delete', ['repo_name', 'rule_id']); |
|
361 | pyroutes.register('repo_reviewers_review_rule_delete', '/%(repo_name)s/settings/review/rules/%(rule_id)s/delete', ['repo_name', 'rule_id']); | |
363 | pyroutes.register('repo_reviewers_review_rule_edit', '/%(repo_name)s/settings/review/rules/%(rule_id)s', ['repo_name', 'rule_id']); |
|
362 | pyroutes.register('repo_reviewers_review_rule_edit', '/%(repo_name)s/settings/review/rules/%(rule_id)s', ['repo_name', 'rule_id']); | |
364 | pyroutes.register('repo_reviewers_review_rule_new', '/%(repo_name)s/settings/review/rules/new', ['repo_name']); |
|
363 | pyroutes.register('repo_reviewers_review_rule_new', '/%(repo_name)s/settings/review/rules/new', ['repo_name']); | |
|
364 | pyroutes.register('repo_settings_quick_actions', '/%(repo_name)s/settings/quick-action', ['repo_name']); | |||
365 | pyroutes.register('repo_stats', '/%(repo_name)s/repo_stats/%(commit_id)s', ['repo_name', 'commit_id']); |
|
365 | pyroutes.register('repo_stats', '/%(repo_name)s/repo_stats/%(commit_id)s', ['repo_name', 'commit_id']); | |
366 | pyroutes.register('repo_summary', '/%(repo_name)s', ['repo_name']); |
|
366 | pyroutes.register('repo_summary', '/%(repo_name)s', ['repo_name']); | |
367 | pyroutes.register('repo_summary_commits', '/%(repo_name)s/summary-commits', ['repo_name']); |
|
367 | pyroutes.register('repo_summary_commits', '/%(repo_name)s/summary-commits', ['repo_name']); |
@@ -27,7 +27,10 b'' | |||||
27 | </div> |
|
27 | </div> | |
28 | <div class="panel-body"> |
|
28 | <div class="panel-body"> | |
29 | <h4>${_('This feature is available in RhodeCode EE edition only. Contact {sales_email} to obtain a trial license.').format(sales_email='<a href="mailto:sales@rhodecode.com">sales@rhodecode.com</a>')|n}</h4> |
|
29 | <h4>${_('This feature is available in RhodeCode EE edition only. Contact {sales_email} to obtain a trial license.').format(sales_email='<a href="mailto:sales@rhodecode.com">sales@rhodecode.com</a>')|n}</h4> | |
30 |
|
30 | <p> | ||
|
31 | Artifacts are a binary file storage within RhodeCode that allows asset management next to version control system with fine-grained access control. | |||
|
32 | This functionality allows release builds or other types of binary asset to be stored and managed by RhodeCode. | |||
|
33 | </p> | |||
31 | </div> |
|
34 | </div> | |
32 | </div> |
|
35 | </div> | |
33 |
|
36 |
@@ -1,9 +1,37 b'' | |||||
1 | <div class="panel panel-default"> |
|
1 | <%inherit file="/base/base.mako"/> | |
2 | <div class="panel-heading"> |
|
2 | ||
3 | <h3 class="panel-title">${_('Admin Automation')}</h3> |
|
3 | <%def name="title()"> | |
|
4 | ${_('Artifacts Admin')} | |||
|
5 | %if c.rhodecode_name: | |||
|
6 | · ${h.branding(c.rhodecode_name)} | |||
|
7 | %endif | |||
|
8 | </%def> | |||
|
9 | ||||
|
10 | <%def name="breadcrumbs_links()"></%def> | |||
|
11 | ||||
|
12 | <%def name="menu_bar_nav()"> | |||
|
13 | ${self.menu_items(active='admin')} | |||
|
14 | </%def> | |||
|
15 | ||||
|
16 | <%def name="menu_bar_subnav()"> | |||
|
17 | ${self.admin_menu(active='automation')} | |||
|
18 | </%def> | |||
|
19 | ||||
|
20 | <%def name="main()"> | |||
|
21 | ||||
|
22 | <div class="box"> | |||
|
23 | ||||
|
24 | <div class="panel panel-default"> | |||
|
25 | <div class="panel-heading"> | |||
|
26 | <h3 class="panel-title">${_('Automation Administration.')}</h3> | |||
|
27 | </div> | |||
|
28 | <div class="panel-body"> | |||
|
29 | <h4>${_('This feature is available in RhodeCode EE edition only. Contact {sales_email} to obtain a trial license.').format(sales_email='<a href="mailto:sales@rhodecode.com">sales@rhodecode.com</a>')|n}</h4> | |||
|
30 | <img alt="admin-automation" style="width: 100%; height: 100%" src="${h.asset('images/ee_features/admin_automation.png')}"/> | |||
|
31 | </div> | |||
4 | </div> |
|
32 | </div> | |
5 | <div class="panel-body"> |
|
33 | ||
6 | <h4>${_('This feature is available in RhodeCode EE edition only. Contact {sales_email} to obtain a trial license.').format(sales_email='<a href="mailto:sales@rhodecode.com">sales@rhodecode.com</a>')|n}</h4> |
|
|||
7 | <img style="width: 100%; height: 100%" src="${h.asset('images/ee_features/admin_automation.png')}"/> |
|
|||
8 | </div> |
|
|||
9 | </div> |
|
34 | </div> | |
|
35 | ||||
|
36 | ||||
|
37 | </%def> |
@@ -39,7 +39,7 b'' | |||||
39 | % if c.rhodecode_user.username != h.DEFAULT_USER: |
|
39 | % if c.rhodecode_user.username != h.DEFAULT_USER: | |
40 | <div class="pull-right"> |
|
40 | <div class="pull-right"> | |
41 | <a class="btn btn-primary" href="${h.route_path('gists_new')}" > |
|
41 | <a class="btn btn-primary" href="${h.route_path('gists_new')}" > | |
42 |
${_( |
|
42 | ${_('Create New Gist')} | |
43 | </a> |
|
43 | </a> | |
44 | </div> |
|
44 | </div> | |
45 | % endif |
|
45 | % endif |
@@ -61,7 +61,7 b'' | |||||
61 | create_url = h.route_path('global_integrations_new') |
|
61 | create_url = h.route_path('global_integrations_new') | |
62 | %> |
|
62 | %> | |
63 | <p class="pull-right"> |
|
63 | <p class="pull-right"> | |
64 |
<a href="${create_url}" class="btn btn-small btn-success">${_( |
|
64 | <a href="${create_url}" class="btn btn-small btn-success">${_('Create new integration')}</a> | |
65 | </p> |
|
65 | </p> | |
66 |
|
66 | |||
67 | <table class="rctable integrations"> |
|
67 | <table class="rctable integrations"> | |
@@ -99,7 +99,7 b'' | |||||
99 | %> |
|
99 | %> | |
100 | %endif |
|
100 | %endif | |
101 |
|
101 | |||
102 |
<a href="${create_url}">${_( |
|
102 | <a href="${create_url}">${_('Create one')}</a> | |
103 | </td> |
|
103 | </td> | |
104 | </tr> |
|
104 | </tr> | |
105 | %endif |
|
105 | %endif |
@@ -39,7 +39,7 b'' | |||||
39 | <td class="delegated-admin-repo-groups">${len(c.auth_user.repository_groups_admin)}</td> |
|
39 | <td class="delegated-admin-repo-groups">${len(c.auth_user.repository_groups_admin)}</td> | |
40 | <td> |
|
40 | <td> | |
41 | % if c.can_create_repo_group: |
|
41 | % if c.can_create_repo_group: | |
42 |
<a href="${h.route_path('repo_group_new')}" class="">${_( |
|
42 | <a href="${h.route_path('repo_group_new')}" class="">${_('Add Repository Group')}</a> | |
43 | % endif |
|
43 | % endif | |
44 | </td> |
|
44 | </td> | |
45 | </tr> |
|
45 | </tr> | |
@@ -48,7 +48,7 b'' | |||||
48 | <td class="delegated-admin-user-groups">${len(c.auth_user.user_groups_admin)}</td> |
|
48 | <td class="delegated-admin-user-groups">${len(c.auth_user.user_groups_admin)}</td> | |
49 | <td> |
|
49 | <td> | |
50 | % if c.can_create_user_group: |
|
50 | % if c.can_create_user_group: | |
51 |
<a href="${h.route_path('user_groups_new')}" class="">${_( |
|
51 | <a href="${h.route_path('user_groups_new')}" class="">${_('Add User Group')}</a> | |
52 | % endif |
|
52 | % endif | |
53 | </td> |
|
53 | </td> | |
54 | </tr> |
|
54 | </tr> |
@@ -27,7 +27,7 b'' | |||||
27 | <ul class="links"> |
|
27 | <ul class="links"> | |
28 | %if c.can_create_repo_group: |
|
28 | %if c.can_create_repo_group: | |
29 | <li> |
|
29 | <li> | |
30 |
<a href="${h.route_path('repo_group_new')}" class="btn btn-small btn-success">${_( |
|
30 | <a href="${h.route_path('repo_group_new')}" class="btn btn-small btn-success">${_('Add Repository Group')}</a> | |
31 | </li> |
|
31 | </li> | |
32 | %endif |
|
32 | %endif | |
33 | </ul> |
|
33 | </ul> |
@@ -27,7 +27,7 b'' | |||||
27 | <ul class="links"> |
|
27 | <ul class="links"> | |
28 | %if c.can_create_repo: |
|
28 | %if c.can_create_repo: | |
29 | <li> |
|
29 | <li> | |
30 |
<a href="${h.route_path('repo_new')}" class="btn btn-small btn-success">${_( |
|
30 | <a href="${h.route_path('repo_new')}" class="btn btn-small btn-success">${_('Add Repository')}</a> | |
31 | </li> |
|
31 | </li> | |
32 | %endif |
|
32 | %endif | |
33 | </ul> |
|
33 | </ul> |
@@ -27,7 +27,7 b'' | |||||
27 | <ul class="links"> |
|
27 | <ul class="links"> | |
28 | %if c.can_create_user_group: |
|
28 | %if c.can_create_user_group: | |
29 | <li> |
|
29 | <li> | |
30 |
<a href="${h.route_path('user_groups_new')}" class="btn btn-small btn-success">${_( |
|
30 | <a href="${h.route_path('user_groups_new')}" class="btn btn-small btn-success">${_('Add User Group')}</a> | |
31 | </li> |
|
31 | </li> | |
32 | %endif |
|
32 | %endif | |
33 | </ul> |
|
33 | </ul> |
@@ -27,7 +27,7 b'' | |||||
27 |
|
27 | |||
28 | <ul class="links"> |
|
28 | <ul class="links"> | |
29 | <li> |
|
29 | <li> | |
30 |
<a href="${h.route_path('users_new')}" class="btn btn-small btn-success">${_( |
|
30 | <a href="${h.route_path('users_new')}" class="btn btn-small btn-success">${_('Add User')}</a> | |
31 | </li> |
|
31 | </li> | |
32 | </ul> |
|
32 | </ul> | |
33 | </div> |
|
33 | </div> |
@@ -107,7 +107,7 b'' | |||||
107 |
|
107 | |||
108 | <ul id="context-pages" class="navigation horizontal-list"> |
|
108 | <ul id="context-pages" class="navigation horizontal-list"> | |
109 |
|
109 | |||
110 | ## super-admin case |
|
110 | ## super-admin case (Top Menu) | |
111 | % if c.is_super_admin: |
|
111 | % if c.is_super_admin: | |
112 | <li class="${h.is_active('audit_logs', active)}"><a href="${h.route_path('admin_audit_logs')}">${_('Admin audit logs')}</a></li> |
|
112 | <li class="${h.is_active('audit_logs', active)}"><a href="${h.route_path('admin_audit_logs')}">${_('Admin audit logs')}</a></li> | |
113 | <li class="${h.is_active('repositories', active)}"><a href="${h.route_path('repos')}">${_('Repositories')}</a></li> |
|
113 | <li class="${h.is_active('repositories', active)}"><a href="${h.route_path('repos')}">${_('Repositories')}</a></li> | |
@@ -115,6 +115,8 b'' | |||||
115 | <li class="${h.is_active('users', active)}"><a href="${h.route_path('users')}">${_('Users')}</a></li> |
|
115 | <li class="${h.is_active('users', active)}"><a href="${h.route_path('users')}">${_('Users')}</a></li> | |
116 | <li class="${h.is_active('user_groups', active)}"><a href="${h.route_path('user_groups')}">${_('User groups')}</a></li> |
|
116 | <li class="${h.is_active('user_groups', active)}"><a href="${h.route_path('user_groups')}">${_('User groups')}</a></li> | |
117 | <li class="${h.is_active('artifacts', active)}"><a href="${h.route_path('admin_artifacts')}">${_('Artifacts')}</a></li> |
|
117 | <li class="${h.is_active('artifacts', active)}"><a href="${h.route_path('admin_artifacts')}">${_('Artifacts')}</a></li> | |
|
118 | <li class="${h.is_active('automation', active)}"><a href="${h.route_path('admin_automation')}">${_('Automation')}</a></li> | |||
|
119 | <li class="${h.is_active('scheduler', active)}"><a href="${h.route_path('admin_scheduler')}">${_('Scheduler')}</a></li> | |||
118 | <li class="${h.is_active('permissions', active)}"><a href="${h.route_path('admin_permissions_application')}">${_('Permissions')}</a></li> |
|
120 | <li class="${h.is_active('permissions', active)}"><a href="${h.route_path('admin_permissions_application')}">${_('Permissions')}</a></li> | |
119 | <li class="${h.is_active('authentication', active)}"><a href="${h.route_path('auth_home', traverse='')}">${_('Authentication')}</a></li> |
|
121 | <li class="${h.is_active('authentication', active)}"><a href="${h.route_path('auth_home', traverse='')}">${_('Authentication')}</a></li> | |
120 | <li class="${h.is_active('integrations', active)}"><a href="${h.route_path('global_integrations_home')}">${_('Integrations')}</a></li> |
|
122 | <li class="${h.is_active('integrations', active)}"><a href="${h.route_path('global_integrations_home')}">${_('Integrations')}</a></li> | |
@@ -540,7 +542,7 b'' | |||||
540 |
|
542 | |||
541 | % if can_create_repo_groups_in_group: |
|
543 | % if can_create_repo_groups_in_group: | |
542 | <li> |
|
544 | <li> | |
543 |
<a href="${h.route_path('repo_group_new',_query=dict(parent_group=c.repo_group.group_id))}">${_( |
|
545 | <a href="${h.route_path('repo_group_new',_query=dict(parent_group=c.repo_group.group_id))}">${_('New Repository Group')}</a> | |
544 | </li> |
|
546 | </li> | |
545 | % endif |
|
547 | % endif | |
546 | % endif |
|
548 | % endif | |
@@ -568,12 +570,12 b'' | |||||
568 |
|
570 | |||
569 | % if can_create_repo_groups: |
|
571 | % if can_create_repo_groups: | |
570 | <li> |
|
572 | <li> | |
571 |
<a href="${h.route_path('repo_group_new')}" >${_( |
|
573 | <a href="${h.route_path('repo_group_new')}" >${_('New Repository Group')}</a> | |
572 | </li> |
|
574 | </li> | |
573 | % endif |
|
575 | % endif | |
574 |
|
576 | |||
575 | <li> |
|
577 | <li> | |
576 |
<a href="${h.route_path('gists_new')}">${_( |
|
578 | <a href="${h.route_path('gists_new')}">${_('New Gist')}</a> | |
577 | </li> |
|
579 | </li> | |
578 |
|
580 | |||
579 | </ol> |
|
581 | </ol> |
General Comments 0
You need to be logged in to leave comments.
Login now