new fields in users management page

This commit is contained in:
Michele Artini 2022-09-16 15:47:13 +02:00
parent 4c7f4ca4c7
commit 098537e067
5 changed files with 179 additions and 52 deletions

View File

@ -20,6 +20,18 @@ public class User implements Serializable {
@Column(name = "email") @Column(name = "email")
private String email; private String email;
@Column(name = "fullname")
private String fullname;
@Column(name = "organization")
private String organization;
@Column(name = "reference_person")
private String referencePerson;
@Column(name = "request_message")
private String requestMessage;
@Column(name = "valid") @Column(name = "valid")
private boolean valid; private boolean valid;
@ -34,6 +46,38 @@ public class User implements Serializable {
this.email = email; this.email = email;
} }
public String getFullname() {
return fullname;
}
public void setFullname(final String fullname) {
this.fullname = fullname;
}
public String getOrganization() {
return organization;
}
public void setOrganization(final String organization) {
this.organization = organization;
}
public String getReferencePerson() {
return referencePerson;
}
public void setReferencePerson(final String referencePerson) {
this.referencePerson = referencePerson;
}
public String getRequestMessage() {
return requestMessage;
}
public void setRequestMessage(final String requestMessage) {
this.requestMessage = requestMessage;
}
public boolean isValid() { public boolean isValid() {
return valid; return valid;
} }
@ -49,5 +93,4 @@ public class User implements Serializable {
public void setRole(final String role) { public void setRole(final String role) {
this.role = role; this.role = role;
} }
} }

View File

@ -30,6 +30,18 @@ public class UserView implements Serializable {
@Column(name = "email") @Column(name = "email")
private String email; private String email;
@Column(name = "fullname")
private String fullname;
@Column(name = "organization")
private String organization;
@Column(name = "reference_person")
private String referencePerson;
@Column(name = "request_message")
private String requestMessage;
@Column(name = "valid") @Column(name = "valid")
private boolean valid; private boolean valid;
@ -93,4 +105,36 @@ public class UserView implements Serializable {
public void setLastAccess(final OffsetDateTime lastAccess) { public void setLastAccess(final OffsetDateTime lastAccess) {
this.lastAccess = lastAccess; this.lastAccess = lastAccess;
} }
public String getFullname() {
return fullname;
}
public void setFullname(final String fullname) {
this.fullname = fullname;
}
public String getOrganization() {
return organization;
}
public void setOrganization(final String organization) {
this.organization = organization;
}
public String getReferencePerson() {
return referencePerson;
}
public void setReferencePerson(final String referencePerson) {
this.referencePerson = referencePerson;
}
public String getRequestMessage() {
return requestMessage;
}
public void setRequestMessage(final String requestMessage) {
this.requestMessage = requestMessage;
}
} }

View File

