dev: sites and workspaces

This commit is contained in:
pablohashescobar 2024-04-29 14:34:48 +05:30
parent ccf87cc478
commit afc2d5a235
7 changed files with 175 additions and 2 deletions

View File

@ -257,4 +257,87 @@ class Migration(migrations.Migration):
model_name="user",
name="use_case",
),
migrations.CreateModel(
name="Site",
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"
),
),
(
"id",
models.UUIDField(
db_index=True,
default=uuid.uuid4,
editable=False,
primary_key=True,
serialize=False,
unique=True,
),
),
("name", models.CharField(max_length=80)),
("description", models.TextField(blank=True)),
("use_case", models.TextField(blank=True)),
("domain", models.TextField(blank=True)),
("user_count", models.IntegerField(default=1)),
(
"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",
),
),
(
"owner",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="sites",
to=settings.AUTH_USER_MODEL,
),
),
(
"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",
),
),
],
options={
"abstract": False,
"verbose_name": "Site",
"verbose_name_plural": "Sites",
"db_table": "sites",
"ordering": ("-created_at",),
},
),
migrations.AddField(
model_name="workspace",
name="site",
field=models.ForeignKey(
null=True,
on_delete=django.db.models.deletion.CASCADE,
related_name="workspaces",
to="db.site",
),
),
migrations.AddField(
model_name="workspace",
name="is_primary",
field=models.BooleanField(default=False),
),
]

View File

@ -75,6 +75,7 @@ from .workspace import (
WorkspaceMemberInvite,
WorkspaceTheme,
WorkspaceUserProperties,
Site,
)
from .importer import Importer

View File

@ -144,6 +144,12 @@ class Site(BaseModel):
"""Return name of site"""
return self.name
class Meta:
verbose_name = "Site"
verbose_name_plural = "Sites"
db_table = "sites"
ordering = ("-created_at",)
class Workspace(BaseModel):
name = models.CharField(max_length=80, verbose_name="Workspace Name")
@ -163,13 +169,24 @@ class Workspace(BaseModel):
)
organization_size = models.CharField(max_length=20, blank=True, null=True)
site = models.ForeignKey(
"db.Site", on_delete=models.CASCADE, related_name="workspaces"
"db.Site",
on_delete=models.CASCADE,
related_name="workspaces",
null=True,
)
is_primary = models.BooleanField(default=False)
def __str__(self):
"""Return name of the Workspace"""
return self.name
def save(self, *args, **kwargs):
if self.is_primary:
Workspace.objects.filter(site_id=self.site_id).update(
is_primary=False
)
super(Workspace, self).save(*args, **kwargs)
class Meta:
verbose_name = "Workspace"
verbose_name_plural = "Workspaces"

View File

@ -16,4 +16,6 @@ from .admin import (
InstanceAdminSignUpEndpoint,
InstanceAdminUserMeEndpoint,
InstanceAdminSignOutEndpoint,
InstanceWorkspacesEndpoint,
PrimaryWorkspaceEndpoint,
)

View File

@ -25,7 +25,7 @@ from plane.license.api.serializers import (
InstanceAdminSerializer,
)
from plane.license.models import Instance, InstanceAdmin
from plane.db.models import User, Profile
from plane.db.models import User, Profile, Workspace, Site
from plane.utils.cache import cache_response, invalidate_cache
from plane.authentication.utils.login import user_login
from plane.authentication.utils.host import base_host
@ -392,3 +392,58 @@ class InstanceAdminSignOutEndpoint(View):
"god-mode/login?" + urlencode({"success": "true"}),
)
return HttpResponseRedirect(url)
class InstanceWorkspacesEndpoint(BaseAPIView):
permission_classes = [
InstanceAdminPermission,
]
def get(self, request):
workspace = Workspace.objects.values()
return Response(workspace, status=status.HTTP_200_OK)
class PrimaryWorkspaceEndpoint(BaseAPIView):
permission_classes = [
InstanceAdminPermission,
]
def post(self, request):
# Get the id of the primary workspace
primary_workspace_id = request.data.get("primary_workspace_id", False)
# Throw error is the primary workspace is not specified
if not primary_workspace_id:
return Response(
{"error": "Primary workspace id is required"},
status=status.HTTP_400_BAD_REQUEST,
)
# Get the primary workspace
primary_workspace = Workspace.objects.get(pk=primary_workspace_id)
# Check if the site exists or not
site = Site.objects.first()
if not site:
# Create a Site
site = Site.objects.create(
name=primary_workspace.name,
owner=primary_workspace.owner,
domain=f"{request.get_host()}",
user_count=User.objects.count(),
)
# Attach this site to all workspaces
Workspace.objects.update(site=site, is_primary=False)
# Update the primary workspace
primary_workspace.is_primary = True
primary_workspace.site = site
primary_workspace.save()
return Response(
{"message": "Primary workspace created succesfully"},
status=status.HTTP_200_OK,
)

View File

@ -155,6 +155,9 @@ class InstanceEndpoint(BaseAPIView):
)
instance_data = serializer.data
instance_data["workspaces_exist"] = Workspace.objects.count() > 1
instance_data["primary_workspace"] = Workspace.objects.filter(
is_primary=True
).exists()
response_data = {"config": data, "instance": instance_data}
return Response(response_data, status=status.HTTP_200_OK)

View File

@ -10,6 +10,8 @@ from plane.license.api.views import (
SignUpScreenVisitedEndpoint,
InstanceAdminUserMeEndpoint,
InstanceAdminSignOutEndpoint,
InstanceWorkspacesEndpoint,
PrimaryWorkspaceEndpoint,
)
urlpatterns = [
@ -63,4 +65,14 @@ urlpatterns = [
EmailCredentialCheckEndpoint.as_view(),
name="email-credential-check",
),
path(
"workspaces/",
InstanceWorkspacesEndpoint.as_view(),
name="instance-workspaces",
),
path(
"primary-workspace/",
PrimaryWorkspaceEndpoint.as_view(),
name="primary-workspace",
),
]