Added pagination and sorting to the user profile, roles, dids and credential tables
This commit is contained in:
parent
68366421bf
commit
01fb0bcaef
|
@ -489,6 +489,7 @@ class VerificableCredential(models.Model):
|
|||
issued_on = models.DateTimeField(null=True)
|
||||
data = models.TextField()
|
||||
csv_data = models.TextField()
|
||||
description = models.TextField(null=True)
|
||||
status = models.PositiveSmallIntegerField(
|
||||
choices=Status.choices,
|
||||
default=Status.ENABLED
|
||||
|
@ -518,7 +519,8 @@ class VerificableCredential(models.Model):
|
|||
def type(self):
|
||||
return self.schema.type
|
||||
|
||||
def description(self):
|
||||
@property
|
||||
def get_description(self):
|
||||
for des in json.loads(self.render()).get('description', []):
|
||||
if settings.LANGUAGE_CODE == des.get('lang'):
|
||||
return des.get('value', '')
|
||||
|
|
|
@ -1,39 +1,11 @@
|
|||
{% extends "idhub/base.html" %}
|
||||
{% load i18n %}
|
||||
{% load render_table from django_tables2 %}
|
||||
|
||||
{% block content %}
|
||||
<h3>
|
||||
<i class="{{ icon }}"></i>
|
||||
{{ subtitle }}
|
||||
</h3>
|
||||
<div class="row mt-5">
|
||||
<div class="col">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped table-sm">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col"><button type="button" class="btn btn-grey border border-dark">{% trans 'Type' %}</button></th>
|
||||
<th scope="col"><button type="button" class="btn btn-grey border border-dark">{% trans 'Details' %}</button></th>
|
||||
<th scope="col"><button type="button" class="btn btn-grey border border-dark">{% trans 'Issued' %}</button></th>
|
||||
<th scope="col" class="text-center"><button type="button" class="btn btn-grey border border-dark">{% trans 'Status' %}</button></th>
|
||||
<th scope="col"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for f in credentials.all %}
|
||||
<tr style="font-size:15px;">
|
||||
<td>{{ f.type }}</td>
|
||||
<td>{{ f.description }}</td>
|
||||
<td>{{ f.get_issued_on }}</td>
|
||||
<td class="text-center">{{ f.get_status }}</td>
|
||||
<td>
|
||||
<a href="{% url 'idhub:user_credential' f.id %}" class="text-primary" title="{% trans 'View' %}"><i class="bi bi-eye"></i></a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% render_table table %}
|
||||
{% endblock %}
|
||||
|
|
|
@ -1,41 +1,15 @@
|
|||
{% extends "idhub/base.html" %}
|
||||
{% load i18n %}
|
||||
{% load render_table from django_tables2 %}
|
||||
|
||||
{% block content %}
|
||||
<h3>
|
||||
<i class="{{ icon }}"></i>
|
||||
{{ subtitle }}
|
||||
</h3>
|
||||
<div class="row mt-5">
|
||||
<div class="col">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped table-sm">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col"><button type="button" class="btn btn-grey border border-dark">{% trans 'Date' %}</button></th>
|
||||
<th scope="col"><button type="button" class="btn btn-grey border border-dark">{% trans 'Label' %}</button></th>
|
||||
<th scope="col"><button type="button" class="btn btn-grey border border-dark">ID</button></th>
|
||||
<th scope="col"></th>
|
||||
<th scope="col"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for d in dids.all %}
|
||||
<tr style="font-size:15px;">
|
||||
<td>{{ d.created_at }}</td>
|
||||
<td>{{ d.label }}</td>
|
||||
<td>{{ d.did }}</td>
|
||||
<td><a class="text-primary" href="{% url 'idhub:user_dids_edit' d.id %}" title="{% trans 'Edit' %}"><i class="bi bi-pencil-square"></i></a></td>
|
||||
<td><a class="text-danger" href="jacascript:void()" data-bs-toggle="modal" data-bs-target="#confirm-delete-{{ d.id }}" title="{% trans 'Remove' %}"><i class="bi bi-trash"></i></a></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="form-actions-no-box">
|
||||
<a class="btn btn-green-user" href="{% url 'idhub:user_dids_new' %}">{% translate "Add Identity" %} <i class="bi bi-plus"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% render_table table %}
|
||||
<div class="form-actions-no-box">
|
||||
<a class="btn btn-green-user" href="{% url 'idhub:user_dids_new' %}">{% translate "Add Identity" %} <i class="bi bi-plus"></i></a>
|
||||
</div>
|
||||
<!-- Modal -->
|
||||
{% for d in dids.all %}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
{% extends "idhub/base.html" %}
|
||||
{% load i18n %}
|
||||
{% load render_table from django_tables2 %}
|
||||
|
||||
{% block content %}
|
||||
<div class="row">
|
||||
|
@ -33,33 +34,6 @@
|
|||
{% bootstrap_form form %}
|
||||
</form>
|
||||
<hr />
|
||||
{% render_table table %}
|
||||
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped table-sm text-center">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col"><button type="button" class="btn btn-grey border border-dark">{% trans 'Membership' %}</button></th>
|
||||
<th scope="col"><button type="button" class="btn btn-grey border border-dark">{% trans 'From' %}</button></th>
|
||||
<th scope="col"><button type="button" class="btn btn-grey border border-dark">{% trans 'To' %}</button></th>
|
||||
<th scope="col"><button type="button" class="btn btn-grey border border-dark">{% trans 'Credentials' %}</button></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for membership in object.memberships.all %}
|
||||
<tr>
|
||||
<td>{{ membership.get_type }}</td>
|
||||
<td>{{ membership.start_date|default:'' }}</td>
|
||||
<td>{{ membership.end_date|default:'' }}</td>
|
||||
<td>
|
||||
<a href="javascript:void()" class="text-primary" title="{% trans 'View' %}"><i class="bi bi-eye"></i></a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
|
|
@ -1,35 +1,12 @@
|
|||
{% extends "idhub/base.html" %}
|
||||
{% load i18n %}
|
||||
{% load render_table from django_tables2 %}
|
||||
|
||||
{% block content %}
|
||||
<h3>
|
||||
<i class="{{ icon }}"></i>
|
||||
{{ subtitle }}
|
||||
</h3>
|
||||
<div class="row mt-5">
|
||||
<div class="col">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped table-sm">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col"><button type="button" class="btn btn-grey border border-dark">{% trans 'Role' %}</button></th>
|
||||
<th scope="col"><button type="button" class="btn btn-grey border border-dark">{% trans 'Description' %}</button></th>
|
||||
<th scope="col"><button type="button" class="btn btn-grey border border-dark">{% trans 'Service' %}</button></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for rol in user.roles.all %}
|
||||
<tr>
|
||||
<td>{{ rol.service.get_roles }}</td>
|
||||
<td>{{ rol.service.description }}</td>
|
||||
<td>{{ rol.service.domain }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% render_table table %}
|
||||
|
||||
{% endblock %}
|
||||
|
|
|
@ -2,20 +2,12 @@ import requests
|
|||
from django import forms
|
||||
from django.conf import settings
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from idhub.models import DID, VerificableCredential, Organization
|
||||
|
||||
from idhub_auth.models import User
|
||||
from idhub.models import DID, VerificableCredential
|
||||
from oidc4vp.models import Organization
|
||||
|
||||
|
||||
class ProfileForm(forms.ModelForm):
|
||||
MANDATORY_FIELDS = ['first_name', 'last_name', 'email']
|
||||
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ('first_name', 'last_name', 'email')
|
||||
|
||||
|
||||
class RequestCredentialForm(forms.Form):
|
||||
did = forms.ChoiceField(label=_("Did"), choices=[])
|
||||
credential = forms.ChoiceField(label=_("Credential"), choices=[])
|
||||
|
|
|
@ -1,5 +1,21 @@
|
|||
from django.utils.html import format_html
|
||||
import django_tables2 as tables
|
||||
from idhub.models import Event
|
||||
from idhub.models import Event, Membership, UserRol, DID, VerificableCredential
|
||||
|
||||
|
||||
class ButtonColumn(tables.Column):
|
||||
attrs = {
|
||||
"a": {
|
||||
"type": "button",
|
||||
"class": "text-primary",
|
||||
}
|
||||
}
|
||||
# it makes no sense to order a column of buttons
|
||||
orderable = False
|
||||
# django_tables will only call the render function if it doesn't find
|
||||
# any empty values in the data, so we stop it from matching the data
|
||||
# to any value considered empty
|
||||
empty_values = ()
|
||||
|
||||
|
||||
class DashboardTable(tables.Table):
|
||||
|
@ -11,3 +27,97 @@ class DashboardTable(tables.Table):
|
|||
model = Event
|
||||
template_name = "idhub/custom_table.html"
|
||||
fields = ("type", "message", "created")
|
||||
|
||||
|
||||
class PersonalInfoTable(tables.Table):
|
||||
type = tables.Column(verbose_name="Membership")
|
||||
credential = ButtonColumn(
|
||||
# TODO: See where this should actually link
|
||||
linkify="idhub:user_credentials",
|
||||
orderable=False
|
||||
)
|
||||
|
||||
def render_credential(self):
|
||||
return format_html('<i class="bi bi-eye"></i>')
|
||||
|
||||
class Meta:
|
||||
model = Membership
|
||||
template_name = "idhub/custom_table.html"
|
||||
fields = ("type", "start_date", "end_date", "credential")
|
||||
|
||||
|
||||
class RolesTable(tables.Table):
|
||||
name = tables.Column(verbose_name="Role", empty_values=())
|
||||
description = tables.Column(empty_values=())
|
||||
service = tables.Column()
|
||||
|
||||
def render_name(self, record):
|
||||
return record.service.get_roles()
|
||||
|
||||
def render_description(self, record):
|
||||
return record.service.description
|
||||
|
||||
def render_service(self, record):
|
||||
return record.service.domain
|
||||
|
||||
def order_name(self, queryset, is_descending):
|
||||
queryset = queryset.order_by(
|
||||
("-" if is_descending else "") + "service__rol__name"
|
||||
)
|
||||
|
||||
return (queryset, True)
|
||||
|
||||
def order_description(self, queryset, is_descending):
|
||||
queryset = queryset.order_by(
|
||||
("-" if is_descending else "") + "service__rol__description"
|
||||
)
|
||||
|
||||
return (queryset, True)
|
||||
|
||||
class Meta:
|
||||
model = UserRol
|
||||
template_name = "idhub/custom_table.html"
|
||||
fields = ("name", "description", "service")
|
||||
|
||||
|
||||
class DIDTable(tables.Table):
|
||||
created_at = tables.Column(verbose_name="Date")
|
||||
did = tables.Column(verbose_name="ID")
|
||||
edit = ButtonColumn(
|
||||
linkify={
|
||||
"viewname": "idhub:user_dids_edit",
|
||||
"args": [tables.A("pk")]
|
||||
},
|
||||
orderable=False
|
||||
)
|
||||
delete_template_code = """<a class="text-danger"
|
||||
href="javascript:void()"
|
||||
data-bs-toggle="modal"
|
||||
data-bs-target="#confirm-delete-{{ record.id }}"
|
||||
title="Remove"
|
||||
><i class="bi bi-trash"></i></a>"""
|
||||
delete = tables.TemplateColumn(template_code=delete_template_code,
|
||||
orderable=False)
|
||||
|
||||
def render_edit(self):
|
||||
return format_html('<i class="bi bi-pencil-square"></i>')
|
||||
|
||||
class Meta:
|
||||
model = DID
|
||||
template_name = "idhub/custom_table.html"
|
||||
fields = ("created_at", "label", "did", "edit", "delete")
|
||||
|
||||
|
||||
class CredentialsTable(tables.Table):
|
||||
description = tables.Column(verbose_name="Details")
|
||||
|
||||
def render_description(self, record):
|
||||
return record.get_description()
|
||||
|
||||
def render_status(self, record):
|
||||
return record.get_status()
|
||||
|
||||
class Meta:
|
||||
model = VerificableCredential
|
||||
template_name = "idhub/custom_table.html"
|
||||
fields = ("type", "description", "issued_on", "status")
|
||||
|
|
|
@ -15,14 +15,18 @@ from django.contrib import messages
|
|||
from django_tables2 import SingleTableView
|
||||
from idhub.user.tables import (
|
||||
DashboardTable,
|
||||
PersonalInfoTable,
|
||||
RolesTable,
|
||||
DIDTable,
|
||||
CredentialsTable
|
||||
)
|
||||
from idhub.user.forms import (
|
||||
ProfileForm,
|
||||
RequestCredentialForm,
|
||||
CredentialPresentationForm
|
||||
)
|
||||
from idhub.mixins import UserView
|
||||
from idhub.models import DID, VerificableCredential, Event
|
||||
from idhub.models import DID, VerificableCredential, Event, Membership
|
||||
from idhub_auth.models import User
|
||||
|
||||
|
||||
class MyProfile(UserView):
|
||||
|
@ -50,13 +54,20 @@ class DashboardView(UserView, SingleTableView):
|
|||
return queryset
|
||||
|
||||
|
||||
class ProfileView(MyProfile, UpdateView):
|
||||
class ProfileView(MyProfile, UpdateView, SingleTableView):
|
||||
template_name = "idhub/user/profile.html"
|
||||
table_class = PersonalInfoTable
|
||||
subtitle = _('My personal data')
|
||||
icon = 'bi bi-person-gear'
|
||||
from_class = ProfileForm
|
||||
fields = ('first_name', 'last_name', 'email')
|
||||
success_url = reverse_lazy('idhub:user_profile')
|
||||
model = User
|
||||
|
||||
def get_queryset(self, **kwargs):
|
||||
queryset = Membership.objects.select_related('user').filter(
|
||||
user=self.request.user)
|
||||
|
||||
return queryset
|
||||
|
||||
def get_object(self):
|
||||
return self.request.user
|
||||
|
@ -72,11 +83,17 @@ class ProfileView(MyProfile, UpdateView):
|
|||
return super().form_valid(form)
|
||||
|
||||
|
||||
class RolesView(MyProfile, TemplateView):
|
||||
class RolesView(MyProfile, SingleTableView):
|
||||
template_name = "idhub/user/roles.html"
|
||||
table_class = RolesTable
|
||||
subtitle = _('My roles')
|
||||
icon = 'fa-brands fa-critical-role'
|
||||
|
||||
def get_queryset(self, **kwargs):
|
||||
queryset = self.request.user.roles.all()
|
||||
|
||||
return queryset
|
||||
|
||||
|
||||
class GDPRView(MyProfile, TemplateView):
|
||||
template_name = "idhub/user/gdpr.html"
|
||||
|
@ -84,8 +101,9 @@ class GDPRView(MyProfile, TemplateView):
|
|||
icon = 'bi bi-file-earmark-medical'
|
||||
|
||||
|
||||
class CredentialsView(MyWallet, TemplateView):
|
||||
class CredentialsView(MyWallet, SingleTableView):
|
||||
template_name = "idhub/user/credentials.html"
|
||||
table_class = CredentialsTable
|
||||
subtitle = _('Credential management')
|
||||
icon = 'bi bi-patch-check-fill'
|
||||
|
||||
|
@ -99,6 +117,12 @@ class CredentialsView(MyWallet, TemplateView):
|
|||
})
|
||||
return context
|
||||
|
||||
def get_queryset(self):
|
||||
queryset = VerificableCredential.objects.filter(
|
||||
user=self.request.user)
|
||||
|
||||
return queryset
|
||||
|
||||
|
||||
class CredentialView(MyWallet, TemplateView):
|
||||
template_name = "idhub/user/credential.html"
|
||||
|
@ -191,8 +215,9 @@ class DemandAuthorizationView(MyWallet, FormView):
|
|||
return super().form_valid(form)
|
||||
|
||||
|
||||
class DidsView(MyWallet, TemplateView):
|
||||
class DidsView(MyWallet, SingleTableView):
|
||||
template_name = "idhub/user/dids.html"
|
||||
table_class = DIDTable
|
||||
subtitle = _('Identities (DIDs)')
|
||||
icon = 'bi bi-patch-check-fill'
|
||||
|
||||
|
@ -203,6 +228,11 @@ class DidsView(MyWallet, TemplateView):
|
|||
})
|
||||
return context
|
||||
|
||||
def get_queryset(self, **kwargs):
|
||||
queryset = DID.objects.filter(user=self.request.user)
|
||||
|
||||
return queryset
|
||||
|
||||
|
||||
class DidRegisterView(MyWallet, CreateView):
|
||||
template_name = "idhub/user/did_register.html"
|
||||
|
|
Loading…
Reference in a new issue