Commit dfa03469 authored by Pierre Dittgen's avatar Pierre Dittgen

Release 'supernumerarycolumns'

parents 078faddb bcc165fc
Pipeline #1282 passed with stage
in 6 minutes and 36 seconds
# 0.3.0
- Repair tabular file structure prior to look for value errors
# 0.2.22
- Fix crash on home page if non existant repo
......
......@@ -9,4 +9,4 @@ python-dotenv==0.10.1
requests==2.22.0
toml==0.10.0
tabulator==1.21.0
validata_core==0.4.1
validata_core==0.5.0
......@@ -13,7 +13,7 @@ with readme_filepath.open('rt', encoding='utf-8') as fd:
setup(
name='validata_ui',
version='0.2.22',
version='0.3.0',
description='Validata Web UI',
long_description=LONG_DESCRIPTION,
......@@ -70,7 +70,7 @@ setup(
'tabulator',
'opendataschema >= 0.5.5, < 0.6',
'validata_core >= 0.4.1, < 0.5',
'validata_core >= 0.5.0, < 0.6',
],
)
......@@ -21,3 +21,28 @@ body {
bottom: 0;
width: 100%;
}
/* Pop-over management */
.popover .popover-body h2 {
font-size: 1.2em;
font-weight: bold;
}
/* CSS trick to allow th to be styled with danger, warning, ...
even if already using class thead-light class */
.table .thead-light th.table-danger {
background-color: #f5c6cb;
}
.table .thead-light th.table-warning {
background-color: #ffeeba;
}
/* Remove margin bottom for repair action items */
div.actions ul li p {
margin-bottom: 0;
}
/* Force align=center for <th> */
body th {
text-align: center;
}
// Popovers that stays while on popover bubble
// https://stackoverflow.com/questions/15989591/how-can-i-keep-bootstrap-popover-alive-while-the-popover-is-being-hovered
$('[data-toggle="popover"]')
.popover({
trigger: "manual",
html: true,
animation: false,
placement: "auto"
})
.on("mouseenter", function() {
var _this = this
$(this).popover("show")
$(".popover").on("mouseleave", function() {
$(_this).popover("hide")
})
})
.on("mouseleave", function() {
var _this = this
setTimeout(function() {
if (!$(".popover:hover").length) {
$(_this).popover("hide")
}
}, 100)
})
// Open links found in error description in a new window/tab
$("body").on("mouseover", "div.popover a", function() {
$(this).prop("title", "Ouvrir dans une nouvelle fenêtre")
})
$("body").on("click", "div.popover a", function() {
var url = $(this).prop("href")
window.open(url, "_blank")
return false
})
{% macro preview(source_data) %}
<p>
Prévisualisation de {{ source_data.preview_rows_nb }} ligne{% if source_data.preview_rows_nb > 1 %}s{% endif %} sur {{ source_data.rows_nb }} au total :
</p>
<div class="table-responsive">
<table class="table table-striped table-bordered table-sm table-hover">
{% macro thead(report, with_lineno_col=False) %}
<thead class="thead-light">
<tr>
{% for col in source_data.header %}
<th scope="col">{{ col }}</th>
{% endfor %}
{% if with_lineno_col %}
<th scope="col">1</th>
{% endif %}
{% for h in report.table.headers %}
<th
scope="col"
{% if report.table.cols_alert[loop.index - 1] != "" %}class="{{ report.table.cols_alert[loop.index - 1] }}"{% endif %}
data-toggle="popover"
title="{{ report.table.headers_title[loop.index - 1]}}"
data-content="{{ report.table.headers_description[loop.index - 1] | commonmark2html | escape}}"
>{{ h }}</th>
{% endfor %}
</tr>
</thead>
{% endmacro %}
{% macro preview(report, source_data) %}
<div class="table-responsive-sm">
<table class="table-striped table-bordered table-sm table-hover">
{{ thead(report) }}
<tbody>
{% for row in source_data.preview_rows %}
<tr>
{% for val in row %}
<td>{{ val }}</td>
<td
{% if report.table.cols_alert[loop.index - 1] != "" %}class="{{ report.table.cols_alert[loop.index - 1] }}"{% endif %}
>{{ val }}</td>
{% endfor %}
</tr>
{% endfor %}
......@@ -70,13 +82,7 @@
{% macro body_errors_screen(report, source_data) %}
<div class="table-responsive-sm">
<table class="table-sm table-bordered table-striped table-hover">
<thead class="thead-light">
<th scope="col">1</th>
{% for h in source_data.header %}
<th scope="col" data-toggle="popover" title="{{ report.table.headers_title[loop.index - 1]}}" data-content="{{ report.table.headers_description[loop.index - 1] | commonmark2html | escape}}">{{
h }}</th>
{% endfor %}
</thead>
{{ thead(report, True) }}
<tbody>
{% for row in report.table.errors.body_by_rows %}
<tr>
......@@ -114,7 +120,7 @@
{% set structure_errors = report.table['error-stats']['structure-errors'] %}
{% if structure_errors['count'] != 0 %}
<p>Erreur de structure ({{ structure_errors['count'] }}) :</p>
<p>Erreurs de structure ({{ structure_errors['count'] }}) :</p>
<ul>
{% for item in structure_errors['count-by-code'] %}
<li>{{ item[0] }} ({{ item[1] }})</li>
......@@ -124,17 +130,16 @@
<p>Aucune erreur de structure.</p>
{% endif %}
{% if report.table.do_display_body_errors %}
{% set value_errors = report.table['error-stats']['value-errors'] %}
{% if value_errors['count'] > 0 %}
<p>Erreur de contenu ({{ value_errors['count'] }} sur {{ value_errors['rows-count'] }} ligne{% if value_errors['rows-count'] > 1 %}s{% endif %}) :</p>
<p>Erreurs de contenu ({{ value_errors['count'] }} sur {{ value_errors['rows-count'] }} ligne{% if value_errors['rows-count'] > 1 %}s{% endif %}) :</p>
<ul>
{% for item in value_errors['count-by-code'] %}
<li>{{ item[0] }} ({{ item[1] }})</li>
{% endfor %}
</ul>
{% endif %}
{% else %}
<p>Aucune erreur de contenu</p>
{% endif %}
{% endmacro %}
......@@ -8,14 +8,13 @@
{% block head %}
{{ super() }}
<style>
.popover .popover-body h2 {
font-size: 1.2em;
font-weight: bold;
}
#table-errors td h2 {
font-size: 1em;
font-weight: bold;
}
ul.structure_errors li p {
margin-bottom: 0;
}
@media print {
.hidden-print {
......@@ -38,8 +37,8 @@
</p>
{% endif %}
{# Schema info #}
<div class="row my-4">
{# Schema info #}
<div class="col-lg-6 mb-4">
<div class="card">
<div class="card-body">
......@@ -47,6 +46,7 @@
</div>
</div>
</div>
{# Validation stats #}
<div class="col-lg-6">
<div class="card">
<div class="card-body">
......@@ -87,104 +87,90 @@
</div>
</div>
</div>
</div>
{% if report.error_count > 0 %}
{% if report.table.errors.structure %}
<h3 class="my-4">Erreurs de structure</h3>
{# Non-column errors #}
{% for err in report.table.errors.structure %}
{% if not err.in_column_comp %}
{{ err.content | safe }}
{% endif %}
{% endfor %}
{# Column errors #}
{% for err in report.table.errors.structure %}
{% if err.in_column_comp %}
{{ err.content | safe }}
{% endif %}
{% endfor %}
{# Afficher un tableau de comparaison des colonnes #}
{% if report.table.column_comparison_needed %}
<table class="table table-bordered table-sm table-striped table-hover">
<thead class="thead-light">
<tr>
<th scope="col">Colonnes du fichier</th>
<th scope="col">Colonnes attendues</th>
</tr>
</thead>
<tbody>
{% for elt in report.table.column_comparison_info.table %}
<tr{% if elt[2] == 'ko' %} class="table-danger"{% endif %}>
<td>{{ elt[0] }}</td>
<td>{{ elt[1] }}</td>
</tr>
<div class="mx-4">
{% if report.table.errors.structure %}
<h3 class="my-4">Erreurs de structure ({{ report.table['error-stats']['structure-errors']['count'] }})</h3>
<p>Prévisualisation du fichier source avec structure invalide (en-têtes)</p>
{# source header display #}
<div class="mb-4">
<div class="table-responsive">
<table class="table table-striped table-bordered table-sm table-hover">
<thead class="thead-light">
<tr>
{% for h, err in source_data.source_header_info %}
<th{% if err %} class="table-danger"{% endif %}>{{ h }}</th>
{% endfor %}
</tbody>
</table>
{% if report.table.column_comparison_info.has_missing %}
<p>Attention : toutes les colonnes attendues doivent être présentes dans le fichier à valider.<p>
{% endif %}
{% if report.table.column_comparison_info.has_case_errors %}
<p>Attention : la casse (minuscules/majuscules) doit être respectée dans les noms de colonne.<p>
{% endif %}
{% endif %}
{% endif %}
</tr>
</thead>
</table>
</div>
</div>
{% endif %}
</div>
{% if report.table.do_display_body_errors %} {# We do display body errors! #}
<div class="mx-4">
{% if report.table.errors.body %}
<h3 class="my-4">Erreurs de contenu</h3>
{{ macros.body_errors(report, source_data, print_mode) }}
{# Display body errors #}
<div class="mx-4">
<h3 class="my-4">
{% if report.table.errors.body %}
{% set value_errors = report.table['error-stats']['value-errors'] %}
Erreurs de contenu ({{ value_errors['count'] }} sur {{ value_errors['rows-count'] }} ligne{% if value_errors['rows-count'] > 1 %}s{% endif %})
{% else %}
{% if report.table.errors.structure %}
Aucune erreur de contenu
{% else %}
{{ macros.preview(source_data) }}
Aucune erreur détectée
{% endif %}
{% endif %}
</h3>
<p>Prévisualisation du fichier source
{% if report.repair_actions %}avec structure réparée{% endif %}
{% if not report.table.errors.body %}
(affichage de {{ source_data.preview_rows_nb }}
ligne{% if source_data.preview_rows_nb > 1 %}s{% endif %}
sur {{ source_data.rows_nb }} au total)
{% endif %}
</p>
{% if report.repair_actions %}
<div id="repair_actions" class="my-4 actions">
<div class="col-lg-6 alert alert-warning">
<p>
La structure de votre fichier a été automatiquement remaniée
<a id="repair_details_link" class="float-right" href="#" title="Voir les détails">détails</a>
</p>
<div id="repair_details_panel" class="d-none">
<ul>
{% for action in report.repair_actions %}
<li>{{ action | commonmark2html | safe}}</li>
{% endfor %}
</ul>
<p>
Il vous appartient d'apporter ces modifications sur votre fichier pour rendre sa structure
valide selon le schéma.
</p>
</div>
</div>
</div>
{% else %} {# do not display errors #}
<p>Veuillez corriger ces erreurs pour visualiser les éventuelles erreurs de contenu.</p>
{% endif %}
{% endif %}
{% if report.table.errors.body %}
{{ macros.body_errors(report, source_data, print_mode) }}
{% else %}
{{ macros.preview(report, source_data) }}
{% endif %}
</div>
{% endblock %}
{% block page_scripts %}
<script src="{{ url_for('static', filename='validata_popover.js') }}"></script>
<script>
// Popovers that stays while on popover bubble
// https://stackoverflow.com/questions/15989591/how-can-i-keep-bootstrap-popover-alive-while-the-popover-is-being-hovered
$('[data-toggle="popover"]').popover({
trigger: 'manual',
html: true,
animation: false,
placement: 'auto'
// Show detail on 'détails' link click
$('#repair_details_link').click(function(e) {
e.preventDefault();
$(this).addClass("d-none");
$("#repair_details_panel").addClass('d-block');
})
.on('mouseenter', function () {
var _this = this;
$(this).popover('show');
$('.popover').on('mouseleave', function () {
$(_this).popover('hide');
});
}).on('mouseleave', function () {
var _this = this;
setTimeout(function () {
if (!$('.popover:hover').length) {
$(_this).popover('hide');
}
}, 100);
});
// Open links found in error description in a new window/tab
$('body').on('mouseover', 'div.popover a', function() {
$(this).prop('title', 'Ouvrir dans une nouvelle fenêtre');
});
$('body').on('click', 'div.popover a', function() {
var url = $(this).prop('href');
window.open(url, '_blank')
return false;
});
</script>
{% endblock %}
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment