-
Notifications
You must be signed in to change notification settings - Fork 3.3k
[WIKI-769] chore: add sort order for project page #8490
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: preview
Are you sure you want to change the base?
Changes from 1 commit
1f8e62f
8a75250
2088d0b
5722ac8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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"]) | ||
|
|
||
NarayanBavisetti marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| 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), | ||
| ] | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -63,13 +63,41 @@ def __str__(self): | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| """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 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
NarayanBavisetti marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| def save(self, *args, **kwargs): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Strip the html tags using html parser | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| self.description_stripped = ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| None | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 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"]) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
NarayanBavisetti marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
NarayanBavisetti marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| super(Page, self).save(*args, **kwargs) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -129,9 +157,12 @@ def __str__(self): | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 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 Meta: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 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"] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+197
to
+208
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 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"] | |
| qs = ProjectPage.objects.filter( | |
| page__access=Page.PRIVATE_ACCESS, | |
| page__owned_by=self.page.owned_by, | |
| project=self.project, | |
| ) | |
| else: | |
| # For public pages, get max sort_order among all public pages in same project | |
| qs = ProjectPage.objects.filter( | |
| page__access=Page.PUBLIC_ACCESS, | |
| project=self.project, | |
| ) | |
| # Exclude the current instance (when it already exists) from the aggregation | |
| if self.pk: | |
| qs = qs.exclude(pk=self.pk) | |
| largest = qs.aggregate(largest=models.Max("sort_order"))["largest"] |
Uh oh!
There was an error while loading. Please reload this page.