Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
83a6db9
fixed link to organization/create
erichu100 Feb 5, 2025
be204f4
Sofia's create/detail organization changes
erichu100 Feb 11, 2025
b6a976b
Onboarding fixes
erichu100 Feb 12, 2025
bf0aed7
stash merge thing
sophiaashraf Feb 19, 2025
fad11bf
comment adds
erichu100 Feb 19, 2025
389591c
Merge branch 'devel-organizations' of https://github.com/sophiaashraf…
erichu100 Feb 19, 2025
862dff3
Dockerfile
sophiaashraf Feb 19, 2025
afa8fb8
Merge branch 'devel-organizations' of https://github.com/sophiaashraf…
sophiaashraf Feb 19, 2025
2ed0359
Add list model
erichu100 Feb 19, 2025
8dd12c3
Merge branch 'devel-organizations' of https://github.com/sophiaashraf…
erichu100 Feb 19, 2025
558cfe2
Update Dockerfile
sophiaashraf Feb 25, 2025
ab7bb15
Update Dockerfile to 3.8
sophiaashraf Feb 26, 2025
9f4c2d8
Update Dockerfile
sophiaashraf Feb 26, 2025
6e9968b
added group list
sophiaashraf Feb 26, 2025
9641b5e
added table & header for groups
sophiaashraf Feb 26, 2025
410cf8a
Merge branch 'devel-organizations' of https://github.com/sophiaashraf…
sophiaashraf Feb 26, 2025
6de3ceb
settings and slight bug fix
erichu100 Mar 6, 2025
efa3596
nullkey fix
erichu100 Mar 6, 2025
fa9f902
Added organizations to group detail/list.
erichu100 Mar 6, 2025
088abbd
Added filtering for groups in organization_detail.
erichu100 Mar 6, 2025
ba16f9b
ignore
sophiaashraf Mar 10, 2025
6bc138f
Added update page for Organizations
erichu100 Mar 22, 2025
a9dd3fd
Merge branch 'devel-organizations' of https://github.com/sophiaashraf…
erichu100 Mar 22, 2025
90fdbe0
Revert "ignore"
erichu100 Mar 22, 2025
20754b3
Added link to group_detail organization field.
erichu100 Mar 22, 2025
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
10 changes: 7 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion emstrack/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 = ["*"]
Expand Down
12 changes: 12 additions & 0 deletions login/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
2 changes: 1 addition & 1 deletion login/migrations/0006_auto_20241120_0110.py
Original file line number Diff line number Diff line change
Expand Up @@ -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'),
),
]
7 changes: 4 additions & 3 deletions login/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -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')
Expand Down Expand Up @@ -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')
Expand Down Expand Up @@ -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(
Expand Down
5 changes: 5 additions & 0 deletions login/tests/setup_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

from hospital.models import Hospital
from equipment.models import EquipmentType, Equipment, EquipmentHolder, EquipmentItem
from login.models import Organization


class TestSetupData:
Expand Down Expand Up @@ -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])
Expand Down
21 changes: 16 additions & 5 deletions login/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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'
Expand All @@ -168,22 +169,30 @@ 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'])

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,
Expand Down Expand Up @@ -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

Expand Down
10 changes: 10 additions & 0 deletions templates/login/group_detail.html
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,16 @@ <h3>{% trans "Details" %}:</h3>
{{ group.groupprofile.description }}
</p>

<p>
<strong>{% trans "Organization" %}:</strong>
{% if group.groupprofile.organization %}
<a href="{% url 'login:detail-organization' pk=group.groupprofile.organization.id %}">{{ group.groupprofile.organization }}</a>
{% else %}
{{ group.groupprofile.organization }}
{% endif %}

</p>

<p>
<strong>{% trans "Priority" %}:</strong>
{{ group.groupprofile.priority }}
Expand Down
4 changes: 4 additions & 0 deletions templates/login/group_list.html
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ <h1>{% trans "Groups" %}</h1>
<tr>
<th>{% trans "Name" %}</th>
<th>{% trans "Description" %}</th>
<th>{% trans "Organization" %}</th>
<th>{% trans "Priority" %}</th>
<th>{% trans "SMS Notifications" %}</th>
<th>{% trans "Number of Users" %}</th>
Expand All @@ -48,6 +49,9 @@ <h1>{% trans "Groups" %}</h1>
<td>
{{ group.groupprofile.description }}
</td>
<td>
{{ group.groupprofile.organization }}
</td>
<td>
{{ group.groupprofile.priority }}
</td>
Expand Down
47 changes: 35 additions & 12 deletions templates/login/organization_create.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,18 @@

<div class="container">

