Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion core/admin.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
from django.contrib import admin
from django.contrib.admin.decorators import register
from .models import Schema, SchemaRef, DocumentationItem
from .models import (
Schema, SchemaRef, DocumentationItem, Organization
)


@register(Schema)
Expand All @@ -17,3 +19,7 @@ class SchemaRefAdmin(admin.ModelAdmin):
class DocumentationItemAdmin(admin.ModelAdmin):
list_display = ['schema', 'name', 'url']


@register(Organization)
class OrganizationAdmin(admin.ModelAdmin):
list_display = ['name', 'url_path_segment', 'primary_account']
31 changes: 31 additions & 0 deletions core/migrations/0009_organization.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Generated by Django 5.2.5 on 2026-01-19 18:26

import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('core', '0008_alter_documentationitem_format_and_more'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]

operations = [
migrations.CreateModel(
name='Organization',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
('name', models.CharField(max_length=200)),
('url_path_segment', models.CharField(max_length=100, unique=True)),
('created_by', models.ForeignKey(on_delete=django.db.models.deletion.RESTRICT, to=settings.AUTH_USER_MODEL)),
('primary_account', models.ForeignKey(on_delete=django.db.models.deletion.RESTRICT, related_name='primary_account_of', to=settings.AUTH_USER_MODEL)),
],
options={
'abstract': False,
},
),
]
24 changes: 24 additions & 0 deletions core/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,16 @@ def url_providers(self):
}
return provider_names

@property
def organization(self):
# TODO: In theory a User could be the primary_account_of multiple Organizations,
# in which case we won't know which of that Users' schemas
# belong to which Organizations.
# For now, we'll assume users (as in "person using Schemas.Pub")
# only manage one organization per User (model)
# and list all their schemas under that one organization.
return Organization.objects.filter(primary_account=self.created_by).first()

def _latest_documentation_item_of_type(self, role):
return self.documentationitem_set.filter(role=role).order_by('-created_at').first()

Expand Down Expand Up @@ -207,6 +217,7 @@ def repo_url(self):
normal_path = "/".join([user, repo, "blob", branch] + filepath)
return f"https://{self.REPO_NETLOC}/{normal_path}"


class ReferenceItem(BaseModel):
class Meta:
abstract = True
Expand Down Expand Up @@ -272,3 +283,16 @@ def __str__(self):
def language(self):
return guess_language_by_extension(self.url, ['markdown'])


class Organization(BaseModel):
name = models.CharField(max_length=200)
primary_account = models.ForeignKey(User, on_delete=models.RESTRICT, related_name="primary_account_of")
url_path_segment = models.CharField(max_length=100, unique=True)

def __str__(self):
return self.name

@property
def public_schemas(self):
return Schema.public_objects.filter(created_by=self.primary_account)

9 changes: 9 additions & 0 deletions core/static/css/site.css
Original file line number Diff line number Diff line change
Expand Up @@ -904,3 +904,12 @@ a.badge--w3c {
padding: 1rem;
gap: 1rem;
}

/* Organization detail */
.organization-detail {
display: flex;
flex-direction: column;
align-items: center;
padding: 1rem;
gap: 1rem;
}
14 changes: 14 additions & 0 deletions core/templates/account/profile.html
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,20 @@ <h1>My Schemas</h1>
{% endif %}
<a href="{% url 'manage_schema_new' %}" class="button button--prominent">Add schema</a>
</section>
{% if request.user.primary_account_of.count %}
<section class="text--secondary">
<h1>Organization{{ request.user.primary_account_of.count|pluralize }}</h1>
<ul>
{% for organization in request.user.primary_account_of.all %}
<li>
<a href="{% url 'organization_detail' organization_id=organization.id %}">
{{ organization.name }}
</a>
</li>
{% endfor %}
</ul>
</section>
{% endif %}
<section class="text--secondary">
<h1>Account</h1>
Email: {{ request.user.email }}
Expand Down
26 changes: 26 additions & 0 deletions core/templates/core/organizations/detail.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{% extends "core/layouts/base.html" %}
{% block head_title %}
{{ organization.name }} | Schemas.Pub
{% endblock %}

{% block page_content %}
<main class="organization-detail">
<h1>{{ organization.name }}</h1>
<div class="main-content">
{% if organization.public_schemas.count %}
<h2>Schema{{ organization.public_schemas.count|pluralize }}</h2>
<ul>
{% for schema in organization.public_schemas.all %}
<li>
<a href="{% url 'schema_detail' schema_id=schema.id %}">
{{ schema.name }}
</a>
</li>
{% endfor %}
</ul>
{% else %}
<p>This organization has no schemas.</p>
{% endif %}
</div>
</main>
{% endblock %}
10 changes: 9 additions & 1 deletion core/templates/core/schemas/layout.html
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,15 @@ <h1>
<div class="header__info">
<span>Added on {{ schema.created_at | date }}</span>
&bull;
<span>Managed by {{ schema.created_by }}</span>
<span>Managed by
{% if schema.organization %}
<a href="{% url 'organization_detail' organization_id=schema.organization.id %}">
{{ schema.organization.name }}
</a>
{% else %}
{{ schema.created_by }}
{% endif %}
</span>
</div>
</div>
<nav class="schema-layout__nav">
Expand Down
3 changes: 2 additions & 1 deletion core/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
path("manage/schema/<int:schema_id>", views.manage_schema, name="manage_schema"),
path("manage/schema/new", views.manage_schema, name="manage_schema_new"),
path("manage/schema/<int:schema_id>/delete", views.manage_schema_delete, name="manage_schema_delete"),
path("manage/schema/<int:schema_id>/publish", views.manage_schema_publish, name="manage_schema_publish")
path("manage/schema/<int:schema_id>/publish", views.manage_schema_publish, name="manage_schema_publish"),
path("organization/<int:organization_id>", views.organization_detail, name="organization_detail")
]

10 changes: 9 additions & 1 deletion core/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
from .models import (Schema,
DocumentationItem,
SchemaRef,
DocumentationItem)
DocumentationItem,
Organization)
from .forms import SchemaForm, DocumentationItemForm


Expand Down Expand Up @@ -301,3 +302,10 @@ def manage_schema_publish(request, schema_id):

def about(request):
return render(request, "core/about.html")


def organization_detail(request, organization_id):
organization = get_object_or_404(Organization, id=organization_id)
return render(request, "core/organizations/detail.html", {
'organization': organization,
})