feat(usermanager): reimplement group edit view

This commit is contained in:
Julian Lobbes 2022-11-29 18:10:46 +01:00
parent 2d48a26c51
commit ebe3bca3a2
5 changed files with 40 additions and 106 deletions

View File

@ -1,9 +1,14 @@
$(function() { $(function() {
for (entry of $(".unsortable")) {
$(entry).data("sorter", false);
}
$("table").tablesorter({ $("table").tablesorter({
theme: 'bootstrap', theme: 'bootstrap',
headerTemplate: '{content} {icon}', headerTemplate: '{content} {icon}',
cssIcon: 'bi-arrow-down-up', cssIcon: 'bi-arrow-down-up',
cssIconNone: '', cssIconNone: '',
cssIconDisabled: '',
cssIconAsc: 'bi-arrow-up', cssIconAsc: 'bi-arrow-up',
cssIconDesc: 'bi-arrow-down', cssIconDesc: 'bi-arrow-down',
}); });
@ -23,102 +28,50 @@ class UserEntry {
} }
onClickLeave() { onClickLeave() {
// Deactivate the last remaining member's togglebutton before leaving
if ($(membersTable).find(".userEntry").length < 2) {
for (entry of $(membersTable).find(".userEntry")) {
if ($(entry).id != this.username) {
$(entry).find(".toggleMembershipButton")[0].prop("disabled", true);
}
}
}
this.setButtonAppearanceInProgress(); this.setButtonAppearanceInProgress();
$.ajax({ $.ajax({
context: { context: {
"userEntry": this "userEntry": this
}, },
url: `/api/group/${groupname}`, url: `/api/group/${groupname}/member/${this.username}`,
type: "GET", type: "DELETE",
dataType: "json", dataType: "json",
}).done(function(groupJson) { }).done(function() {
$.ajax({ this.userEntry.isMember = false;
context: { $(this.userEntry.buttonElement).off("click");
"userEntry": this.userEntry, $(this.userEntry.buttonElement).click(() => this.userEntry.onClickJoin());
}, $(this.userEntry.rowElement).prependTo($("#tableNonMembers").find("tbody"));
url: `/api/group/${groupname}`, this.userEntry.setButtonAppearanceJoinGroup();
type: "PUT", // TODO check status code!
dataType: "json",
data: JSON.stringify(groupJson),
contentType: "application/json",
})
.done(function(groupJson) {
this.userEntry.isMember = false;
$(this.userEntry.buttonElement).off("click");
$(this.userEntry.buttonElement).click(() => this.userEntry.onClickJoin());
$(this.userEntry.rowElement).prependTo($("#tableNonMembers").find("tbody"));
this.userEntry.setButtonAppearanceJoinGroup();
})
.fail(function(xhr, status, errorThrown) {
console.log(`Error: ${errorThrown}`);
console.log(`Status: ${status}`);
console.dir(xhr);
alert("Sorry, there was a problem sending information to the server.");
this.userEntry.setButtonAppearanceLeaveGroup();
});
}).fail(function(xhr, status, errorThrown) { }).fail(function(xhr, status, errorThrown) {
console.log(`Error: ${errorThrown}`); console.log(`Error: ${errorThrown}`);
console.log(`Status: ${status}`); console.log(`Status: ${status}`);
alert("Sorry, there was a problem retrieving information from the server."); alert("Sorry, there was a problem retrieving information from the server.");
this.userEntry.setButtonAppearanceLeaveGroup(); this.userEntry.setButtonAppearanceLeaveGroup();
}); });
} }
onClickJoin() { onClickJoin() {
this.setButtonAppearanceInProgress(); this.setButtonAppearanceInProgress();
$.ajax({ $.ajax({
context: { context: {
"userEntry": this "userEntry": this
}, },
url: `/api/group/${groupname}`, url: `/api/group/${groupname}/member/${this.username}`,
type: "GET", type: "POST",
dataType: "json", dataType: "json",
}).done(function(groupJson) { }).done(function() {
// Add current user to the members array this.userEntry.isMember = true;
groupJson.group.members.push(this.userEntry.username); $(this.userEntry.buttonElement).off("click");
$.ajax({ $(this.userEntry.buttonElement).click(() => this.userEntry.onClickLeave());
context: { $(this.userEntry.rowElement).prependTo($("#tableMembers").find("tbody"));
"userEntry": this.userEntry, this.userEntry.setButtonAppearanceLeaveGroup();
}, // TODO check status code!
url: `/api/group/${groupname}`,
type: "PUT",
dataType: "json",
data: JSON.stringify(groupJson),
contentType: "application/json",
})
.done(function(groupJson) {
this.userEntry.isMember = true;
$(this.userEntry.buttonElement).off("click");
$(this.userEntry.buttonElement).click(() => this.userEntry.onClickLeave());
$(this.userEntry.rowElement).prependTo($("#tableMembers").find("tbody"));
this.userEntry.setButtonAppearanceLeaveGroup();
})
.fail(function(xhr, status, errorThrown) {
console.log(`Error: ${errorThrown}`);
console.log(`Status: ${status}`);
console.dir(xhr);
alert("Sorry, there was a problem sending information to the server.");
this.userEntry.setButtonAppearanceJoinGroup();
});
}).fail(function(xhr, status, errorThrown) { }).fail(function(xhr, status, errorThrown) {
console.log(`Error: ${errorThrown}`); console.log(`Error: ${errorThrown}`);
console.log(`Status: ${status}`); console.log(`Status: ${status}`);
alert("Sorry, there was a problem retrieving information from the server."); alert("Sorry, there was a problem retrieving information from the server.");
this.userEntry.setButtonAppearanceJoinGroup(); this.userEntry.setButtonAppearanceLeaveGroup();
}); });
} }

View File

@ -0,0 +1,10 @@
$(function() {
$("table").tablesorter({
theme: 'bootstrap',
headerTemplate: '{content} {icon}',
cssIcon: 'bi-arrow-down-up',
cssIconNone: '',
cssIconAsc: 'bi-arrow-up',
cssIconDesc: 'bi-arrow-down',
});
});

View File

@ -11,7 +11,7 @@
<table class="table table-hover align-middle" id="tableNonMembers"> <table class="table table-hover align-middle" id="tableNonMembers">
<thead> <thead>
<tr> <tr>
<th scope="col" colspan="3" class="text-center text-opacity-75 fs-4">Other users</th> <th scope="col" colspan="3">Username</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@ -41,7 +41,7 @@
<table class="table table-hover align-middle" id="tableMembers"> <table class="table table-hover align-middle" id="tableMembers">
<thead> <thead>
<tr> <tr>
<th scope="col" colspan="3" class="text-center text-primary text-opacity-75 fs-4">{{ groupname }}</th> <th scope="col" colspan="3">Username</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>

View File

@ -16,18 +16,17 @@
<thead> <thead>
<tr> <tr>
<th scope="col">Group Name</th> <th scope="col">Group Name</th>
<th scope="col">Members</th> <th scope="col">Number of Members</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{% for group in groups | sort %} {% for group in groups | sort %}
<tr> <tr>
<th scope="row"> <th scope="row">
<a href="{{ url_for('usermanager.group_view', groupname=group.groupname) }}">{{ group.groupname }}</a> <a href="{{ url_for('usermanager.group_update', groupname=group.groupname) }}">{{ group.groupname }}</a>
</th> </th>
<td class="align-middle"> <td class="align-middle">
{% for user in group.members %} {{ group.members|length }}
{% endfor %}
</td> </td>
</tr> </tr>
{% endfor %} {% endfor %}
@ -39,4 +38,5 @@
<p class="text-muted">There are currently no groups.</p> <p class="text-muted">There are currently no groups.</p>
</div> </div>
{% endif %} {% endif %}
<script src="{{ url_for('static', filename='js/group_list.js') }}"></script>
{% endblock content %} {% endblock content %}

View File

@ -339,35 +339,6 @@ def group_create():
abort(404) abort(404)
@bp.route("/groups/view/<string:groupname>")
def group_view(groupname: str):
"""Displays a form allowing group creation."""
try:
conn = ldap.get_connection()
except Exception:
abort(500)
try:
group = ldap.get_group(conn, groupname)
except ldap.EntryNotFoundException:
conn.unbind()
abort(404)
conn.unbind()
# TODO implement
abort(404)
class GroupUpdateForm(FlaskForm):
updated_members = HiddenField(
'Group Members',
)
submit = SubmitField(
'Apply',
)
@bp.route("/groups/update/<string:groupname>") @bp.route("/groups/update/<string:groupname>")
def group_update(groupname: str): def group_update(groupname: str):
"""Detail and Update view for a group. """Detail and Update view for a group.