Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Project Configuration UI #66

Merged
merged 41 commits into from
Oct 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
e7b29bb
feat: Add basic ProjectConfig component
annehaley Aug 14, 2024
13f00ea
ui: Redesign main drawer contents
annehaley Sep 16, 2024
7afef9b
refactor: populate store vars when fetching for Project contents
annehaley Sep 16, 2024
b84303d
feat: Toggle dataset layers with maplibre
annehaley Sep 16, 2024
971e991
fix: Add matplotlib to requirements for raster colormaps
annehaley Sep 16, 2024
407eccf
fix: change loading behavior of Project contents panels
annehaley Sep 17, 2024
58f59a4
fix: adjust map state watchers
annehaley Sep 18, 2024
e7e0e3c
ui: Set primary color to blue
annehaley Sep 18, 2024
8977ada
deps: Upgrade vuetify
annehaley Sep 18, 2024
bb21859
feat: Add Dataset selection panel to Project Config page
annehaley Sep 19, 2024
d91be55
feat: create/delete projects, edit project names and default map posi…
annehaley Sep 19, 2024
dba0516
feat: add Access Control interface
annehaley Sep 20, 2024
b933d2f
fix: Change groupBy control to radio buttons
annehaley Sep 25, 2024
a070f83
style: Adjust vertical alignment of object counts, flush with icons
annehaley Sep 25, 2024
3a71b3a
fix: add `item_counts` to `ProjectSerializer` for new sidebar design
annehaley Sep 30, 2024
294ab3c
fix: update setting permissions in Project `partial_update`
annehaley Sep 30, 2024
513959a
fix: update references to `resetMap` -> `setMapCenter`
annehaley Sep 30, 2024
744e124
fix: reverse map coord ordering in API
annehaley Oct 1, 2024
99bee91
fix: update `set_permissions` call in `ProjectViewSet.partial_update`
annehaley Oct 1, 2024
cff13c4
refactor: update web/src/storeFunctions.ts
annehaley Oct 1, 2024
d2bffde
refactor: separate Project update endpoints, don't override `partial_…
annehaley Oct 3, 2024
07f1a9d
style: remove unused imports
annehaley Oct 3, 2024
ccb3e39
refactor: `setMapCenter` implicit undefined argument
annehaley Oct 3, 2024
6ce1e6f
refactor: explicitly define acceptable values for `projectConfigMode`
annehaley Oct 3, 2024
80fe54e
fix: order Project queryset by name
annehaley Oct 3, 2024
d2ad119
fix: improve map location menu hover/click behavior
annehaley Oct 3, 2024
38d2cc9
refactor: explicitly define acceptable values for `saving`
annehaley Oct 3, 2024
33f53f3
Reset project name text fields if focus is lossed
jjnesbitt Oct 8, 2024
7eb640c
refactor: Use Vue `script setup` syntax on new/modified components
annehaley Oct 8, 2024
ce33080
feat: default to `flyTo` when setting map center
annehaley Oct 8, 2024
754d1be
refactor: Apply suggestion to `toggleDatasets` function in `ProjectCo…
annehaley Oct 10, 2024
245871b
style: replace double equals with triple equals
annehaley Oct 10, 2024
ba7fbcf
style: use title case for component tag
annehaley Oct 10, 2024
816dd25
refactor: Remove ownership claim mode
annehaley Oct 10, 2024
f5bc7ad
refactor: Apply suggestion to use sets in `savePermissions`
annehaley Oct 10, 2024
4464033
Apply suggestion to typing in AccessControl.vue
annehaley Oct 10, 2024
a843439
refactor: enforce consistent naming of permission levels
annehaley Oct 10, 2024
16e6140
fix: Prevent multiple permissions for single user in project
jjnesbitt Oct 10, 2024
1c83360
fix: modify `savePermissions` to move users between followers and col…
annehaley Oct 10, 2024
5cddada
Merge branch 'master' into project-config-ui
annehaley Oct 10, 2024
7051ab4
fix: Remove current project owner from users list
annehaley Oct 10, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
'djangorestframework==3.15.2',
'django-large-image==0.10.0',
'drf-yasg==1.21.7',
'matplotlib==3.9.2', # for raster colormaps
'osmnx==1.9.4',
'geopandas==0.14.4',
'networkx==3.3',
Expand Down
25 changes: 23 additions & 2 deletions uvdat/core/rest/project.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
from typing import Any

from django.contrib.auth.models import User
from django.http import HttpResponse
from drf_yasg.utils import swagger_auto_schema
from rest_framework.decorators import action
from rest_framework.request import Request
from rest_framework.response import Response
from rest_framework.viewsets import ModelViewSet

from uvdat.core.models import Project
from uvdat.core.rest.access_control import GuardianFilter, GuardianPermission
from uvdat.core.rest.serializers import ProjectSerializer
from uvdat.core.rest.serializers import ProjectPermissionsSerializer, ProjectSerializer
from uvdat.core.tasks.osmnx import load_roads


class ProjectViewSet(ModelViewSet):
queryset = Project.objects.all()
queryset = Project.objects.all().order_by('name')
serializer_class = ProjectSerializer
permission_classes = [GuardianPermission]
filter_backends = [GuardianFilter]
Expand All @@ -21,6 +26,22 @@ def perform_create(self, serializer):
user: User = self.request.user
project.set_permissions(owner=user)

jjnesbitt marked this conversation as resolved.
Show resolved Hide resolved
@swagger_auto_schema(method='PUT', request_body=ProjectPermissionsSerializer)
@action(detail=True, methods=['PUT'])
def permissions(self, request: Request, *args: Any, **kwargs: Any):
serializer = ProjectPermissionsSerializer(data=request.data)
serializer.is_valid(raise_exception=True)

data = serializer.validated_data
project: Project = self.get_object()
project.set_permissions(
owner=User.objects.get(id=data['owner_id']),
collaborator=list(User.objects.filter(id__in=data['collaborator_ids'])),
follower=list(User.objects.filter(id__in=data['follower_ids'])),
)

return Response(ProjectSerializer(project).data, status=200)

@action(detail=True, methods=['get'])
def regions(self, request, **kwargs):
project = self.get_object()
Expand Down
27 changes: 27 additions & 0 deletions uvdat/core/rest/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,30 @@ class Meta:
fields = ['id', 'username', 'email', 'first_name', 'last_name', 'is_superuser']


class ProjectPermissionsSerializer(serializers.Serializer):
owner_id = serializers.IntegerField()
collaborator_ids = serializers.ListField(child=serializers.IntegerField())
follower_ids = serializers.ListField(child=serializers.IntegerField())

def validate(self, attrs):
collaborators = set(attrs['collaborator_ids'])
followers = set(attrs['follower_ids'])
owner = attrs['owner_id']

if collaborators & followers or owner in (collaborators | followers):
raise serializers.ValidationError(
'A user cannot have multiple permissions on a single project'
)

return super().validate(attrs)


class ProjectSerializer(serializers.ModelSerializer):
default_map_center = serializers.SerializerMethodField('get_center')
owner = serializers.SerializerMethodField('get_owner')
collaborators = serializers.SerializerMethodField('get_collaborators')
followers = serializers.SerializerMethodField('get_followers')
item_counts = serializers.SerializerMethodField('get_item_counts')

def get_center(self, obj):
# Web client expects Lon, Lat
Expand All @@ -54,6 +73,14 @@ def get_followers(self, obj):
users = get_users_with_perms(obj, only_with_perms_in=['follower'])
return [UserSerializer(user).data for user in users.all()]

def get_item_counts(self, obj):
return {
'datasets': obj.datasets.count(),
'regions': obj.derived_regions.count(),
'charts': obj.charts.count(),
'simulations': obj.simulation_results.count(),
}

def to_internal_value(self, data):
center = data.get('default_map_center')
data = super().to_internal_value(data)
Expand Down
Loading
Loading