chore: add sort order for project page

This commit is contained in:
NarayanBavisetti
2026-01-05 19:14:10 +05:30
parent 3d5e427894
commit 1f8e62fdce
2 changed files with 88 additions and 0 deletions

View File

@@ -0,0 +1,32 @@
# Generated by Django 4.2.22 on 2026-01-05 13:28
from django.db import migrations, models
def update_projectpage_sort_order(apps, schema_editor):
ProjectPage = apps.get_model("db", "ProjectPage")
Project = apps.get_model("db", "Project")
for project in Project.objects.all():
pages = list(
ProjectPage.objects.filter(project=project).order_by("created_at")
)
for index, page in enumerate(pages):
page.sort_order = index * 10000
ProjectPage.objects.bulk_update(pages, ["sort_order"])
class Migration(migrations.Migration):
dependencies = [
('db', '0113_webhook_version'),
]
operations = [
migrations.AddField(
model_name='projectpage',
name='sort_order',
field=models.FloatField(default=65535),
),
migrations.RunPython(update_projectpage_sort_order, reverse_code=migrations.RunPython.noop),
]

View File

@@ -63,6 +63,22 @@ class Page(BaseModel):
"""Return owner email and page name"""
return f"{self.owned_by.email} <{self.name}>"
def _get_sort_order(self, project):
"""Get the next sort order for the page within a specific project."""
if self.access == Page.PRIVATE_ACCESS:
largest = ProjectPage.objects.filter(
page__access=Page.PRIVATE_ACCESS,
page__owned_by=self.owned_by,
project=project,
).aggregate(largest=models.Max("sort_order"))["largest"]
else:
largest = ProjectPage.objects.filter(
page__access=Page.PUBLIC_ACCESS,
project=project,
).aggregate(largest=models.Max("sort_order"))["largest"]
return (largest or self.DEFAULT_SORT_ORDER) + 10000
def save(self, *args, **kwargs):
# Strip the html tags using html parser
self.description_stripped = (
@@ -70,6 +86,18 @@ class Page(BaseModel):
if (self.description_html == "" or self.description_html is None)
else strip_tags(self.description_html)
)
if not self._state.adding:
original = Page.objects.get(pk=self.pk)
if original.access != self.access:
# Get the project pages for the page and update the sort order
project_pages = list(ProjectPage.objects.filter(page=self).select_related("project"))
for project_page in project_pages:
project_page.sort_order = self._get_sort_order(project_page.project)
# Bulk update all project pages in a single query
if project_pages:
ProjectPage.objects.bulk_update(project_pages, ["sort_order"])
super(Page, self).save(*args, **kwargs)
@@ -129,9 +157,12 @@ class PageLabel(BaseModel):
class ProjectPage(BaseModel):
DEFAULT_SORT_ORDER = 65535
project = models.ForeignKey("db.Project", on_delete=models.CASCADE, related_name="project_pages")
page = models.ForeignKey("db.Page", on_delete=models.CASCADE, related_name="project_pages")
workspace = models.ForeignKey("db.Workspace", on_delete=models.CASCADE, related_name="project_pages")
sort_order = models.FloatField(default=DEFAULT_SORT_ORDER)
class Meta:
unique_together = ["project", "page", "deleted_at"]
@@ -150,6 +181,31 @@ class ProjectPage(BaseModel):
def __str__(self):
return f"{self.project.name} {self.page.name}"
def _get_sort_order(self):
"""Get the next sort order for the project page based on page access type."""
if self.page.access == Page.PRIVATE_ACCESS:
# For private pages, get max sort_order among pages owned by same user in same project
largest = ProjectPage.objects.filter(
page__access=Page.PRIVATE_ACCESS,
page__owned_by=self.page.owned_by,
project=self.project,
).aggregate(largest=models.Max("sort_order"))["largest"]
else:
# For public pages, get max sort_order among all public pages in same project
largest = ProjectPage.objects.filter(
page__access=Page.PUBLIC_ACCESS,
project=self.project,
).aggregate(largest=models.Max("sort_order"))["largest"]
return (largest or self.DEFAULT_SORT_ORDER) + 10000
def save(self, *args, **kwargs):
# Set sort_order for new project pages
if self._state.adding and self.sort_order == self.DEFAULT_SORT_ORDER:
self.sort_order = self._get_sort_order()
super(ProjectPage, self).save(*args, **kwargs)
class PageVersion(BaseModel):
workspace = models.ForeignKey("db.Workspace", on_delete=models.CASCADE, related_name="page_versions")