diff --git a/idhub/models.py b/idhub/models.py
index 83dd90a..b5c91e6 100644
--- a/idhub/models.py
+++ b/idhub/models.py
@@ -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', '')
diff --git a/idhub/templates/idhub/user/credentials.html b/idhub/templates/idhub/user/credentials.html
index 6f68e56..fcb0378 100644
--- a/idhub/templates/idhub/user/credentials.html
+++ b/idhub/templates/idhub/user/credentials.html
@@ -1,39 +1,11 @@
{% extends "idhub/base.html" %}
{% load i18n %}
+{% load render_table from django_tables2 %}
{% block content %}
-
-
-
-
-
- |
- |
- |
- |
- |
-
-
-
- {% for d in dids.all %}
-
- {{ d.created_at }} |
- {{ d.label }} |
- {{ d.did }} |
- |
- |
-
- {% endfor %}
-
-
-
-
-
+{% render_table table %}
+
{% for d in dids.all %}
diff --git a/idhub/templates/idhub/user/profile.html b/idhub/templates/idhub/user/profile.html
index 3a5d5f3..6efdc48 100644
--- a/idhub/templates/idhub/user/profile.html
+++ b/idhub/templates/idhub/user/profile.html
@@ -1,5 +1,6 @@
{% extends "idhub/base.html" %}
{% load i18n %}
+{% load render_table from django_tables2 %}
{% block content %}
@@ -33,33 +34,6 @@
{% bootstrap_form form %}
+{% render_table table %}
-
-
-
-
-
-
- |
- |
- |
- |
-
-
-
- {% for membership in object.memberships.all %}
-
- {{ membership.get_type }} |
- {{ membership.start_date|default:'' }} |
- {{ membership.end_date|default:'' }} |
-
-
- |
-
- {% endfor %}
-
-
-
-
-
{% endblock %}
diff --git a/idhub/templates/idhub/user/roles.html b/idhub/templates/idhub/user/roles.html
index 2c32e97..22777ee 100644
--- a/idhub/templates/idhub/user/roles.html
+++ b/idhub/templates/idhub/user/roles.html
@@ -1,35 +1,12 @@
{% extends "idhub/base.html" %}
{% load i18n %}
+{% load render_table from django_tables2 %}
{% block content %}
{{ subtitle }}
-
-
-
-
-
-
- |
- |
- |
-
-
-
- {% for rol in user.roles.all %}
-
- {{ rol.service.get_roles }} |
- {{ rol.service.description }} |
- {{ rol.service.domain }} |
-
- {% endfor %}
-
-
-
-
-
-
+{% render_table table %}
{% endblock %}
diff --git a/idhub/user/forms.py b/idhub/user/forms.py
index 5ac04ad..f39b102 100644
--- a/idhub/user/forms.py
+++ b/idhub/user/forms.py
@@ -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=[])
diff --git a/idhub/user/tables.py b/idhub/user/tables.py
index 0331bd6..cf90d33 100644
--- a/idhub/user/tables.py
+++ b/idhub/user/tables.py
@@ -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('
')
+
+ 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 = """
"""
+ delete = tables.TemplateColumn(template_code=delete_template_code,
+ orderable=False)
+
+ def render_edit(self):
+ return format_html('
')
+
+ 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")
diff --git a/idhub/user/views.py b/idhub/user/views.py
index 042bc10..c5c2752 100644
--- a/idhub/user/views.py
+++ b/idhub/user/views.py
@@ -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"