diff --git a/.gitignore b/.gitignore index fb60ae2f..be6c789d 100644 --- a/.gitignore +++ b/.gitignore @@ -160,4 +160,7 @@ dmypy.json *.iws # OS -.DS_Store \ No newline at end of file +.DS_Store + +# devel +dev-notes.md \ No newline at end of file diff --git a/citizenvoice/apiapp/migrations/0001_initial.py b/citizenvoice/apiapp/migrations/0001_initial.py index cc507596..2b0a12da 100644 --- a/citizenvoice/apiapp/migrations/0001_initial.py +++ b/citizenvoice/apiapp/migrations/0001_initial.py @@ -1,10 +1,11 @@ -# Generated by Django 4.1.12 on 2023-11-08 09:39 +# Generated by Django 5.0 on 2024-02-29 23:12 import apiapp.models.mapview -from django.conf import settings import django.contrib.gis.db.models.fields -from django.db import migrations, models import django.db.models.deletion +import uuid +from django.conf import settings +from django.db import migrations, models class Migration(migrations.Migration): @@ -20,8 +21,8 @@ class Migration(migrations.Migration): name='Answer', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('created', models.DateTimeField(verbose_name='Creation date')), - ('updated', models.DateTimeField(verbose_name='Last edited')), + ('created', models.DateTimeField(auto_now_add=True, verbose_name='Creation date')), + ('updated', models.DateTimeField(auto_now=True, verbose_name='Last edited')), ('body', models.TextField(verbose_name='Answer Body')), ], ), @@ -32,33 +33,7 @@ class Migration(migrations.Migration): ('name', models.CharField(default='Delft', max_length=150, verbose_name='Name of the MapView location')), ('map_service_url', models.CharField(default=apiapp.models.mapview.default_service_url, max_length=150, verbose_name='Map Service URL')), ('options', models.JSONField(default=apiapp.models.mapview.default_options, verbose_name='Map service specific options')), - ('geometries', models.JSONField(null=True, verbose_name='Custom geometries for the map view')), - ], - ), - migrations.CreateModel( - name='Survey', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.CharField(max_length=150, verbose_name='Name of the survey')), - ('description', models.TextField(blank=True, verbose_name='Description')), - ('is_published', models.BooleanField(default=False, verbose_name='Survey is visible and accessible to users')), - ('need_logged_user', models.BooleanField(default=False, verbose_name='Only authenticated users have access to this survey')), - ('editable_answers', models.BooleanField(default=True, verbose_name='Answers can be edited after submission')), - ('publish_date', models.DateTimeField(verbose_name='Date that survey was made available')), - ('expire_date', models.DateTimeField(verbose_name='Expiry date of survey')), - ('public_url', models.CharField(default='', max_length=255, verbose_name='Public URL')), - ('designer', models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), - ], - ), - migrations.CreateModel( - name='Response', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('created', models.DateTimeField(auto_now_add=True, verbose_name='Date response was submitted')), - ('updated', models.DateTimeField(auto_now=True, verbose_name='Last edit')), - ('interview_uuid', models.CharField(max_length=150, verbose_name='Unique ID of interview')), - ('respondent', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), - ('survey', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='apiapp.survey')), + ('geometries', models.JSONField(blank=True, null=True, verbose_name='Custom geometries for the map view')), ], ), migrations.CreateModel( @@ -72,7 +47,6 @@ class Migration(migrations.Migration): ('choices', models.TextField(blank=True, null=True, verbose_name='Choices for answers')), ('is_geospatial', models.BooleanField(default=False, verbose_name='If the question must be answered geospatially or not')), ('map_view', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='apiapp.mapview')), - ('survey', models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, to='apiapp.survey')), ], options={ 'verbose_name': 'question', @@ -124,9 +98,43 @@ class Migration(migrations.Migration): name='question', field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='apiapp.question'), ), + migrations.CreateModel( + name='Response', + fields=[ + ('created', models.DateTimeField(auto_now_add=True, verbose_name='Date response was submitted')), + ('updated', models.DateTimeField(auto_now=True, verbose_name='Last edit')), + ('interview_uuid', models.UUIDField(default=uuid.uuid4, primary_key=True, serialize=False, unique=True, verbose_name='Unique ID of interview')), + ('respondent', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + ), migrations.AddField( model_name='answer', name='response', field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='apiapp.response'), ), + migrations.CreateModel( + name='Survey', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=150, verbose_name='Name of the survey')), + ('description', models.TextField(blank=True, verbose_name='Description')), + ('is_published', models.BooleanField(default=False, verbose_name='Survey is visible and accessible to users')), + ('need_logged_user', models.BooleanField(default=False, verbose_name='Only authenticated users have access to this survey')), + ('editable_answers', models.BooleanField(default=True, verbose_name='Answers can be edited after submission')), + ('publish_date', models.DateTimeField(verbose_name='Date that survey was made available')), + ('expire_date', models.DateTimeField(verbose_name='Expiry date of survey')), + ('public_url', models.CharField(blank=True, max_length=255, verbose_name='Public URL')), + ('designer', models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + ), + migrations.AddField( + model_name='response', + name='survey', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='apiapp.survey'), + ), + migrations.AddField( + model_name='question', + name='survey', + field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, to='apiapp.survey'), + ), ] diff --git a/citizenvoice/apiapp/migrations/0002_alter_response_respondent.py b/citizenvoice/apiapp/migrations/0002_alter_response_respondent.py deleted file mode 100644 index a475e430..00000000 --- a/citizenvoice/apiapp/migrations/0002_alter_response_respondent.py +++ /dev/null @@ -1,21 +0,0 @@ -# Generated by Django 4.1.12 on 2023-11-08 09:44 - -from django.conf import settings -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ('apiapp', '0001_initial'), - ] - - operations = [ - migrations.AlterField( - model_name='response', - name='respondent', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL), - ), - ] diff --git a/citizenvoice/apiapp/migrations/0003_alter_mapview_geometries.py b/citizenvoice/apiapp/migrations/0003_alter_mapview_geometries.py deleted file mode 100644 index 279c5691..00000000 --- a/citizenvoice/apiapp/migrations/0003_alter_mapview_geometries.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 4.1.12 on 2023-11-08 10:48 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('apiapp', '0002_alter_response_respondent'), - ] - - operations = [ - migrations.AlterField( - model_name='mapview', - name='geometries', - field=models.JSONField(blank=True, null=True, verbose_name='Custom geometries for the map view'), - ), - ] diff --git a/citizenvoice/apiapp/migrations/0004_remove_response_id_alter_response_interview_uuid.py b/citizenvoice/apiapp/migrations/0004_remove_response_id_alter_response_interview_uuid.py deleted file mode 100644 index 788731fe..00000000 --- a/citizenvoice/apiapp/migrations/0004_remove_response_id_alter_response_interview_uuid.py +++ /dev/null @@ -1,23 +0,0 @@ -# Generated by Django 4.1.12 on 2023-11-15 10:42 - -from django.db import migrations, models -import uuid - - -class Migration(migrations.Migration): - - dependencies = [ - ('apiapp', '0003_alter_mapview_geometries'), - ] - - operations = [ - migrations.RemoveField( - model_name='response', - name='id', - ), - migrations.AlterField( - model_name='response', - name='interview_uuid', - field=models.UUIDField(default=uuid.uuid4, primary_key=True, serialize=False, verbose_name='Unique ID of interview'), - ), - ] diff --git a/citizenvoice/apiapp/migrations/0005_remove_answer_response_alter_response_interview_uuid.py b/citizenvoice/apiapp/migrations/0005_remove_answer_response_alter_response_interview_uuid.py deleted file mode 100644 index b21cb154..00000000 --- a/citizenvoice/apiapp/migrations/0005_remove_answer_response_alter_response_interview_uuid.py +++ /dev/null @@ -1,23 +0,0 @@ -# Generated by Django 5.0 on 2024-02-28 08:25 - -import uuid -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('apiapp', '0004_remove_response_id_alter_response_interview_uuid'), - ] - - operations = [ - migrations.RemoveField( - model_name='answer', - name='response', - ), - migrations.AlterField( - model_name='response', - name='interview_uuid', - field=models.UUIDField(default=uuid.uuid4, primary_key=True, serialize=False, unique=True, verbose_name='Unique ID of interview'), - ), - ] diff --git a/citizenvoice/apiapp/migrations/0006_answer_response.py b/citizenvoice/apiapp/migrations/0006_answer_response.py deleted file mode 100644 index 3b0c3410..00000000 --- a/citizenvoice/apiapp/migrations/0006_answer_response.py +++ /dev/null @@ -1,20 +0,0 @@ -# Generated by Django 5.0 on 2024-02-28 08:28 - -import django.db.models.deletion -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('apiapp', '0005_remove_answer_response_alter_response_interview_uuid'), - ] - - operations = [ - migrations.AddField( - model_name='answer', - name='response', - field=models.ForeignKey(default='0122260b-3fcc-477e-85d2-fe43f0611100', on_delete=django.db.models.deletion.CASCADE, to='apiapp.response'), - preserve_default=False, - ), - ] diff --git a/citizenvoice/apiapp/migrations/0007_alter_answer_response.py b/citizenvoice/apiapp/migrations/0007_alter_answer_response.py deleted file mode 100644 index 851d83d5..00000000 --- a/citizenvoice/apiapp/migrations/0007_alter_answer_response.py +++ /dev/null @@ -1,19 +0,0 @@ -# Generated by Django 5.0 on 2024-02-28 08:31 - -import django.db.models.deletion -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('apiapp', '0006_answer_response'), - ] - - operations = [ - migrations.AlterField( - model_name='answer', - name='response', - field=models.ForeignKey(default='0122260b-3fcc-477e-85d2-fe43f0611b45', on_delete=django.db.models.deletion.CASCADE, to='apiapp.response'), - ), - ] diff --git a/citizenvoice/apiapp/migrations/0008_alter_answer_response.py b/citizenvoice/apiapp/migrations/0008_alter_answer_response.py deleted file mode 100644 index d1c0b5ad..00000000 --- a/citizenvoice/apiapp/migrations/0008_alter_answer_response.py +++ /dev/null @@ -1,19 +0,0 @@ -# Generated by Django 5.0 on 2024-02-28 08:33 - -import django.db.models.deletion -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('apiapp', '0007_alter_answer_response'), - ] - - operations = [ - migrations.AlterField( - model_name='answer', - name='response', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='apiapp.response'), - ), - ] diff --git a/citizenvoice/apiapp/migrations/0009_alter_answer_created_alter_answer_updated.py b/citizenvoice/apiapp/migrations/0009_alter_answer_created_alter_answer_updated.py deleted file mode 100644 index 817fb779..00000000 --- a/citizenvoice/apiapp/migrations/0009_alter_answer_created_alter_answer_updated.py +++ /dev/null @@ -1,23 +0,0 @@ -# Generated by Django 5.0 on 2024-02-28 09:28 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('apiapp', '0008_alter_answer_response'), - ] - - operations = [ - migrations.AlterField( - model_name='answer', - name='created', - field=models.DateTimeField(auto_now_add=True, verbose_name='Creation date'), - ), - migrations.AlterField( - model_name='answer', - name='updated', - field=models.DateTimeField(auto_now=True, verbose_name='Last edited'), - ), - ] diff --git a/citizenvoice/apiapp/models/survey.py b/citizenvoice/apiapp/models/survey.py index 3196bd74..cbfc81f6 100644 --- a/citizenvoice/apiapp/models/survey.py +++ b/citizenvoice/apiapp/models/survey.py @@ -24,7 +24,7 @@ class Survey(models.Model): editable_answers = models.BooleanField(_("Answers can be edited after submission"), default=True) publish_date = models.DateTimeField(_("Date that survey was made available")) expire_date = models.DateTimeField(_("Expiry date of survey")) - public_url = models.CharField(_("Public URL"), max_length=255, default='') # TODO: [manuel] this should be auto-generated at the creation of the survey using an UUID + public_url = models.CharField(_("Public URL"), max_length=255, blank=True) # TODO: [manuel] this should be auto-generated when chosen by the designer designer = models.ForeignKey(User, on_delete=models.CASCADE, default=1) def __str__(self): diff --git a/citizenvoice/apiapp/views.py b/citizenvoice/apiapp/views.py index bcbd5418..2d99ce1d 100644 --- a/citizenvoice/apiapp/views.py +++ b/citizenvoice/apiapp/views.py @@ -342,6 +342,7 @@ def submit_response(self, request, *args, **kwargs): print("Submitting response...") # TODO: test submision using this endpoint + # TODO: this is already possible via the answers endpoint user = self.request.user answers = self.request.data["answers"] responseId = self.request.data["responseId"] diff --git a/citizenvoice/citizenvoice/settings.py b/citizenvoice/citizenvoice/settings.py index e1922680..874ceb4a 100644 --- a/citizenvoice/citizenvoice/settings.py +++ b/citizenvoice/citizenvoice/settings.py @@ -37,12 +37,16 @@ # Build paths inside the project like this: BASE_DIR / 'subdir'. BASE_DIR = Path(__file__).resolve().parent.parent +# read environment variable form .env file +load_dotenv("../.env") + # Quick-start development settings - unsuitable for production # See https://docs.djangoproject.com/en/4.0/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret! SECRET_KEY = os.getenv('SECRET_KEY') + # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True @@ -84,16 +88,15 @@ # CORS 'corsheaders.middleware.CorsMiddleware', 'django.middleware.common.CommonMiddleware', - 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ] -CORS_ORIGIN_WHITELIST = ( +CORS_ORIGIN_WHITELIST = [ 'http://localhost:3000', -) +] CSRF_TRUSTED_ORIGINS = ['http://localhost:3000'] diff --git a/frontend/components/AnswerMapView.vue b/frontend/components/AnswerMapView.vue new file mode 100644 index 00000000..80ba217c --- /dev/null +++ b/frontend/components/AnswerMapView.vue @@ -0,0 +1,321 @@ + + + + + \ No newline at end of file diff --git a/frontend/components/Header.vue b/frontend/components/Header.vue index 89e1c7d7..2f40a0fb 100644 --- a/frontend/components/Header.vue +++ b/frontend/components/Header.vue @@ -63,6 +63,10 @@ export default { { label: 'About', link: '/about' + }, + { + label: 'Components', + link: '/comp' } ], itemsAccount: [ diff --git a/frontend/components/MapView.vue b/frontend/components/MapView.vue index c4b65dc2..92cfc986 100644 --- a/frontend/components/MapView.vue +++ b/frontend/components/MapView.vue @@ -3,7 +3,7 @@