@ -318,11 +318,15 @@ CREATE TABLE user_roles(role text PRIMARY KEY);
INSERT INTO user_roles VALUES ('ADMIN'), ('NATIONAL_ADMIN'), ('USER'), ('PENDING'), ('NOT_AUTHORIZED'); INSERT INTO user_roles VALUES ('ADMIN'), ('NATIONAL_ADMIN'), ('USER'), ('PENDING'), ('NOT_AUTHORIZED');
CREATE TABLE users ( CREATE TABLE users (
email text PRIMARY KEY, email text PRIMARY KEY,
valid boolean DEFAULT true, fullname text,
role text NOT NULL default 'USER' REFERENCES user_roles(role), organization text,
first_access timestamp with time zone DEFAULT now(), reference_person text,
last_access timestamp with time zone DEFAULT now() request_message text,
valid boolean DEFAULT true,
role text NOT NULL default 'USER' REFERENCES user_roles(role),
first_access timestamp with time zone DEFAULT now(),
last_access timestamp with time zone DEFAULT now()
); );
CREATE TABLE user_countries ( CREATE TABLE user_countries (
@ -586,6 +590,10 @@ GROUP BY
CREATE VIEW users_view AS SELECT CREATE VIEW users_view AS SELECT
u.email, u.email,
u.fullname,
u.organization,
u.reference_person,
u.request_message,
u.valid, u.valid,
u.role, u.role,
u.first_access, u.first_access,
@ -594,7 +602,16 @@ CREATE VIEW users_view AS SELECT
FROM FROM
users u users u
LEFT OUTER JOIN user_countries uc ON (u.email = uc.email) LEFT OUTER JOIN user_countries uc ON (u.email = uc.email)
GROUP BY u.email, u.valid, u.role, u.first_access, u.last_access GROUP BY
u.email,
u.fullname,
u.organization,
u.reference_person,
u.request_message,
u.valid,
u.role,
u.first_access,
u.last_access
ORDER BY u.email; ORDER BY u.email;
CREATE VIEW suggestions_info_by_country_view AS SELECT CREATE VIEW suggestions_info_by_country_view AS SELECT

View File

@ -5,7 +5,7 @@
<div class="col-sm-12 col-lg-10"> <div class="col-sm-12 col-lg-10">
<input type="text" class="form-control form-control-sm mb-3" ng-model="userFilter.email" placeholder="Filter..."> <input type="text" class="form-control form-control-sm mb-3" ng-model="userFilter.email" placeholder="Filter...">
<table class="table table-sm table-hover"> <table class="table table-sm table-hover table-striped">
<thead class="thead-light"> <thead class="thead-light">
<tr class="d-flex"> <tr class="d-flex">
<th class="col-3">User</th> <th class="col-3">User</th>
@ -19,7 +19,11 @@
</thead> </thead>
<tbody> <tbody>
<tr ng-repeat="u in users | filter:userFilter" class="d-flex"> <tr ng-repeat="u in users | filter:userFilter" class="d-flex">
<th class="col-3" ng-class="{'text-secondary': !u.valid}">{{u.email}}</th> <th class="col-3" ng-class="{'text-secondary': !u.valid}">
<i>{{u.email}}</i>
<small ng-if="u.fullname"><br />Fullname: {{u.fullname}}</small>
<small ng-if="u.organization"><br />Organization: {{u.organization}}</small>
</th>
<td class="col-1 text-center text-success"> <td class="col-1 text-center text-success">
<i class="fa fa-check-circle" ng-if="u.valid"></i> <i class="fa fa-check-circle" ng-if="u.valid"></i>
<span class="text-warning" ng-if="u.role == 'PENDING'">not configured</span> <span class="text-warning" ng-if="u.role == 'PENDING'">not configured</span>
@ -60,54 +64,69 @@
<h5 class="modal-title">Edit user</h5> <h5 class="modal-title">Edit user</h5>
<button type="button" class="close" data-dismiss="modal">&times;</button> <button type="button" class="close" data-dismiss="modal">&times;</button>
</div> </div>
<div class="modal-body" style="min-height: 300px; max-height: 500px; overflow-y: auto;"> <div class="modal-body" style="min-height: 400px; max-height: 800px; overflow-y: auto;">
<form> <table class="table table-noborder">
<div class="form-group row"> <tr class="d-flex">
<label class="col-sm-2 col-form-label">Email</label> <th class="col-3">Fullname</th>
<div class="col-sm-10"><a href="mailto:{{currentUser.email}}">{{currentUser.email}}</a></div> <td class="col-9" ng-if="currentUser.fullname">{{currentUser.fullname}}</td>
</div> <td class="col-9 text-muted" ng-if="!currentUser.fullname"><i>not specified</i></td>
<div class="form-group row"> </tr>
<label class="col-sm-2 col-form-label">Enabled</label> <tr class="d-flex">
<div class="col-sm-10"> <th class="col-3">Email</th>
<div class="form-check"> <td class="col-9"><a href="mailto:{{currentUser.email}}">{{currentUser.email}}</a></td>
<input class="form-check-input" type="checkbox" ng-model="currentUser.valid" /> </tr>
</div> <tr class="d-flex">
</div> <th class="col-3">Organization</th>
</div> <td class="col-9" ng-if="currentUser.organization">{{currentUser.organization}}</td>
<div class="form-group row" ng-if="superAdminMode && currentUser.valid"> <td class="col-9 text-muted" ng-if="!currentUser.organization"><i>not specified</i></td>
<label class="col-sm-2 col-form-label">Role</label> </tr>
<div class="col-sm-10"> <tr class="d-flex">
<div class="form-check form-check-inline"> <th class="col-3">Registration Request</th>
<input class="form-check-input" type="radio" value="USER" ng-model="currentUser.role"> <td class="col-9" ng-if="currentUser.referencePerson || currentUser.requestMessage">
<label class="form-check-label">USER</label> <span ng-show="currentUser.referencePerson"><b>Reference person: </b>{{currentUser.referencePerson}}<br /></span>
</div> <pre ng-show="currentUser.requestMessage">{{currentUser.requestMessage}}</pre>
<div class="form-check form-check-inline"> </td>
<input class="form-check-input" type="radio" value="NATIONAL_ADMIN" ng-model="currentUser.role"> <td class="col-9 text-muted" ng-if="!currentUser.referencePerson && !currentUser.requestMessage">
<label class="form-check-label">NATIONAL ADMIN</label> <i>not specified</i>
</div> </td>
<div class="form-check form-check-inline"> </tr>
<input class="form-check-input" type="radio" value="ADMIN" ng-model="currentUser.role"> <tr class="d-flex">
<label class="form-check-label">SUPER ADMIN</label> <th class="col-3">Enabled</th>
</div> <td class="col-9">
</div> <input type="checkbox" ng-model="currentUser.valid" />
</div> </td>
</tr>
<tr class="d-flex" ng-if="superAdminMode && currentUser.valid">
<th class="col-3">Role</th>
<td class="col-3">
<input type="radio" value="USER" ng-model="currentUser.role" />
<label>USER</label>
</td>
<td class="col-3">
<input type="radio" value="NATIONAL_ADMIN" ng-model="currentUser.role" />
<label>NATIONAL ADMIN</label>
</td>
<td class="col-3">
<input type="radio" value="ADMIN" ng-model="currentUser.role" />
<label>SUPER ADMIN</label>
</td>
</tr>
</table>
<div class="card mb-3" ng-if="currentUser.valid && ((currentUser.role == 'USER') || (currentUser.role == 'NATIONAL_ADMIN'))"> <div class="card mb-3" ng-if="currentUser.valid && ((currentUser.role == 'USER') || (currentUser.role == 'NATIONAL_ADMIN'))">
<div class="card-header bg-primary text-white py-1">Countries</div> <div class="card-header bg-primary text-white py-1">Countries</div>
<div class="card-body"> <div class="card-body">
<input type="text" class="form-control form-control-sm mb-3" ng-model="countryFilter" ng-show="vocabularies.countries.length > 10" placeholder="Filter country..."> <input type="text" class="form-control form-control-sm mb-3" ng-model="countryFilter" ng-show="vocabularies.countries.length > 10" placeholder="Filter country...">
<div class="form-group row"> <div class="form-group row">
<div class="col-xs-12 col-md-6 col-lg-4" ng-repeat="c in vocabularies.countries | filter:countryFilter"> <div class="col-xs-12 col-md-6 col-lg-4" ng-repeat="c in vocabularies.countries | filter:countryFilter">
<div class="form-check form-check-inline"> <div class="form-check form-check-inline">
<input class="form-check-input" type="checkbox" checklist-model="currentUser.countries" checklist-value="c.value"/> <input class="form-check-input" type="checkbox" checklist-model="currentUser.countries" checklist-value="c.value"/>
<label class="form-check-label">{{c.name}}</label> <label class="form-check-label">{{c.name}}</label>
</div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div>
</form>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button> <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>

View File

@ -47,6 +47,10 @@ fieldset > legend { font-size : 1.2rem !important; }
text-align: left !important; text-align: left !important;
} }
.table-noborder td, .table-noborder th {
border: none !important;
}
</style> </style>