diff --git a/apiserver/plane/db/migrations/0090_rename_dashboard_deprecateddashboard_and_more.py b/apiserver/plane/db/migrations/0090_rename_dashboard_deprecateddashboard_and_more.py index 393317493f..e0d16d5a61 100644 --- a/apiserver/plane/db/migrations/0090_rename_dashboard_deprecateddashboard_and_more.py +++ b/apiserver/plane/db/migrations/0090_rename_dashboard_deprecateddashboard_and_more.py @@ -1,6 +1,9 @@ -# Generated by Django 4.2.17 on 2025-01-09 12:16 + # 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): @@ -51,4 +54,34 @@ class Migration(migrations.Migration): 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')}, + ), ] diff --git a/apiserver/plane/db/models/workspace.py b/apiserver/plane/db/models/workspace.py index 4ea74cbc51..c06b1957a6 100644 --- a/apiserver/plane/db/models/workspace.py +++ b/apiserver/plane/db/models/workspace.py @@ -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" @@ -383,3 +386,44 @@ 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): + INITIATIVES = "initiatives", "Initiatives" + TEAMS = "teams", "Teams" + 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",)