Skip to content

Commit

Permalink
feat: consolidate enum formats
Browse files Browse the repository at this point in the history
  • Loading branch information
shrouxm committed Mar 20, 2024
1 parent f19112f commit d547edd
Show file tree
Hide file tree
Showing 9 changed files with 149 additions and 121 deletions.
41 changes: 10 additions & 31 deletions terraso_backend/apps/graphql/schema/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -642,7 +642,6 @@ type ProjectNode implements Node {
membershipList: ProjectMembershipListNode!
privacy: ProjectManagementProjectPrivacyChoices!
archived: Boolean!
measurementUnits: ProjectManagementProjectMeasurementUnitsChoices!
siteInstructions: String
siteSet(
offset: Int
Expand Down Expand Up @@ -694,16 +693,17 @@ type ProjectMembershipNodeEdge {
type ProjectMembershipNode implements Node {
membershipList: CollaborationMembershipListNode!
user: UserNode!
userRole: UserRole!
userRole: ProjectManagementProjectRoleChoices!
membershipStatus: CollaborationMembershipMembershipStatusChoices!
pendingEmail: String
id: ID!
}

enum UserRole {
viewer
contributor
manager
"""An enumeration."""
enum ProjectManagementProjectRoleChoices {
VIEWER
CONTRIBUTOR
MANAGER
}

"""An enumeration."""
Expand All @@ -715,15 +715,6 @@ enum ProjectManagementProjectPrivacyChoices {
PUBLIC
}

"""An enumeration."""
enum ProjectManagementProjectMeasurementUnitsChoices {
"""Metric"""
METRIC

"""Imperial"""
IMPERIAL
}

type SiteNodeConnection {
"""Pagination data for this connection."""
pageInfo: PageInfo!
Expand Down Expand Up @@ -2039,24 +2030,13 @@ type ProjectAddMutationPayload {

input ProjectAddMutationInput {
name: String!
privacy: ProjectPrivacy!
privacy: ProjectManagementProjectPrivacyChoices
description: String
measurementUnits: MeasurementUnits!
siteInstructions: String
createSoilSettings: Boolean
clientMutationId: String
}

enum ProjectPrivacy {
PRIVATE
PUBLIC
}

enum MeasurementUnits {
METRIC
IMPERIAL
}

type ProjectUpdateMutationPayload {
errors: GenericScalar
project: ProjectNode
Expand All @@ -2066,9 +2046,8 @@ type ProjectUpdateMutationPayload {
input ProjectUpdateMutationInput {
id: ID!
name: String
privacy: ProjectPrivacy = null
privacy: ProjectManagementProjectPrivacyChoices
description: String
measurementUnits: MeasurementUnits = null
siteInstructions: String
clientMutationId: String
}
Expand Down Expand Up @@ -2107,7 +2086,7 @@ type ProjectAddUserMutationPayload {
input ProjectAddUserMutationInput {
projectId: ID!
userId: ID!
role: UserRole!
role: ProjectManagementProjectRoleChoices!
clientMutationId: String
}

Expand All @@ -2134,7 +2113,7 @@ type ProjectUpdateUserRoleMutationPayload {
input ProjectUpdateUserRoleMutationInput {
projectId: ID!
userId: ID!
newRole: UserRole!
newRole: ProjectManagementProjectRoleChoices!
clientMutationId: String
}

Expand Down
10 changes: 7 additions & 3 deletions terraso_backend/apps/project_management/collaboration_roles.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see https://www.gnu.org/licenses/.

ROLE_MANAGER = "manager"
ROLE_CONTRIBUTOR = "contributor"
ROLE_VIEWER = "viewer"
from django.db import models


class ProjectRole(models.TextChoices):
VIEWER = "VIEWER"
CONTRIBUTOR = "CONTRIBUTOR"
MANAGER = "MANAGER"
48 changes: 13 additions & 35 deletions terraso_backend/apps/project_management/graphql/projects.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
membership_deleted_signal,
membership_updated_signal,
)
from apps.project_management import collaboration_roles
from apps.project_management.collaboration_roles import ProjectRole
from apps.project_management.models import (
Project,
ProjectMembership,
Expand All @@ -55,30 +55,17 @@
from apps.project_management.models.sites import Site
from apps.soil_id.models.project_soil_settings import ProjectSoilSettings


class UserRole(graphene.Enum):
viewer = collaboration_roles.ROLE_VIEWER
contributor = collaboration_roles.ROLE_CONTRIBUTOR
manager = collaboration_roles.ROLE_MANAGER
ProjectRoleEnum = graphene.Enum(
"ProjectManagementProjectRoleChoices", [(c[0], c[1]) for c in ProjectRole.choices]
)


class ProjectMembershipNode(DjangoObjectType, MembershipNodeMixin):
class Meta(MembershipNodeMixin.Meta):
model = ProjectMembership

user = graphene.Field(UserNode, required=True)
user_role = graphene.Field(UserRole, required=True)

def resolve_user_role(self, info):
match self.user_role:
case "viewer":
return UserRole.viewer
case "contributor":
return UserRole.contributor
case "manager":
return UserRole.manager
case _:
raise Exception(f"Unexpected user role: {self.user_role}")
user_role = graphene.Field(ProjectRoleEnum, required=True)


class ProjectMembershipFilterSet(FilterSet):
Expand Down Expand Up @@ -140,7 +127,6 @@ class Meta:
"site_set",
"archived",
"membership_list",
"measurement_units",
"site_instructions",
)

Expand All @@ -153,6 +139,10 @@ def resolve_seen(self, info):
return True
return self.seen_by.filter(id=user.id).exists()

@classmethod
def privacy_enum(cls):
return cls._meta.fields["privacy"].type.of_type()

@classmethod
def get_queryset(cls, queryset, info):
# limit queries to membership lists of projects to which the user belongs
Expand All @@ -163,16 +153,6 @@ def get_queryset(cls, queryset, info):
)


class ProjectPrivacy(graphene.Enum):
PRIVATE = Project.PRIVATE
PUBLIC = Project.PUBLIC


class MeasurementUnits(graphene.Enum):
METRIC = "METRIC"
IMPERIAL = "IMPERIAL"


class ProjectAddMutation(BaseWriteMutation):
skip_field_validation = ["membership_list", "settings"]
project = graphene.Field(ProjectNode, required=True)
Expand All @@ -181,9 +161,8 @@ class ProjectAddMutation(BaseWriteMutation):

class Input:
name = graphene.String(required=True)
privacy = graphene.Field(ProjectPrivacy, required=True)
privacy = ProjectNode.privacy_enum()
description = graphene.String()
measurement_units = graphene.Field(MeasurementUnits, required=True)
site_instructions = graphene.String()
create_soil_settings = graphene.Boolean()

Expand Down Expand Up @@ -294,9 +273,8 @@ class ProjectUpdateMutation(BaseWriteMutation):
class Input:
id = graphene.ID(required=True)
name = graphene.String()
privacy = graphene.Field(ProjectPrivacy)
privacy = ProjectNode.privacy_enum()
description = graphene.String()
measurement_units = graphene.Field(MeasurementUnits)
site_instructions = graphene.String()

@classmethod
Expand Down Expand Up @@ -338,7 +316,7 @@ class ProjectAddUserMutation(BaseWriteMutation):
class Input:
project_id = graphene.ID(required=True)
user_id = graphene.ID(required=True)
role = graphene.Field(UserRole, required=True)
role = graphene.Field(ProjectRoleEnum, required=True)

@classmethod
def mutate_and_get_payload(cls, root, info, project_id, user_id, role):
Expand Down Expand Up @@ -437,7 +415,7 @@ class ProjectUpdateUserRoleMutation(BaseWriteMutation):
class Input:
project_id = graphene.ID(required=True)
user_id = graphene.ID(required=True)
new_role = graphene.Field(UserRole, required=True)
new_role = graphene.Field(ProjectRoleEnum, required=True)

@classmethod
def mutate_and_get_payload(cls, root, info, project_id, user_id, new_role):
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# Copyright © 2024 Technology Matters
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see https://www.gnu.org/licenses/.

# Generated by Django 5.0.2 on 2024-03-14 23:15

from django.db import migrations, models


def migrate_data(apps, schema_editor):
Project = apps.get_model("project_management", "Project")
Project.objects.filter(privacy_old="private").update(privacy="PRIVATE")
Project.objects.filter(privacy_old="public").update(privacy="PUBLIC")

Membership = apps.get_model("collaboration", "Membership")
project_memberships = Membership.objects.filter(membership_list__project__isnull=False)
project_memberships.filter(user_role="manager").update(user_role="MANAGER")
project_memberships.filter(user_role="contributor").update(user_role="CONTRIBUTOR")
project_memberships.filter(user_role="viewer").update(user_role="VIEWER")


def unmigrate_data(apps, schema_editor):
Project = apps.get_model("project_management", "Project")
Project.objects.filter(privacy="PRIVATE").update(privacy_old="private")
Project.objects.filter(privacy="PUBLIC").update(privacy_old="public")

Membership = apps.get_model("collaboration", "Membership")
project_memberships = Membership.objects.filter(membership_list__project__isnull=False)
project_memberships.filter(user_role="MANAGER").update(user_role="manager")
project_memberships.filter(user_role="CONTRIBUTOR").update(user_role="contributor")
project_memberships.filter(user_role="VIEWER").update(user_role="viewer")


class Migration(migrations.Migration):

dependencies = [
("project_management", "0025_sitenote_deleted_at_sitenote_deleted_by_cascade_and_more"),
("collaboration", "0006_membership_status_approved_lowercase"),
]

operations = [
migrations.RenameField(model_name="project", old_name="privacy", new_name="privacy_old"),
migrations.AddField(
model_name="project",
name="privacy",
field=models.CharField(
choices=[("PRIVATE", "Private"), ("PUBLIC", "Public")],
default="PRIVATE",
max_length=32,
),
),
migrations.RunPython(migrate_data, unmigrate_data),
migrations.RemoveField(model_name="project", name="privacy_old"),
migrations.RemoveField(
model_name="project",
name="measurement_units",
),
]
Loading

0 comments on commit d547edd

Please sign in to comment.