fix: workspace user perferences model and migrations

This commit is contained in:
sriram veeraghanta 2025-01-10 19:54:48 +05:30
parent cfdb3373c9
commit 39ca600091
6 changed files with 155 additions and 26 deletions

View file

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

View file

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

View file

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

View file

@ -1,4 +1,5 @@
# Python imports # Python imports
from django.db.models.functions import Ln
import pytz import pytz
# Django imports # Django imports
@ -345,6 +346,8 @@ class WorkspaceUserLink(WorkspaceBaseModel):
class WorkspaceHomePreference(BaseModel): class WorkspaceHomePreference(BaseModel):
"""Preference for the home page of a workspace for a user"""
class HomeWidgetKeys(models.TextChoices): class HomeWidgetKeys(models.TextChoices):
QUICK_LINKS = "quick_links", "Quick Links" QUICK_LINKS = "quick_links", "Quick Links"
RECENTS = "recents", "Recents" RECENTS = "recents", "Recents"
@ -365,7 +368,7 @@ class WorkspaceHomePreference(BaseModel):
key = models.CharField(max_length=255) key = models.CharField(max_length=255)
is_enabled = models.BooleanField(default=True) is_enabled = models.BooleanField(default=True)
config = models.JSONField(default=dict) config = models.JSONField(default=dict)
sort_order = models.PositiveIntegerField(default=65535) sort_order = models.FloatField(default=65535)
class Meta: class Meta:
unique_together = ["workspace", "user", "key", "deleted_at"] unique_together = ["workspace", "user", "key", "deleted_at"]
@ -383,3 +386,42 @@ class WorkspaceHomePreference(BaseModel):
def __str__(self): def __str__(self):
return f"{self.workspace.name} {self.user.email} {self.key}" 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",)