use card layout for app list,
This commit is contained in:
parent
a44ce732be
commit
05dc03ef8a
|
@ -14,108 +14,45 @@
|
|||
</div>
|
||||
|
||||
<div class="row row-cards row-deck mt-4">
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover table-outline table-vcenter text-nowrap card-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="text-center w-1"><i class="icon-people"></i></th>
|
||||
<th>Name</th>
|
||||
<th>OAuth2 Client ID</th>
|
||||
<th>#Users</th>
|
||||
<th>Edit</th>
|
||||
<!--<th>Publish</th>-->
|
||||
<th>Delete</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for client in clients %}
|
||||
<tr>
|
||||
<td class="text-center">
|
||||
{% if client.icon_id %}
|
||||
<div class="avatar d-block" style="background-image: url({{ client.icon.get_url() }})">
|
||||
<span class="avatar-status bg-green"></span>
|
||||
</div>
|
||||
{% endif %}
|
||||
</td>
|
||||
{% for client in clients %}
|
||||
<div class="col-md-6 col-xl-4">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<div class="card-title d-flex align-items-center">
|
||||
{% if client.icon_id %}
|
||||
<span class="avatar" style="background-image: url({{ client.icon.get_url() }})"></span>
|
||||
{% endif %}
|
||||
<span class="">
|
||||
{{ client.name }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<td>
|
||||
<div>
|
||||
<a href="{{ url_for('developer.client_detail', client_id=client.id) }}">
|
||||
{{ client.name }}
|
||||
</a>
|
||||
</div>
|
||||
<div class="small text-muted">
|
||||
Created at: {{ client.created_at |dt }}
|
||||
</div>
|
||||
</td>
|
||||
<div class="card-options">
|
||||
<a href="{{ url_for('developer.client_detail', client_id=client.id) }}"
|
||||
class="btn btn-primary btn-sm">
|
||||
Edit
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<td>
|
||||
{{ client.oauth_client_id }}
|
||||
</td>
|
||||
<div class="card-body">
|
||||
App ID: <em>{{ client.oauth_client_id }} </em><br>
|
||||
<span class="h1 m-0">{{ client.nb_user() }}</span> Users <br>
|
||||
Created {{ client.created_at |dt }} <br>
|
||||
{% if client.last_user_login() %}
|
||||
Last User Login: {{ client.last_user_login().get_user_name() }}
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<td>
|
||||
{{ client.nb_user() }}
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<a href="{{ url_for('developer.client_detail', client_id=client.id) }}" class="icon">
|
||||
<i class="fe fe-edit"></i>
|
||||
</a>
|
||||
</td>
|
||||
|
||||
<!-- TODO: uncomment when bringing back "Discover" feature
|
||||
<td>
|
||||
<form method="post">
|
||||
<input type="hidden" name="form-name" value="switch-client-publish">
|
||||
<input type="hidden" name="client-id" value="{{ client.id }}">
|
||||
|
||||
<label class="custom-switch">
|
||||
<input type="checkbox" class="custom-switch-input"
|
||||
{{ "checked" if client.published else "" }}>
|
||||
<span class="custom-switch-indicator"></span>
|
||||
</label>
|
||||
</form>
|
||||
</td>
|
||||
-->
|
||||
|
||||
|
||||
<td>
|
||||
<form method="post">
|
||||
<input type="hidden" name="form-name" value="delete-client">
|
||||
<input type="hidden" name="client-id" value="{{ client.id }}">
|
||||
<span class="icon delete-client">
|
||||
<i class="fe fe-trash"></i>
|
||||
</span>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block script %}
|
||||
<script>
|
||||
$(".delete-client").on("click", function (e) {
|
||||
notie.confirm({
|
||||
text: "This operation is not reversible, please confirm",
|
||||
cancelCallback: () => {
|
||||
// nothing to do
|
||||
},
|
||||
submitCallback: () => {
|
||||
$(this).closest("form").submit();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$(".custom-switch-input").change(function (e) {
|
||||
// Only ask for confirmation when publishing, not when un-publishing
|
||||
if (e.target.checked) {
|
||||
|
|
|
@ -11,22 +11,8 @@ from app.models import Client
|
|||
@developer_bp.route("/", methods=["GET", "POST"])
|
||||
@login_required
|
||||
def index():
|
||||
# delete client
|
||||
if request.method == "POST":
|
||||
if request.form.get("form-name") == "delete-client":
|
||||
client_id = int(request.form.get("client-id"))
|
||||
client = Client.get(client_id)
|
||||
|
||||
if client.user_id != current_user.id:
|
||||
flash("You cannot remove this client", "warning")
|
||||
else:
|
||||
client_name = client.name
|
||||
Client.delete(client.id)
|
||||
db.session.commit()
|
||||
LOG.d("Remove client %s", client)
|
||||
flash(f"Client {client_name} has been deleted successfully", "success")
|
||||
|
||||
elif request.form.get("form-name") == "switch-client-publish":
|
||||
if request.form.get("form-name") == "switch-client-publish":
|
||||
client_id = int(request.form.get("client-id"))
|
||||
client = Client.get(client_id)
|
||||
|
||||
|
|
|
@ -326,6 +326,16 @@ class Client(db.Model, ModelMixin):
|
|||
else:
|
||||
return URL + "/static/default-icon.svg"
|
||||
|
||||
def last_user_login(self) -> "ClientUser":
|
||||
client_user = (
|
||||
ClientUser.query.filter(ClientUser.client_id == self.id)
|
||||
.order_by(ClientUser.updated_at)
|
||||
.first()
|
||||
)
|
||||
if client_user:
|
||||
return client_user
|
||||
return None
|
||||
|
||||
|
||||
class RedirectUri(db.Model, ModelMixin):
|
||||
"""Valid redirect uris for a client"""
|
||||
|
@ -431,6 +441,12 @@ class ClientUser(db.Model, ModelMixin):
|
|||
def get_email(self):
|
||||
return self.gen_email.email if self.gen_email_id else self.user.email
|
||||
|
||||
def get_user_name(self):
|
||||
if self.name:
|
||||
return self.name
|
||||
else:
|
||||
return self.user.name
|
||||
|
||||
def get_user_info(self) -> dict:
|
||||
"""return user info according to client scope
|
||||
Return dict with key being scope name. For now all the fields are the same for all clients:
|
||||
|
|
Loading…
Reference in New Issue