src: add menu to manage repos

The menu includes a list of the repos of each server. The user can
select a server or a repo to make changes.

As of now, the only action possible is to add a repo to selected
server.

The work contained in this commit can be structured in:

1. Add the repos menu:
- Add a 'repos' button in the menus bar (base.html).
- Add repos.html template to create the management repos menu.
- In ogcp.js, add function to store in browser's local storage which
  elements of the sidebar are uncollapsed. This saves the sidebar state
  after a page refresh.
- Add manage_repos() in views.py

2. Allow to add a repo:
- Add template with form to add a repo (repos_details.html)
- Create RepoForm(FlaskForm) in action_forms.py
- Add repo_add_get() and repo_add_post() in views.py
master
Javier Hernandez 2023-12-01 15:55:15 +01:00 committed by OpenGnSys Support Team
parent 215e3c2fc0
commit 2858436341
6 changed files with 145 additions and 1 deletions

View File

@ -98,6 +98,12 @@ class ImageRestoreForm(FlaskForm):
choices=[('TIPTORRENT', 'TIPTORRENT')])
restore = SubmitField(label=_l('Restore'))
class RepoForm(FlaskForm):
server = HiddenField()
name = StringField(label=_l('Name'))
ip = StringField(label=_l('IP'))
create = SubmitField(label=_l('Create'))
class ClientDetailsForm(FlaskForm):
server = HiddenField()
name = StringField(label=_l('Name'))

View File

@ -136,6 +136,25 @@ function keepSelectedClients() {
});
}
function keepReposTreeState() {
const repos_tree = $('#repos-list .collapse')
repos_tree.on('hidden.bs.collapse', function (event) {
event.stopPropagation();
localStorage.removeItem(this.id);
});
repos_tree.on('shown.bs.collapse', function (event) {
event.stopPropagation();
localStorage.setItem(this.id, 'show');
});
repos_tree.each(function () {
if (localStorage.getItem(this.id) == 'show') {
$(this).collapse('show');
}
});
}
function keepScopesTreeState() {
const scopes_tree = $('#scopes .collapse')

View File

@ -0,0 +1,16 @@
{% extends 'repos.html' %}
{% import "bootstrap/wtf.html" as wtf %}
{% set btn_back = true %}
{% block nav_repos %} active{% endblock %}
{% block nav_repos_details %} active{% endblock %}
{% block nav_repos_add %}active{% endblock %}
{% block content %}
<h1 class="m-5">{{_('Repo details')}}</h1>
{{ wtf.quick_form(form,
method='post',
button_map={'create': 'primary'},
extra_classes="mx-5") }}
{% endblock %}

View File

@ -37,6 +37,9 @@
<li class="nav-item {% block nav_scopes%}{% endblock %}">
<a class="nav-link" href="{{ url_for('scopes') }}">{{ _('Scopes management') }}</a>
</li>
<li class="nav-item {% block nav_repos %}{% endblock %}">
<a class="nav-link" href="{{ url_for('manage_repos') }}">{{ _('Repos') }}</a>
</li>
<li class="nav-item {% block nav_servers %}{% endblock %}">
<a class="nav-link" href="{{ url_for('manage_servers') }}">{{ _('Servers') }}</a>
</li>

View File

@ -0,0 +1,59 @@
{% extends 'base.html' %}
{% block nav_repos %}active{% endblock %}
{% block container %}
<form id="reposForm">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
</form>
{{ super() }}
</form>
{% endblock %}
{% block sidebar %}
<ul id="repos-list" class="nav ogcp-nav flex-column nav-pills">
{% for repos in repos_resp %}
{% set server_name = repos["server"].name %}
{% set server_ip_port = repos["server"].ip ~ ":" ~ repos["server"].port %}
{% set repos_list = repos["json"]["repositories"] %}
<li class="nav-item">
<input class="form-check-input" type="checkbox" form="reposForm"
value="{{ server_ip_port }}" name="selected-server" />
<a class="nav-link {% if not repos_list %}disabled{% endif %}" href="#server{{loop.index}}"
{% if repos_list %}data-toggle="collapse"{% endif %}>
{{ server_name }}
</a>
<ul class="nav flex-column collapse" id="server{{loop.index}}">
{% for r in repos_list %}
<li class="nav-item">
<input class="form-check-input" type="checkbox" form="reposForm"
value="{{ r["id"] }}"
name="selected-repo" />
{{ r["name"] }}
</li>
{% endfor %}
</ul>
</li>
{% endfor %}
</ul>
<script>
// Launch the javascript on document ready, so all the global functions exists
// in the scope
document.addEventListener('readystatechange', () => {
if (document.readyState === 'complete') {
keepReposTreeState()
}
});
</script>
{% endblock %}
{% block commands %}
<input class="btn btn-light {% block nav_repo_add %}{% endblock %}" type="submit" value="{{ _('Add repo') }}"
form="reposForm" formaction="{{ url_for('repo_add_get') }}" formmethod="get">
{% if btn_back %}
<button class="btn btn-danger ml-3" type="button" id="backButton" onclick="history.back()">
{{ _("Back") }}
</button>
{% endif %}
{% endblock %}

View File

@ -13,7 +13,7 @@ from ogcp.forms.action_forms import (
SessionForm, ImageRestoreForm, ImageCreateForm, SoftwareForm, BootModeForm,
RoomForm, DeleteRoomForm, CenterForm, DeleteCenterForm, OgliveForm,
GenericForm, SelectClientForm, ImageUpdateForm, ImportClientsForm,
ServerForm, DeleteRepositoryForm
ServerForm, DeleteRepositoryForm, RepoForm
)
from flask_login import (
current_user, LoginManager,
@ -1475,6 +1475,47 @@ def images():
return render_template('images.html', responses=responses)
@app.route('/repos/', methods=['GET'])
@login_required
def manage_repos():
responses = multi_request('get', '/repositories')
return render_template('repos.html', repos_resp=responses)
@app.route('/repo/add', methods=['GET'])
@login_required
def repo_add_get():
form = RepoForm()
params = request.args.to_dict()
if not params.get('selected-server'):
flash(_('Please, select a server'), category='error')
return redirect(url_for('manage_repos'))
form.server.data = params['selected-server']
form.create.render_kw = {"formaction": url_for('repo_add_post')}
responses = multi_request('get', '/repositories')
return render_template('actions/repos_details.html', form=form,
repos_resp=responses)
@app.route('/repo/add', methods=['POST'])
@login_required
def repo_add_post():
form = RepoForm(request.form)
if not form.validate():
flash(form.errors, category='error')
return redirect(url_for('manage_repos'))
payload = {"name": form.name.data,
"ip": form.ip.data,
"center": 1}
server = get_server_from_ip_port(form.server.data)
r = server.post('/repository/add', payload)
if r.status_code != requests.codes.ok:
flash(_('ogServer: error adding repo'),
category='error')
else:
flash(_('Repo added successfully'), category='info')
return redirect(url_for("manage_repos"))
@app.route('/servers/', methods=['GET'])
@login_required
def manage_servers():