Skip to content

Commit

Permalink
Merge pull request #479 from elixir-luxembourg/438-dish-import-button
Browse files Browse the repository at this point in the history
Import datasets, projects and partners using the ui
  • Loading branch information
Fancien authored Oct 27, 2023
2 parents 2e8abb5 + 3e1f1ab commit 19badf8
Show file tree
Hide file tree
Showing 14 changed files with 500 additions and 4 deletions.
20 changes: 20 additions & 0 deletions conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,26 @@ def user_data_steward(django_user_model):
return u


@pytest.fixture
def user_legal(django_user_model):
u = django_user_model.objects.create_user(
username="user.legal", password="password", email="legal@email.com"
)
g, _ = Group.objects.get_or_create(name=GroupConstants.LEGAL.value)
u.groups.add(g)
return u


@pytest.fixture
def user_auditor(django_user_model):
u = django_user_model.objects.create_user(
username="user.auditor", password="password", email="auditor@email.com"
)
g, _ = Group.objects.get_or_create(name=GroupConstants.AUDITOR.value)
u.groups.add(g)
return u


@pytest.fixture
def user_admin(django_user_model):
u = django_user_model.objects.create_superuser(
Expand Down
5 changes: 5 additions & 0 deletions core/forms/importer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from django import forms


class ImportForm(forms.Form):
file = forms.FileField(required=True, label="Choose File")
84 changes: 84 additions & 0 deletions data/demo/elu-core.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
{
"$id": "https://raw.githubusercontent.com/elixir-luxembourg/json-schemas/v0.0.5/schemas/elu-core.json",
"title": "ELIXIR Luxembourg Core json schema",
"description": "Schema containing core attributes for any json serialisable ELIXIR Luxembourg record.",
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"required": [
"source",
"name"
],
"properties": {
"source": {
"type": "string",
"format": "uri"
},
"acronym": {
"type": ["string", "null"]
},
"name": {
"type": "string"
},
"description": {
"type": ["string", "null"]
},
"external_id": {
"type": ["string", "null"]
},
"elu_uuid": {
"type": ["string", "null"]
},
"other_external_id": {
"type": ["string", "null"]
},
"url": {
"type": ["string", "null"]
},
"contacts": {
"type": "array",
"items": {
"type": "object",
"properties": {
"first_name": {
"type": "string"
},
"last_name": {
"type": "string"
},
"role": {
"type": "string",
"enum": [
"Principal_Investigator",
"Researcher",
"Data_Manager",
"Data_Protection_Officer",
"Legal_Representative",
"Other"
]
},
"email": {
"type": "string",
"format": "email"
},
"affiliations": {
"description": "Names of the affiliated institutions.",
"type": "array",
"minItems": 1,
"uniqueItems": true,
"items": {
"type": ["string", "null"]
}
}
},
"required": [
"first_name",
"last_name",
"role",
"email",
"affiliations"
]
}
}
}
}

26 changes: 26 additions & 0 deletions data/demo/partners.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"items": [
{
"name": "Centre Hospitalier de Togo",
"external_id": "ELU_I_19309",
"acronym": "CHT",
"is_clinical": true,
"geo_category": "National",
"sector_category": "PUBLIC",
"address": "Ave De La 6, Espoir Vie Togo, Lome",
"country_code": "TO",
"source": "example.com"
},
{
"name": "Hospitalier de Madagascar",
"external_id": "ELU_I_1939",
"acronym": "HMDGSK",
"is_clinical": true,
"geo_category": "National",
"sector_category": "PUBLIC",
"address": "Ave De La 6, Espoir Vie Togo, Antananarivo",
"country_code": "MG",
"source": "example.com"
}
]
}
5 changes: 5 additions & 0 deletions web/static/css/daisy.scss
Original file line number Diff line number Diff line change
Expand Up @@ -424,3 +424,8 @@ a.no-underline:hover {
text-align: left !important;
}
}
.log-container {
max-height: 500px;
overflow-y: auto;
white-space: pre-line;
}
46 changes: 46 additions & 0 deletions web/static/js/importer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
$(document).ready(function () {
// Show the modal when the button is clicked
$('#importModalButton').click(function () {
$('#importModal').modal('show');
fetchForm();
});

// Fetch the form via AJAX
function fetchForm() {
$.get(importDataUrl, function (data) {
$("#importForm").html(data.form_html);
// Initially disable the submit button
$("#ajaxSubmitButton").prop("disabled", true);
// Monitor changes on the file input
$("#id_file").on("change", function () {
// If file input has a file, enable the submit button
if ($(this).val()) {
$("#ajaxSubmitButton").prop("disabled", false);
} else {
$("#ajaxSubmitButton").prop("disabled", true);
}
});
$('#ajaxSubmitButton').on('click', function () {
submitForm();
});
});
}
});

