diff --git a/assets/src/components/ResultCard.js b/assets/src/components/ResultCard.js
index 6af3a567..4b3f21ce 100644
--- a/assets/src/components/ResultCard.js
+++ b/assets/src/components/ResultCard.js
@@ -1,158 +1,179 @@
import React from "react"
import { makeStyles } from '@material-ui/core/styles';
import TermCard from "../components/TermCard"
import Accordion from '@material-ui/core/Accordion';
import AccordionSummary from '@material-ui/core/AccordionSummary';
import AccordionDetails from '@material-ui/core/AccordionDetails';
import Typography from '@material-ui/core/Typography';
import ExpandMoreIcon from '@material-ui/icons/ExpandMore';
import Badge from '@material-ui/core/Badge';
import DescriptionIcon from '@material-ui/icons/Description'
import { HiOutlineDocumentDuplicate } from "react-icons/hi";
import { HiOutlineDocument } from "react-icons/hi";
const useStyles = makeStyles((theme) =>({
card: {
width: '100%',
marginTop: "1rem",
},
root: {
flexGrow: 1,
},
chip: {
margin: 0.5,
},
heading: {
fontSize: theme.typography.pxToRem(15),
fontWeight: theme.typography.fontWeightRegular,
},
}))
function ResultCard({result}) {
const classes = useStyles();
//create one array to organize the frontend output
const termresult = []
const termArray = result?.map(i=>(
// get condition details
i.term?.map(j =>(
// termresult.push([j, i.id, i.comment, i.condition_type])
termresult.push([j, [i.id, i.comment, i.condition_type]])
))
))
//groupyBy array
function groupBy(objectArray, property) {
// console.log(objectArray)
return objectArray.reduce((acc, obj) => {
// console.log(obj[0])
const key = obj[0][property][0].description;
if (!acc[key]) {
acc[key] = [];
}
// Add object to list for given key's value
acc[key].push(obj);
return acc;
}, {});
}
const groupedTerm = groupBy(termresult, 'version')
//first version
// console.log(groupedTerm[1])
//convert object into array
-const termItem = Object.entries(groupedTerm);
+const termItem = Object.entries(groupedTerm)
+//manage the display order
+
+function orderVersion (version) {
+ if (version[0] ==="Submitted version") {
+
+ version.unshift(3)
+ }
+ else if (version[0] === "Published version") {
+ version.unshift(1)
+ }
+ else if (version[0] === "Accepted version") {
+ version.unshift(2)
+ }
+}
+//apply the function for each version
+termItem?.map(i=>(
+ orderVersion(i)
+ ))
+
+termItem.sort()
+
console.log(termItem)
const displayVersion =
termItem?.map(item =>(
}
aria-controls="panel1a-content"
id="panel1a-header"
>
{item?.map(i => (
{typeof i === "string" && i} {typeof i === "object" && i.length > 1 ? : typeof i === "object" && }
))
}
{item?.map(j => (
{typeof j === "object" &&
j?.map(k => (
))
}
))
}
))
return (
//level 0
{displayVersion}
)
}
export default ResultCard
\ No newline at end of file
diff --git a/conf/nginx-app.conf b/conf/nginx-app.conf
index cba9c761..58039a7a 100644
--- a/conf/nginx-app.conf
+++ b/conf/nginx-app.conf
@@ -1,140 +1,140 @@
# nginx-app.conf
# Enable CORS for selected origins
# map instead of many if's
map $http_origin $cors {
default "null";
"https://www.test-cors.org" $http_origin;
"https://www.epfl.ch" $http_origin;
"http://127.0.0.1" $http_origin;
"https://localhost" $http_origin;
}
# the upstream component nginx needs to connect to
upstream django {
server unix:/oacct_checker/app.sock; # for a file socket
# server 127.0.0.1:8001; # for a web port socket (we'll use this first)
}
server {
listen 8080 default_server;
#listen [::]:80 ;
server_name 127.0.0.1;
## Redirige le HTTP vers le HTTPS ##
#return 301 https://$server_name$request_uri;
add_header "Content-Security-Policy" "default-src 'self' https://web2018.epfl.ch https://cdn.datatables.net";
add_header "Strict-Transport-Security" "max-age=31536000";
# Django media; not needed in this project
location /media {
alias /oacct_checker; # your Django project's media files - amend as required
}
location /static {
alias /oacct_checker/staticfiles; # your Django project's static files - amend as required
# Simple requests
if ($request_method ~* "(GET|POST)") {
add_header "Access-Control-Allow-Origin" "$cors";
}
# Preflighted requests
if ($request_method = OPTIONS ) {
add_header "Access-Control-Allow-Origin" "$cors";
add_header "Access-Control-Allow-Methods" "GET, POST, OPTIONS, HEAD";
add_header "Access-Control-Allow-Headers" "Authorization, Origin, X-Requested-With, Content-Type, Accept";
return 200;
}
}
# Finally, send all non-media requests to the Django server.
location / {
uwsgi_pass django;
include /oacct_checker/conf/uwsgi_params; # the uwsgi_params file you installed
# Simple requests
if ($request_method ~* "(GET|POST)") {
add_header "Access-Control-Allow-Origin" "$cors";
}
# Preflighted requests
if ($request_method = OPTIONS ) {
add_header "Access-Control-Allow-Origin" "$cors";
add_header "Access-Control-Allow-Methods" "GET, POST, OPTIONS, HEAD";
add_header "Access-Control-Allow-Headers" "Authorization, Origin, X-Requested-With, Content-Type, Accept";
return 200;
}
}
}
# configuration of the server
server {
# the port your site will be served on, default_server indicates that this server block
# is the block to use if no blocks match the server_name
# SSL configuration
listen 4443 ssl http2 default_server;
listen [::]:4443 ssl http2 ;
include snippets/self-signed.conf;
include snippets/ssl-params.conf;
# the domain name it will serve for
server_name 127.0.0.1; # substitute your machine's IP address or FQDN
charset utf-8;
# max upload size
client_max_body_size 75M; # adjust to taste
add_header "Content-Security-Policy" "default-src 'self' https://web2018.epfl.ch https://cdn.datatables.net";
add_header "Strict-Transport-Security" "max-age=31536000";
# Django media
location /media {
alias /oacct_checker; # your Django project's media files - amend as required
}
location /static {
alias /oacct_checker/staticfiles; # your Django project's static files - amend as required
# Simple requests
if ($request_method ~* "(GET|POST)") {
add_header "Access-Control-Allow-Origin" "$cors";
}
# Preflighted requests
if ($request_method = OPTIONS ) {
add_header "Access-Control-Allow-Origin" "$cors";
add_header "Access-Control-Allow-Methods" "GET, POST, OPTIONS, HEAD";
add_header "Access-Control-Allow-Headers" "Authorization, Origin, X-Requested-With, Content-Type, Accept";
return 200;
}
}
# Finally, send all non-media requests to the Django server.
location / {
uwsgi_pass django;
include /oacct_checker/conf/uwsgi_params; # the uwsgi_params file you installed
# default timout of 60s too short for significant JSON uploads?
- uwsgi_read_timeout 180s;
+ uwsgi_read_timeout 300s;
uwsgi_send_timeout 300s;
# Simple requests
if ($request_method ~* "(GET|POST)") {
add_header "Access-Control-Allow-Origin" "$cors";
}
# Preflighted requests
if ($request_method = OPTIONS ) {
add_header "Access-Control-Allow-Origin" "$cors";
add_header "Access-Control-Allow-Methods" "GET, POST, OPTIONS, HEAD";
add_header "Access-Control-Allow-Headers" "Authorization, Origin, X-Requested-With, Content-Type, Accept";
return 200;
}
}
}
diff --git a/django_api/admin.py b/django_api/admin.py
index e7bdaf0e..f279f4f1 100644
--- a/django_api/admin.py
+++ b/django_api/admin.py
@@ -1,237 +1,237 @@
from django.contrib import admin
from datetime import date
from import_export.admin import ImportExportModelAdmin
from django.contrib.admin import TabularInline
#from inline_actions.admin import InlineActionsMixin
#from inline_actions.admin import InlineActionsModelAdminMixin
from django.shortcuts import render
from django.http import HttpResponseRedirect
from .models import Country
from .models import Language
from .models import Issn
from .models import Oa
from .models import Publisher
from .models import Journal
from .models import Organization
from .models import Version
from .models import Licence
from .models import Cost_factor_type
from .models import Cost_factor
from .models import Term
from .models import ConditionType
from .models import ConditionSet
from .models import OrganizationCondition
from .models import JournalCondition
# Register your models here.
@admin.register(Journal)
class JournalAdmin(ImportExportModelAdmin):
list_display = ("id", "name", "journal_issns",)
- list_filter = ('publisher__name', )
+ list_filter = ('publisher__name', 'oa_status')
filter_horizontal = ('publisher', 'language', )
def journal_issns(self, obj):
# TBD
pass
@admin.register(Language)
class LanguageAdmin(ImportExportModelAdmin):
pass
@admin.register(Organization)
class OrganizationAdmin(ImportExportModelAdmin):
list_display = ("id", "name")
list_filter = ('is_funder',)
filter_horizontal = ('country', )
@admin.register(Version)
class VersionAdmin(ImportExportModelAdmin):
pass
@admin.register(Country)
class CountryAdmin(ImportExportModelAdmin):
pass
@admin.register(Issn)
class IssnAdmin(ImportExportModelAdmin):
list_filter = ('issn_type', )
@admin.register(Oa)
class OaAdmin(ImportExportModelAdmin):
pass
@admin.register(Publisher)
class PublisherAdmin(ImportExportModelAdmin):
list_display = ("id", "name")
# Experimental: what will happen with 200+ countries in the database?
list_filter = ('country__name', )
filter_horizontal = ('country', )
@admin.register(Term)
class TermAdmin(ImportExportModelAdmin):
list_filter = ('version', 'licence')
filter_horizontal = ('version', 'cost_factor', 'licence', )
@admin.register(ConditionType)
class ConditionTypeAdmin(ImportExportModelAdmin):
list_display = ("id", "condition_issuer")
#class JournalConditionInline(InlineActionsMixin, TabularInline):
class JournalConditionInline(TabularInline):
model = JournalCondition
extra = 1
inline_actions = ['connect_all_journals']
def connect_all_journals(self, request, obj, parent_obj=None):
# Do stuff here, then return None to go to current view
return None
connect_all_journals.short_description = ("Connect Condition Set with all Journals")
class OrganizationConditionInline(TabularInline):
#class OrganizationConditionInline(InlineActionsMixin, TabularInline):
model = OrganizationCondition
extra = 1
def connect_with_all_journals(modeladmin, request, queryset):
print(request.POST)
if request.POST.get('apply'):
try:
valid_from = date.fromisoformat(request.POST['valid_from'])
valid_until = date.fromisoformat(request.POST['valid_until'])
if valid_from > valid_until:
raise ValueError
# print((valid_from, valid_until))
all_journals = Journal.objects.all()
for condition_set in queryset:
# print('-----------------')
# print(condition_set)
for j in all_journals:
print(j)
# search for existing connections
existing_connections = JournalCondition.objects.filter(journal=j,
condition_set=condition_set,
valid_from__lt=date.today(),
valid_until__gt=date.today())
# print(existing_connections)
if len(existing_connections) == 0:
new_journal_condition = JournalCondition(journal=j,
condition_set=condition_set,
valid_from=valid_from,
valid_until=valid_until)
new_journal_condition.save()
return None
except ValueError:
pass
return render(request, 'admin/get_validity_dates.html', context={'queryset': queryset, 'objects': 'journals'})
connect_with_all_journals.short_description = 'Apply selected condition sets to all Journals'
def connect_with_all_organizations(modeladmin, request, queryset):
print(request.POST)
if request.POST.get('apply'):
try:
valid_from = date.fromisoformat(request.POST['valid_from'])
valid_until = date.fromisoformat(request.POST['valid_until'])
if valid_from > valid_until:
raise ValueError
# print((valid_from, valid_until))
all_orgs = Organization.objects.all()
for condition_set in queryset:
# print('-----------------')
# print(condition_set)
for o in all_orgs:
print(o)
# search for existing connections
existing_connections = OrganizationCondition.objects.filter(organization=o,
condition_set=condition_set,
valid_from__lt=date.today(),
valid_until__gt=date.today())
# print(existing_connections)
if len(existing_connections) == 0:
new_organization_condition = OrganizationCondition(organization=o,
condition_set=condition_set,
valid_from=valid_from,
valid_until=valid_until)
new_organization_condition.save()
return None
except ValueError:
pass
return render(request, 'admin/get_validity_dates.html', context={'queryset': queryset, 'objects': 'organizations'})
connect_with_all_organizations.short_description = 'Apply selected condition sets to all Organizations'
@admin.register(ConditionSet)
class ConditionSetAdmin(ImportExportModelAdmin):
# class ConditionSetAdmin(InlineActionsModelAdminMixin, ImportExportModelAdmin):
list_display = ("id", "condition_type", "comment")
search_fields = ['organization__name', 'journal__name', 'comment']
list_filter = ('condition_type', )
filter_horizontal = ('term', )
inlines = (OrganizationConditionInline, JournalConditionInline, )
actions = [connect_with_all_journals, connect_with_all_organizations]
@admin.register(OrganizationCondition)
class OrganizationConditionAdmin(ImportExportModelAdmin):
list_display = ("id", "organization_name", "condition_set", "valid_from", "valid_until")
list_filter = ('condition_set__condition_type', )
def organization_name(self, obj):
return obj.organization.name
@admin.register(Licence)
class LicenceAdmin(ImportExportModelAdmin):
pass
@admin.register(JournalCondition)
class JournalConditionAdmin(ImportExportModelAdmin):
list_display = ("id", "journal_name", "condition_set", "valid_from", "valid_until")
list_filter = ('condition_set__condition_type', )
def journal_name(self, obj):
return obj.journal.name
# unsuccessful attempt
# def formfield_for_foreignkey(self, db_field, request, **kwargs):
# if db_field.name == "journal":
# kwargs["queryset"] = Journal.objects.filter(publisher__name__in=Publisher.objects.order_by().values('name').distinct())
# return super().formfield_for_foreignkey(db_field, request, **kwargs)
@admin.register(Cost_factor)
class Cost_factorAdmin(ImportExportModelAdmin):
list_display = ("id", "comment", "amount", "symbol")
list_filter = ('cost_factor_type', 'symbol')
@admin.register(Cost_factor_type)
class Cost_factor_typeAdmin(ImportExportModelAdmin):
list_display = ("id", "name")