<!-- FIXED: Changed breadcrumb from 'Groups' to 'Organizations' -->
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="{% url 'login:list-group' %}">{% trans "Groups" %}</a></li>
{% if group %}
<li class="breadcrumb-item"><a href="{% url 'login:detail-group' pk=group.id %}">{{ group.name }}</a></li>
<li class="breadcrumb-item">
<a href="{% url 'login:list-organization' %}">{% trans "Organizations" %}</a>
<!-- ^^^ Changed 'list-group' to 'list-organization' -->
</li>
{% if organization %}
<li class="breadcrumb-item">
<a href="{% url 'login:detail-organization' pk=organization.id %}">{{ organization.name }}</a>
<!-- ^^^ Changed 'detail-group' to 'detail-organization' -->
</li>
<li class="breadcrumb-item active" aria-current="page">{% trans "Update" %}</li>
{% else %}
<li class="breadcrumb-item active" aria-current="page">{% trans "Create" %}</li>
Expand All @@ -20,28 +27,44 @@

<div class="row">
<div class="col">

<h1>{% trans "Group" %}</h1>
<!-- FIXED: Changed heading from 'Group' to 'Organization' -->
<h1>
{% if organization %}
{% trans "Update Organization" %}
<!-- ^^^ Changed 'Update Group' to 'Update Organization' -->
{% else %}
{% trans "Create Organization" %}
<!-- ^^^ Changed 'Create Group' to 'Create Organization' -->
{% endif %}
</h1>

<form method="POST" class="post-form">
{% csrf_token %}

<h3>{% trans "Details" %}:</h3>
<!-- FIXED: Updated section heading from 'Details' to 'Organization Details' -->
<h3>{% trans "Organization Details" %}</h3>

<!-- FIXED: Changed `{{ form }}` to `{{ form.as_table }}` for better formatting -->
<table>
{{ form }}
{{ form.as_table }}
</table>

<p>
{% trans "Edit the group after creation to provide more details." %}
</p>
<p>{% trans "Edit the organization after creation to provide more details." %}</p>
<!-- ^^^ Changed 'group' to 'organization' in the message -->

<p>
<button type="submit" class="btn btn-primary">{% trans "Save" %}</button>
<button type="submit" class="btn btn-primary">
{% if organization %}
{% trans "Update" %}
<!-- ^^^ Changed 'Save' to 'Update' for clarity -->
{% else %}
{% trans "Create" %}
<!-- ^^^ Changed 'Save' to 'Create' for clarity -->
{% endif %}
</button>
</p>
</form>
</div>
</div>
</div>

{% endblock %}
61 changes: 54 additions & 7 deletions templates/login/organization_detail.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,19 @@

<div class="container">

<!-- FIXED: Changed breadcrumb from 'Groups' to 'Organizations' -->
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="{% url 'login:list-organization' %}">{% trans "Organizations" %}</a></li>
<li class="breadcrumb-item">
<a href="{% url 'login:list-organization' %}">{% trans "Organizations" %}</a>
</li>
<li class="breadcrumb-item active" aria-current="page">{{ organization.name }}</li>
</ol>
</nav>

<div class="row">
<div class="col">

<h1>{% trans "Organization" %}</h1>

<h3>{% trans "Details" %}:</h3>
<h1>{% trans "Organization Details" %}</h1>

<p>
<strong>{% trans "Name" %}:</strong>
Expand All @@ -27,11 +27,58 @@ <h3>{% trans "Details" %}:</h3>

<p>
<strong>{% trans "Description" %}:</strong>
{{ organization.description }}
{{ organization.description|default:"<em>No description provided</em>"|safe }}
</p>

{% if organization.permissions.all %}
<h3>{% trans "Organization Permissions" %}</h3>
<ul>
{% for permission in organization.permissions.all %}
<li>{{ permission.name }}</li>
{% endfor %}
</ul>
{% else %}
<h3>{% trans "Organization Permissions" %}</h3>
<p><em>{% trans "No permissions assigned." %}</em></p>
{% endif %}

{% if organization.ambulances.all %}
<h3>{% trans "Ambulances in this Organization" %}</h3>
<ul>
{% for ambulance in organization.ambulances.all %}
<li>{{ ambulance.name }}</li>
{% endfor %}
</ul>
{% else %}
<h3>{% trans "Ambulances in this Organization" %}</h3>
<p><em>{% trans "No ambulances assigned." %}</em></p>
{% endif %}

<!-- ADDED: Groups in Organization -->
<h3>{% trans "Groups in this Organization" %}</h3>

{% if group_list %}
<table class="table table-striped table-sm">
<thead>
<tr>
<th>{% trans "Name" %}</th>
</tr>
</thead>
<tbody>
{% for group_profile in group_list %}
<tr>
<td>
<a href="{% url 'login:detail-group' pk=group_profile.group.id %}">{{ group_profile.group.name }}</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<p><em>{% trans "No groups assigned." %}</em></p>
{% endif %}

</div>
</div>
</div>

{% endblock %}
26 changes: 26 additions & 0 deletions templates/login/organization_form.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{% extends "base.html" %}
{% load static %}
{% load i18n %}

{% block content %}

<div class="container">
<div class="row">
<div class="col">

<h1>{% trans "Organization" %}</h1>

<form method="POST" class="post-form">
{% csrf_token %}

{{ form.as_p }}

<p>
<button type="submit" class="btn btn-primary">{% trans "Save" %}</button>
</p>
</form>
</div>
</div>
</div>

{% endblock %}
Loading