function submitForm() {
const formData = new FormData($('#importForm form')[0]);
$.ajax({
url: importDataUrl,
type: 'POST',
data: formData,
cache: false,
contentType: false,
processData: false,
success: function (data) {
$("#importForm form").html(data.form_html);
},
error: function (data) {
$("#importForm form").html(data.form_html);
}
});
}
20 changes: 17 additions & 3 deletions web/templates/_includes/search_form.html
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
{% load static daisy_utils %}
<div class="row">
<div class="col-6">
<h1 class="display-4">
Browse {{title}}
</h1>
</div>
<div class="col-5">
<div class="col-5 d-flex align-items-center justify-content-end">
{% if request.user|has_group:"daisy-data-steward" %}
{% if search_url == 'projects' or search_url == 'datasets' or search_url == 'partners' %}
<button id="importModalButton" type="button" class="btn btn-secondary btn-outline float-right mx-2">
Import
</button>
{% include 'importer/import_modal.html' %}
{% endif %}
{% endif %}
{% if request.user.is_superuser %}
<a class="btn btn-secondary btn-outline float-right" href="export?{% if filters %}filters={{ filters }}&{% endif %}{% if order_by %}order_by={{ order_by | default:'' }}&{% endif %}{% if query %}query={{ query | default:'' }}{% endif %}">Save the results as xlsx</a>
{% endif %}
Expand All @@ -29,13 +38,13 @@ <h1 class="display-4">
</div>
{% endif %}
</div>

<span class="form-group bmd-form-group"> <!-- needed to match padding for floating labels -->
<button type="submit" class="btn btn-primary">Search</button>
</span>
</form>
</div>

<div class="col-xl-7 col-lg-12 mt-4 mb-2">
{% if order_by_fields %}
<div class="mr-auto float-right">
Expand All @@ -50,3 +59,8 @@ <h1 class="display-4">
</div>
</div>
</div>
<script>
const importDataUrl = `/import_data/{{ search_url }}/`;
</script>
<script defer src="{% static 'js/daisy.js' %}"></script>
<script defer src="{% static 'js/importer.js' %}"></script>
49 changes: 49 additions & 0 deletions web/templates/importer/import_form.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<div id="importForm">
{% if form %}
<!-- Display the form -->
<form class="form col-md-12 nice-selects" method="post" enctype="multipart/form-data" novalidate
action="{% url 'import_data' model_type=model_type %}">
{% csrf_token %}
<!-- File Upload Field -->
<div class="form-group required">
<strong>{{ form.file.label_tag }}</strong>
<input type="file" name="{{ form.file.name }}" class="form-control" required
id="{{ form.file.id_for_label }}" accept=".json">
{% if form.file.errors %}
<div class="text-danger">
{{ form.file.errors|striptags }}
</div>
{% endif %}
</div>
<button id="ajaxSubmitButton" type="button" class="btn btn-primary btn-raised btn-block">Submit</button>
</form>
{% else %}
<div class="p-0">
<!-- Display output message -->
{% if output.message %}
<div class="alert alert-{% if not output.error %}success{% else %}info{% endif %} rounded" role="alert">
<strong>Output:</strong>
<p>{{ output.message|linebreaksbr }}</p>
</div>
{% endif %}
<!-- Display error -->
{% if output.error %}
<div class="alert alert-danger rounded" role="alert">
<strong>Error:</strong>
<p>{{ output.error|linebreaksbr }}</p>
</div>
{% endif %}
<!-- Display logs -->
{% if output.logs %}
<div class="alert alert-secondary rounded" role="alert">
<strong> Logs:</strong>
<div class="log-container">
<p>{{ output.logs|linebreaksbr }}</p>
</div>
</div>
{% endif %}


</div>
{% endif %}
</div>
16 changes: 16 additions & 0 deletions web/templates/importer/import_modal.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<div class="modal fade" id="importModal" tabindex="-1" aria-labelledby="modalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="modalLabel">Import {{ search_url }}</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body px-2">
<div id="importForm">
</div>
</div>
</div>
</div>
</div>
5 changes: 5 additions & 0 deletions web/templatetags/daisy_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ def form_add_class(field, css_class):
return field.as_widget(attrs={"class": css_class})


@register.filter(name="has_group")
def has_group(user, group_name):
return user.is_part_of(group_name)


@register.filter
def can_see_protected(user, obj: Union[Project, Contract, Dataset]):
has_perm = user.can_see_protected(obj)
Expand Down
Loading

0 comments on commit 19badf8

Please sign in to comment.