...
 
Commits (35)
# Generated by Django 2.1.3 on 2019-01-17 18:54
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('core', '0026_auto_20181211_0937'),
]
operations = [
migrations.AlterField(
model_name='project',
name='type',
field=models.CharField(choices=[('research', 'Thesis project'), ('regular', 'Research project'), ('applied', 'Applied project')], max_length=20),
),
]
# Generated by Django 2.1.3 on 2019-01-18 16:24
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('core', '0027_auto_20190117_1854'),
]
operations = [
migrations.AddField(
model_name='project',
name='references',
field=models.ManyToManyField(blank=True, to='core.Reference'),
),
migrations.AlterField(
model_name='project',
name='type',
field=models.CharField(choices=[('research', 'Thesis project'), ('regular', 'Research project'), ('applied', 'Applied research')], max_length=20),
),
]
# Generated by Django 2.1.3 on 2019-01-19 09:10
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('core', '0028_auto_20190118_1624'),
]
operations = [
migrations.AlterField(
model_name='project',
name='references',
field=models.ManyToManyField(blank=True, limit_choices_to={'status': 'active'}, to='core.Reference'),
),
]
# Generated by Django 2.1.3 on 2019-01-19 09:40
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('multiplicity', '0033_auto_20190119_0911'),
('core', '0029_auto_20190119_0910'),
]
operations = [
migrations.AddField(
model_name='video',
name='primary_space',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='multiplicity.ReferenceSpace'),
),
]
# Generated by Django 2.1.3 on 2019-01-19 09:44
import django.contrib.sites.managers
from django.db import migrations, models
import django.db.models.deletion
import django.db.models.manager
import tinymce.models
class Migration(migrations.Migration):
dependencies = [
('sites', '0002_alter_domain_unique'),
('core', '0030_video_primary_space'),
]
operations = [
migrations.CreateModel(
name='VideoCollection',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('title', models.CharField(max_length=255)),
('description', tinymce.models.HTMLField(blank=True, null=True, verbose_name='description')),
('site', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='sites.Site')),
],
managers=[
('objects', django.db.models.manager.Manager()),
('on_site', django.contrib.sites.managers.CurrentSiteManager()),
],
),
migrations.AddField(
model_name='video',
name='collection',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='core.VideoCollection'),
),
]
# Generated by Django 2.1.3 on 2019-01-19 10:03
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('core', '0031_auto_20190119_0944'),
]
operations = [
migrations.AddField(
model_name='video',
name='thumbnail',
field=models.ImageField(blank=True, null=True, upload_to='video_thumbnails'),
),
]
# Generated by Django 2.1.3 on 2019-01-19 11:56
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('multiplicity', '0033_auto_20190119_0911'),
('core', '0032_video_thumbnail'),
]
operations = [
migrations.AddField(
model_name='video',
name='license',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='multiplicity.License'),
),
]
# Generated by Django 2.1.3 on 2019-01-20 09:25
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('core', '0033_video_license'),
]
operations = [
migrations.AddField(
model_name='project',
name='thesistype',
field=models.CharField(blank=True, choices=[('bachelor', 'Bachelor'), ('masters', 'Masters'), ('phd', 'PhD')], max_length=20, null=True),
),
migrations.AlterField(
model_name='project',
name='type',
field=models.CharField(choices=[('theses', 'Thesis project'), ('projects', 'Research project'), ('applied', 'Applied research')], max_length=20),
),
]
# Generated by Django 2.1.3 on 2019-01-20 10:00
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('core', '0034_auto_20190120_0925'),
]
operations = [
migrations.AddField(
model_name='userlog',
name='description',
field=models.TextField(blank=True, null=True),
),
migrations.AddField(
model_name='userlog',
name='model',
field=models.CharField(blank=True, max_length=255, null=True),
),
migrations.AlterField(
model_name='project',
name='type',
field=models.CharField(choices=[('theses', 'Theses projects'), ('projects', 'Research projects'), ('applied', 'Applied research')], max_length=20),
),
]
from django.db import models
from multiplicity.models import ReferenceSpace
from multiplicity.models import ReferenceSpace, License
from django.forms import ModelForm
from django.template.defaultfilters import slugify
from tinymce import HTMLField
......@@ -202,6 +202,22 @@ class EventForm(ModelForm):
model = Event
exclude = ['article']
class VideoCollection(models.Model):
title = models.CharField(max_length=255)
description = HTMLField('description', null=True, blank=True)
site = models.ForeignKey(Site, on_delete=models.CASCADE)
objects = models.Manager()
on_site = CurrentSiteManager()
def __str__(self):
return self.title
class VideoCollectionForm(ModelForm):
class Meta:
model = VideoCollection
exclude = ['id', 'site']
class Video(models.Model):
title = models.CharField(max_length=255)
url = models.CharField(max_length=255)
......@@ -213,10 +229,18 @@ class Video(models.Model):
site = models.ForeignKey(Site, on_delete=models.CASCADE)
objects = models.Manager()
on_site = CurrentSiteManager()
primary_space = models.ForeignKey(ReferenceSpace, on_delete=models.CASCADE, null=True, blank=True)
collection = models.ForeignKey(VideoCollection, on_delete=models.CASCADE, null=True, blank=True)
thumbnail = models.ImageField(null=True, blank=True, upload_to='video_thumbnails')
license = models.ForeignKey(License, on_delete=models.CASCADE, null=True, blank=True)
def __str__(self):
return self.title
labels = {
'primary_space': 'Reference space (optional)'
}
class VideoForm(ModelForm):
class Meta:
model = Video
......@@ -345,6 +369,8 @@ class UserLog(models.Model):
date = models.DateTimeField(auto_now_add=True)
action = models.ForeignKey(UserAction, on_delete=models.CASCADE)
points = models.PositiveSmallIntegerField()
model = models.CharField(max_length=255, null=True, blank=True)
description = models.TextField(null=True, blank=True)
class Meta:
ordering = ["date"]
......@@ -374,14 +400,22 @@ class Project(models.Model):
active = models.BooleanField(default=True)
pending_review = models.BooleanField(default=True)
TYPE = (
('research', 'Individual research project'),
('regular', 'Regular project'),
('theses', 'Theses projects'),
('projects', 'Research projects'),
('applied', 'Applied research'),
)
type = models.CharField(max_length=20, choices=TYPE)
THESISTYPE = (
('bachelor', 'Bachelor'),
('masters', 'Masters'),
('phd', 'PhD'),
)
thesistype = models.CharField(max_length=20, choices=THESISTYPE, null=True, blank=True)
site = models.ForeignKey(Site, on_delete=models.CASCADE)
objects = models.Manager()
on_site = CurrentSiteManager()
url = models.CharField(max_length=255, null=True, blank=True)
references = models.ManyToManyField(Reference, blank=True, limit_choices_to={'status': 'active'})
def __str__(self):
return self.name
......@@ -392,7 +426,16 @@ class Project(models.Model):
class ProjectForm(ModelForm):
class Meta:
model = Project
exclude = ['id', 'site']
exclude = ['id', 'site', 'references']
class ProjectUserForm(ModelForm):
class Meta:
model = Project
fields = ['name', 'researcher', 'type', 'thesistype', 'institution', 'supervisor', 'email', 'description', 'target_finish_date', 'start_date', 'end_date', 'status', 'url']
labels = {
'name': 'Project title',
'thesistype': 'Thesis type',
}
class Timeline(models.Model):
title = models.CharField(max_length=255)
......
......@@ -4,6 +4,15 @@ from django.conf.urls import include
from . import views
# both for the link names and the view names, try to stick to this:
# projects -> list
# if the singular version already has an 's' at the end, use:
# thesis_list -> list
# project -> project view
# project_form -> add new/edit existing project
app_name = 'core'
urlpatterns = [
......@@ -13,12 +22,14 @@ urlpatterns = [
path('more', views.empty, name='more'),
path('resources/videos', views.videos, name='videos'),
path('resources/videos/<int:id>', views.video, name='video'),
path('community/news', views.articles, {'parent': 'news'}, name='news'),
path('community/news/<int:id>', views.article, name='news'),
path('community/blog', views.articles, {'parent': 60}, name='blog'),
path('community/blog/<int:id>', views.article, name='blog'),
path('community/events', views.articles, {'parent': 'events'}, name='events'),
path('community/events/<int:id>', views.article, name='event'),
path('news_events', views.news_and_events, name='news_and_events'),
path('page/<slug:slug>', views.page, name='page'),
path('cities', views.sectionpage, { 'id': 33}, name='sectionpage'),
......@@ -27,24 +38,29 @@ urlpatterns = [
path('about/team', views.team, name='team'),
path('about/task-forces', views.taskforces, name='taskforces'),
path('about/task-forces/<slug:slug>', views.taskforce, name='taskforce'),
path('community/people', views.people, name='people'),
path('community/people/<int:id>', views.peopledetails, name='peopledetails'),
path('community/user/<int:id>', views.peopledetails, name='userdetails'),
path('community/research', views.projects, {'type': 'research', 'status': 'ongoing', 'page': 50}, name='research_projects'),
path('community/research/<int:id>', views.project_view, {'type': 'research', 'status': 'ongoing'}, name='research_project'),
path('community/research/past', views.projects, {'type': 'research', 'status': 'finished', 'page': 51}, name='past_research_projects'),
path('community/research/past/<int:id>', views.project_view, {'type': 'research', 'status': 'finished'}, name='past_research_project'),
path('community/projects', views.projects, {'type': 'projects', 'status': 'ongoing', 'page': 57}, name='projects'),
path('community/projects/<int:id>', views.project_view, {'type': 'projects', 'status': 'ongoing'}, name='project'),
path('community/projects/past', views.projects, {'type': 'projects', 'status': 'finished', 'page': 56}, name='past_projects'),
path('community/projects/past/<int:id>', views.project_view, {'type': 'projects', 'status': 'finished'}, name='past_project'),
#path('community/research', views.projects, {'type': 'research', 'status': 'ongoing', 'page': 50}, name='research_projects'),
#path('community/research/<int:id>', views.project_view, {'type': 'research', 'status': 'ongoing'}, name='research_project'),
#path('community/research/past', views.projects, {'type': 'research', 'status': 'finished', 'page': 51}, name='past_research_projects'),
#path('community/research/past/<int:id>', views.project_view, {'type': 'research', 'status': 'finished'}, name='past_research_project'),
#path('community/projects', views.projects, {'type': 'projects', 'status': 'ongoing', 'page': 57}, name='projects'),
#path('community/projects/<int:id>', views.project_view, {'type': 'projects', 'status': 'ongoing'}, name='project'),
#path('community/projects/past', views.projects, {'type': 'projects', 'status': 'finished', 'page': 56}, name='past_projects'),
#path('community/projects/past/<int:id>', views.project_view, {'type': 'projects', 'status': 'finished'}, name='past_project'),
path('resources/journals', views.journals, name='journals'),
path('resources/journals/<int:id>', views.journal, name='journal'),
path('community/organizations/<int:id>', views.organization, name='organization'),
path('community/organizations/<slug:type>', views.organizations, name='organizations'),
path('research/projects', views.projects, {'type': 'regular', 'page': 149}, name='regular_research_projects'),
path('research/theses', views.projects, {'type': 'research', 'page': 148}, name='theses_research_projects'),
path('community/research/create', views.project_form, name='project_form'),
path('community/research/<slug:type>', views.projects, name='projects'),
path('community/research/<slug:type>/<int:id>', views.project, name='project'),
path('resources', views.journals, name='resources_home'),
path('community', views.empty, name='community_home'),
......@@ -70,6 +86,7 @@ urlpatterns = [
path('resources/publications', views.references, name='references'),
path('resources/publication/<int:id>', views.reference),
path('resources/publications/<int:id>', views.reference, name='reference'),
path('resources/publications/<int:id>/edit', views.referenceform, name='editreference'),
path('resources/publications/add', views.referenceform, name='newreference'),
path('resources/publications/create/<int:dataset>', views.referenceform, name='newflowreference'),
path('resources/publications/tags/<int:tag>', views.references, name='tag_search'),
......@@ -85,11 +102,16 @@ urlpatterns = [
path('admin/videos', views.admin_video_list, name='admin_video_list'),
path('admin/videos/create', views.admin_video, name='admin_video_create'),
path('admin/videos/<int:id>', views.admin_video, name='admin_video'),
path('admin/videocollections', views.admin_videocollections, name='admin_videocollections'),
path('admin/videocollections/create', views.admin_videocollection, name='admin_videocollection_create'),
path('admin/videocollections/<int:id>', views.admin_videocollection, name='admin_videocollection'),
path('admin/articles/<int:id>', views.admin_article, name='admin_article'),
path('admin/events/create', views.admin_article, {'type': 'event'}, name='admin_article'),
path('admin/articles/create/parent=<int:parent>', views.admin_article, name='admin_article_parent'),
path('admin/project/create', views.admin_project, name='admin_project_create'),
path('admin/project/<int:id>', views.admin_project, name='admin_project'),
path('admin/projects', views.admin_project_list, name='admin_project_list'),
path('admin/projects/<slug:status>', views.admin_project_list, name='admin_project_list'),
path('admin/tags', views.admin_tag_list, name='admin_tag_list'),
path('admin/tags/create', views.admin_tag, name='admin_tag'),
path('admin/tags/<int:id>', views.admin_tag, name='admin_tag'),
......
from django.shortcuts import render, get_object_or_404, redirect
from django.urls import reverse
from .models import Video, Journal, Organization, Publisher, Reference, ReferenceForm, ReferenceFormAdmin, People, Article, PeopleForm, Video, VideoForm, ReferenceOrganization, Project, UserAction, UserLog, SimpleArticleForm, ProjectForm, EventForm, ReferenceType, Tag, Event, TagForm, OrganizationForm
from .models import Journal, Organization, Publisher, Reference, ReferenceForm, ReferenceFormAdmin, People, Article, PeopleForm, Video, VideoForm, ReferenceOrganization, Project, UserAction, UserLog, SimpleArticleForm, ProjectForm, ProjectUserForm, EventForm, ReferenceType, Tag, Event, TagForm, OrganizationForm, VideoCollection, VideoCollectionForm
from team.models import Category, TaskForceMember, TaskForceTicket, TaskForceUnit
from multiplicity.models import ReferenceSpace
from staf.models import Data, Process
......@@ -9,7 +9,7 @@ from django.contrib.auth.decorators import login_required
from django.db.models import Count
from django.contrib import messages
from django.db.models import Q
from django.http import JsonResponse
from django.http import JsonResponse, HttpResponse
from django.contrib.auth.models import User
from django.contrib.auth import login
from django.contrib.sites.models import Site
......@@ -442,7 +442,7 @@ def updateorgs(request):
info.type = 'universities'
info.parent = Organization.objects.get(pk=49)
info.save()
if info.id == 51:
info.parent = Organization.objects.get(pk=57)
info.name = "Department of Environmental & Geographical Science"
......@@ -493,22 +493,75 @@ def updateorgs(request):
context = { 'section': 'literature', 'page': 'journals', 'list': list}
return render(request, 'core/empty.html', context)
def projects(request, type, page, status=False):
def projects(request, type, status=False):
if status:
list = Project.on_site.filter(type=type, status=status)
else:
list = Project.on_site.filter(type=type)
if request.site.id == 1:
if type == 'projects':
page = 50
elif type == 'theses':
page = 57
elif request.site.id == 2:
if type == 'projects':
page = 149
elif type == 'theses':
page = 148
page = get_object_or_404(Article, pk=page)
addlink = reverse('core:admin_project_create')
context = { 'section': 'community', 'list': list, 'page': page, 'addlink': addlink }
return render(request, 'core/projects.html', context)
def project_view(request, type, status, id):
def project(request, type, id):
info = get_object_or_404(Project, pk=id)
editlink = reverse('core:admin_project', args=[info.id])
context = { 'section': 'community', 'list': list, 'info': info, 'editlink': editlink}
references = info.references.all()
context = { 'section': 'community', 'list': list, 'info': info, 'editlink': editlink, 'references': references}
return render(request, 'core/project.view.html', context)
def project_form(request, id=False):
if request.site.id == 1:
page = 50
else:
page = 50
if id:
info = get_object_or_404(Project, pk=id)
form = ProjectUserForm(instance=info)
else:
info = False
form = ProjectUserForm()
if request.method == 'POST':
if not id:
new_record = True
form = ProjectUserForm(request.POST)
else:
form = ProjectUserForm(request.POST, instance=info)
if form.is_valid():
info = form.save(commit=False)
info.site = request.site
info.save()
if new_record:
create_record = get_object_or_404(UserAction, pk=1)
log = UserLog(user=request.user, action=create_record, model='Research', points=5, description=info.name)
info.pending_review = True
info.save()
# Must send mail to admins!
else:
edit_record = get_object_or_404(UserAction, pk=2)
log = UserLog(user=request.user, action=edit_record, model='Research', points=1, description=info.name)
messages.success(request, 'We have received your submitted. We will review your project and activate it shortly if it is relevant to the website. Thanks!')
return redirect('core:project', id=info.id, type=info.type)
else:
messages.error(request, 'We could not save your form, please correct the errors')
context = { 'section': 'community', 'page': 'research', 'info': info, 'form': form }
return render(request, 'core/project.form.html', context)
def reference_search_ajax(request, active_only=False):
if active_only:
references = Reference.objects.filter(title__icontains=request.GET['term'],status='active').order_by('title')
......@@ -612,13 +665,30 @@ def admin_project(request, id=False):
info = form.save(commit=False)
info.site = request.site
info.save()
info.references.clear()
selected = request.POST.getlist('references')
for reference in selected:
info.references.add(Reference.objects.get(pk=reference))
messages.success(request, 'Information was saved.')
return redirect(reverse('core:project', args=[info.id]))
else:
messages.error(request, 'We could not save your form, please correct the errors')
context = { 'navbar': 'backend', 'form': form, 'info': info, 'tinymce': True }
context = { 'navbar': 'backend', 'form': form, 'info': info, 'tinymce': True, 'select2': True }
return render(request, 'core/admin/project.html', context)
@staff_member_required
def admin_project_list(request, status='published'):
if status == 'published':
list = Project.on_site.filter(active=True, pending_review=False)
elif status == 'deleted':
list = Project.on_site.filter(active=False, pending_review=False)
elif status == 'pending':
list = Project.on_site.filter(pending_review=True)
context = { 'navbar': 'backend', 'list': list, 'datatables': True, 'tab': status }
return render(request, 'core/admin/project.list.html', context)
@staff_member_required
def admin_tag_list(request):
......@@ -688,6 +758,38 @@ def admin_video(request, id=False):
return render(request, 'core/admin/video.html', context)
@staff_member_required
def admin_videocollections(request):
list = VideoCollection.on_site.all()
context = { 'navbar': 'backend', 'list': list, 'datatables': True }
return render(request, 'core/admin/videocollections.html', context)
@staff_member_required
def admin_videocollection(request, id=False):
if id:
info = get_object_or_404(VideoCollection, pk=id)
form = VideoCollectionForm(instance=info)
else:
info = False
form = VideoCollectionForm()
if request.method == 'POST':
if not id:
form = VideoCollectionForm(request.POST)
else:
form = VideoCollectionForm(request.POST, instance=info)
if form.is_valid():
info = form.save(commit=False)
if not id:
info.site = request.site
info.save()
messages.success(request, 'Information was saved.')
return redirect(reverse('core:admin_videocollections'))
else:
messages.error(request, 'We could not save your form, please correct the errors')
context = { 'navbar': 'backend', 'form': form, 'info': info }
return render(request, 'core/admin/videocollection.html', context)
@staff_member_required
def admin_organization_list(request):
list = Organization.on_site.all()
......
# Generated by Django 2.1.3 on 2019-01-19 09:11
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('multiplicity', '0032_auto_20181219_1146'),
]
operations = [
migrations.AddField(
model_name='photo',
name='secondary_space',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='photos', to='multiplicity.ReferenceSpace'),
),
migrations.AlterField(
model_name='photo',
name='primary_space',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='photo_gallery', to='multiplicity.ReferenceSpace'),
),
]
# Generated by Django 2.1.3 on 2019-01-19 13:02
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('multiplicity', '0033_auto_20190119_0911'),
]
operations = [
migrations.RemoveField(
model_name='referencespace',
name='image',
),
]
# Generated by Django 2.1.3 on 2019-01-20 07:46
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('multiplicity', '0034_remove_referencespace_image'),
]
operations = [
migrations.AddField(
model_name='feature',
name='exclusively_for',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='multiplicity.ReferenceSpace'),
),
]
# Generated by Django 2.1.3 on 2019-01-21 13:48
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('multiplicity', '0035_feature_exclusively_for'),
]
operations = [
migrations.AddField(
model_name='information',
name='topic',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='multiplicity.Topic'),
),
]
......@@ -130,13 +130,12 @@ class ReferenceSpace(models.Model):
description = models.TextField(null=True, blank=True)
url = models.CharField(max_length=255, null=True, blank=True)
slug = models.SlugField(db_index=True, max_length=255, null=True)
image = models.ImageField(null=True, blank=True, upload_to='referencespace')
location = models.ForeignKey('multiplicity.ReferenceSpaceLocation', on_delete=models.SET_NULL, null=True, blank=True)
csv = models.ForeignKey('multiplicity.ReferenceSpaceCSV', on_delete=models.CASCADE, null=True, blank=True)
tag = models.ForeignKey('core.Tag', on_delete=models.CASCADE, null=True, blank=True)
def __str__(self):
return self.name
return self.name + " (" + self.type.name + ")"
def save(self, *args, **kwargs):
if not self.id:
# Newly created object, so set slug
......@@ -149,7 +148,7 @@ class ReferenceSpace(models.Model):
class ReferenceSpaceForm(ModelForm):
class Meta:
model = ReferenceSpace
fields = ['name', 'type', 'country', 'image']
fields = ['name', 'type', 'country']
class ReferenceSpaceLocation(models.Model):
name = models.CharField(max_length=255, null=True, blank=True)
......@@ -176,6 +175,7 @@ class Feature(models.Model):
description = models.TextField(null=True, blank=True)
type = models.ForeignKey(ReferenceSpaceType, on_delete=models.CASCADE)
unit = models.ForeignKey('staf.Unit', on_delete=models.CASCADE, null=True, blank=True)
exclusively_for = models.ForeignKey(ReferenceSpace, on_delete=models.CASCADE, null=True, blank=True)
show_in_table = models.BooleanField(default=False)
def __str__(self):
return self.name
......@@ -243,7 +243,8 @@ class Photo(TimestampedModel):
source_url = models.CharField(max_length=255, null=True, blank=True)
process = models.ForeignKey('staf.Process', on_delete=models.CASCADE, null=True, blank=True, limit_choices_to={'slug__isnull': False})
description = models.TextField(null=True, blank=True)
primary_space = models.ForeignKey(ReferenceSpace, on_delete=models.CASCADE)
primary_space = models.ForeignKey(ReferenceSpace, on_delete=models.CASCADE, related_name='photo_gallery') # This is the main system this photo belongs to
secondary_space = models.ForeignKey(ReferenceSpace, on_delete=models.CASCADE, related_name='photos', null=True, blank=True) # A specific space (e.g. Airport or Factory) this photo belongs to
uploaded_by = models.ForeignKey(User, on_delete=models.CASCADE)
deleted = models.BooleanField(default=False, db_index=True)
license = models.ForeignKey(License, on_delete=models.CASCADE, null=True, blank=True)
......@@ -262,7 +263,8 @@ class PhotoForm(ModelForm):
model = Photo
exclude = ['id', 'uploaded_by', 'primary_space', 'process']
labels = {
'deleted': 'Do not show in the gallery'
'deleted': 'Do not show in the gallery',
'secondary_space': 'Reference space (optional)'
}
class ReferencePhoto(models.Model):
......@@ -287,6 +289,8 @@ class Information(TimestampedModel):
references = models.ManyToManyField("core.Reference", blank=True)
dataset_types = models.ManyToManyField(DatasetType, blank=True, limit_choices_to={'active': True})
process = models.ForeignKey("staf.Process", on_delete=models.CASCADE, blank=True, null=True, limit_choices_to={'slug__isnull': False})
topic = models.ForeignKey(Topic, on_delete=models.CASCADE, null=True, blank=True)
def __str__(self):
return self.title
......
......@@ -89,7 +89,7 @@ h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6, #page-title{color:#333}
.leaflet-popup-content{text-align:center}
.legend img{position:relative;top:6px}
#editpagebutton,#controlpanelbutton, #addpagebutton, #datasetbutton, #deletepagebutton, #editextrabutton {
#editpagebutton,#controlpanelbutton, #addpagebutton, #datasetbutton, #deletepagebutton, #editextrabutton, #photouploadlink {
display: inline-block;
background-color: #3a444e;
border-radius: 7px 0 0 7px !important;
......@@ -116,6 +116,9 @@ h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6, #page-title{color:#333}
#datasetbutton {
top:350px;
}
#photouploadlink {
top:450px;
}
#deletepagebutton {
top:auto;
bottom:20px;
......@@ -125,7 +128,7 @@ h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6, #page-title{color:#333}
opacity:1;
background-color:red;
}
#editpagebutton i,#controlpanelbutton i,#addpagebutton i, #datasetbutton i, #deletepagebutton i, #editextrabutton i{
#editpagebutton i,#controlpanelbutton i,#addpagebutton i, #datasetbutton i, #deletepagebutton i, #editextrabutton i, #photouploadlink i{
font-size: 25px;
display: block;
margin: 5px 0;
......
......@@ -41,6 +41,9 @@ urlpatterns = [
#path('<slug:city>/material-flows/<slug:slug>/<slug:type>', views.flow, name='flow'),
#path('<slug:city>/material-stocks', views.overview, {'slug': 'material-stocks' }, name='overview_stocks'),
path('<slug:city>/profile/<slug:topic>', views.topic, name='topic'),
#path('<slug:city>/<slug:topic>', views.topic, name='topic'),
path('<slug:city>/maps', views.map, name='map_home'),
path('<slug:city>/maps/<slug:type>', views.map, name='map'),
path('<slug:city>/datasets', views.datasets, name='datasets'),
......@@ -73,10 +76,10 @@ urlpatterns = [
path('<slug:city>/upload/flow/<int:type>/<int:id>/meta', views.upload_flow_meta, name='upload_flow_meta'),
path('<slug:city>/upload/stock', views.upload_flow, {'type': 'stocks'}, name='upload_stock'),
path('<slug:city>/<slug:topic>', views.topic, name='topic'),
path('<slug:city>/infrastructure/<slug:topic>/<slug:type>/<slug:space>', views.space, name='space'),
path('<slug:city>/infrastructure/<slug:topic>/<slug:type>', views.space_list, name='space_list'),
path('<slug:city>/infrastructure/<slug:type>/<slug:space>', views.space, name='space'),
path('<slug:city>/infrastructure/<slug:type>', views.space_list, name='space_list'),
path('<slug:city>/infrastructure/<slug:topic>', views.infrastructure_list, name='infrastructure_list'),
path('<slug:city>/infrastructure', views.infrastructure_list, name='infrastructure_list'),
path('<slug:city>/<slug:main>/<slug:topic>', views.topic, name='subtopic'),
path('<slug:city>/<slug:main>/<slug:topic>/input', views.topic, {'tab': 'input'}, name='subtopic_input'),
path('<slug:city>/<slug:main>/<slug:topic>/use', views.topic, {'tab': 'use' }, name='subtopic_use'),
......
This diff is collapsed.
......@@ -16,6 +16,18 @@
<h2>{{ info|yesno:"Edit details,Add new project" }}</h2>
<form method="post" class="form form-horizontal boxit pad-all" enctype="multipart/form-data">
{% bootstrap_form form layout='horizontal' %}
<div class="form-group">
<label class="col-md-3 control-label" for="id_url">Publication(s)</label>
<div class="col-md-9">
<select id="references" name="references" width="100%" class="form-control" multiple>
{% for details in info.references.all %}
<option value="{{ details.id }}" selected>{{ details.title }} ({{ details.year }})</option>
{% endfor %}
</select>
</div>
</div>
{% buttons %}
<div class="col-sm-offset-3 col-sm-9">
<button type="submit" class="btn btn-success">Save</button>
......@@ -42,6 +54,19 @@
$(function(){
$("#id_start_date").attr("type", "date");
$("#id_end_date").attr("type", "date");
$('#references').select2({
width: '100%',
ajax: {
url: '{% url 'core:reference_search_ajax' %}',
dataType: 'json',
processResults: function (data) {
return {
results: data
};
},
}
});
});
</script>
{% endblock %}
{% extends 'multiplicity/base.html' %}
{% load static %}
{% block title %}Projects{% endblock %}
{% block container %}stretch-bg-head{% endblock %}
{% block content %}
<ol class="breadcrumb">
<li><a href="./"><i class="pli-home"></i></a></li>
<li><a href="{% url 'team:controlpanel' %}">Back-end</a></li>
<li class="active">Projects</li>
</ol>
<h3>Projects</h3>
<ul class="nav nav-tabs">
<li {% if tab == 'published' %} class="active"{% endif %}><a href="{% url 'core:admin_project_list' 'published' %}">Published</a></li>
<li {% if tab == 'pending' %} class="active"{% endif %}><a href="{% url 'core:admin_project_list' 'pending' %}">Pending review</a></li>
<li {% if tab == 'deleted' %} class="active"{% endif %}><a href="{% url 'core:admin_project_list' 'deleted' %}">Deleted</a></li>
</ul>
<div class="row">
<div class="col-lg-12">
<div class="boxit pad-all">
<table class="table table-striped datatable">
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Status</th>
</tr>
</thead>
<tbody>
{% for details in list %}
<tr>
<td><a href="{% url 'core:admin_project' details.id %}">{{ details.name|truncatewords:10 }}</a></td>
<td>{{ details.get_type_display }}</td>
<td>{{ details.get_status_display }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
<p class="pad-top"><a href="{% url 'core:admin_project_create' %}" class="btn btn-success"><i class="fas fa-plus fa-fw"></i> Add new project</a></p>
</div>
{% endblock %}
{% block head %}
{% endblock %}
{% block sidebar %}
{% include 'multiplicity/sidebar.default.html' %}
{% endblock %}
{% block footer %}
{% endblock %}
......@@ -56,6 +56,7 @@
<script type="text/javascript">
$(function(){
$("#id_date").attr("type", "date");
$("#id_primary_space").select2();
$("#id_website").attr("placeholder", "'youtube' or 'vimeo' (lowercase, no spaces, no quotation marks)");
$('#id_description').summernote({
height : '230px'
......
{% extends 'multiplicity/base.html' %}
{% load bootstrap3 %}
{% load static %}
{% block title %}Video{% endblock %}
{% block container %}stretch-bg-head{% endblock %}
{% block content %}
<ol class="breadcrumb">
<li><a href="./"><i class="pli-home"></i></a></li>
<li><a href="{% url 'team:controlpanel' %}">Back-end</a></li>
<li><a href="{% url 'core:admin_videocollections' %}">Video Collections</a></li>
{% if info.id %}
<li class="active">{{ info.title }}</li>
{% else %}
<li class="active">Create new video collection</li>
{% endif %}
</ol>
<h2>{{ info|yesno:"Edit details,Add new video collection" }}</h2>
<form method="post" class="form form-horizontal boxit pad-all" enctype="multipart/form-data">
{% bootstrap_form form layout='horizontal' %}
{% buttons %}
<div class="col-sm-offset-3 col-sm-9">
<button type="submit" class="btn btn-success">Save</button>
</div>
{% endbuttons %}
{% csrf_token %}
</form>
{% endblock %}
{% block head %}
<link rel="stylesheet" href="{% static 'ie/js/summernote/summernote.min.css' %}" />
{% endblock %}
{% block sidebar %}
{% include 'multiplicity/sidebar.default.html' %}
{% endblock %}
{% block footer %}
<script type="text/javascript" src="{% static 'ie/js/summernote/summernote.min.js' %}"></script>
<script type="text/javascript">
$(function(){
$('#id_description').summernote({
height : '230px'
});
});
</script>
{% endblock %}
{% extends 'multiplicity/base.html' %}
{% load static %}
{% block title %}Video Collections{% endblock %}
{% block container %}stretch-bg-head{% endblock %}
{% block content %}
<ol class="breadcrumb">
<li><a href="./"><i class="pli-home"></i></a></li>
<li><a href="{% url 'team:controlpanel' %}">Back-end</a></li>
<li class="active">Video Collections</li>
</ol>
<h3>Video Collections</h3>
<div class="row">
<div class="col-lg-12">
<div class="boxit pad-all">
<table class="table table-striped datatable">
<thead>
<tr>
<th>Title</th>
<th>Options</th>
</tr>
</thead>
<tbody>
{% for details in list %}
<tr>
<td>{{ details.title }}</td>
<td><a class="btn btn-info" href="{% url 'core:admin_videocollection' details.id %}"><i class="fa fa-pencil"></i> Edit</a></td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
<p class="pad-top"><a href="{% url 'core:admin_videocollection_create' %}" class="btn btn-success"><i class="fas fa-plus fa-fw"></i> Add new video collection</a></p>
</div>
{% endblock %}
{% block head %}
{% endblock %}
{% block sidebar %}
{% include 'multiplicity/sidebar.default.html' %}
{% endblock %}
{% block footer %}
{% endblock %}
<div class="modal fade" id="bibtex-modal" tabindex="-1" role="dialog" aria-labelledby="Bibtex" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
<h4 class="modal-title">Bibtex</h4>
</div>
<div id="form-modal-body" class="modal-body">
<pre id="bibtex-ref">@article{reference_tag,
author = "{{info.authorlist}}",
title = "{{info.title}}",{% if info.journal %}
journal = "{{info.journal}}",{% endif %}
year = {{info.year}},{% if info.url %}url = "{{info.url}}",{% endif %}{% if info.doi %}
doi = "{{info.doi}}",{% endif %}
}</pre>
</div>
<div class="modal-footer">
<span id="bibtex-success" class="success">
</span>
<button type="button" class="btn btn-success copy" data-target="bibtex-ref" data-success="bibtex-success">Copy</button>
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
......@@ -49,8 +49,6 @@
<ul class="list-unstyled">
<li><a href="{% url 'core:organizations' 'universities' %}">Universities</a></li>
<li><a href="{% url 'core:community' 'people' %}">People</a></li>
<li><a href="{% url 'core:research_projects' %}">Current Research</a></li>
<li><a href="{% url 'core:past_research_projects' %}">Past Research</a></li>
</ul>
<p class="pad-top text-main text-sm text-uppercase text-bold"><i class="icon-lg psi-hotel icon-fw"></i>Non-academic</p>
<ul class="list-unstyled">
......@@ -59,11 +57,11 @@
</ul>
</div>
<div class="col-md-6">
<p class="pad-top text-main text-sm text-uppercase text-bold"><i class="icon-lg pli-open-book icon-fw"></i>Projects</p>
<p class="pad-top text-main text-sm text-uppercase text-bold"><i class="icon-lg pli-open-book icon-fw"></i>Research</p>
<ul class="list-unstyled">
<li><a href="{% url 'core:projects' %}">Current Projects</a></li>
<li><a href="{% url 'core:past_projects' %}">Past Projects</a></li>
<li><a href="{% url 'core:community' 'createprojects' %}"><span class="pull-right label label-success">Contribute</span>Add Projects</a></li>
<li><a href="{% url 'core:projects' 'projects' %}">Research Projects</a></li>
<li><a href="{% url 'core:projects' 'theses' %}">Theses</a></li>
<li><a href="{% url 'core:project_form' %}"><span class="pull-right label label-success">Contribute</span>Add Research</a></li>
</ul>
<p class="pad-top text-main text-sm text-uppercase text-bold"><i class="icon-lg psi-bulleted-list icon-fw"></i>Updates</p>
<ul class="list-unstyled">
......
......@@ -26,8 +26,8 @@
</a>
<div class="dropdown-menu dropdown-menu-sm dropdown-menu-right panel-default">
<ul class="head-list">
<li><a href="/research/projects">Projects</a></li>
<li><a href="/research/theses">Theses</a></li>
<li><a href="{% url 'core:projects' 'projects' %}">Research Projects</a></li>
<li><a href="{% url 'core:projects' 'theses' %}">Theses</a></li>
</ul>
</div>
......
<div class="modal fade" id="ris-modal" tabindex="-1" role="dialog" aria-labelledby="RIS" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
<h4 class="modal-title">RIS</h4>
</div>
<div id="form-modal-body" class="modal-body">
<pre id="ris-ref">TY - JOUR
T1 - {{info.title}}
AU - {{info.authorlist}}
Y1 - {{info.year}}{% if info.url %}
UR - {{info.url}}{% endif %}{% if info.doi %}
DO - {{info.doi}}{% endif %}
N2 - {{info.abstract}}
ER - </pre>
</div>
<div class="modal-footer">
<span id="ris-success" class="success">
</span>
<button type="button" class="btn btn-success copy" data-target="ris-ref" data-success="ris-success">Copy</button>
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
......@@ -27,13 +27,13 @@
<div class="col-lg-4">
<div class="panel widget">
<div class="widget-header bg-purple city-header slideshow photos">
<img class="widget-bg img-responsive" src="https://prototype.metabolismofislands.org/media/referencespace/English_Barbour_Antigua_resized_800_p.jpg" />
<img class="widget-bg img-responsive" src="https://prototype.metabolismofislands.org/media/referencespace/Trinket.jpg" alt="">
<img class="widget-bg img-responsive" src="https://metabolismofislands.org/media/referencespace/English_Barbour_Antigua_resized_800_p.jpg" />
<img class="widget-bg img-responsive" src="https://metabolismofislands.org/media/referencespace/Trinket.jpg" alt="">
</div>
<div class="widget-body text-center">
<div class="slideshow maps">
<img alt="" class="widget-img img-circle img-border-light" src="https://prototype.metabolismofislands.org/static/multiplicity/img/cities/map-antigua-barbuda.jpg">
<img alt="" class="widget-img img-circle img-border-light" src="https://prototype.metabolismofislands.org/static/multiplicity/img/cities/map-antwerp.jpg">
<img alt="" class="widget-img img-circle img-border-light" src="https://metabolismofislands.org/static/multiplicity/img/cities/map-antigua-barbuda.jpg">
<img alt="" class="widget-img img-circle img-border-light" src="https://metabolismofislands.org/static/multiplicity/img/cities/map-antwerp.jpg">
</div>
<h4 class="mar-no text-main island-name">Samothraki</h4>
<p class="text-muted mar-no island-area">Europe</p>
......@@ -107,7 +107,7 @@
<ul class="list-group bg-trans list-todo mar-no">
{% for details in projects %}
<li class="list-group-item">
<a href="{% url 'core:project' details.id %}">{{ details.name }}</a><br>
<a href="{% url 'core:project' details.type details.id %}">{{ details.name }}</a><br>
</li>
{% endfor %}
</ul>
......
{% extends 'multiplicity/base.html' %}
{% load bootstrap3 %}
{% load static %}
{% block title %}{% if info %}Edit{% else %}Add{% endif %} Research{% endblock %}
{% block container %}stretch-bg-head{% endblock %}
{% block content %}
<div class="row">
<div class="col-lg-12">
<div class="panel panel-body">
<div class="panel-heading">
<h3>{% if info %}Edit{% else %}Add{% endif %} research</h3>
</div>
<div class="panel-body">
<form method="post" class="form form-horizontal">
{% csrf_token %}
{% bootstrap_form form layout='horizontal' %}
{% buttons %}
<div class="col-sm-offset-3 col-sm-9">
<button type="submit" class="btn btn-success">Save</button>
</div>
{% endbuttons %}
</form>
</div>
</div>
</div>
</div>
{% endblock %}
{% block head %}
{% endblock %}
{% block sidebar %}
{% include 'multiplicity/sidebar.default.html' %}
{% endblock %}
{% block pagehead %}
<div id="page-head">
<div id="page-title">
<h1 class="page-header text-overflow">{% if info %}Edit{% else %}Add{% endif %} research</h1>
</div>
<ol class="breadcrumb">
<li><a href="./"><i class="pli-home"></i></a></li>
{% if SITE_ID == 1 %}
<li><a href="{% url 'core:community_home' %}">Community</a></li>
{% else %}
<li><a href="{% url 'core:section_home' 'research' %}">Research</a></li>
{% endif %}
<li class="active">Add research</li>
</ol>
</div>
{% endblock %}
{% block footer %}
<script type="text/javascript">
$(function(){
$("#id_start_date").attr("type", "date");
$("#id_end_date").attr("type", "date");
$("option[value=applied]").hide();
$("#id_type").change(function(){
if ($(this).val() != "theses") {
$("#id_thesistype").closest(".form-group").hide('fast');
} else {
$("#id_thesistype").closest(".form-group").show('fast');
}
});
});
</script>{% endblock %}
......@@ -20,6 +20,12 @@
<p>{{ info.description|safe }}</p>
</div>
</div>
{% if references %}
<h4 style="margin-top:50px">Related publications</h4>
{% include 'core/includes/references.list.html' %}
{% endif %}
</div>
<div class="col-lg-6">
<div class="panel panel-body panel-colorful panel-default">
......@@ -81,13 +87,10 @@
</div>
<p>
{% if info.status == 'ongoing' %}
<a href="{% url 'core:research_projects' %}" class="btn btn-info">
{% else %}
<a href="{% url 'core:past_research_projects' %}" class="btn btn-info">
{% endif %}
Back to list</a></p>
<a href="{% url 'core:projects' info.type %}" class="btn btn-info">
Back to list
</a>
</p>
{% endblock %}
......@@ -107,19 +110,7 @@ Back to list</a></p>
<div id="page-title">
<h1 class="page-header text-overflow">
{% if SITE_ID == 1 %}
{% if info.status == 'ongoing' %}
Current Research
{% else %}
Past Research
{% endif %}
{% else %}
{% if info.type == 'regular' %}
Projects
{% else %}
Theses
{% endif %}
{% endif %}
{{ info.get_type_display }}
</h1>
</div>
......@@ -127,19 +118,10 @@ Back to list</a></p>
<li><a href="./"><i class="pli-home"></i></a></li>
{% if SITE_ID == 1 %}
<li><a href="{% url 'core:community_home' %}">Community</a></li>
{% if info.status == 'ongoing' %}
<li><a href="{% url 'core:research_projects' %}">Current Research</a></li>
{% else %}
<li><a href="{% url 'core:past_research_projects' %}">Past Research</a></li>
{% endif %}
{% else %}
<li><a href="{% url 'core:section_home' 'research' %}">Research</a></li>
{% if info.type == 'regular' %}
<li><a href="{% url 'core:regular_research_projects' %}">Projects</a></li>
{% else %}
<li><a href="{% url 'core:theses_research_projects' %}">Theses</a></li>
{% endif %}
{% endif %}
<li><a href="{% url 'core:projects' info.type %}">{{ info.get_type_display }}</a></li>
<li class="active">{{ info.name|truncatechars:40 }}</li>
</ol>
......
......@@ -32,7 +32,7 @@
<tbody>
{% for details in list %}
<tr>
<td><a href="{% url 'core:research_project' details.id %}">{{ details.name }}</a></td>
<td><a href="{% url 'core:project' details.type details.id %}">{{ details.name }}</a></td>
<td>{{ details.researcher }}</td>
<td>{{ details.institution }}</td>
</tr>
......
{% extends 'multiplicity/base.html' %}
{% load static %}
{% block title %}{{ info.title }} | Publications | {% endblock %}
......@@ -6,6 +7,9 @@
{% block content %}
{% include 'core/includes/bibtex.html' %}
{% include 'core/includes/ris.html' %}
{% if request.user.is_staff %}
<a title="Edit tags" href="{% url 'core:admin_referencetags' info.id %}" id="editextrabutton" class="btn"><i class="psi-tag"></i></a>
{% endif %}
...