diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 7c977ce57..f239e9c76 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -200,7 +200,7 @@ git remote add upstream https://github.com/activist-org/activist.git
# docker compose --env-file .env.dev down
```
-5. You can visit to see the development build once the container is up and running.
+5. You can visit to see the development build once the container is up and running. From there click `View organizations` or `View events` to explore the platform.
> [!NOTE]
> Feel free to contact the team in the [Development room on Matrix](https://matrix.to/#/!CRgLpGeOBNwxYCtqmK:matrix.org?via=matrix.org&via=acter.global&via=chat.0x7cd.xyz) if you're having problems getting your environment setup!
diff --git a/README.md b/README.md
index d28c5c081..a6ec8fcd5 100644
--- a/README.md
+++ b/README.md
@@ -210,7 +210,7 @@ git remote add upstream https://github.com/activist-org/activist.git
# docker compose --env-file .env.dev down
```
-6. You can then visit to see the development frontend build once the container is up and running.
+6. You can then visit to see the development frontend build once the container is up and running. From there click `View organizations` or `View events` to explore the platform.
> [!NOTE]
> Feel free to contact the team in the [Development room on Matrix](https://matrix.to/#/!CRgLpGeOBNwxYCtqmK:matrix.org?via=matrix.org&via=acter.global&via=chat.0x7cd.xyz) if you're having problems getting your environment setup! If you're having issues with Docker and just want to get the frontend or backend up and running, please see [the section on this in the contributing guide](https://github.com/activist-org/activist/blob/main/CONTRIBUTING.md#using-yarn-or-python).
diff --git a/backend/authentication/admin.py b/backend/authentication/admin.py
index 9761b2108..ebd476ccb 100644
--- a/backend/authentication/admin.py
+++ b/backend/authentication/admin.py
@@ -86,7 +86,7 @@ class UserAdmin(BaseUserAdmin):
add_form = UserCreationForm
# The fields to be used in displaying the User model.
- list_display = ["email", "is_admin"]
+ list_display = ["username", "email", "is_admin"]
list_filter = ["is_admin"]
fieldsets = [
(None, {"fields": ["email", "password"]}),
diff --git a/backend/authentication/factories.py b/backend/authentication/factories.py
index e833d3782..987419dc1 100644
--- a/backend/authentication/factories.py
+++ b/backend/authentication/factories.py
@@ -39,6 +39,7 @@ class Meta:
username = factory.Faker("user_name")
name = factory.Faker("name")
+ location = factory.Faker("city")
description = factory.Faker("text", max_nb_chars=500)
verified = factory.Faker("boolean")
verification_method = factory.Faker("word")
diff --git a/backend/authentication/models.py b/backend/authentication/models.py
index 5f1f3d18b..4ad430c5e 100644
--- a/backend/authentication/models.py
+++ b/backend/authentication/models.py
@@ -87,6 +87,7 @@ class UserModel(AbstractUser, PermissionsMixin):
username = models.CharField(max_length=255, unique=True)
name = models.CharField(max_length=255, blank=True)
password = models.CharField(max_length=255)
+ location = models.CharField(max_length=100, blank=True)
description = models.TextField(max_length=500, blank=True)
verified = models.BooleanField(default=False)
verification_method = models.CharField(max_length=30, blank=True)
diff --git a/backend/backend/management/commands/populate_db.py b/backend/backend/management/commands/populate_db.py
index 262bd4280..e799d7a94 100644
--- a/backend/backend/management/commands/populate_db.py
+++ b/backend/backend/management/commands/populate_db.py
@@ -1,10 +1,12 @@
+import random
from argparse import ArgumentParser
from typing import TypedDict, Unpack
from django.core.management.base import BaseCommand
-from authentication.factories import UserFactory
+from authentication.factories import UserFactory, UserTopicFactory
from authentication.models import UserModel
+from content.models import Topic
from entities.factories import (
GroupFactory,
GroupTextFactory,
@@ -18,9 +20,9 @@
class Options(TypedDict):
users: int
- orgs: int
- groups: int
- events: int
+ orgs_per_user: int
+ groups_per_org: int
+ events_per_org: int
class Command(BaseCommand):
@@ -28,15 +30,15 @@ class Command(BaseCommand):
def add_arguments(self, parser: ArgumentParser) -> None:
parser.add_argument("--users", type=int, default=10)
- parser.add_argument("--opu", type=int, default=1) # orgs per user
- parser.add_argument("--gpo", type=int, default=1) # groups per org
- parser.add_argument("--epo", type=int, default=1) # events per org
+ parser.add_argument("--orgs-per-user", type=int, default=1)
+ parser.add_argument("--groups-per-org", type=int, default=1)
+ parser.add_argument("--events-per-org", type=int, default=1)
def handle(self, *args: str, **options: Unpack[Options]) -> None:
- n_users = options.get("users")
- n_orgs_per_user = options.get("opu")
- n_groups_per_org = options.get("gpo")
- n_events_per_org = options.get("epo")
+ num_users = options["users"]
+ num_orgs_per_user = options["orgs_per_user"]
+ num_groups_per_org = options["groups_per_org"]
+ num_events_per_org = options["events_per_org"]
# Clear all tables before creating new data.
UserModel.objects.exclude(username="admin").delete()
@@ -44,73 +46,60 @@ def handle(self, *args: str, **options: Unpack[Options]) -> None:
Group.objects.all().delete()
Event.objects.all().delete()
+ topics = Topic.objects.all()
+
try:
users = [
UserFactory(username=f"activist_{i}", name=f"Activist {i}")
- for i in range(n_users)
+ for i in range(num_users)
]
- for i, user in enumerate(users):
- user_location = "Berlin"
- user_topic = "Climate"
+ for u, user in enumerate(users):
+ user_topic = random.choice(topics)
+ UserTopicFactory(user_id=user, topic_id=user_topic)
- for _ in range(n_orgs_per_user):
+ for o in range(num_orgs_per_user):
user_org = OrganizationFactory(
- name=f"{user_location} {user_topic} Organization {i}",
+ name=f"{user_topic.name} Organization (U{u}:O{o})",
created_by=user,
)
- OrganizationTextFactory(
- org_id=user_org,
- iso="en",
- primary=True,
- description="This is an org",
- get_involved="Get involved!",
- donate_prompt="Donate!",
- )
+ OrganizationTextFactory(org_id=user_org, iso="wt", primary=True)
- for g in range(n_groups_per_org):
+ for g in range(num_groups_per_org):
user_org_group = GroupFactory(
org_id=user_org,
- name=f"{user_location} {user_topic} Group {i}-{g}",
+ name=f"{user_topic.name} Group (U{u}:O{o}:G{g})",
created_by=user,
)
GroupTextFactory(
- group_id=user_org_group,
- iso="en",
- primary=True,
- description="This is a group",
- get_involved="Get involved!",
- donate_prompt="Donate!",
+ group_id=user_org_group, iso="en", primary=True
)
- for e in range(n_events_per_org):
+ for e in range(num_events_per_org):
user_org_event = EventFactory(
- name=f"{user_location} {user_topic} Event {i}-{e}",
+ name=f"{user_topic.name} Event (U{u}:O{o}:E{e})",
+ type=random.choice(["learn", "action"]),
created_by=user,
)
EventTextFactory(
- event_id=user_org_event,
- iso="en",
- primary=True,
- description="This is a group",
- get_involved="Get involved!",
+ event_id=user_org_event, iso="en", primary=True
)
self.stdout.write(
self.style.ERROR(
- f"Number of users created: {n_users}\n"
- f"Number of organizations created: {n_users * n_orgs_per_user}\n"
- f"Number of groups created: {n_users * n_orgs_per_user * n_groups_per_org}\n"
- f"Number of events created: {n_users * n_orgs_per_user * n_events_per_org}\n"
+ f"Number of users created: {num_users}\n"
+ f"Number of organizations created: {num_users * num_orgs_per_user}\n"
+ f"Number of groups created: {num_users * num_orgs_per_user * num_groups_per_org}\n"
+ f"Number of events created: {num_users * num_orgs_per_user * num_events_per_org}\n"
)
)
- except Exception as error:
+ except TypeError as error:
self.stdout.write(
self.style.ERROR(
- f"An error occurred during the creation of dummy data: {error}"
+ f"A type error occurred during the creation of dummy data: {error}. Make sure to use dashes for populate_db arguments and that they're of the appropriate types."
)
)
diff --git a/backend/backend/settings.py b/backend/backend/settings.py
index c2f8f7237..94c45627a 100644
--- a/backend/backend/settings.py
+++ b/backend/backend/settings.py
@@ -174,7 +174,7 @@
"rest_framework.throttling.AnonRateThrottle",
"rest_framework.throttling.UserRateThrottle",
],
- "DEFAULT_THROTTLE_RATES": {"anon": "7/min", "user": "10/min"},
+ "DEFAULT_THROTTLE_RATES": {"anon": "40/min", "user": "60/min"},
"DEFAULT_SCHEMA_CLASS": "drf_spectacular.openapi.AutoSchema",
"DEFAULT_PAGINATION_CLASS": "rest_framework.pagination.PageNumberPagination",
"DEFAULT_PAGINATION_ORDERS_OBJECTS": False,
diff --git a/backend/content/serializers.py b/backend/content/serializers.py
index e8fe3e32d..77ba9550e 100644
--- a/backend/content/serializers.py
+++ b/backend/content/serializers.py
@@ -117,13 +117,13 @@ class Meta:
fields = "__all__"
def validate(self, data: Dict[str, Union[str, int]]) -> Dict[str, Union[str, int]]:
- if data["active"] is True and data["deprecation_date"] is not None:
+ if data["active"] is True and data.get("deprecation_date") is not None:
raise serializers.ValidationError(
_("Active topics cannot have a deprecation date."),
code="active_topic_with_deprecation_error",
)
- if data["active"] is False and data["deprecation_date"] is None:
+ if data["active"] is False and data.get("deprecation_date") is None:
raise serializers.ValidationError(
_("Deprecated topics must have a deprecation date."),
code="inactive_topic_no_deprecation_error",
diff --git a/backend/entities/factories.py b/backend/entities/factories.py
index b3892ba77..418645f72 100644
--- a/backend/entities/factories.py
+++ b/backend/entities/factories.py
@@ -103,9 +103,9 @@ class Meta:
group_id = factory.SubFactory(GroupFactory)
iso = factory.Faker("word")
primary = factory.Faker("boolean")
- description = factory.Faker("text")
- get_involved = factory.Faker("text")
- donate_prompt = factory.Faker("text")
+ description = factory.Faker(provider="text", locale="la", max_nb_chars=1000)
+ get_involved = factory.Faker(provider="text", locale="la")
+ donate_prompt = factory.Faker(provider="text", locale="la")
class GroupTopicFactory(factory.django.DjangoModelFactory):
@@ -190,9 +190,9 @@ class Meta:
org_id = factory.SubFactory(OrganizationFactory)
iso = "en"
primary = factory.Faker("boolean")
- description = factory.Faker("text")
- get_involved = factory.Faker("text")
- donate_prompt = factory.Faker("text")
+ description = factory.Faker(provider="text", locale="la", max_nb_chars=1000)
+ get_involved = factory.Faker(provider="text", locale="la")
+ donate_prompt = factory.Faker(provider="text", locale="la")
class OrganizationTopicFactory(factory.django.DjangoModelFactory):
diff --git a/backend/entities/models.py b/backend/entities/models.py
index 4dcd1d000..a3e4de22f 100644
--- a/backend/entities/models.py
+++ b/backend/entities/models.py
@@ -8,6 +8,7 @@
from django.db import models
from authentication import enums
+from utils.models import ISO_CHOICES
# MARK: Main Tables
@@ -129,7 +130,7 @@ def __str__(self) -> str:
class GroupText(models.Model):
group_id = models.ForeignKey(Group, on_delete=models.CASCADE)
- iso = models.CharField(max_length=2)
+ iso = models.CharField(max_length=2, choices=ISO_CHOICES)
primary = models.BooleanField(default=False)
description = models.TextField(max_length=500)
get_involved = models.TextField(max_length=500, blank=True)
@@ -216,7 +217,7 @@ def __str__(self) -> str:
class OrganizationText(models.Model):
org_id = models.ForeignKey(Organization, on_delete=models.CASCADE)
- iso = models.CharField(max_length=2)
+ iso = models.CharField(max_length=2, choices=ISO_CHOICES)
primary = models.BooleanField(default=False)
description = models.TextField(max_length=2500)
get_involved = models.TextField(max_length=500, blank=True)
diff --git a/backend/entities/serializers.py b/backend/entities/serializers.py
index afceeb74b..7f2ba3097 100644
--- a/backend/entities/serializers.py
+++ b/backend/entities/serializers.py
@@ -79,17 +79,19 @@ def validate(self, data: dict[str, Any]) -> dict[str, Any]:
raise serializers.ValidationError(
"You must accept the terms of service to create an organization."
)
- return data
+ return data
def create(self, validated_data: dict[str, Any]) -> Organization:
description = validated_data.pop("description", None)
org = Organization.objects.create(**validated_data)
+
if org and description:
org_text = OrganizationText.objects.create(
org_id=org, description=description
)
org.org_text = org_text
+
return org
diff --git a/backend/entities/views.py b/backend/entities/views.py
index 972b0d5f0..a4b7f1852 100644
--- a/backend/entities/views.py
+++ b/backend/entities/views.py
@@ -2,7 +2,7 @@
from django.utils import timezone
from rest_framework import status, viewsets
from rest_framework.authentication import TokenAuthentication
-from rest_framework.permissions import IsAuthenticated
+from rest_framework.permissions import IsAuthenticatedOrReadOnly
from rest_framework.request import Request
from rest_framework.response import Response
from rest_framework.throttling import AnonRateThrottle, UserRateThrottle
@@ -60,20 +60,24 @@ class GroupViewSet(viewsets.ModelViewSet[Group]):
def list(self, request: Request, *args: str, **kwargs: int) -> Response:
serializer = self.get_serializer(self.queryset, many=True)
+
return Response(serializer.data, status=status.HTTP_200_OK)
def create(self, request: Request) -> Response:
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
serializer.save(created_by=request.user)
- data = {"message": f"New Group created: {serializer.data}"}
+ data = {"message": f"New group created: {serializer.data}"}
+
return Response(data, status=status.HTTP_201_CREATED)
def retrieve(self, request: Request, *args: str, **kwargs: int) -> Response:
- group = self.queryset.get(id=kwargs["pk"])
- serializer = self.get_serializer(group)
+ if group := self.queryset.get(id=kwargs["pk"]):
+ serializer = self.get_serializer(group)
- return Response(serializer.data, status=status.HTTP_200_OK)
+ return Response(serializer.data, status=status.HTTP_200_OK)
+
+ return Response({"error": "Group not found"}, status.HTTP_404_NOT_FOUND)
def partial_update(self, request: Request, *args: str, **kwargs: int) -> Response:
group = self.queryset.filter(id=kwargs["pk"]).first()
@@ -82,6 +86,7 @@ def partial_update(self, request: Request, *args: str, **kwargs: int) -> Respons
return Response(
{"error": "Group not found"}, status=status.HTTP_404_NOT_FOUND
)
+
if request.user != group.created_by:
return Response(
{"error": "You are not authorized to update this group"},
@@ -91,6 +96,7 @@ def partial_update(self, request: Request, *args: str, **kwargs: int) -> Respons
serializer = self.get_serializer(group, data=request.data, partial=True)
serializer.is_valid(raise_exception=True)
serializer.save()
+
return Response(serializer.data, status=status.HTTP_200_OK)
def destroy(self, request: Request, *args: str, **kwargs: int) -> Response:
@@ -100,12 +106,15 @@ def destroy(self, request: Request, *args: str, **kwargs: int) -> Response:
return Response(
{"error": "Group not found"}, status=status.HTTP_404_NOT_FOUND
)
+
if request.user != group.created_by:
return Response(
{"error": "You are not authorized to delete this group"},
status.HTTP_401_UNAUTHORIZED,
)
+
group.delete()
+
return Response(
{"message": "Group deleted successfully"}, status=status.HTTP_200_OK
)
@@ -116,31 +125,31 @@ class OrganizationViewSet(viewsets.ModelViewSet[Organization]):
serializer_class = OrganizationSerializer
pagination_class = CustomPagination
throttle_classes = [AnonRateThrottle, UserRateThrottle]
- permission_classes = [
- IsAuthenticated,
- ]
- authentication_classes = [
- TokenAuthentication,
- ]
+ permission_classes = [IsAuthenticatedOrReadOnly]
+ authentication_classes = [TokenAuthentication]
+
+ def list(self, request: Request) -> Response:
+ serializer = self.get_serializer(self.get_queryset(), many=True)
+
+ return Response(serializer.data, status=status.HTTP_200_OK)
def create(self, request: Request) -> Response:
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
org = serializer.save(created_by=request.user)
OrganizationApplication.objects.create(org_id=org)
- return Response(serializer.data, status=status.HTTP_201_CREATED)
+ data = {"message": f"New organization created: {serializer.data}"}
+
+ return Response(data, status=status.HTTP_201_CREATED)
def retrieve(self, request: Request, pk: str | None = None) -> Response:
if org := self.queryset.filter(id=pk).first():
serializer = self.get_serializer(org)
+
return Response(serializer.data, status=status.HTTP_200_OK)
return Response({"error": "Organization not found"}, status.HTTP_404_NOT_FOUND)
- def list(self, request: Request) -> Response:
- serializer = self.get_serializer(self.get_queryset(), many=True)
- return Response(serializer.data, status=status.HTTP_200_OK)
-
def update(self, request: Request, pk: str | None = None) -> Response:
org = self.queryset.filter(id=pk).first()
if org is None:
@@ -157,6 +166,7 @@ def update(self, request: Request, pk: str | None = None) -> Response:
serializer = self.get_serializer(org, data=request.data, partial=True)
serializer.is_valid(raise_exception=True)
serializer.save()
+
return Response(serializer.data, status.HTTP_200_OK)
def partial_update(self, request: Request, pk: str | None = None) -> Response:
@@ -175,6 +185,7 @@ def partial_update(self, request: Request, pk: str | None = None) -> Response:
serializer = self.get_serializer(org, data=request.data, partial=True)
serializer.is_valid(raise_exception=True)
serializer.save()
+
return Response(serializer.data, status.HTTP_200_OK)
def destroy(self, request: Request, pk: str | None = None) -> Response:
diff --git a/backend/events/factories.py b/backend/events/factories.py
index c2aafa09d..f89b20e9f 100644
--- a/backend/events/factories.py
+++ b/backend/events/factories.py
@@ -23,11 +23,13 @@
class EventFactory(factory.django.DjangoModelFactory):
class Meta:
model = Event
+ django_get_or_create = ("created_by",)
name = factory.Faker("word")
tagline = factory.Faker("word")
- type = factory.Faker("word")
+ type = random.choice(["learn", "action"])
online_location_link = factory.Faker("url")
+ offline_location = factory.Faker("city")
offline_location_lat = factory.Faker("latitude")
offline_location_long = factory.Faker("longitude")
start_time = factory.LazyFunction(
@@ -142,8 +144,8 @@ class Meta:
event_id = factory.SubFactory(EventFactory)
iso = factory.Faker("word")
primary = factory.Faker("boolean")
- description = factory.Faker("text")
- get_involved = factory.Faker("text")
+ description = factory.Faker(provider="text", locale="la", max_nb_chars=1000)
+ get_involved = factory.Faker(provider="text", locale="la")
class EventTopicFactory(factory.django.DjangoModelFactory):
diff --git a/backend/events/models.py b/backend/events/models.py
index 936d8685b..5a9ea051b 100644
--- a/backend/events/models.py
+++ b/backend/events/models.py
@@ -8,6 +8,7 @@
from django.db import models
from backend.mixins.models import CreationDeletionMixin
+from utils.models import ISO_CHOICES
# MARK: Main Tables
@@ -26,6 +27,7 @@ class Event(CreationDeletionMixin):
)
type = models.CharField(max_length=255)
online_location_link = models.CharField(max_length=255, blank=True)
+ offline_location = models.CharField(max_length=255, blank=True)
offline_location_lat = models.FloatField(null=True, blank=True)
offline_location_long = models.FloatField(null=True, blank=True)
get_involved_url = models.URLField(blank=True)
@@ -35,6 +37,9 @@ class Event(CreationDeletionMixin):
is_private = models.BooleanField(default=False)
start_time = models.DateTimeField()
end_time = models.DateTimeField()
+ event_text = models.ForeignKey(
+ "EventText", on_delete=models.CASCADE, null=True, blank=True
+ )
def __str__(self) -> str:
return self.name
@@ -130,7 +135,7 @@ def __str__(self) -> str:
class EventText(models.Model):
event_id = models.ForeignKey(Event, on_delete=models.CASCADE)
- iso = models.CharField(max_length=2)
+ iso = models.CharField(max_length=2, choices=ISO_CHOICES)
primary = models.BooleanField()
description = models.TextField(max_length=500)
get_involved = models.TextField(max_length=500, blank=True)
diff --git a/backend/events/serializers.py b/backend/events/serializers.py
index 144c1f59a..5ecbd1024 100644
--- a/backend/events/serializers.py
+++ b/backend/events/serializers.py
@@ -2,7 +2,7 @@
Serializers for the events app.
"""
-from typing import Dict, Union
+from typing import Any, Dict, Union
from django.utils.dateparse import parse_datetime
from django.utils.translation import gettext as _
@@ -31,10 +31,43 @@
# MARK: Main Tables
+class EventTextSerializer(serializers.ModelSerializer[EventText]):
+ class Meta:
+ model = EventText
+ fields = "__all__"
+
+
class EventSerializer(serializers.ModelSerializer[Event]):
+ event_text = EventTextSerializer(read_only=True)
+ description = serializers.CharField(write_only=True, required=False)
+
class Meta:
model = Event
- fields = "__all__"
+
+ extra_kwargs = {
+ "created_by": {"read_only": True},
+ "social_links": {"required": False},
+ "description": {"write_only": True},
+ }
+
+ fields = [
+ "id",
+ "name",
+ "tagline",
+ "icon_url",
+ "type",
+ "online_location_link",
+ "offline_location",
+ "offline_location_lat",
+ "offline_location_long",
+ "created_by",
+ "social_links",
+ "is_private",
+ "start_time",
+ "end_time",
+ "event_text",
+ "description",
+ ]
def validate(self, data: Dict[str, Union[str, int]]) -> Dict[str, Union[str, int]]:
if parse_datetime(data["start_time"]) > parse_datetime(data["end_time"]): # type: ignore
@@ -47,6 +80,18 @@ def validate(self, data: Dict[str, Union[str, int]]) -> Dict[str, Union[str, int
return data
+ def create(self, validated_data: dict[str, Any]) -> Event:
+ description = validated_data.pop("description", None)
+ event = Event.objects.create(**validated_data)
+
+ if event and description:
+ event_text = EventText.objects.create(
+ event_id=event, description=description
+ )
+ event.event_text = event_text
+
+ return event
+
class FormatSerializer(serializers.ModelSerializer[Event]):
class Meta:
@@ -115,12 +160,6 @@ class Meta:
fields = "__all__"
-class EventTextSerializer(serializers.ModelSerializer[EventText]):
- class Meta:
- model = EventText
- fields = "__all__"
-
-
class EventTopicSerializer(serializers.ModelSerializer[EventTopic]):
class Meta:
model = EventTopic
diff --git a/backend/events/views.py b/backend/events/views.py
index d1de501d4..1713a1c2b 100644
--- a/backend/events/views.py
+++ b/backend/events/views.py
@@ -1,4 +1,8 @@
-from rest_framework import viewsets
+from rest_framework import status, viewsets
+from rest_framework.authentication import TokenAuthentication
+from rest_framework.permissions import IsAuthenticatedOrReadOnly
+from rest_framework.request import Request
+from rest_framework.response import Response
from rest_framework.throttling import (
AnonRateThrottle,
UserRateThrottle,
@@ -41,6 +45,78 @@ class EventViewSet(viewsets.ModelViewSet[Event]):
serializer_class = EventSerializer
pagination_class = CustomPagination
throttle_classes = [AnonRateThrottle, UserRateThrottle]
+ permission_classes = [IsAuthenticatedOrReadOnly]
+ authentication_classes = [TokenAuthentication]
+
+ def list(self, request: Request, *args: str, **kwargs: int) -> Response:
+ serializer = self.get_serializer(self.get_queryset(), many=True)
+
+ return Response(serializer.data, status=status.HTTP_200_OK)
+
+ def create(self, request: Request, *args: str, **kwargs: int) -> Response:
+ serializer = self.get_serializer(data=request.data)
+ serializer.is_valid(raise_exception=True)
+ serializer.save(created_by=request.user)
+ data = {"message": f"New event created: {serializer.data}"}
+
+ return Response(data, status=status.HTTP_201_CREATED)
+
+ def retrieve(self, request: Request, *args: str, **kwargs: int) -> Response:
+ if event := self.queryset.get(id=kwargs["pk"]):
+ serializer = self.get_serializer(event)
+
+ return Response(serializer.data, status=status.HTTP_200_OK)
+
+ return Response({"error": "Event not found"}, status.HTTP_404_NOT_FOUND)
+
+ def update(self, request: Request, *args: str, **kwargs: int) -> Response:
+ event = self.queryset.filter(id=kwargs["pk"]).first()
+ if event is None:
+ return Response({"error": "Event not found"}, status.HTTP_404_NOT_FOUND)
+
+ if request.user != event.created_by:
+ return Response(
+ {"error": "You are not authorized to update this event"},
+ status.HTTP_401_UNAUTHORIZED,
+ )
+
+ serializer = self.get_serializer(event, data=request.data, partial=True)
+ serializer.is_valid(raise_exception=True)
+ serializer.save()
+
+ return Response(serializer.data, status.HTTP_200_OK)
+
+ def partial_update(self, request: Request, *args: str, **kwargs: int) -> Response:
+ event = self.queryset.filter(id=kwargs["pk"]).first()
+ if event is None:
+ return Response({"error": "Event not found"}, status.HTTP_404_NOT_FOUND)
+
+ if request.user != event.created_by:
+ return Response(
+ {"error": "You are not authorized to update this event"},
+ status.HTTP_401_UNAUTHORIZED,
+ )
+
+ serializer = self.get_serializer(event, data=request.data, partial=True)
+ serializer.is_valid(raise_exception=True)
+ serializer.save()
+
+ return Response(serializer.data, status.HTTP_200_OK)
+
+ def destroy(self, request: Request, *args: str, **kwargs: int) -> Response:
+ event = self.queryset.filter(id=kwargs["pk"]).first()
+ if event is None:
+ return Response({"error": "Event not found"}, status.HTTP_404_NOT_FOUND)
+
+ if request.user != event.created_by:
+ return Response(
+ {"error": "You are not authorized to delete this event"},
+ status.HTTP_401_UNAUTHORIZED,
+ )
+
+ event.delete()
+
+ return Response({"message": "Event deleted successfully"}, status.HTTP_200_OK)
class FormatViewSet(viewsets.ModelViewSet[Format]):
diff --git a/backend/fixtures/superuser.json b/backend/fixtures/superuser.json
index 1b22a93a1..1b741b6fd 100644
--- a/backend/fixtures/superuser.json
+++ b/backend/fixtures/superuser.json
@@ -20,7 +20,7 @@
"email": "admin@activist.org",
"is_high_risk": false,
"is_active": true,
- "is_admin": false,
+ "is_admin": true,
"is_confirmed": true,
"groups": [],
"user_permissions": []
diff --git a/backend/fixtures/topics.json b/backend/fixtures/topics.json
new file mode 100644
index 000000000..00995272c
--- /dev/null
+++ b/backend/fixtures/topics.json
@@ -0,0 +1,98 @@
+[
+{
+ "model": "content.topic",
+ "pk": "24b970c6-5231-403b-9e9d-7de8375193ef",
+ "fields": {
+ "name": "Democracy",
+ "active": true,
+ "description": "Democracy",
+ "creation_date": "2024-09-21T20:21:47.121Z",
+ "last_updated": "2024-09-21T20:21:47.121Z",
+ "deprecation_date": null
+ }
+},
+{
+ "model": "content.topic",
+ "pk": "2c649964-f64c-4693-be31-0a9fdf981974",
+ "fields": {
+ "name": "Women's Rights",
+ "active": true,
+ "description": "Women's Rights",
+ "creation_date": "2024-09-21T20:24:41.462Z",
+ "last_updated": "2024-09-21T20:24:41.462Z",
+ "deprecation_date": null
+ }
+},
+{
+ "model": "content.topic",
+ "pk": "2d49b6e2-8916-4543-83f3-9782e8a9680a",
+ "fields": {
+ "name": "Animal Rights",
+ "active": true,
+ "description": "Animal Rights",
+ "creation_date": "2024-09-21T20:22:07.547Z",
+ "last_updated": "2024-09-21T20:22:07.547Z",
+ "deprecation_date": null
+ }
+},
+{
+ "model": "content.topic",
+ "pk": "b3c6c355-a084-4766-9963-3e54e1af3004",
+ "fields": {
+ "name": "Racial Justice",
+ "active": true,
+ "description": "Racial Justice",
+ "creation_date": "2024-09-21T20:24:28.226Z",
+ "last_updated": "2024-09-21T20:24:28.226Z",
+ "deprecation_date": null
+ }
+},
+{
+ "model": "content.topic",
+ "pk": "b8d8c9c2-e75b-4d49-aca7-c22cfb1f8b77",
+ "fields": {
+ "name": "Housing",
+ "active": true,
+ "description": "Housing",
+ "creation_date": "2024-09-21T20:22:46.519Z",
+ "last_updated": "2024-09-21T20:22:46.519Z",
+ "deprecation_date": null
+ }
+},
+{
+ "model": "content.topic",
+ "pk": "d13860c9-4467-4810-a2d5-7826f3769913",
+ "fields": {
+ "name": "Education",
+ "active": true,
+ "description": "Education",
+ "creation_date": "2024-09-21T20:22:23.446Z",
+ "last_updated": "2024-09-21T20:22:23.446Z",
+ "deprecation_date": null
+ }
+},
+{
+ "model": "content.topic",
+ "pk": "e3715e45-153d-4cce-b957-d68f5a6d4256",
+ "fields": {
+ "name": "Climate",
+ "active": true,
+ "description": "Climate",
+ "creation_date": "2024-09-21T20:20:33.450Z",
+ "last_updated": "2024-09-21T20:20:33.450Z",
+ "deprecation_date": null
+ }
+},
+{
+ "model": "content.topic",
+ "pk": "ec635e18-a89c-46d3-9a14-8f84be96af9b",
+ "fields": {
+ "name": "LGTBQIA+",
+ "active": true,
+ "description": "LGTBQIA+",
+ "creation_date": "2024-09-21T20:23:58.389Z",
+ "last_updated": "2024-09-21T20:23:58.389Z",
+ "deprecation_date": null
+ }
+}
+]
diff --git a/backend/utils/models.py b/backend/utils/models.py
new file mode 100644
index 000000000..e21207136
--- /dev/null
+++ b/backend/utils/models.py
@@ -0,0 +1,7 @@
+ISO_CHOICES = [
+ ("de", "de"),
+ ("en", "en"),
+ ("es", "es"),
+ ("fr", "fr"),
+ ("pt", "pt"),
+]
diff --git a/backend/utils/utils.py b/backend/utils/utils.py
index a73262c96..f757b2145 100644
--- a/backend/utils/utils.py
+++ b/backend/utils/utils.py
@@ -12,7 +12,7 @@ def validate_creation_and_deletion_dates(data: Any) -> None:
code="invalid_creation_date",
)
- if data["creation_date"] < data["deletion_date"]:
+ if data.get("deletion_date") and data.get("deletion_date") < data["creation_date"]:
raise serializers.ValidationError(
_("The field deletion_date cannot be before creation_date."),
code="invalid_date_order",
@@ -20,31 +20,11 @@ def validate_creation_and_deletion_dates(data: Any) -> None:
def validate_creation_and_deprecation_dates(data: Any) -> None:
- if data["deprecation_date"] < data["creation_date"]:
+ if (
+ data.get("deprecation_date")
+ and data.get("deprecation_date") < data["creation_date"]
+ ):
raise serializers.ValidationError(
_("The field deprecation_date cannot be before creation_date."),
code="invalid_date_order",
)
-
-
-def validate_flags_number(data: Any) -> None:
- if int(data["total_flags"]) < 0:
- raise serializers.ValidationError(
- _("The field total_flags cannot be negative."),
- code="negative_total_flags",
- )
-
-
-def validate_empty(value: Any, field_name: Any) -> None:
- if value == "" or value is None:
- raise serializers.ValidationError(
- _(f"The field {field_name} has to be filled."), code="empty_field"
- )
-
-
-def validate_object_existence(model: Any, object_id: Any) -> None:
- if model.objects.filter(id=object_id).exists():
- raise serializers.ValidationError(
- _(f"There is no {model.__name__} object with id {object_id}."),
- code="inexistent_object",
- )
diff --git a/docker-compose.yml b/docker-compose.yml
index aaef93c25..6e68aeff6 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -11,7 +11,8 @@ services:
python manage.py migrate &&
python manage.py loaddata fixtures/superuser.json &&
python manage.py loaddata fixtures/status_types.json &&
- python manage.py populate_db --users 10 --opu 1 --gpo 1 --epo 1 &&
+ python manage.py loaddata fixtures/topics.json &&
+ python manage.py populate_db --users 10 --orgs-per-user 1 --groups-per-org 1 --events-per-org 1 &&
python manage.py runserver 0.0.0.0:${BACKEND_PORT}"
ports:
- "${BACKEND_PORT}:${BACKEND_PORT}"
diff --git a/frontend/assets/css/tailwind.css b/frontend/assets/css/tailwind.css
index 76aa6984a..20319c392 100644
--- a/frontend/assets/css/tailwind.css
+++ b/frontend/assets/css/tailwind.css
@@ -131,6 +131,10 @@
@apply focus-brand elem-shadow-sm bg-light-layer-0 text-light-text hover:bg-light-highlight active:bg-light-layer-0 dark:border dark:border-dark-text dark:bg-dark-layer-0 dark:text-dark-text dark:hover:bg-dark-highlight dark:active:bg-dark-layer-0;
}
+ .style-btns-next-to-one-another {
+ @apply mx-auto grid max-w-[70%] grid-cols-1 gap-y-4 sm:mx-0 sm:max-w-[90%] sm:grid-cols-2 sm:grid-rows-1 sm:gap-x-4 sm:gap-y-0 md:max-w-[70%] md:gap-x-6 lg:max-w-[60%] xl:max-w-[70%] xl:gap-x-8 2xl:max-w-[80%];
+ }
+
.style-cta {
@apply focus-brand border border-light-text bg-light-cta-orange fill-light-text text-light-text hover:bg-light-cta-orange/80 active:bg-light-cta-orange dark:border-dark-cta-orange dark:bg-dark-cta-orange/10 dark:fill-dark-cta-orange dark:text-dark-cta-orange dark:hover:bg-dark-cta-orange/25 dark:active:bg-dark-cta-orange/10;
}
diff --git a/frontend/components/FriendlyCaptcha.vue b/frontend/components/FriendlyCaptcha.vue
index 1130246b8..1d528d7bb 100644
--- a/frontend/components/FriendlyCaptcha.vue
+++ b/frontend/components/FriendlyCaptcha.vue
@@ -7,7 +7,7 @@
}"
>
{
console.log("Captcha response:", response);
diff --git a/frontend/components/card/about/CardAboutGroup.vue b/frontend/components/card/about/CardAboutGroup.vue
index 5cb356e88..12e1de7ff 100644
--- a/frontend/components/card/about/CardAboutGroup.vue
+++ b/frontend/components/card/about/CardAboutGroup.vue
@@ -91,7 +91,10 @@ const props = defineProps<{
const res = await useAsyncData(
async () =>
- await fetchWithToken(`/entities/group_texts?group_id=${props.group.id}`, {})
+ await fetchWithOptionalToken(
+ `/entities/group_texts?group_id=${props.group.id}`,
+ {}
+ )
);
const groupTexts = res.data as unknown as GroupText[];
diff --git a/frontend/components/card/search-result/CardSearchResult.vue b/frontend/components/card/search-result/CardSearchResult.vue
index 3e7dc83cf..73b757805 100644
--- a/frontend/components/card/search-result/CardSearchResult.vue
+++ b/frontend/components/card/search-result/CardSearchResult.vue
@@ -210,11 +210,11 @@
-
{{ description }}
-
+
diff --git a/frontend/components/header/HeaderWebsite.vue b/frontend/components/header/HeaderWebsite.vue
index 928d680c5..46b0a9381 100644
--- a/frontend/components/header/HeaderWebsite.vue
+++ b/frontend/components/header/HeaderWebsite.vue
@@ -52,7 +52,47 @@
+
+
+
+
{{ $t(text) }}
-
+
+
+
+
+
diff --git a/frontend/components/page/PageCommunityFooter.vue b/frontend/components/page/PageCommunityFooter.vue
index 77bc2dafd..4dc1375ca 100644
--- a/frontend/components/page/PageCommunityFooter.vue
+++ b/frontend/components/page/PageCommunityFooter.vue
@@ -88,9 +88,7 @@
-
+
diff --git a/frontend/composables/fetch.ts b/frontend/composables/fetch.ts
index cb895551a..238be4195 100644
--- a/frontend/composables/fetch.ts
+++ b/frontend/composables/fetch.ts
@@ -1,15 +1,30 @@
-export const fetchWithToken = async (
+/**
+ * Returns data given the authentication status of the user.
+ * @param url Backend URL to make the request to.
+ * @param data Data to be returned.
+ * @returns The resulting data from the table.
+ */
+export const fetchWithOptionalToken = async (
url: string,
data: object | {} | undefined
) => {
const token = localStorage.getItem("accessToken");
- const res = await $fetch.raw(BASE_BACKEND_URL + url, {
- data,
- headers: {
- Authorization: `Token ${token}`,
- },
- });
+ if (token) {
+ const res = await $fetch.raw(BASE_BACKEND_URL + url, {
+ data,
+ headers: {
+ Authorization: `Token ${token}`,
+ },
+ });
- return res._data;
+ return res._data;
+ } else {
+ const res = await $fetch.raw(BASE_BACKEND_URL + url, {
+ data,
+ headers: {},
+ });
+
+ return res._data;
+ }
};
diff --git a/frontend/i18n/en-US.json b/frontend/i18n/en-US.json
index 098141e2e..59bf2a1b5 100644
--- a/frontend/i18n/en-US.json
+++ b/frontend/i18n/en-US.json
@@ -248,6 +248,10 @@
"components.landing_splash.message_1": "A platform for growing our movements and organizing actions.",
"components.landing_splash.message_2": "Free, open-source, privacy-focused and governed by our community.",
"components.landing_splash.request_access_aria_label": "Request access to activist.org",
+ "components.landing_splash.view_events": "View events",
+ "components.landing_splash.view_events_aria_label": "View the events section of the activist platform",
+ "components.landing_splash.view_organizations": "View organizations",
+ "components.landing_splash.view_organizations_aria_label": "View the organizations section of the activist platform",
"components.landing_tech_banner.open_header": "Open",
"components.landing_tech_banner.open_source_tagline": "Our code and processes",
"components.landing_tech_banner.open_source_text": "We're dedicated to working in the open to build trust with our partner organizations and fellow activists. All who want to help us build are welcome!",
diff --git a/frontend/package.json b/frontend/package.json
index c009f682a..922c2ef12 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -37,7 +37,7 @@
"playwright": "1.47.1",
"prettier": "3.2.5",
"prettier-plugin-tailwindcss": "0.5.13",
- "rollup": "4.14.1",
+ "rollup": "4.22.4",
"typescript": "5.4.4",
"vite": "5.2.14",
"vue": "3.4.21",
diff --git a/frontend/pages/events/index.vue b/frontend/pages/events/index.vue
index a70d5c430..810315598 100644
--- a/frontend/pages/events/index.vue
+++ b/frontend/pages/events/index.vue
@@ -13,23 +13,18 @@
-
-
+
diff --git a/frontend/pages/organizations/[id]/groups/[id]/about.vue b/frontend/pages/organizations/[id]/groups/[id]/about.vue
index 81dbfc9c3..a8b5c667c 100644
--- a/frontend/pages/organizations/[id]/groups/[id]/about.vue
+++ b/frontend/pages/organizations/[id]/groups/[id]/about.vue
@@ -97,9 +97,12 @@ const aboveLargeBP = useBreakpoint("lg");
const { id } = useRoute().params;
const [resOrg, resOrgTexts] = await Promise.all([
- useAsyncData(async () => await fetchWithToken(`/entities/groups/${id}`, {})),
useAsyncData(
- async () => await fetchWithToken(`/entities/group_texts?org_id=${id}`, {})
+ async () => await fetchWithOptionalToken(`/entities/groups/${id}`, {})
+ ),
+ useAsyncData(
+ async () =>
+ await fetchWithOptionalToken(`/entities/group_texts?org_id=${id}`, {})
),
]);
diff --git a/frontend/stores/dev.ts b/frontend/stores/dev.ts
new file mode 100644
index 000000000..a7ac6d6d8
--- /dev/null
+++ b/frontend/stores/dev.ts
@@ -0,0 +1,14 @@
+import { useLocalStorage } from "@vueuse/core";
+import { defineStore } from "pinia";
+
+export const useDevMode = defineStore("devMode", {
+ state: () => ({
+ active: useLocalStorage("active", false),
+ }),
+
+ actions: {
+ check() {
+ this.active = window.location.href.includes("localhost:3000");
+ },
+ },
+});
diff --git a/frontend/stores/event.ts b/frontend/stores/event.ts
index 5ca47ef40..0ec3ff0b1 100644
--- a/frontend/stores/event.ts
+++ b/frontend/stores/event.ts
@@ -1,7 +1,10 @@
import type {
Event,
+ EventText,
PiniaResEvent,
+ PiniaResEvents,
PiniaResEventText,
+ PiniaResEventTexts,
} from "~/types/events/event";
interface EventStore {
@@ -23,18 +26,23 @@ export const useEventStore = defineStore("event", {
createdBy: "",
iconURL: "",
type: "learn",
+ onlineLocationLink: "",
offlineLocation: "",
+ offlineLocationLat: "",
+ offlineLocationLong: "",
getInvolvedURL: "",
socialLinks: [""],
startTime: "",
+ endTime: "",
+ creationDate: "",
- // event_organizations
organizations: [],
- // event_text
+ eventTextID: "",
description: "",
getInvolved: "",
},
+
events: [],
}),
actions: {
@@ -49,25 +57,28 @@ export const useEventStore = defineStore("event", {
const [resEvent, resEventTexts] = await Promise.all([
useAsyncData(
- async () => await fetchWithToken(`/entities/events/${id}`, {})
+ async () => await fetchWithOptionalToken(`/events/events/${id}`, {})
),
// useAsyncData(
// async () =>
- // await fetchWithToken(
+ // await fetchWithOptionalToken(
// `/entities/event_faq?event_id=${id}`,
// {}
// )
// ),
// useAsyncData(
// async () =>
- // await fetchWithToken(
+ // await fetchWithOptionalToken(
// `/entities/event_resources?event_id=${id}`,
// {}
// )
// ),
useAsyncData(
async () =>
- await fetchWithToken(`/entities/event_texts?event_id=${id}`, {})
+ await fetchWithOptionalToken(
+ `/events/event_texts?event_id=${id}`,
+ {}
+ )
),
]);
@@ -98,7 +109,69 @@ export const useEventStore = defineStore("event", {
// MARK: Fetch All
- async fetchAll() {},
+ async fetchAll() {
+ this.loading = true;
+
+ const [responseEvents] = await Promise.all([
+ useAsyncData(
+ async () => await fetchWithOptionalToken(`/events/events/`, {})
+ ),
+ ]);
+
+ const events = responseEvents.data as unknown as PiniaResEvents;
+
+ console.log(`Here: ${JSON.stringify(events._value)}`);
+
+ if (events._value) {
+ const responseEventTexts = (await Promise.all(
+ events._value.map((event) =>
+ useAsyncData(
+ async () =>
+ await fetchWithOptionalToken(
+ `/events/event_texts?event_id=${event.id}`,
+ {}
+ )
+ )
+ )
+ )) as unknown as PiniaResEventTexts[];
+
+ const eventTextsData = responseEventTexts.map(
+ (text) => text.data._value.results[0]
+ ) as unknown as EventText[];
+
+ const eventsWithTexts = events._value.map(
+ (event: Event, index: number) => {
+ const texts = eventTextsData[index];
+ return {
+ id: event.id,
+ name: event.name,
+ tagline: event.tagline,
+ createdBy: event.createdBy,
+ iconURL: event.iconURL,
+ type: event.type,
+ onlineLocationLink: event.onlineLocationLink,
+ offlineLocation: event.offlineLocation,
+ offlineLocationLat: event.offlineLocationLat,
+ offlineLocationLong: event.offlineLocationLong,
+ getInvolvedURL: event.getInvolvedURL,
+ socialLinks: event.socialLinks,
+ startTime: event.startTime,
+ endTime: event.endTime,
+ creationDate: event.creationDate,
+ organizations: event.organizations,
+
+ eventTextID: event.eventTextID,
+ description: texts.description,
+ getInvolved: texts.getInvolved,
+ };
+ }
+ );
+
+ this.events = eventsWithTexts;
+ }
+
+ this.loading = false;
+ },
// MARK: Update
@@ -106,6 +179,10 @@ export const useEventStore = defineStore("event", {
// MARK: Delete
- async delete() {},
+ async delete(id: string | undefined) {
+ this.loading = true;
+
+ this.loading = false;
+ },
},
});
diff --git a/frontend/stores/group.ts b/frontend/stores/group.ts
index 081ba8bfb..74e312dbb 100644
--- a/frontend/stores/group.ts
+++ b/frontend/stores/group.ts
@@ -34,29 +34,35 @@ export const useGroupStore = defineStore("group", {
const [resGroup, resGroupOrg, resGroupTexts] = await Promise.all([
useAsyncData(
- async () => await fetchWithToken(`/entities/groups/${id}`, {})
+ async () => await fetchWithOptionalToken(`/entities/groups/${id}`, {})
),
useAsyncData(
async () =>
- await fetchWithToken(`/entities/organizations?group_id=${id}`, {})
+ await fetchWithOptionalToken(
+ `/entities/organizations?group_id=${id}`,
+ {}
+ )
),
// useAsyncData(
// async () =>
- // await fetchWithToken(
+ // await fetchWithOptionalToken(
// `/entities/group_faq?group_id=${id}`,
// {}
// )
// ),
// useAsyncData(
// async () =>
- // await fetchWithToken(
+ // await fetchWithOptionalToken(
// `/entities/group_resources?group_id=${id}`,
// {}
// )
// ),
useAsyncData(
async () =>
- await fetchWithToken(`/entities/group_texts?group_id=${id}`, {})
+ await fetchWithOptionalToken(
+ `/entities/group_texts?group_id=${id}`,
+ {}
+ )
),
]);
diff --git a/frontend/stores/modals.ts b/frontend/stores/modals.ts
index d47fe7f22..d5578ae6d 100644
--- a/frontend/stores/modals.ts
+++ b/frontend/stores/modals.ts
@@ -11,7 +11,7 @@ export const useModals = defineStore("modals", {
actions: {
openModal(modalName: string) {
- const modals = this.modals;
+ const { modals } = this;
for (const key in modals) {
modals[key].isOpen = false;
}
diff --git a/frontend/stores/organization.ts b/frontend/stores/organization.ts
index 1dbdbd9d9..b0e9620ea 100644
--- a/frontend/stores/organization.ts
+++ b/frontend/stores/organization.ts
@@ -33,7 +33,7 @@ export const useOrganizationStore = defineStore("organization", {
status: 1,
groups: [],
- organization_text_id: "",
+ organizationTextID: "",
description: "",
getInvolved: "",
donationPrompt: "",
@@ -89,28 +89,29 @@ export const useOrganizationStore = defineStore("organization", {
const [responseOrg, responseOrgTexts] = await Promise.all([
useAsyncData(
- async () => await fetchWithToken(`/entities/organizations/${id}`, {})
+ async () =>
+ await fetchWithOptionalToken(`/entities/organizations/${id}`, {})
),
// useAsyncData(
// async () =>
- // await fetchWithToken(
+ // await fetchWithOptionalToken(
// `/entities/organization_faq?org_id=${id}`,
// {}
// )
// ),
// useAsyncData(
- // async () => await fetchWithToken(`/entities/groups?org_id=${id}`, {})
+ // async () => await fetchWithOptionalToken(`/entities/groups?org_id=${id}`, {})
// ),
// useAsyncData(
// async () =>
- // await fetchWithToken(
+ // await fetchWithOptionalToken(
// `/entities/organization_resources?org_id=${id}`,
// {}
// )
// ),
useAsyncData(
async () =>
- await fetchWithToken(
+ await fetchWithOptionalToken(
`/entities/organization_texts?org_id=${id}`,
{}
)
@@ -144,7 +145,7 @@ export const useOrganizationStore = defineStore("organization", {
this.organization.description = texts.description;
this.organization.getInvolved = texts.getInvolved;
this.organization.donationPrompt = texts.donationPrompt;
- this.organization.organization_text_id = texts.id;
+ this.organization.organizationTextID = texts.id;
this.loading = false;
},
@@ -156,7 +157,8 @@ export const useOrganizationStore = defineStore("organization", {
const [responseOrgs] = await Promise.all([
useAsyncData(
- async () => await fetchWithToken(`/entities/organizations/`, {})
+ async () =>
+ await fetchWithOptionalToken(`/entities/organizations/`, {})
),
]);
@@ -167,7 +169,7 @@ export const useOrganizationStore = defineStore("organization", {
orgs._value.map((org) =>
useAsyncData(
async () =>
- await fetchWithToken(
+ await fetchWithOptionalToken(
`/entities/organization_texts?org_id=${org.id}`,
{}
)
@@ -179,8 +181,6 @@ export const useOrganizationStore = defineStore("organization", {
(text) => text.data._value.results[0]
) as unknown as OrganizationText[];
- console.log(`Here: ${JSON.stringify(orgTextsData)}`);
-
const organizationsWithTexts = orgs._value.map(
(organization: Organization, index: number) => {
const texts = orgTextsData[index];
@@ -195,7 +195,8 @@ export const useOrganizationStore = defineStore("organization", {
socialLinks: organization.socialLinks,
status: organization.status,
groups: organization.groups,
- organization_text_id: organization.organization_text_id,
+
+ organizationTextID: organization.organizationTextID,
description: texts.description,
getInvolved: texts.getInvolved,
donationPrompt: texts.donationPrompt,
@@ -235,7 +236,7 @@ export const useOrganizationStore = defineStore("organization", {
const responseOrgTexts = await $fetch(
BASE_BACKEND_URL +
- `/entities/organization_texts/${org.organization_text_id}/`,
+ `/entities/organization_texts/${org.organizationTextID}/`,
{
method: "PUT",
body: {
diff --git a/frontend/types/entities/organization.d.ts b/frontend/types/entities/organization.d.ts
index 83f0d2d1d..42380eeb5 100644
--- a/frontend/types/entities/organization.d.ts
+++ b/frontend/types/entities/organization.d.ts
@@ -36,7 +36,7 @@ export interface Organization {
// organization_task
// task?: Task[];
- organization_text_id: string;
+ organizationTextID: string;
description: string;
getInvolved: string;
donationPrompt: string;
diff --git a/frontend/types/events/event.d.ts b/frontend/types/events/event.d.ts
index 5cec4c85a..2bb67e826 100644
--- a/frontend/types/events/event.d.ts
+++ b/frontend/types/events/event.d.ts
@@ -30,7 +30,7 @@ export interface Event {
// event_task
// task?: Task[];
- // event_text
+ eventTextID: string;
description: string;
getInvolved: string;
@@ -100,6 +100,13 @@ export interface PiniaResEvent {
_value: Event;
}
+export interface PiniaResEvents {
+ __v_isShallow: boolean;
+ __v_isRef: boolean;
+ _rawValue: Event[];
+ _value: Event[];
+}
+
export interface PiniaResEventText {
__v_isShallow: boolean;
__v_isRef: boolean;
@@ -116,3 +123,39 @@ export interface PiniaResEventText {
results: EventText[];
};
}
+
+export interface PiniaResEventTexts {
+ data: {
+ __v_isShallow: boolean;
+ __v_isRef: boolean;
+ _rawValue: {
+ count: number;
+ next: null;
+ previous: null;
+ results: EventText[];
+ };
+ _value: {
+ count: number;
+ next: null;
+ previous: null;
+ results: EventText[];
+ };
+ };
+ pending: {
+ __v_isShallow: boolean;
+ __v_isRef: boolean;
+ _rawValue: boolean;
+ _value: boolean;
+ };
+ error: {
+ _object: { [$key: string]: null };
+ _key: string;
+ __v_isRef: boolean;
+ };
+ status: {
+ __v_isShallow: boolean;
+ __v_isRef: boolean;
+ _rawValue: string;
+ _value: string;
+ };
+}
diff --git a/frontend/utils/testEntities.ts b/frontend/utils/testEntities.ts
index 3d805dfac..4b5bcd49a 100644
--- a/frontend/utils/testEntities.ts
+++ b/frontend/utils/testEntities.ts
@@ -48,7 +48,7 @@ export const testClimateOrg: Organization = {
groups: ["Fundraising", "Campaigning"],
socialLinks: ["climate-org@mastodon", "climate-org@email"],
iconURL: "URL/for/image",
- organization_text_id: "06cb36a3-13c5-4518-b676-33ec734744ed",
+ organizationTextID: "06cb36a3-13c5-4518-b676-33ec734744ed",
description: "Testing how organizations work",
getInvolved: "Hey, get involved!",
donationPrompt: "Hey thanks!",
@@ -119,7 +119,7 @@ export const testTechOrg: Organization = {
groups: [testTechGroup1, testTechGroup2],
socialLinks: ["tfb@mastodon", "tfb@email"],
// donationPrompt: "Hey thanks!",
- organization_text_id: "06cb36a3-13c5-4518-b676-33ec734744ed",
+ organizationTextID: "06cb36a3-13c5-4518-b676-33ec734744ed",
description: "Testing how organizations work",
getInvolved: "Hey, get involved!",
donationPrompt: "Hey thanks!",
@@ -145,6 +145,7 @@ export const testClimateEvent: Event = {
// supportingUsers: [user, user],
// iconURL: "/images/an_image.svg",
socialLinks: ["climate_org@mastodon", "climate_org@email.com"],
+ eventTextID: "",
};
export const testTechEvent: Event = {
@@ -162,6 +163,7 @@ export const testTechEvent: Event = {
startTime: new Date().toLocaleDateString(),
// supportingUsers: [user, user, user],
socialLinks: [""],
+ eventTextID: "",
};
export const testResource: Resource = {
diff --git a/frontend/yarn.lock b/frontend/yarn.lock
index c1e21e00d..72467adfb 100644
--- a/frontend/yarn.lock
+++ b/frontend/yarn.lock
@@ -1922,160 +1922,85 @@
estree-walker "^2.0.2"
picomatch "^2.3.1"
-"@rollup/rollup-android-arm-eabi@4.14.1":
- version "4.14.1"
- resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.14.1.tgz#ca0501dd836894216cb9572848c5dde4bfca3bec"
- integrity sha512-fH8/o8nSUek8ceQnT7K4EQbSiV7jgkHq81m9lWZFIXjJ7lJzpWXbQFpT/Zh6OZYnpFykvzC3fbEvEAFZu03dPA==
-
-"@rollup/rollup-android-arm-eabi@4.22.2":
- version "4.22.2"
- resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.22.2.tgz#4e0c4c462692ecb7ae2b008f25af4cced05ac4f9"
- integrity sha512-8Ao+EDmTPjZ1ZBABc1ohN7Ylx7UIYcjReZinigedTOnGFhIctyGPxY2II+hJ6gD2/vkDKZTyQ0e7++kwv6wDrw==
-
-"@rollup/rollup-android-arm64@4.14.1":
- version "4.14.1"
- resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.14.1.tgz#154ca7e4f815d2e442ffc62ee7f64aee8b2547b0"
- integrity sha512-Y/9OHLjzkunF+KGEoJr3heiD5X9OLa8sbT1lm0NYeKyaM3oMhhQFvPB0bNZYJwlq93j8Z6wSxh9+cyKQaxS7PQ==
-
-"@rollup/rollup-android-arm64@4.22.2":
- version "4.22.2"
- resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.22.2.tgz#d97ed02a950061adc2056d6d2d6df8f05d877ae9"
- integrity sha512-I+B1v0a4iqdS9DvYt1RJZ3W+Oh9EVWjbY6gp79aAYipIbxSLEoQtFQlZEnUuwhDXCqMxJ3hluxKAdPD+GiluFQ==
-
-"@rollup/rollup-darwin-arm64@4.14.1":
- version "4.14.1"
- resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.14.1.tgz#02b522ab6ccc2c504634651985ff8e657b42c055"
- integrity sha512-+kecg3FY84WadgcuSVm6llrABOdQAEbNdnpi5X3UwWiFVhZIZvKgGrF7kmLguvxHNQy+UuRV66cLVl3S+Rkt+Q==
-
-"@rollup/rollup-darwin-arm64@4.22.2":
- version "4.22.2"
- resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.22.2.tgz#06dec35316de9fe433d66c849ecc056e221ba422"
- integrity sha512-BTHO7rR+LC67OP7I8N8GvdvnQqzFujJYWo7qCQ8fGdQcb8Gn6EQY+K1P+daQLnDCuWKbZ+gHAQZuKiQkXkqIYg==
-
-"@rollup/rollup-darwin-x64@4.14.1":
- version "4.14.1"
- resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.14.1.tgz#217737f9f73de729fdfd7d529afebb6c8283f554"
- integrity sha512-2pYRzEjVqq2TB/UNv47BV/8vQiXkFGVmPFwJb+1E0IFFZbIX8/jo1olxqqMbo6xCXf8kabANhp5bzCij2tFLUA==
-
-"@rollup/rollup-darwin-x64@4.22.2":
- version "4.22.2"
- resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.22.2.tgz#22ee27a0ccfdc045c2a37f6980351329516ce119"
- integrity sha512-1esGwDNFe2lov4I6GsEeYaAMHwkqk0IbuGH7gXGdBmd/EP9QddJJvTtTF/jv+7R8ZTYPqwcdLpMTxK8ytP6k6Q==
-
-"@rollup/rollup-linux-arm-gnueabihf@4.14.1":
- version "4.14.1"
- resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.14.1.tgz#a87e478ab3f697c7f4e74c8b1cac1e0667f8f4be"
- integrity sha512-mS6wQ6Do6/wmrF9aTFVpIJ3/IDXhg1EZcQFYHZLHqw6AzMBjTHWnCG35HxSqUNphh0EHqSM6wRTT8HsL1C0x5g==
-
-"@rollup/rollup-linux-arm-gnueabihf@4.22.2":
- version "4.22.2"
- resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.22.2.tgz#d86df2d8c600ebdd7251110a3357c53e0a583ace"
- integrity sha512-GBHuY07x96OTEM3OQLNaUSUwrOhdMea/LDmlFHi/HMonrgF6jcFrrFFwJhhe84XtA1oK/Qh4yFS+VMREf6dobg==
-
-"@rollup/rollup-linux-arm-musleabihf@4.22.2":
- version "4.22.2"
- resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.22.2.tgz#a8b7b6a805356c8bd0409e4c5f56664d80a50aaa"
- integrity sha512-Dbfa9Sc1G1lWxop0gNguXOfGhaXQWAGhZUcqA0Vs6CnJq8JW/YOw/KvyGtQFmz4yDr0H4v9X248SM7bizYj4yQ==
-
-"@rollup/rollup-linux-arm64-gnu@4.14.1":
- version "4.14.1"
- resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.14.1.tgz#4da6830eca27e5f4ca15f9197e5660952ca185c6"
- integrity sha512-p9rGKYkHdFMzhckOTFubfxgyIO1vw//7IIjBBRVzyZebWlzRLeNhqxuSaZ7kCEKVkm/kuC9fVRW9HkC/zNRG2w==
-
-"@rollup/rollup-linux-arm64-gnu@4.22.2":
- version "4.22.2"
- resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.22.2.tgz#766064021d2bfc42f13f4653f8870a9b8bbdc31d"
- integrity sha512-Z1YpgBvFYhZIyBW5BoopwSg+t7yqEhs5HCei4JbsaXnhz/eZehT18DaXl957aaE9QK7TRGFryCAtStZywcQe1A==
-
-"@rollup/rollup-linux-arm64-musl@4.14.1":
- version "4.14.1"
- resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.14.1.tgz#0b0ed35720aebc8f5e501d370a9ea0f686ead1e0"
- integrity sha512-nDY6Yz5xS/Y4M2i9JLQd3Rofh5OR8Bn8qe3Mv/qCVpHFlwtZSBYSPaU4mrGazWkXrdQ98GB//H0BirGR/SKFSw==
-
-"@rollup/rollup-linux-arm64-musl@4.22.2":
- version "4.22.2"
- resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.22.2.tgz#490f49236102b97738d9406eaf5cd8d9dad35c15"
- integrity sha512-66Zszr7i/JaQ0u/lefcfaAw16wh3oT72vSqubIMQqWzOg85bGCPhoeykG/cC5uvMzH80DQa2L539IqKht6twVA==
-
-"@rollup/rollup-linux-powerpc64le-gnu@4.14.1":
- version "4.14.1"
- resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.14.1.tgz#024ad04d162726f25e62915851f7df69a9677c17"
- integrity sha512-im7HE4VBL+aDswvcmfx88Mp1soqL9OBsdDBU8NqDEYtkri0qV0THhQsvZtZeNNlLeCUQ16PZyv7cqutjDF35qw==
-
-"@rollup/rollup-linux-powerpc64le-gnu@4.22.2":
- version "4.22.2"
- resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.22.2.tgz#03a67f1476dd80f115ce35bc9b0d03c50c16679d"
- integrity sha512-HpJCMnlMTfEhwo19bajvdraQMcAq3FX08QDx3OfQgb+414xZhKNf3jNvLFYKbbDSGBBrQh5yNwWZrdK0g0pokg==
-
-"@rollup/rollup-linux-riscv64-gnu@4.14.1":
- version "4.14.1"
- resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.14.1.tgz#180694d1cd069ddbe22022bb5b1bead3b7de581c"
- integrity sha512-RWdiHuAxWmzPJgaHJdpvUUlDz8sdQz4P2uv367T2JocdDa98iRw2UjIJ4QxSyt077mXZT2X6pKfT2iYtVEvOFw==
-
-"@rollup/rollup-linux-riscv64-gnu@4.22.2":
- version "4.22.2"
- resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.22.2.tgz#d86e9b7b5b242652cd691c46d1939130c35cb68d"
- integrity sha512-/egzQzbOSRef2vYCINKITGrlwkzP7uXRnL+xU2j75kDVp3iPdcF0TIlfwTRF8woBZllhk3QaxNOEj2Ogh3t9hg==
-
-"@rollup/rollup-linux-s390x-gnu@4.14.1":
- version "4.14.1"
- resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.14.1.tgz#f7b4e2b0ca49be4e34f9ef0b548c926d94edee87"
- integrity sha512-VMgaGQ5zRX6ZqV/fas65/sUGc9cPmsntq2FiGmayW9KMNfWVG/j0BAqImvU4KTeOOgYSf1F+k6at1UfNONuNjA==
-
-"@rollup/rollup-linux-s390x-gnu@4.22.2":
- version "4.22.2"
- resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.22.2.tgz#c8fca373bec6df8550b31b3dbb56e2b241bc8718"
- integrity sha512-qgYbOEbrPfEkH/OnUJd1/q4s89FvNJQIUldx8X2F/UM5sEbtkqZpf2s0yly2jSCKr1zUUOY1hnTP2J1WOzMAdA==
-
-"@rollup/rollup-linux-x64-gnu@4.14.1":
- version "4.14.1"
- resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.14.1.tgz#0aaf79e5b9ccf7db3084fe6c3f2d2873a27d5af4"
- integrity sha512-9Q7DGjZN+hTdJomaQ3Iub4m6VPu1r94bmK2z3UeWP3dGUecRC54tmVu9vKHTm1bOt3ASoYtEz6JSRLFzrysKlA==
-
-"@rollup/rollup-linux-x64-gnu@4.22.2":
- version "4.22.2"
- resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.22.2.tgz#be182ef761c9b0147496e647ace44fd1b912344f"
- integrity sha512-a0lkvNhFLhf+w7A95XeBqGQaG0KfS3hPFJnz1uraSdUe/XImkp/Psq0Ca0/UdD5IEAGoENVmnYrzSC9Y2a2uKQ==
-
-"@rollup/rollup-linux-x64-musl@4.14.1":
- version "4.14.1"
- resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.14.1.tgz#38f0a37ca5015eb07dff86a1b6f94279c179f4ed"
- integrity sha512-JNEG/Ti55413SsreTguSx0LOVKX902OfXIKVg+TCXO6Gjans/k9O6ww9q3oLGjNDaTLxM+IHFMeXy/0RXL5R/g==
-
-"@rollup/rollup-linux-x64-musl@4.22.2":
- version "4.22.2"
- resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.22.2.tgz#c280202d5b54d04f1e2b810359fe73c4973e8b72"
- integrity sha512-sSWBVZgzwtsuG9Dxi9kjYOUu/wKW+jrbzj4Cclabqnfkot8Z3VEHcIgyenA3lLn/Fu11uDviWjhctulkhEO60g==
-
-"@rollup/rollup-win32-arm64-msvc@4.14.1":
- version "4.14.1"
- resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.14.1.tgz#84d48c55740ede42c77373f76e85f368633a0cc3"
- integrity sha512-ryS22I9y0mumlLNwDFYZRDFLwWh3aKaC72CWjFcFvxK0U6v/mOkM5Up1bTbCRAhv3kEIwW2ajROegCIQViUCeA==
-
-"@rollup/rollup-win32-arm64-msvc@4.22.2":
- version "4.22.2"
- resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.22.2.tgz#8ae561401b92acb8ca7a842ffadececb22a2247e"
- integrity sha512-t/YgCbZ638R/r7IKb9yCM6nAek1RUvyNdfU0SHMDLOf6GFe/VG1wdiUAsxTWHKqjyzkRGg897ZfCpdo1bsCSsA==
-
-"@rollup/rollup-win32-ia32-msvc@4.14.1":
- version "4.14.1"
- resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.14.1.tgz#c1e0bc39e20e760f0a526ddf14ae0543af796605"
- integrity sha512-TdloItiGk+T0mTxKx7Hp279xy30LspMso+GzQvV2maYePMAWdmrzqSNZhUpPj3CGw12aGj57I026PgLCTu8CGg==
-
-"@rollup/rollup-win32-ia32-msvc@4.22.2":
- version "4.22.2"
- resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.22.2.tgz#c3a8b081595026eab9fccfe581624cb31af0d6f8"
- integrity sha512-kTmX5uGs3WYOA+gYDgI6ITkZng9SP71FEMoHNkn+cnmb9Zuyyay8pf0oO5twtTwSjNGy1jlaWooTIr+Dw4tIbw==
-
-"@rollup/rollup-win32-x64-msvc@4.14.1":
- version "4.14.1"
- resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.14.1.tgz#299eee74b7d87e116083ac5b1ce8dd9434668294"
- integrity sha512-wQGI+LY/Py20zdUPq+XCem7JcPOyzIJBm3dli+56DJsQOHbnXZFEwgmnC6el1TPAfC8lBT3m+z69RmLykNUbew==
-
-"@rollup/rollup-win32-x64-msvc@4.22.2":
- version "4.22.2"
- resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.22.2.tgz#c770006ccc780b2de7b2151fc7f37b49121a21c1"
- integrity sha512-Yy8So+SoRz8I3NS4Bjh91BICPOSVgdompTIPYTByUqU66AXSIOgmW3Lv1ke3NORPqxdF+RdrZET+8vYai6f4aA==
+"@rollup/rollup-android-arm-eabi@4.22.4":
+ version "4.22.4"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.22.4.tgz#8b613b9725e8f9479d142970b106b6ae878610d5"
+ integrity sha512-Fxamp4aEZnfPOcGA8KSNEohV8hX7zVHOemC8jVBoBUHu5zpJK/Eu3uJwt6BMgy9fkvzxDaurgj96F/NiLukF2w==
+
+"@rollup/rollup-android-arm64@4.22.4":
+ version "4.22.4"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.22.4.tgz#654ca1049189132ff602bfcf8df14c18da1f15fb"
+ integrity sha512-VXoK5UMrgECLYaMuGuVTOx5kcuap1Jm8g/M83RnCHBKOqvPPmROFJGQaZhGccnsFtfXQ3XYa4/jMCJvZnbJBdA==
+
+"@rollup/rollup-darwin-arm64@4.22.4":
+ version "4.22.4"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.22.4.tgz#6d241d099d1518ef0c2205d96b3fa52e0fe1954b"
+ integrity sha512-xMM9ORBqu81jyMKCDP+SZDhnX2QEVQzTcC6G18KlTQEzWK8r/oNZtKuZaCcHhnsa6fEeOBionoyl5JsAbE/36Q==
+
+"@rollup/rollup-darwin-x64@4.22.4":
+ version "4.22.4"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.22.4.tgz#42bd19d292a57ee11734c980c4650de26b457791"
+ integrity sha512-aJJyYKQwbHuhTUrjWjxEvGnNNBCnmpHDvrb8JFDbeSH3m2XdHcxDd3jthAzvmoI8w/kSjd2y0udT+4okADsZIw==
+
+"@rollup/rollup-linux-arm-gnueabihf@4.22.4":
+ version "4.22.4"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.22.4.tgz#f23555ee3d8fe941c5c5fd458cd22b65eb1c2232"
+ integrity sha512-j63YtCIRAzbO+gC2L9dWXRh5BFetsv0j0va0Wi9epXDgU/XUi5dJKo4USTttVyK7fGw2nPWK0PbAvyliz50SCQ==
+
+"@rollup/rollup-linux-arm-musleabihf@4.22.4":
+ version "4.22.4"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.22.4.tgz#f3bbd1ae2420f5539d40ac1fde2b38da67779baa"
+ integrity sha512-dJnWUgwWBX1YBRsuKKMOlXCzh2Wu1mlHzv20TpqEsfdZLb3WoJW2kIEsGwLkroYf24IrPAvOT/ZQ2OYMV6vlrg==
+
+"@rollup/rollup-linux-arm64-gnu@4.22.4":
+ version "4.22.4"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.22.4.tgz#7abe900120113e08a1f90afb84c7c28774054d15"
+ integrity sha512-AdPRoNi3NKVLolCN/Sp4F4N1d98c4SBnHMKoLuiG6RXgoZ4sllseuGioszumnPGmPM2O7qaAX/IJdeDU8f26Aw==
+
+"@rollup/rollup-linux-arm64-musl@4.22.4":
+ version "4.22.4"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.22.4.tgz#9e655285c8175cd44f57d6a1e8e5dedfbba1d820"
+ integrity sha512-Gl0AxBtDg8uoAn5CCqQDMqAx22Wx22pjDOjBdmG0VIWX3qUBHzYmOKh8KXHL4UpogfJ14G4wk16EQogF+v8hmA==
+
+"@rollup/rollup-linux-powerpc64le-gnu@4.22.4":
+ version "4.22.4"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.22.4.tgz#9a79ae6c9e9d8fe83d49e2712ecf4302db5bef5e"
+ integrity sha512-3aVCK9xfWW1oGQpTsYJJPF6bfpWfhbRnhdlyhak2ZiyFLDaayz0EP5j9V1RVLAAxlmWKTDfS9wyRyY3hvhPoOg==
+
+"@rollup/rollup-linux-riscv64-gnu@4.22.4":
+ version "4.22.4"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.22.4.tgz#67ac70eca4ace8e2942fabca95164e8874ab8128"
+ integrity sha512-ePYIir6VYnhgv2C5Xe9u+ico4t8sZWXschR6fMgoPUK31yQu7hTEJb7bCqivHECwIClJfKgE7zYsh1qTP3WHUA==
+
+"@rollup/rollup-linux-s390x-gnu@4.22.4":
+ version "4.22.4"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.22.4.tgz#9f883a7440f51a22ed7f99e1d070bd84ea5005fc"
+ integrity sha512-GqFJ9wLlbB9daxhVlrTe61vJtEY99/xB3C8e4ULVsVfflcpmR6c8UZXjtkMA6FhNONhj2eA5Tk9uAVw5orEs4Q==
+
+"@rollup/rollup-linux-x64-gnu@4.22.4":
+ version "4.22.4"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.22.4.tgz#70116ae6c577fe367f58559e2cffb5641a1dd9d0"
+ integrity sha512-87v0ol2sH9GE3cLQLNEy0K/R0pz1nvg76o8M5nhMR0+Q+BBGLnb35P0fVz4CQxHYXaAOhE8HhlkaZfsdUOlHwg==
+
+"@rollup/rollup-linux-x64-musl@4.22.4":
+ version "4.22.4"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.22.4.tgz#f473f88219feb07b0b98b53a7923be716d1d182f"
+ integrity sha512-UV6FZMUgePDZrFjrNGIWzDo/vABebuXBhJEqrHxrGiU6HikPy0Z3LfdtciIttEUQfuDdCn8fqh7wiFJjCNwO+g==
+
+"@rollup/rollup-win32-arm64-msvc@4.22.4":
+ version "4.22.4"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.22.4.tgz#4349482d17f5d1c58604d1c8900540d676f420e0"
+ integrity sha512-BjI+NVVEGAXjGWYHz/vv0pBqfGoUH0IGZ0cICTn7kB9PyjrATSkX+8WkguNjWoj2qSr1im/+tTGRaY+4/PdcQw==
+
+"@rollup/rollup-win32-ia32-msvc@4.22.4":
+ version "4.22.4"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.22.4.tgz#a6fc39a15db618040ec3c2a24c1e26cb5f4d7422"
+ integrity sha512-SiWG/1TuUdPvYmzmYnmd3IEifzR61Tragkbx9D3+R8mzQqDBz8v+BvZNDlkiTtI9T15KYZhP0ehn3Dld4n9J5g==
+
+"@rollup/rollup-win32-x64-msvc@4.22.4":
+ version "4.22.4"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.22.4.tgz#3dd5d53e900df2a40841882c02e56f866c04d202"
+ integrity sha512-j8pPKp53/lq9lMXN57S8cFz0MynJk8OWNuUnXct/9KCpKU7DgU3bYMJhwWmcqC0UU29p8Lr0/7KEVcaM6bf47Q==
"@rushstack/eslint-patch@^1.10.3":
version "1.10.4"
@@ -8740,53 +8665,29 @@ rollup-plugin-visualizer@^5.12.0:
source-map "^0.7.4"
yargs "^17.5.1"
-rollup@4.14.1:
- version "4.14.1"
- resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.14.1.tgz#228d5159c3f4d8745bd24819d734bc6c6ca87c09"
- integrity sha512-4LnHSdd3QK2pa1J6dFbfm1HN0D7vSK/ZuZTsdyUAlA6Rr1yTouUTL13HaDOGJVgby461AhrNGBS7sCGXXtT+SA==
+rollup@4.22.4, rollup@^4.13.0, rollup@^4.18.0, rollup@^4.20.0:
+ version "4.22.4"
+ resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.22.4.tgz#4135a6446671cd2a2453e1ad42a45d5973ec3a0f"
+ integrity sha512-vD8HJ5raRcWOyymsR6Z3o6+RzfEPCnVLMFJ6vRslO1jt4LO6dUo5Qnpg7y4RkZFM2DMe3WUirkI5c16onjrc6A==
dependencies:
"@types/estree" "1.0.5"
optionalDependencies:
- "@rollup/rollup-android-arm-eabi" "4.14.1"
- "@rollup/rollup-android-arm64" "4.14.1"
- "@rollup/rollup-darwin-arm64" "4.14.1"
- "@rollup/rollup-darwin-x64" "4.14.1"
- "@rollup/rollup-linux-arm-gnueabihf" "4.14.1"
- "@rollup/rollup-linux-arm64-gnu" "4.14.1"
- "@rollup/rollup-linux-arm64-musl" "4.14.1"
- "@rollup/rollup-linux-powerpc64le-gnu" "4.14.1"
- "@rollup/rollup-linux-riscv64-gnu" "4.14.1"
- "@rollup/rollup-linux-s390x-gnu" "4.14.1"
- "@rollup/rollup-linux-x64-gnu" "4.14.1"
- "@rollup/rollup-linux-x64-musl" "4.14.1"
- "@rollup/rollup-win32-arm64-msvc" "4.14.1"
- "@rollup/rollup-win32-ia32-msvc" "4.14.1"
- "@rollup/rollup-win32-x64-msvc" "4.14.1"
- fsevents "~2.3.2"
-
-rollup@^4.13.0, rollup@^4.18.0, rollup@^4.20.0:
- version "4.22.2"
- resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.22.2.tgz#d762fa52c6ddb1307c1d6e8b463ba79432ffbb6b"
- integrity sha512-JWWpTrZmqQGQWt16xvNn6KVIUz16VtZwl984TKw0dfqqRpFwtLJYYk1/4BTgplndMQKWUk/yB4uOShYmMzA2Vg==
- dependencies:
- "@types/estree" "1.0.5"
- optionalDependencies:
- "@rollup/rollup-android-arm-eabi" "4.22.2"
- "@rollup/rollup-android-arm64" "4.22.2"
- "@rollup/rollup-darwin-arm64" "4.22.2"
- "@rollup/rollup-darwin-x64" "4.22.2"
- "@rollup/rollup-linux-arm-gnueabihf" "4.22.2"
- "@rollup/rollup-linux-arm-musleabihf" "4.22.2"
- "@rollup/rollup-linux-arm64-gnu" "4.22.2"
- "@rollup/rollup-linux-arm64-musl" "4.22.2"
- "@rollup/rollup-linux-powerpc64le-gnu" "4.22.2"
- "@rollup/rollup-linux-riscv64-gnu" "4.22.2"
- "@rollup/rollup-linux-s390x-gnu" "4.22.2"
- "@rollup/rollup-linux-x64-gnu" "4.22.2"
- "@rollup/rollup-linux-x64-musl" "4.22.2"
- "@rollup/rollup-win32-arm64-msvc" "4.22.2"
- "@rollup/rollup-win32-ia32-msvc" "4.22.2"
- "@rollup/rollup-win32-x64-msvc" "4.22.2"
+ "@rollup/rollup-android-arm-eabi" "4.22.4"
+ "@rollup/rollup-android-arm64" "4.22.4"
+ "@rollup/rollup-darwin-arm64" "4.22.4"
+ "@rollup/rollup-darwin-x64" "4.22.4"
+ "@rollup/rollup-linux-arm-gnueabihf" "4.22.4"
+ "@rollup/rollup-linux-arm-musleabihf" "4.22.4"
+ "@rollup/rollup-linux-arm64-gnu" "4.22.4"
+ "@rollup/rollup-linux-arm64-musl" "4.22.4"
+ "@rollup/rollup-linux-powerpc64le-gnu" "4.22.4"
+ "@rollup/rollup-linux-riscv64-gnu" "4.22.4"
+ "@rollup/rollup-linux-s390x-gnu" "4.22.4"
+ "@rollup/rollup-linux-x64-gnu" "4.22.4"
+ "@rollup/rollup-linux-x64-musl" "4.22.4"
+ "@rollup/rollup-win32-arm64-msvc" "4.22.4"
+ "@rollup/rollup-win32-ia32-msvc" "4.22.4"
+ "@rollup/rollup-win32-x64-msvc" "4.22.4"
fsevents "~2.3.2"
run-applescript@^7.0.0: