views: add action to delete repo

allow the user to delete a repo by selecting one and pressing the delete
button. Previous to deletion, show the user a confirmation page (a form)
with the details of the repo to delete

the confirmation form is constructed with the fields of Repoform.
RepoForm is also used in template used to create a repo. To make both
templates work with RepoForm, RepoForm's field 'create' has been renamed to
'submit'

ogcp.js: add a function to make that, when the user selects a
repository, the server in which it is contained is automatically
checked. We need it checked so that action_repo_delete can know the
server to which it has to send the delete request. Use data-server in
repos_details.html to make this work

Validate, in action_delete_repo, that user has only selected one repo to
delete. In order to do that, action_delete_repo view needs to be able to
get a list of all selected repos. This is only possible if <input>
elements that are associated with repos info contain a different name
attribute per repo. In this case, template repos.html has been modified
to use name={repo name}-{repo_id}.  After this, parse_elements() will
work and parse a set containing all selected repos.

modify html input associated to repos server in order to follow same
convention as in other templates. For example, images uses image-server;
scopes, scope-server.
master
Javier Hernandez 2023-12-05 09:58:43 +01:00 committed by OpenGnSys Support Team
parent 0718ccac75
commit 152337b6bd
5 changed files with 70 additions and 9 deletions

View File

@ -100,9 +100,10 @@ class ImageRestoreForm(FlaskForm):
class RepoForm(FlaskForm):
server = HiddenField()
repo_id = HiddenField()
name = StringField(label=_l('Name'))
ip = StringField(label=_l('IP'))
create = SubmitField(label=_l('Create'))
submit = SubmitField(label=_l('Submit'))
class ClientDetailsForm(FlaskForm):
server = HiddenField()

View File

@ -329,6 +329,23 @@ function checkImageServer() {
});
}
function checkRepoServer() {
const repos = $('input:checkbox[form|="reposForm"][name!="repos-server"]')
repos.on('change', function() {
const selectedServer = $('#' + $.escapeSelector(this.dataset.server));
const serversSelector = 'input:checkbox[name|="repos-server"]';
const nonSelectedServers = $(serversSelector).not(selectedServer);
selectedServer.prop('checked', true);
nonSelectedServers.each(function() {
$(this).prop('checked', false);
const checkboxes = $('input:checkbox[data-server|="' + this.id + '"]');
checkboxes.prop('checked', false);
});
});
}
function limitCheckboxes() {
const checkboxes = $('input:checkbox[form|="scopesForm"]');

View File

@ -10,7 +10,8 @@
<h1 class="m-5">{{_('Repo details')}}</h1>
{{ wtf.quick_form(form,
action=url_for('repo_add_post'),
method='post',
button_map={'create': 'primary'},
button_map={'submit': 'primary'},
extra_classes="mx-5") }}
{% endblock %}

View File

@ -17,8 +17,8 @@
{% 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" />
<input id="{{ server_ip_port }}"class="form-check-input" type="checkbox" form="reposForm"
value="{{ server_ip_port }}" name="repos-server" />
<a class="nav-link {% if not repos_list %}disabled{% endif %}" href="#server{{loop.index}}"
{% if repos_list %}data-toggle="collapse"{% endif %}>
{{ server_name }}
@ -27,8 +27,9 @@
{% for r in repos_list %}
<li class="nav-item">
<input class="form-check-input" type="checkbox" form="reposForm"
data-server="{{server_ip_port}}"
value="{{ r["id"] }}"
name="selected-repo" />
name="{{ r["name"]~_~r["id"] }}" />
{{ r["name"] }}
</li>
{% endfor %}
@ -42,6 +43,7 @@
document.addEventListener('readystatechange', () => {
if (document.readyState === 'complete') {
keepReposTreeState()
checkRepoServer()
}
});
</script>
@ -50,6 +52,8 @@
{% 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">
<input class="btn btn-light {% block nav_repo_delete %}{% endblock %}" type="submit" value="{{ _('Delete repo') }}"
form="reposForm" formaction="{{ url_for('action_repo_delete') }}" formmethod="get">
{% if btn_back %}
<button class="btn btn-danger ml-3" type="button" id="backButton" onclick="history.back()">

View File

@ -97,7 +97,7 @@ def validate_elements(elements, min_len=1, max_len=float('inf')):
def parse_elements(checkboxes_dict):
unwanted_elements = ['csrf_token', 'scope-server', 'scope-center',
'scope-room', 'image-server']
'scope-room', 'image-server', 'repos-server']
elements = set()
for key, elements_list in checkboxes_dict.items():
if key not in unwanted_elements:
@ -1486,12 +1486,11 @@ def manage_repos():
def repo_add_get():
form = RepoForm()
params = request.args.to_dict()
if not params.get('selected-server'):
if not params.get('repos-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')}
form.server.data = params['repos-server']
responses = multi_request('get', '/repositories')
return render_template('actions/repos_details.html', form=form,
@ -1516,6 +1515,45 @@ def repo_add_post():
flash(_('Repo added successfully'), category='info')
return redirect(url_for("manage_repos"))
@app.route('/action/repo/delete', methods=['GET', 'POST'])
@login_required
def action_repo_delete():
form = RepoForm(request.form)
if request.method == 'POST':
server = get_server_from_ip_port(form.server.data)
payload = { 'id': form.repo_id.data }
r = server.post('/repository/delete', payload)
if r.status_code != requests.codes.ok:
flash(_('ogServer: error deleting repo'),
category='error')
else:
flash(_('Repo deleted successfully'),
category='info')
return redirect(url_for('manage_repos'))
else:
params = request.args.to_dict()
repos = parse_elements(params)
print(repos)
if not validate_elements(repos, max_len=1):
return redirect(url_for('manage_repos'))
repo_id = repos.pop()
if not repo_id:
flash(_('Please, select a repo'), category='error')
return redirect(url_for('manage_repos'))
repo_id = int(repo_id)
server_ip_port = params.get('repos-server')
server = get_server_from_ip_port(server_ip_port)
repository = get_repository(repo_id, server)
form.server.data = server_ip_port
form.repo_id.data = repo_id
form.name.data = repository['name']
form.name.render_kw = {'readonly': True}
form.ip.data = repository['ip']
form.ip.render_kw = {'readonly': True}
responses = multi_request('get', '/repositories')
return render_template('actions/delete_repo.html', form=form,
repos_resp=responses)
@app.route('/servers/', methods=['GET'])
@login_required
def manage_servers():