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")