summaryrefslogtreecommitdiff
path: root/ishtar_common
diff options
context:
space:
mode:
authorÉtienne Loks <etienne.loks@iggdrasil.net>2023-08-10 18:13:55 +0200
committerÉtienne Loks <etienne.loks@iggdrasil.net>2024-02-05 10:51:51 +0100
commitff9cb4b4d71d0df8d0b0f0a96c4a5e45a02ad904 (patch)
treef4dcd0f599164f9351f7d44521db7548127b62b9 /ishtar_common
parent90e033d2d9cfdf56a76b4d6561069a362d4675cb (diff)
downloadIshtar-ff9cb4b4d71d0df8d0b0f0a96c4a5e45a02ad904.tar.bz2
Ishtar-ff9cb4b4d71d0df8d0b0f0a96c4a5e45a02ad904.zip
🚸 imports: auto-refresh import state and progress
Diffstat (limited to 'ishtar_common')
-rw-r--r--ishtar_common/models_imports.py8
-rw-r--r--ishtar_common/static/js/ishtar.js56
-rw-r--r--ishtar_common/templates/ishtar/import_table.html69
-rw-r--r--ishtar_common/urls.py5
-rw-r--r--ishtar_common/views.py35
5 files changed, 146 insertions, 27 deletions
diff --git a/ishtar_common/models_imports.py b/ishtar_common/models_imports.py
index 718f76ef3..ff920fbf2 100644
--- a/ishtar_common/models_imports.py
+++ b/ishtar_common/models_imports.py
@@ -1313,6 +1313,10 @@ class ImportGroup(BaseImport):
def __str__(self):
return f"{self.name} ({self.importer_type.name})"
+ @property
+ def import_id(self):
+ return f"group-{self.id}"
+
def import_list(self):
"""
Sorted import list by order in the importer group
@@ -1529,6 +1533,10 @@ class Import(BaseImport):
def __str__(self):
return "{} | {}".format(self.name or "-", self.importer_type)
+ @property
+ def import_id(self):
+ return str(self.id)
+
def need_matching(self):
return bool(
TargetKey.objects.filter(associated_import=self, is_set=False).count()
diff --git a/ishtar_common/static/js/ishtar.js b/ishtar_common/static/js/ishtar.js
index 1c7474c57..1656cb427 100644
--- a/ishtar_common/static/js/ishtar.js
+++ b/ishtar_common/static/js/ishtar.js
@@ -2107,3 +2107,59 @@ var bs_hide_table = function(name){
$("#grid_" + name).DataTable().clear().draw();
current_modal = null;
}
+
+var import_table_import_state = new Array();
+
+var import_table_update_import_list = function(import_ids){
+ $.post('/import-get-status/',
+ {items: import_ids},
+ import_table_refresh_import_list
+ );
+}
+
+var import_table_refresh_import_item = function(item){
+ $("#status-" + item["full_id"]).html(item["status"]);
+ let display = "display:none";
+ if (item["state"] == "IP" || item["state"] == "PP"){
+ display = "";
+ }
+ $("#progress-display-" + item["full_id"]).attr("style", display);
+ let actions = "<option value=''>--------</option>";
+ for (action_id in item["actions"]){
+ let action = item["actions"][action_id];
+ actions += "<option value='" + action[0] + "'>" + action[1] + "</option>";
+ }
+ if (!import_table_import_state[item["full_id"]]){
+ import_table_import_state[item["full_id"]] = actions;
+ }
+ if (import_table_import_state[item["full_id"]] != actions){
+ $("#import-action-" + item["full_id"]).html(actions);
+ import_table_import_state[item["full_id"]] = actions;
+ }
+};
+
+var import_table_refresh_import_list = function(data){
+ for (item_id in data["group"]){
+ let item = data["group"][item_id];
+ import_table_refresh_import_item(item);
+ }
+ for (item_id in data["import"]){
+ let item = data["import"][item_id];
+ import_table_refresh_import_item(item);
+ if (item["current_line"]){
+ $("#progress-" + item["full_id"]).attr("aria-valuenow", item["current_line"]);
+ $("#progress-" + item["full_id"]).attr("aria-valuemax", item["status"]);
+ $("#progress-" + item["full_id"]).attr("style", "width: " + item["progress_percent"] + "%");
+ let cls = "progress-bar progress-bar-striped ";
+ if (item["state"] == "IP"){
+ $("#progress-" + item["full_id"]).removeClass("bg-info").addClass("bg-success");
+ } else {
+ $("#progress-" + item["full_id"]).removeClass("bg-success").addClass("bg-info");
+ }
+ cls += " progress-bar-animated";
+ $("#progress-" + item["full_id"]).html(
+ item["current_line"] + "/" + item["number_of_line"]
+ );
+ }
+ }
+}
diff --git a/ishtar_common/templates/ishtar/import_table.html b/ishtar_common/templates/ishtar/import_table.html
index 138dbba65..f027e07c5 100644
--- a/ishtar_common/templates/ishtar/import_table.html
+++ b/ishtar_common/templates/ishtar/import_table.html
@@ -1,21 +1,36 @@
{% load i18n l10n inline_formset %}
{% localize off %}<script type="text/javascript">
-var html = $("#message_list").html();
-{% if MESSAGES and AJAX %}{% for message, message_type in MESSAGES %}
-html += '<div class="alert alert-{{message_type}} alert-dismissible fade show"';
-html += ' role="alert">';
-html += ' {{message}}';
-html += ' <button type="button" class="close" data-dismiss="alert"';
-html += ' aria-label="Close">';
-html += ' <span aria-hidden="true">&times;</span>';
-html += ' </button>';
-html += ' </div>';
-{% endfor %}{% endif %}
-$("#message_list").html(html);
+ var html = $("#message_list").html();
+ {% if MESSAGES and AJAX %}{% for message, message_type in MESSAGES %}
+ html += '<div class="alert alert-{{message_type}} alert-dismissible fade show"';
+ html += ' role="alert">';
+ html += ' {{message}}';
+ html += ' <button type="button" class="close" data-dismiss="alert"';
+ html += ' aria-label="Close">';
+ html += ' <span aria-hidden="true">&times;</span>';
+ html += ' </button>';
+ html += ' </div>';
+ {% endfor %}{% endif %}
+ $("#message_list").html(html);
-$("#import-list").find('select').prop('disabled', true);
-$("#import-list").find('input').prop('disabled', true);
+ $("#import-list").find('select').prop('disabled', true);
+ $("#import-list").find('input').prop('disabled', true);
+ var import_table_update_import_ids = new Array();
+ var import_table_import_state = new Array();
+ {% for import in object_list %}{% if import.state == 'IP' or import.state == 'PP' %}
+ import_table_update_import_ids.push("{{import.import_id}}");
+ {% if not import.importer_type.type_label %}{# group #}{% for sub in import.import_list %}
+ import_table_update_import_ids.push("{{sub.id}}");{% endfor %}
+ {% endif %}{% endif %}{% endfor %}
+ var need_refresh = false;
+ if (import_table_update_import_ids.length) need_refresh = true;
+
+ $(document).ready(function(){
+ if (need_refresh) setInterval(function(){
+ import_table_update_import_list(import_table_update_import_ids)
+ }, 3 * 1000);
+ });
</script>
<h2>{{page_name}}</h2>
<div class='form' id="import-list">
@@ -37,7 +52,7 @@ $("#import-list").find('input').prop('disabled', true);
<th>{% trans "Match" %}</th>
</tr>
{% for import in object_list %}
- <tr{% if import.pk in refreshed_pks %} class='bg-info'{% endif %}>
+ <tr id="import-{{import.import_id}}"{% if import.pk in refreshed_pks %} class='bg-info'{% endif %}>
<td>
{{import.name|default:"-"}}
</td>
@@ -61,11 +76,13 @@ $("#import-list").find('input').prop('disabled', true);
<td>
{{import.creation_date|date:"DATE_FORMAT"}} {{import.creation_date|time:"H:i"}} - {{import.user}}
</td>
- <td>
+ <td id="status-{{import.import_id}}">
{{import.status}}
</td>
<td>
- <select class="form-control" name='import-action-{% if not import.importer_type.type_label %}group-{% endif %}{{import.pk}}'>
+ <select class="form-control"
+ id='import-action-{{import.import_id}}'
+ name='import-action-{{import.import_id}}'>
<option value=''>--------</option>
{% for action, lbl in import.get_actions %}
<option value='{{action}}'>{{lbl}}</option>
@@ -87,11 +104,12 @@ $("#import-list").find('input').prop('disabled', true);
<a href='{{import.match_file.url}}'>{% trans "File" context "not a directory" %}</a>
{% endif %}</td>
</tr>
- {% if import.importer_type.type_label and import.state == 'IP' or import.state == 'PP' and import.current_line %}
- <tr>
+ {% if import.importer_type.type_label %}
+ <tr></tr>{# only for even and odd style #}
+ <tr id="progress-display-{{import.id}}"{% if sub.state != 'IP' and sub.state != 'PP' %} style="display:none"{% endif %}>
<td colspan="11">
<div class="progress bg-secondary">
- <div class="progress-bar progress-bar-striped {% if import.state == 'IP'%}bg-success{% else %}bg-info{% endif %} progress-bar-animated" role="progressbar"
+ <div id="progress-{{import.id}}" class="progress-bar progress-bar-striped {% if import.state == 'IP'%}bg-success{% else %}bg-info{% endif %} progress-bar-animated" role="progressbar"
aria-valuenow="{{import.current_line}}" aria-valuemin="0" aria-valuemax="{{import.number_of_line}}" style="width: {{import.progress_percent}}%">
&nbsp;{{import.current_line}} / {{import.number_of_line}}
</div>
@@ -101,7 +119,7 @@ $("#import-list").find('input').prop('disabled', true);
{% endif %}
{% if not import.importer_type.type_label %} {# group #}
{% for sub in import.import_list %}
- <tr>
+ <tr id="import-{{sub.import_id}}">
<td></td>
<td>{{sub.importer_type}}</td>
<td>{% if sub.imported_file %}
@@ -113,7 +131,7 @@ $("#import-list").find('input').prop('disabled', true);
{% endif %}
</td>
<td></td>
- <td>{{sub.status}}</td>
+ <td id="status-{{sub.import_id}}">{{sub.status}}</td>
<td></td>
<td>{% if sub.need_matching %}
<a href='{% url "import_link_unmatched" sub.pk %}'>{% trans "Match"%}</a>
@@ -128,18 +146,17 @@ $("#import-list").find('input').prop('disabled', true);
<a href='{{sub.match_file.url}}'>{% trans "File" context "not a directory" %}</a>
{% endif %}</td>
</tr>
- {% if sub.state == 'IP' or sub.state == 'PP' %}
- <tr>
+ <tr></tr>{# only for even and odd style #}
+ <tr id="progress-display-{{sub.id}}"{% if sub.state != 'IP' and sub.state != 'PP' %} style="display:none"{% endif %}>
<td colspan="11">
<div class="progress bg-secondary">
- <div class="progress-bar progress-bar-striped {% if sub.state == 'IP'%}bg-success{% else %}bg-info{% endif %} progress-bar-animated" role="progressbar"
+ <div id="progress-{{sub.id}}" class="progress-bar progress-bar-striped {% if sub.state == 'IP'%}bg-success{% else %}bg-info{% endif %} progress-bar-animated" role="progressbar"
aria-valuenow="{{sub.current_line}}" aria-valuemin="0" aria-valuemax="{{sub.number_of_line}}" style="width: {{sub.progress_percent}}%">
&nbsp;{{sub.current_line}} / {{sub.number_of_line}}
</div>
</div>
</td>
</tr>
- {% endif %}
{% endfor %}
{% endif %}
{% endfor %}
diff --git a/ishtar_common/urls.py b/ishtar_common/urls.py
index 16f04175e..eb35ea36b 100644
--- a/ishtar_common/urls.py
+++ b/ishtar_common/urls.py
@@ -239,6 +239,11 @@ urlpatterns = [
name="current_imports_table",
),
url(
+ r"^import-get-status/$",
+ check_rights(["change_import"])(views.import_get_status),
+ name="import_get_status",
+ ),
+ url(
r"^import-list-old/$",
check_rights(["change_import"])(views.ImportOldListView.as_view()),
name="old_imports",
diff --git a/ishtar_common/views.py b/ishtar_common/views.py
index 74691256b..1ab5931e4 100644
--- a/ishtar_common/views.py
+++ b/ishtar_common/views.py
@@ -1535,7 +1535,7 @@ class ImportListView(IshtarMixin, LoginRequiredMixin, ListView):
q2 = q2.filter(user=user)
q1 = q1.filter(group__isnull=True).order_by("-creation_date", "-pk")
q2 = q2.order_by("-creation_date", "-pk")
- return reversed(sorted(list(q1) + list(q2), key=lambda x: x.creation_date))
+ return list(reversed(sorted(list(q1) + list(q2), key=lambda x: x.creation_date)))
def post(self, request, *args, **kwargs):
for field in request.POST:
@@ -2029,6 +2029,39 @@ class ImportOldListView(ImportListView):
return q.filter(user=user).order_by("-creation_date")
+def import_get_status(request, current_right=None):
+ response = {"group": [], "import": []}
+ import_ids = request.POST.getlist("items[]", [])
+ for import_id in import_ids:
+ model = models.Import
+ key = "import"
+ if import_id.startswith("group-"):
+ model = models.ImportGroup
+ key = "group"
+ idx = import_id.split("-")[-1]
+ q = model.objects.filter(pk=idx)
+ if not q.count():
+ continue
+ item = q.all()[0]
+ item_dct = {
+ "id": item.id,
+ "full_id": ("group-" if key == "group" else "") + str(item.id),
+ "state": item.state,
+ "status": str(item.status),
+ }
+ if key == "import":
+ item_dct.update({
+ "current_line": item.current_line,
+ "number_of_line": item.number_of_line,
+ "progress_percent": item.progress_percent,
+ })
+ item_dct["actions"] = [(key, str(lbl)) for key, lbl in item.get_actions()]
+ response[key].append(item_dct)
+
+ data = json.dumps(response)
+ return HttpResponse(data, content_type="application/json")
+
+
class ImportLinkView(IshtarMixin, LoginRequiredMixin, ModelFormSetView):
template_name = "ishtar/formset_import_match.html"
model = models.TargetKey