Commit 3c01a449 authored by Christophe Benz's avatar Christophe Benz

Enhance UX

parent 2bf9a556
{ {
"sections": [ "sections": [
{ {
"code": "scdl", "name": "scdl",
"title": "Validateurs SCDL", "title": "Socle Commun des Données Locales",
"catalog": "https://git.opendatafrance.net/scdl/catalog/raw/master/catalog.json" "catalog": "https://git.opendatafrance.net/scdl/catalog/raw/master/catalog.json"
}, },
{ {
"code": "external", "name": "external",
"title": "Validateurs externes", "title": "Validateurs externes",
"catalog": [ "catalog": [
{ {
......
...@@ -36,11 +36,11 @@ if config.HOMEPAGE_CONFIG: ...@@ -36,11 +36,11 @@ if config.HOMEPAGE_CONFIG:
caching_session = cachecontrol.CacheControl(requests.Session()) caching_session = cachecontrol.CacheControl(requests.Session())
schema_from_url = generate_schema_from_url_func(caching_session) schema_from_url = generate_schema_from_url_func(caching_session)
for section in config.HOMEPAGE_CONFIG['sections']: for section in config.HOMEPAGE_CONFIG['sections']:
code = section['code'] name = section['name']
log.info('Initializing homepage section "{}"...'.format(code)) log.info('Initializing homepage section "{}"...'.format(name))
if isinstance(section['catalog'], str) and section['catalog'].startswith('http'): if isinstance(section['catalog'], str) and section['catalog'].startswith('http'):
url = section['catalog'] url = section['catalog']
schema_catalog_map[code] = opendataschema.SchemaCatalog(url, session=caching_session) schema_catalog_map[name] = opendataschema.SchemaCatalog(url, session=caching_session)
log.info("...done") log.info("...done")
# Flask things # Flask things
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
<!-- Bootstrap CSS --> <!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous"> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.5.0/css/all.css" integrity="sha384-B4dIYHKNBt8Bc12p+WXckhzcICo0wtJAoU8YZTY5qE0Id1GSseTk6S+L3BlXeVIU" crossorigin="anonymous"> <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.5.0/css/all.css" integrity="sha384-B4dIYHKNBt8Bc12p+WXckhzcICo0wtJAoU8YZTY5qE0Id1GSseTk6S+L3BlXeVIU" crossorigin="anonymous">
<title>Validata - {% block title %}{% endblock %}</title> <title>Validata {% block title %}{% endblock %}</title>
<style> <style>
body { body {
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
<body> <body>
<!-- horizontal navigation bar --> <!-- horizontal navigation bar -->
<nav class="nav px-3 py-2"> <nav class="nav px-3 py-2 border-bottom">
<a class="navbar-brand" href="{{ url_for('home') }}"> <a class="navbar-brand" href="{{ url_for('home') }}">
<img src="{{ url_for('static', filename='img/logo-horizontal.png') }}" height="15" alt="Validata" /> <img src="{{ url_for('static', filename='img/logo-horizontal.png') }}" height="15" alt="Validata" />
</a> </a>
...@@ -41,14 +41,21 @@ ...@@ -41,14 +41,21 @@
</nav> </nav>
<!-- Breadcrumbs --> <!-- Breadcrumbs -->
{% if breadcrumbs %}
<nav aria-label="breadcrumb"> <nav aria-label="breadcrumb">
<ol class="breadcrumb"> <ol class="breadcrumb">
{% for bc in breadcrumbs %} {% for bc in breadcrumbs %}
<li class="breadcrumb-item"><a href="{{ bc.url }}">{{ bc.title|e }}</a></li> <li class="breadcrumb-item">
{% if bc.url %}
<a href="{{ bc.url }}">{{ bc.title|e }}</a>
{% else %}
<span>{{ bc.title|e }}</span>
{% endif %}
</li>
{% endfor %} {% endfor %}
<li class="breadcrumb-item active" aria-current="page">{{ title|e }}</li>
</ol> </ol>
</nav> </nav>
{% endif %}
<!-- Flashing messages --> <!-- Flashing messages -->
{% with messages = get_flashed_messages(with_categories=true) %} {% with messages = get_flashed_messages(with_categories=true) %}
...@@ -62,8 +69,8 @@ ...@@ -62,8 +69,8 @@
{% endwith %} {% endwith %}
<!-- main content --> <!-- main content -->
<div id="content" class="container-fluid"> <div id="content" class="container">
{% block content %}{% endblock %} {% block content %}{% endblock %}
</div> </div>
<footer class="footer hidden-print"> <footer class="footer hidden-print">
......
{% extends "base_template.html" %} {% block title %}{{ title }}{% endblock %} {% {% extends "base_template.html" %}
block head %}
{{ super() }} {% block title %}Accueil{% endblock %}
{% endblock %} {% block content %}
<h1 class="my-4">Validez vos jeux de données</h1> {% block content %}
{% for section in config.sections %}
{% if section.name != "external" %}
<div class="mb-5">
<h2 class="my-4">{{section.title}}</h2>
<form action="{{ url_for('custom_validator') }}" method="GET">
<div class="form-row">
<div class="form-group col-lg-9">
<select required name="schema_name" class="form-control">
<option disabled selected value="">Choisissez un schéma</option>
{% for val in section.catalog | sort(attribute='title') %}
<option value="{{ val.name }}">{{ val.title }}</option>
{% endfor %}
</select>
</div>
<div class="form-group col-lg-3">
<button type="submit" class="btn btn-primary">Valider un fichier</button>
</div>
</div>
<input type="hidden" name="schema_ref" value="master" />
</form>
</div>
{% endif %}
{% endfor %}
<div class="my-5">
<h2 class="my-4">Autre schéma</h2>
<form action="{{ url_for('custom_validator') }}" method="GET">
<div class="form-row">
<div class="form-group col-lg-9">
<input
name="schema_url"
type="url"
class="form-control"
id="schema_url"
aria-describedby="urlHelpBlock"
placeholder="https://example.com/schema.json"
required
/>
<small id="urlHelpBlock" class="form-text text-muted">
Le schéma doit être au format
<a href="https://frictionlessdata.io/docs/table-schema/" target="_blank">Table Schema</a>.
</small>
</div>
<div class="form-group col-lg-3">
<button type="submit" class="btn btn-primary">Valider un fichier</button>
</div>
</div>
</form>
</div>
{% for section in config.sections %} {% for section in config.sections %}
<h2>{{section.title}}</h2> {% if section.name == "external" %}
<div class="row my-4"> <div class="my-5">
{% for val in section.catalog %} <h2 class="my-4">{{ section.title }}</h2>
{% if val.website %} <div class="row my-4">
<div class="col-sm-4 col-md-3 mb-4"> {% for val in section.catalog %}
<div class="card text-center h-100"> <div class="col-sm-4 mb-4">
<div class="card h-100">
<div class="card-body d-flex flex-column"> <div class="card-body d-flex flex-column">
<h4 class="card-title">{{ val.title }}</h4> <h4 class="card-title">{{ val.title }}</h4>
<p class="card-text">{{ val.description }}</p> <p class="card-text">{{ val.description }}</p>
<a <a
href="{{ val.website }}" target="_blank" href="{{ val.website }}" target="_blank"
class="btn btn-primary mt-auto" class="btn btn-outline-secondary mt-auto"
>Voir >Utiliser
<i class="fas fa-external-link-alt ml-1"></i> <i class="fas fa-external-link-alt ml-1"></i>
</a </a
> >
</div> </div>
</div> </div>
</div> </div>
{% else %} {% endfor %}
<div class="col-sm-4 col-md-3 mb-4"> </div>
<div class="card text-center h-100">
<div class="card-body d-flex flex-column">
<h4 class="card-title">{{ val.title }}</h4>
<p class="card-text">{{ val.description }}</p>
<a
href="{{ url_for('custom_validator') }}?schema_name={{val.name}}&schema_ref=master"
class="btn btn-primary mt-auto"
>Choisir</a
>
</div>
</div>
</div>
{% endif %}
{% endfor %}
</div> </div>
{% endif %}
{% endfor %} {% endfor %}
<h2>Validation à la carte</h2>
<p>
<form action="{{ url_for('custom_validator') }}" method="GET">
<div class="form-group">
<label for="schema_url">Indiquez ici l'URL du schéma de validation à utiliser</label>
<input
name="schema_url"
type="url"
class="form-control"
id="schema_url"
aria-describedby="urlHelp"
placeholder="https://..."
/>
</div>
<input type="submit" class="btn btn-primary" value="Continuer" />
</form>
</p>
{% endblock %} {% endblock %}
{% macro html(schema_info, schema_versions, schema_current_version, doc_url) %} {% macro html(schema_info, schema_versions, schema_current_version, doc_url) %}
<h5 class="card-title"> <h2 class="card-title">
Schéma
{% if schema_info.title %} {% if schema_info.title %}
« {{ schema_info.title }} » {{ schema_info.title }}
{% endif %} {% endif %}
{% if schema_info.version %} {% if schema_info.version %}
<span class="badge badge-primary">{{ schema_info.version }}</span> <span class="badge badge-primary">{{ schema_info.version }}</span>
{% endif %} {% endif %}
</h5> </h2>
{% if schema_versions %}
<form class="form-inline my-2">
<div class="form-group">
<label for="git_ref" class="mr-2">Version</label>
<select class="form-control" id="version_select" name="git_ref">
{% for sv in schema_versions %}
<option{% if sv.name == schema_current_version %} selected="selected"{% endif %}>{{ sv.name }}</option>
{% endfor %}
</select>
</div>
</form>
{% endif %}
{% if schema_info.description %} {% if schema_info.description %}
<h6 class="card-subtitle mb-2 text-muted">{{ schema_info.description }}</h6> <p>{{ schema_info.description }}</p>
{% endif %} {% endif %}
{% if schema_info.contributors %} {% if schema_info.contributors %}
<p> <p>Contributeurs :</p>
<h6>Contributeur{% if schema_info.contributors|length > 1 %}s{% endif %} :</h6> <ul>
<ul> {% for contributor in schema_info.contributors %}
{% for contributor in schema_info.contributors %} <li>
<li> {{ contributor.title }}{% if contributor.title and contributor.organisation %}, {% endif %}
{{ contributor.title }}{% if contributor.title and contributor.organisation %}, {% endif %} {% if contributor.organisation %}{{ contributor.organisation }}{% endif %}
{% if contributor.organisation %}{{ contributor.organisation }}{% endif %}
{# role #}
{# role #} {% if contributor.role == 'author' %}(auteur){% endif %}
{% if contributor.role == 'author' %}(auteur){% endif %} {% if contributor.role == 'contributor' %}(contributeur){% endif %}
{% if contributor.role == 'contributor' %}(contributeur){% endif %} </li>
</li> {% endfor %}
{% endfor %} </ul>
</ul>
</p>
{% endif %} {% endif %}
{% if schema_info.homepage or schema_info.url %}
<p> {% if schema_info.homepage %}
{% if schema_info.homepage %} <a href="{{ schema_info.homepage }}" target="_blank" class="card-link d-block ml-0">
Site : <a href="{{ schema_info.homepage }}" target="_blank" title="{{ schema_info.homepage }}" class="card-link">{{ schema_info.homepage | truncate(40) }}</a> Page d'accueil
{% endif %} </a>
{#
{% if schema_info.homepage and schema_info.url %}<br />{% endif %}
{% if schema_info.url %}
Source : <a href="{{ schema_info.url }}" target="_blank" title="{{ schema_info.url }}" class="card-link">{{ schema_info.url | truncate(40) }}</a>
{% endif %}
#}
</p>
{% endif %} {% endif %}
{% if schema_versions %}
<p> {% if schema_current_version == 'master' %}
Changer de version Git : <a href="{{ doc_url }}" target="_blank" class="card-link d-block ml-0">Documentation</a>
<select id="version_select">
{% for sv in schema_versions %}
<option{% if sv.name == schema_current_version %} selected="selected"{% endif %}>{{ sv.name }}</option>
{% endfor %}
</select>
{% if schema_current_version == 'master' %}
<br />
<a href="{{ doc_url }}" target="_blank">Documentation</a>
{% endif %}
</p>
{% endif %} {% endif %}
{% endmacro %} {% endmacro %}
......
{% extends "base_template.html" %} {% extends "base_template.html" %}
{% import 'schema_info_part.html' as schema_info_part %} {% import 'schema_info_macros.html' as schema_info_macros %}
{% block title %}{{ title }}{% endblock %} {% block title %}{{ section_title }} – {{ schema_info.title }}{% endblock %}
{% block content %} {% block content %}
<h1 class="my-4">{{ title }}</h1> <div class="row my-4">
<div class="col-lg-6 mb-4">
{% set cols_my_classes = 'my-md-0 my-4' %} <div class="card">
<div class="row">
<div class="col-md-4 {{ cols_my_classes }}">
<div class="card bg-faded">
<div class="card-body"> <div class="card-body">
{{ schema_info_part.html(schema_info, schema_versions, schema_current_version, doc_url) }} {{ schema_info_macros.html(schema_info, schema_versions, schema_current_version, doc_url) }}
</div> </div>
</div> </div>
</div> </div>
<div class="col-md-8 {{ cols_my_classes }}"> <div class="col-lg-6">
<h2>Outil de validation</h2>
<!-- Tab validator -->
<p class="text">Validez ici le fichier de votre choix</p>
<ul class="nav nav-tabs" id="myTab" role="tablist"> <ul class="nav nav-tabs" id="myTab" role="tablist">
<li class="nav-item"> <li class="nav-item">
<a class="nav-link active" id="file-tab" data-toggle="tab" href="#file" role="tab" aria-controls="file" <a class="nav-link active" id="file-tab" data-toggle="tab" href="#file" role="tab" aria-controls="file"
...@@ -38,51 +32,52 @@ ...@@ -38,51 +32,52 @@
</ul> </ul>
{% set padding_class = 'p-3' %} {% set padding_class = 'p-3' %}
<div class="tab-content" id="myTabContent"> <div class="tab-content" id="myTabContent">
<div class="tab-pane fade show active {{ padding_class }}" id="file" role="tabpanel" aria-labelledby="file-tab"> <div class="tab-pane show active {{ padding_class }}" id="file" role="tabpanel" aria-labelledby="file-tab">
<form method="POST" enctype="multipart/form-data"> <form method="POST" enctype="multipart/form-data">
<input type="hidden" name="input" value="file" /> <input type="hidden" name="input" value="file" />
{% for key, value in schema_params.items() %} {% for key, value in schema_params.items() %}
<input type="hidden" name="{{ key }}" value="{{ value }}" /> <input type="hidden" name="{{ key }}" value="{{ value }}" />
{% endfor %} {% endfor %}
<div class="form-group"> <div class="form-group">
<label for="file">Choisissez un fichier tabulaire à valider (.xlsx, .xls, .ods, .csv, .tsv, <input required type="file" class="form-control-file" name="file" id="file" accept=".csv, .xls, .xlsx, .ods" aria-describedby="fileHelpBlock" />
etc.)</label> <small id="fileHelpBlock" class="form-text text-muted">
<input type="file" class="form-control-file" name="file" id="file" accept=".csv, .xls, .xlsx, .ods" /> Exemple : .xlsx, .xls, .ods, .csv, .tsv, etc.
</small>
</div> </div>
<button type="submit" class="btn btn-primary">Valider</button> <button type="submit" class="btn btn-primary">Valider le fichier</button>
</form> </form>
</div> </div>
<div class="tab-pane fade {{ padding_class }}" id="url" role="tabpanel" aria-labelledby="url-tab"> <div class="tab-pane {{ padding_class }}" id="url" role="tabpanel" aria-labelledby="url-tab">
<form method="GET"> <form method="GET">
<input type="hidden" name="input" value="url" /> <input type="hidden" name="input" value="url" />
{% for key, value in schema_params.items() %} {% for key, value in schema_params.items() %}
<input type="hidden" name="{{ key }}" value="{{ value }}" /> <input type="hidden" name="{{ key }}" value="{{ value }}" />
{% endfor %} {% endfor %}
<div class="form-group"> <div class="form-group">
<label for="url">Indiquez l'URL de la table à valider</label> <input required name="url" type="url" class="form-control" id="url" aria-describedby="urlHelpBlock" placeholder="https://example.com/file.csv" />
<input name="url" type="url" class="form-control" id="url" aria-describedby="urlHelp" <small id="urlHelpBlock" class="form-text text-muted">
placeholder="https://..." /> Exemple : .xlsx, .xls, .ods, .csv, .tsv, etc.
</small>
</div> </div>
<button type="submit" class="btn btn-primary">Valider</button> <button type="submit" class="btn btn-primary">Valider le fichier</button>
</form> </form>
</div> </div>
{% if schema_info.resources %} {% if schema_info.resources %}
<div class="tab-pane fade {{ padding_class }}" id="example" role="tabpanel" aria-labelledby="examples-tab"> <div class="tab-pane {{ padding_class }}" id="example" role="tabpanel" aria-labelledby="examples-tab">
<form method="GET"> <form method="GET">
<input name="input" value="example" type="hidden"> <input name="input" value="example" type="hidden">
{% for key, value in schema_params.items() %} {% for key, value in schema_params.items() %}
<input type="hidden" name="{{ key }}" value="{{ value }}" /> <input type="hidden" name="{{ key }}" value="{{ value }}" />
{% endfor %} {% endfor %}
<div class="form-group"> <div class="form-group">
<label for="url">Choisissez l'exemple à valider</label> <select required name="url" id="url" class="form-control">
<select name="url" id="url" class="form-control"> <option selected disabled value="">Choisissez un fichier tabulaire d'exemple</option>
<option value="">...</option>
{% for res in schema_info.resources %} {% for res in schema_info.resources %}
<option value="{{ res.path }}">{{ res.title }}</option> <option value="{{ res.path }}">{{ res.title }}</option>
{% endfor %} {% endfor %}
</select> </select>
</div> </div>
<button type="submit" class="btn btn-primary">Valider</button> <button type="submit" class="btn btn-primary">Valider le fichier</button>
</form> </form>
</div> </div>
{% endif %} {% endif %}
...@@ -93,6 +88,6 @@ ...@@ -93,6 +88,6 @@
{% block page_scripts %} {% block page_scripts %}
{% if schema_versions %} {% if schema_versions %}
{{ schema_info_part.script() }} {{ schema_info_macros.script() }}
{% endif %} {% endif %}
{% endblock %} {% endblock %}
\ No newline at end of file
{% macro preview(source_data) %} {% macro preview(source_data) %}
<p class="text"> <p>
Affichage de {{ source_data.preview_rows_nb }} lignes sur {{ source_data.rows_nb }} au total 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> </p>
<div class="table-responsive"> <div class="table-responsive">
<table class="table table-striped table-bordered table-sm table-hover"> <table class="table table-striped table-bordered table-sm table-hover">
...@@ -114,41 +114,26 @@ ...@@ -114,41 +114,26 @@
{% set structure_errors = report.table['error-stats']['structure-errors'] %} {% set structure_errors = report.table['error-stats']['structure-errors'] %}
{% if structure_errors['count'] != 0 %} {% if structure_errors['count'] != 0 %}
Erreurs de structure ({{ structure_errors['count'] }}) : <p>Erreur de structure ({{ structure_errors['count'] }}) :</p>
<ul> <ul>
{% for elt in structure_errors['count-by-code'] %} {% for item in structure_errors['count-by-code'] %}
<li>{{ elt[0] }} : {{ elt[1] }}</li> <li>{{ item[0] }} ({{ item[1] }})</li>
{% endfor %} {% endfor %}
</ul> </ul>
{% else %} {% else %}
Aucune erreur de structure.<br/> <p>Aucune erreur de structure.</p>
{% endif %} {% endif %}
{% if report.table.do_display_body_errors %} {% if report.table.do_display_body_errors %}
{% set value_errors = report.table['error-stats']['value-errors'] %} {% set value_errors = report.table['error-stats']['value-errors'] %}
{% if value_errors['count'] != 0 %} {% if value_errors['count'] > 0 %}
Erreurs de contenu ({{ value_errors['count'] }}) : <p>Erreur de contenu ({{ value_errors['count'] }} sur {{ value_errors['rows-count'] }} ligne{% if value_errors['rows-count'] > 1 %}s{% endif %}) :</p>
<ul> <ul>
{% for elt in value_errors['count-by-code'] %} {% for item in value_errors['count-by-code'] %}
<li>{{ elt[0] }} : {{ elt[1] }}</li> <li>{{ item[0] }} ({{ item[1] }})</li>
{% endfor %} {% endfor %}
</ul> </ul>
<p>
{% if value_errors['rows-count'] == 1 %}
1 ligne en erreur
{% else %}
{{ value_errors['rows-count'] }} lignes en erreur
{% endif %}
sur
{% if report.table['row-count'] == 1 %}
1 ligne
{% else %}
{{ report.table['row-count'] }} lignes
{% endif %}
au total
</p>
{% endif %} {% endif %}
{% endif %} {% endif %}
......
{% extends "base_template.html" %} {% extends "base_template.html" %}
{% import 'schema_info_part.html' as schema_info_part %} {% import 'schema_info_macros.html' as schema_info_macros %}
{% import 'validation_macros.html' as macros %}
{% block title %}{{ title }}{% endblock %} {% block title %}{{ section_title }} – {{ schema_info.title }}{% endblock %}
{% block head %} {% block head %}
{{ super() }} {{ super() }}
...@@ -25,82 +26,75 @@ ...@@ -25,82 +26,75 @@
{% endblock %} {% endblock %}
{% block content %} {% block content %}
{% if print_mode %}
<div class="row"> <p>Validation effectuée {{ validation_date }}</p>
<div class="col-md-5">
{% endif %}
<h1 class="my-4">{{ title }}</h1>
<p>Validation effectuée {{ validation_date }}</p>
{% if display_badge %}
<p><img src="{{ badge_url }}" alt="{{ badge_msg }}" title="{{ badge_msg }}"/></p>
{% endif %}
{% if print_mode %}
</div>
<div class="col-md-7">
<img src="{{ url_for('static', filename='img/logo-horizontal.png') }}" height="80" alt="Validata" />
</div>
</div>
{% endif %}
{% if source.type == 'url' %} {% if source.type == 'url' %}
<p class="hidden-print"> <p class="hidden-print">
<a href="{{ pdf_report_url }}&url={{source.url|urlencode}}" target="_blank"> <a class="btn btn-outline-secondary" href="{{ pdf_report_url }}&url={{source.url|urlencode}}" target="_blank">
Télécharger en PDF Télécharger en PDF
</a> </a>
</p> </p>
{% endif %} {% endif %}
{# Schema info #} {# Schema info #}
<div class="row"> <div class="row my-4">
<div class="col-md-{% if print_mode %}12{% else %}5{% endif %} my-4"> <div class="col-lg-6 mb-4">
<div class="card bg-faded"> <div class="card">
<div class="card-body">
{{ schema_info_macros.html(schema_info, None, schema_current_version, doc_url) }}
</div>
</div>
</div>
<div class="col-lg-6">
<div class="card">
<div class="card-body"> <div class="card-body">
{{ schema_info_part.html(schema_info, schema_versions, schema_current_version, doc_url) }} <h2 class="card-title">
<hr /> Fichier {% if report.error_count == 0 %}valide{% else %}invalide{% endif %}
<div> </h2>
<h5 class="card-title">
Fichier traité {% if display_badge %}
</h5> <p><img src="{{ badge_url }}" alt="{{ badge_msg }}" /></p>
{% endif %}
<p>
<code>
{% if source.type == 'file' %} {% if source.type == 'file' %}
{{ source.filename }} {{ source.filename }}
{% elif source.type == 'url' %}
<a href="{{source.url}}" target="_blank">{{source.filename}}</a>
{% endif %} {% endif %}
{% if source.type == 'url' %} </code>
<a href="{{source.url}}" target="_blank"> ({{ report.table.col_count }} colonnes × {{ report.table.row_count }} lignes)
{{source.url}} </p>
</a>
{% if report.error_count == 0 %}
<p>Aucune erreur détectée</p>
{% else %}
{{ macros.error_statistics(report) }}
<p>
{% set error_count = report.table['error-stats']['count'] %}
Total :
{% if error_count == 1 %}
1 erreur détectée
{% else %}
{{ error_count }} erreurs détectées
{% endif %} {% endif %}
<br /> </p>
Dimensions : {{ report.table.col_count }} colonnes et {{ report.table.row_count }} lignes {% endif %}
</div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
{% import 'validation_macros.html' as macros %}
{% if report.error_count == 0 %} {% if report.error_count == 0 %}
<h2>La table est valide</h2>
<p>Aucune erreur détectée</p>
{{ macros.preview(source_data) }} {{ macros.preview(source_data) }}
{% else %} {% else %}
<h2>La table est invalide</h2>
<p>
{% set error_count = report.table['error-stats']['count'] %}
{% if error_count == 1 %}
1 erreur détectée.
{% else %}
{{ error_count }} erreurs détectées.
{% endif %}
</p>
{{ macros.error_statistics(report) }}
{% if report.table.errors.structure %} {% if report.table.errors.structure %}