diff --git a/Dockerfile b/Dockerfile index 8bb62063..e563b571 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ # Using ubuntu as a base image -FROM python:3.7 +FROM python:3.8 # Getting rid of debconf messages ARG DEBIAN_FRONTEND=noninteractive @@ -14,8 +14,12 @@ RUN set -x && \ rsync # Install node -# RUN curl -sL https://deb.nodesource.com/setup_21.x | bash - && \ -RUN apt-get install -y nodejs npm +RUN curl -sL https://deb.nodesource.com/setup_21.x | bash - && \ + apt-get install -y nodejs + +#RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash +#RUN nvm install node + # Build variables ARG BUILD_APP_HOME=/app diff --git a/emstrack/settings.py b/emstrack/settings.py index 4746c4d0..20844d1d 100644 --- a/emstrack/settings.py +++ b/emstrack/settings.py @@ -43,7 +43,7 @@ } # SECURITY WARNING: don't run with debug turned on in production! -DEBUG = env.bool('DJANGO_DEBUG', default=False) +DEBUG = env.bool('DJANGO_DEBUG', default=True) allowed_hosts = env.str('DJANGO_HOSTNAMES', default="*") if allowed_hosts == "*": ALLOWED_HOSTS = ["*"] diff --git a/login/forms.py b/login/forms.py index fa3c67df..de8009b0 100644 --- a/login/forms.py +++ b/login/forms.py @@ -275,6 +275,18 @@ class Media(object): # Other form media here ) +# Currently unused, but probably needed in future. +class OrganizationAdminUpdateForm(forms.ModelForm): + class Meta: + model = Organization + fields = ['name', 'description'] + + def __init__(self, *args, **kwargs): + # call super + super().__init__(*args, **kwargs) + + # disable name + self.fields['name'].disabled = True class GroupProfileAdminForm(forms.ModelForm): class Meta: diff --git a/login/migrations/0006_auto_20241120_0110.py b/login/migrations/0006_auto_20241120_0110.py index c766468c..5156b769 100644 --- a/login/migrations/0006_auto_20241120_0110.py +++ b/login/migrations/0006_auto_20241120_0110.py @@ -15,6 +15,6 @@ class Migration(migrations.Migration): model_name='groupprofile', name='organization', # Remove default to make "required field" - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='login.Organization', verbose_name='organization'), + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='login.Organization', verbose_name='organization'), ), ] \ No newline at end of file diff --git a/login/models.py b/login/models.py index 52a87524..a825a7ea 100644 --- a/login/models.py +++ b/login/models.py @@ -57,6 +57,7 @@ def is_guest(user): class Organization(models.Model): name = models.CharField(_('name'), max_length=100, unique=True) description = models.CharField(_('description'), max_length=100, blank=True) + #symmetrical relationships users = models.ManyToManyField(User) ambulances = models.ManyToManyField('ambulance.Ambulance') equipment_set = models.ManyToManyField('equipment.EquipmentSet') @@ -119,7 +120,7 @@ def can_sms_notifications(): # GroupProfile class GroupProfile(ClearPermissionCacheMixin, models.Model): - organization = models.ForeignKey(Organization, on_delete = models.CASCADE, verbose_name = _('organization'), null = False) + organization = models.ForeignKey(Organization, on_delete = models.CASCADE, verbose_name = _('organization'), null = True) group = models.OneToOneField( Group, on_delete=models.CASCADE, verbose_name=_('group') @@ -235,8 +236,8 @@ def __str__(self): self.can_write, ) #OrganizationAmbulancePermission -class OrganizationAmbulancePermission(ClearPermissionCacheMixin, Permission): - pass +#class OrganizationAmbulancePermission(ClearPermissionCacheMixin, Permission): +# pass # random string def random_string_generator( diff --git a/login/tests/setup_data.py b/login/tests/setup_data.py index 1249091a..32c01a10 100644 --- a/login/tests/setup_data.py +++ b/login/tests/setup_data.py @@ -12,6 +12,7 @@ from hospital.models import Hospital from equipment.models import EquipmentType, Equipment, EquipmentHolder, EquipmentItem +from login.models import Organization class TestSetupData: @@ -243,6 +244,10 @@ def setUpTestData(cls): can_write=False) #TODO: Add organizations to groups + cls.o1 = Organization.objects.create( + name = "CruzRoja", + description = "Red Cross" + ) cls.u4.groups.set([cls.g2]) cls.u5.groups.set([cls.g1, cls.g3]) diff --git a/login/views.py b/login/views.py index 340807df..f514d34b 100644 --- a/login/views.py +++ b/login/views.py @@ -18,7 +18,7 @@ from django.views.generic import ListView, DetailView from django.views.generic.base import View, TemplateView from django.views.generic.detail import BaseDetailView -from django.views.generic.edit import FormView, CreateView +from django.views.generic.edit import FormView, CreateView, UpdateView from drf_extra_fields.geo_fields import PointField from extra_views import ( InlineFormSetFactory, @@ -152,6 +152,7 @@ class OrganizationAdminListView(PaginationViewMixin, ListView): template_name = 'login/organization_list.html' ordering = 'name' +#https://docs.djangoproject.com/en/5.1/topics/db/queries/#lookups-that-span-relationships class OrganizationAdminDetailView(DetailView): model = Organization template_name = 'login/organization_detail.html' @@ -168,12 +169,14 @@ def get_context_data(self, **kwargs): # retrieve users and add to context # context['user_list'] = self.object.user_set.all() + context['group_list'] = GroupProfile.objects.filter(organization = self.object) return context class OrganizationAdminCreateView(SuccessMessageMixin, CreateView): + model = Organization + template_name = 'login/organization_create.html' fields = ['name', 'description'] - #template_name = 'login/group_create.html' def get_success_message(self, cleaned_data): return "Successfully created organization '{}'".format(cleaned_data['name']) @@ -181,9 +184,15 @@ def get_success_message(self, cleaned_data): def get_success_url(self): return self.object.get_absolute_url() -class OrganizationAdminUpdateView(SuccessMessageWithInlinesMixin, UpdateWithInlinesView): +#class OrganizationAdminInline(InlineFormSetFactory): +# model = Organization + # form_class = Orga + +#TODO: Convert to UpdateWithInlinesView, remove UpdateView import +class OrganizationAdminUpdateView(SuccessMessageMixin, UpdateView): model = Organization - #template_name = 'login/group_form.html' + fields = ['name', 'description'] + template_name = 'login/organization_form.html' #form_class = GroupAdminUpdateForm #inlines = [ # GroupProfileAdminInline, @@ -302,8 +311,10 @@ def get_context_data(self, **kwargs): context['ambulance_list'] = self.object.userambulancepermission_set.all() context['hospital_list'] = self.object.userhospitalpermission_set.all() - # retrieve groups and add to context + # TODO: retrieve organizations user is in and add to context context['group_list'] = self.object.groups.all() + # Autogenerated fetch method name + context['org_list'] = self.object.organization_set.all() return context diff --git a/templates/login/group_detail.html b/templates/login/group_detail.html index a9d8bce8..eefbdbbc 100644 --- a/templates/login/group_detail.html +++ b/templates/login/group_detail.html @@ -30,6 +30,16 @@
+ {% trans "Organization" %}: + {% if group.groupprofile.organization %} + {{ group.groupprofile.organization }} + {% else %} + {{ group.groupprofile.organization }} + {% endif %} + +
+{% trans "Priority" %}: {{ group.groupprofile.priority }} diff --git a/templates/login/group_list.html b/templates/login/group_list.html index 66cc1f97..71f45bb1 100644 --- a/templates/login/group_list.html +++ b/templates/login/group_list.html @@ -34,6 +34,7 @@
{% trans "Name" %}: @@ -27,11 +27,58 @@
{% trans "Description" %}: - {{ organization.description }} + {{ organization.description|default:"No description provided"|safe }}
+ {% if organization.permissions.all %} +{% trans "No permissions assigned." %}
+ {% endif %} + + {% if organization.ambulances.all %} +{% trans "No ambulances assigned." %}
+ {% endif %} + + +{% trans "Name" %} | +
---|
+ {{ group_profile.group.name }} + | +
{% trans "No groups assigned." %}
+ {% endif %} +{% trans "Name" %} | +{% trans "Description" %} | +
---|---|
+ {{ org.name }} + | ++ {{ org.description }} + | +
{% trans "This user does not belongs to any organization yet." %}
+ + {% endif %} +