Compare commits

...

4 Commits

Author SHA1 Message Date
pablohashescobar
5d15ab1be1 chore: update preferences 2025-01-10 17:22:09 +05:30
pablohashescobar
6d84a1b5bc Merge branch 'preview' of github.com:makeplane/plane into chore-preference-migrations 2025-01-10 17:10:25 +05:30
pablohashescobar
0e8ff37ccc chore: add migration for workspace user preference 2025-01-09 20:16:36 +05:30
pablohashescobar
44c241d94b fix: home preferences 2025-01-09 17:59:31 +05:30
6 changed files with 155 additions and 26 deletions

View File

@@ -1,6 +1,6 @@
# Module imports
from .base import BaseSerializer
from plane.db.models import Dashboard, Widget
from plane.db.models import DeprecatedDashboard, DeprecatedWidget
# Third party frameworks
from rest_framework import serializers
@@ -8,7 +8,7 @@ from rest_framework import serializers
class DashboardSerializer(BaseSerializer):
class Meta:
model = Dashboard
model = DeprecatedDashboard
fields = "__all__"
@@ -17,5 +17,5 @@ class WidgetSerializer(BaseSerializer):
widget_filters = serializers.JSONField(read_only=True)
class Meta:
model = Widget
model = DeprecatedWidget
fields = ["id", "key", "is_visible", "widget_filters"]

View File

@@ -32,15 +32,15 @@ from plane.app.serializers import (
WidgetSerializer,
)
from plane.db.models import (
Dashboard,
DashboardWidget,
DeprecatedDashboard,
DeprecatedDashboardWidget,
Issue,
IssueActivity,
FileAsset,
IssueLink,
IssueRelation,
Project,
Widget,
DeprecatedWidget,
WorkspaceMember,
CycleIssue,
)
@@ -687,7 +687,7 @@ class DashboardEndpoint(BaseAPIView):
if not dashboard_id:
dashboard_type = request.GET.get("dashboard_type", None)
if dashboard_type == "home":
dashboard, created = Dashboard.objects.get_or_create(
dashboard, created = DeprecatedDashboard.objects.get_or_create(
type_identifier=dashboard_type,
owned_by=request.user,
is_default=True,
@@ -707,7 +707,7 @@ class DashboardEndpoint(BaseAPIView):
updated_dashboard_widgets = []
for widget_key in widgets_to_fetch:
widget = Widget.objects.filter(key=widget_key).values_list(
widget = DeprecatedWidget.objects.filter(key=widget_key).values_list(
"id", flat=True
)
if widget:
@@ -722,9 +722,9 @@ class DashboardEndpoint(BaseAPIView):
)
widgets = (
Widget.objects.annotate(
DeprecatedWidget.objects.annotate(
is_visible=Exists(
DashboardWidget.objects.filter(
DeprecatedDashboardWidget.objects.filter(
widget_id=OuterRef("pk"),
dashboard_id=dashboard.id,
is_visible=True,

View File

@@ -0,0 +1,87 @@
# Generated by Django 4.2.17 on 2025-01-09 14:43
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import uuid
class Migration(migrations.Migration):
dependencies = [
('db', '0089_workspacehomepreference_and_more'),
]
operations = [
migrations.RenameModel(
old_name='Dashboard',
new_name='DeprecatedDashboard',
),
migrations.RenameModel(
old_name='DashboardWidget',
new_name='DeprecatedDashboardWidget',
),
migrations.RenameModel(
old_name='Widget',
new_name='DeprecatedWidget',
),
migrations.AlterModelOptions(
name='deprecateddashboard',
options={'ordering': ('-created_at',), 'verbose_name': 'DeprecatedDashboard', 'verbose_name_plural': 'DeprecatedDashboards'},
),
migrations.AlterModelOptions(
name='deprecateddashboardwidget',
options={'ordering': ('-created_at',), 'verbose_name': 'Deprecated Dashboard Widget', 'verbose_name_plural': 'Deprecated Dashboard Widgets'},
),
migrations.AlterModelOptions(
name='deprecatedwidget',
options={'ordering': ('-created_at',), 'verbose_name': 'DeprecatedWidget', 'verbose_name_plural': 'DeprecatedWidgets'},
),
migrations.AlterField(
model_name='workspacehomepreference',
name='sort_order',
field=models.FloatField(default=65535),
),
migrations.AlterModelTable(
name='deprecateddashboard',
table='deprecated_dashboards',
),
migrations.AlterModelTable(
name='deprecateddashboardwidget',
table='deprecated_dashboard_widgets',
),
migrations.AlterModelTable(
name='deprecatedwidget',
table='deprecated_widgets',
),
migrations.CreateModel(
name='WorkspaceUserPreference',
fields=[
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Created At')),
('updated_at', models.DateTimeField(auto_now=True, verbose_name='Last Modified At')),
('deleted_at', models.DateTimeField(blank=True, null=True, verbose_name='Deleted At')),
('id', models.UUIDField(db_index=True, default=uuid.uuid4, editable=False, primary_key=True, serialize=False, unique=True)),
('key', models.CharField(max_length=255)),
('is_pinned', models.BooleanField(default=False)),
('sort_order', models.FloatField(default=65535)),
('created_by', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='%(class)s_created_by', to=settings.AUTH_USER_MODEL, verbose_name='Created By')),
('updated_by', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='%(class)s_updated_by', to=settings.AUTH_USER_MODEL, verbose_name='Last Modified By')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='workspace_user_preferences', to=settings.AUTH_USER_MODEL)),
('workspace', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='workspace_user_preferences', to='db.workspace')),
],
options={
'verbose_name': 'Workspace User Preference',
'verbose_name_plural': 'Workspace User Preferences',
'db_table': 'workspace_user_preferences',
'ordering': ('-created_at',),
},
),
migrations.AddConstraint(
model_name='workspaceuserpreference',
constraint=models.UniqueConstraint(condition=models.Q(('deleted_at__isnull', True)), fields=('workspace', 'user', 'key'), name='workspace_user_preferences_unique_workspace_user_key_when_deleted_at_null'),
),
migrations.AlterUniqueTogether(
name='workspaceuserpreference',
unique_together={('workspace', 'user', 'key', 'deleted_at')},
),
]

View File

@@ -3,7 +3,7 @@ from .api import APIActivityLog, APIToken
from .asset import FileAsset
from .base import BaseModel
from .cycle import Cycle, CycleIssue, CycleUserProperties
from .dashboard import Dashboard, DashboardWidget, Widget
from .dashboard import DeprecatedDashboard, DeprecatedDashboardWidget, DeprecatedWidget
from .deploy_board import DeployBoard
from .draft import (
DraftIssue,

View File

@@ -8,7 +8,7 @@ from ..mixins import TimeAuditModel
from .base import BaseModel
class Dashboard(BaseModel):
class DeprecatedDashboard(BaseModel):
DASHBOARD_CHOICES = (
("workspace", "Workspace"),
("project", "Project"),
@@ -36,13 +36,13 @@ class Dashboard(BaseModel):
return f"{self.name}"
class Meta:
verbose_name = "Dashboard"
verbose_name_plural = "Dashboards"
db_table = "dashboards"
verbose_name = "DeprecatedDashboard"
verbose_name_plural = "DeprecatedDashboards"
db_table = "deprecated_dashboards"
ordering = ("-created_at",)
class Widget(TimeAuditModel):
class DeprecatedWidget(TimeAuditModel):
id = models.UUIDField(
default=uuid.uuid4, unique=True, editable=False, db_index=True, primary_key=True
)
@@ -55,18 +55,18 @@ class Widget(TimeAuditModel):
return f"{self.key}"
class Meta:
verbose_name = "Widget"
verbose_name_plural = "Widgets"
db_table = "widgets"
verbose_name = "DeprecatedWidget"
verbose_name_plural = "DeprecatedWidgets"
db_table = "deprecated_widgets"
ordering = ("-created_at",)
class DashboardWidget(BaseModel):
class DeprecatedDashboardWidget(BaseModel):
widget = models.ForeignKey(
Widget, on_delete=models.CASCADE, related_name="dashboard_widgets"
DeprecatedWidget, on_delete=models.CASCADE, related_name="dashboard_widgets"
)
dashboard = models.ForeignKey(
Dashboard, on_delete=models.CASCADE, related_name="dashboard_widgets"
DeprecatedDashboard, on_delete=models.CASCADE, related_name="dashboard_widgets"
)
is_visible = models.BooleanField(default=True)
sort_order = models.FloatField(default=65535)
@@ -86,7 +86,7 @@ class DashboardWidget(BaseModel):
name="dashboard_widget_unique_widget_dashboard_when_deleted_at_null",
)
]
verbose_name = "Dashboard Widget"
verbose_name_plural = "Dashboard Widgets"
db_table = "dashboard_widgets"
verbose_name = "Deprecated Dashboard Widget"
verbose_name_plural = "Deprecated Dashboard Widgets"
db_table = "deprecated_dashboard_widgets"
ordering = ("-created_at",)

View File

@@ -1,4 +1,5 @@
# Python imports
from django.db.models.functions import Ln
import pytz
# Django imports
@@ -345,6 +346,8 @@ class WorkspaceUserLink(WorkspaceBaseModel):
class WorkspaceHomePreference(BaseModel):
"""Preference for the home page of a workspace for a user"""
class HomeWidgetKeys(models.TextChoices):
QUICK_LINKS = "quick_links", "Quick Links"
RECENTS = "recents", "Recents"
@@ -365,7 +368,7 @@ class WorkspaceHomePreference(BaseModel):
key = models.CharField(max_length=255)
is_enabled = models.BooleanField(default=True)
config = models.JSONField(default=dict)
sort_order = models.PositiveIntegerField(default=65535)
sort_order = models.FloatField(default=65535)
class Meta:
unique_together = ["workspace", "user", "key", "deleted_at"]
@@ -383,3 +386,42 @@ class WorkspaceHomePreference(BaseModel):
def __str__(self):
return f"{self.workspace.name} {self.user.email} {self.key}"
class WorkspaceUserPreference(BaseModel):
"""Preference for the workspace for a user"""
class UserPreferenceKeys(models.TextChoices):
CYCLES = "cycles", "Cycles"
VIEWS = "views", "Views"
ANALYTICS = "analytics", "Analytics"
PROJECTS = "projects", "Projects"
workspace = models.ForeignKey(
"db.Workspace",
on_delete=models.CASCADE,
related_name="workspace_user_preferences",
)
user = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
related_name="workspace_user_preferences",
)
key = models.CharField(max_length=255)
is_pinned = models.BooleanField(default=False)
sort_order = models.FloatField(default=65535)
class Meta:
unique_together = ["workspace", "user", "key", "deleted_at"]
constraints = [
models.UniqueConstraint(
fields=["workspace", "user", "key"],
condition=models.Q(deleted_at__isnull=True),
name="workspace_user_preferences_unique_workspace_user_key_when_deleted_at_null",
)
]
verbose_name = "Workspace User Preference"
verbose_name_plural = "Workspace User Preferences"
db_table = "workspace_user_preferences"
ordering = ("-created_at",)