Ajout du frontend et branchement sur l'API axione #9

Merged
felix.baylac merged 21 commits from johan/frontend into master 2022-02-13 19:39:12 +01:00
3 changed files with 143 additions and 78 deletions
Showing only changes of commit 7672a52239 - Show all commits

View file

@ -34,7 +34,7 @@ def fantoirRequest(insee, rivoli, numVoie):
<com:operateurCommercial nom="AQUILENET" identifiant=""/>
</ent:entete>
<ent:referenceAdresse>
<com:referenceRivoli codeInsee="{insee}" codeRivoli="{rivoli}" numeroVoie="{numvoie}"/>
<com:referenceRivoli codeInsee="{insee}" codeRivoli="{rivoli}" numeroVoie="{numVoie}"/>
</ent:referenceAdresse>
</ent:obtentionStructureAdresseDemandeSoap>
</soapenv:Body>

View file

@ -1,17 +1,24 @@
<!doctype html>
<html lang="fr">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<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">
<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
<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">
<script src="https://code.jquery.com/jquery-3.6.0.min.js"
integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"
integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1"
crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"
integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM"
crossorigin="anonymous"></script>
<title>Aquilenet: Éligibilité FTTH</title>
<style>
{% include 'style.css' %}
{% include 'style.css'%}
</style>
</head>
@ -24,16 +31,20 @@
<div class="col-12 text-intro">
<div id="methodPto" class="collapse show testMethods">
<h2 class="text-center form-title">Test d'éligibilité par PTO</h1>
<h2 class="text-center form-title">Test d'éligibilité par PTO</h2>
<form method="post" action="/test/pto">
<div class="form-group" id="ptoForm">
<label class="form-label" for="pto-number">Numéro PTO</label>
<input required type="text" class="form-control" name="pto" id="pto-number" aria-describedby="ptoHelp" placeholder="OOOO-XXXX-XXXX" oninvalid="this.setCustomValidity('Veuillez renseigner le PTO')" oninput="setCustomValidity('')">
<input required type="text" class="form-control" name="pto" id="pto-number" aria-describedby="ptoHelp"
placeholder="OOOO-XXXX-XXXX" oninvalid="this.setCustomValidity('Veuillez renseigner le PTO')"
oninput="setCustomValidity('')">
<small id="ptoHelp" class="form-text btn btn-link" data-toggle="collapse" data-target="#ptoInfo" aria-expanded="true" aria-controls="ptoInfo">Où trouver mon numéro de PTO ?</small>
<small id="ptoHelp" class="form-text btn btn-link" data-toggle="collapse" data-target="#ptoInfo"
aria-expanded="true" aria-controls="ptoInfo">Où trouver mon numéro de PTO ?</small>
<div id="ptoInfo" class="collapse" aria-labelledby="ptoForm" data-parent="#ptoForm">
<div class="card-body">
PTO (Point de terminaison optique) est un numéro unique que vous pouvez trouver sur le boîtier de raccordement de la fibre.
PTO (Point de terminaison optique) est un numéro unique que vous pouvez trouver sur le boîtier de
raccordement de la fibre.
C'est un petit boîtier blanc installé dans la maison
<br>
<img src="{{url_for('static', filename='find_pto.jpg')}}" class="img-fluid" alt="Responsive image">
@ -44,105 +55,150 @@
</form>
<br>
<button id="buttonNoPto" type="button" data-toggle="collapse" data-target=".testMethods" class="btn btn-link" aria-expanded="false" aria-controls="methodPto methodAddress">Je n'ai pas/ne trouve pas le PTO, tester autrement</button>
<button id="buttonNoPto" type="button" data-toggle="collapse" data-target=".testMethods"
class="btn btn-link" aria-expanded="false" aria-controls="methodPto methodAddress">Je n'ai pas/ne trouve
pas le PTO, tester autrement</button>
</div>
<div id="methodAddress" class="collapse testMethods">
<h2 class="text-center form-title">Test d'éligibilité par adresse</h1>
<form method="post" action="/test/address">
<div class="form-group" id="communeForm">
<label class="form-label" for="communeInput">Commune</label>
<input autocomplete="off" type="text" list="communes" name="commune" class="form-control" id="communeInput" ondblclick="this.focus();this.select()" aria-describedby="communeHelp" placeholder="Nom de la commune ou code postal">
<datalist id="communes">
</datalist>
</div>
<div class="form-row collapse" id="voieForm">
<div class="col-sm-3 my-1">
<label class="form-label" for="numeroVoieInput">Numéro de voie</label>
<input required type="text" name="numeroVoie" class="form-control" id="numeroVoieInput" aria-describedby="numeroVoieHelp" placeholder="Numéro de voie" oninvalid="this.setCustomValidity('Veuillez renseigner le numéro de voie')" oninput="setCustomValidity('')">
</div>
<div class="col-sm-9 my-1">
<label class="form-label" for="voieInput">Nom de voie</label>
<input autocomplete="off" type="text" name="voie" list="voies" class="form-control" id="voieInput" aria-describedby="voieHelp" placeholder="Nom de voie">
<datalist id="voies">
<h2 class="text-center form-title">Test d'éligibilité par adresse</h2>
<form id="formAddressTest" method="post" action="/test/address">
<div class="form-group" id="communeForm">
<label class="form-label" for="communeInput">Commune</label>
<input autocomplete="off" type="text" list="communes" name="commune" class="form-control"
id="communeInput" ondblclick="this.focus();this.select()" aria-describedby="communeHelp"
placeholder="Nom de la commune ou code postal">
<datalist id="communes">
</datalist>
</div>
</div>
<div class="form-row collapse" id="voieForm">
<div class="col-sm-3 my-1">
<label class="form-label" for="numeroVoieInput">Numéro de voie</label>
<input required type="text" name="numeroVoie" class="form-control" id="numeroVoieInput"
aria-describedby="numeroVoieHelp" placeholder="Numéro de voie"
oninvalid="this.setCustomValidity('Veuillez renseigner le numéro de voie')"
oninput="setCustomValidity('')">
</div>
<div class="col-sm-9 my-1">
<label class="form-label" for="voieInput">Nom de voie</label>
<input autocomplete="off" type="text" name="voie" list="voies" class="form-control" id="voieInput"
aria-describedby="voieHelp" placeholder="Nom de voie">
<datalist id="voies">
</datalist>
</div>
</div>
<br>
<button id="btnTestAdresse" type="submit" class="btn btn-sable collapse">Tester l'adresse</button>
</form>
<br>
<button id="btnTestAdresse" type="submit" class="btn btn-sable collapse">Tester l'adresse</button>
</form>
<br>
<button id="buttonReturnPto" type="button" data-toggle="collapse" data-target=".testMethods" class="btn btn-link" aria-expanded="false" aria-controls="methodPto methodAddress">Revenir au test par PTO</button>
<button id="buttonReturnPto" type="button" data-toggle="collapse" data-target=".testMethods"
class="btn btn-link" aria-expanded="false" aria-controls="methodPto methodAddress">Revenir au test par
PTO</button>
</div>
</div>
</div>
</div>
<script>
$(document).ready(function(){
var communes=[]
var codeInsee=0
var voies=[]
var voie=""
function fillCommunes(search='') {
var api="addresses/communes?limit=15";
$(document).ready(function () {
// AbortController allows to cancel promises
const controllerCommunes = new AbortController();
const { signalCommunes } = controllerCommunes;
const controllerVoies = new AbortController();
const { signalVoies } = controllerVoies;
// Global variables
var communes = []
var codeInsee = 0
var voies = []
var voie = ""
function sanitizeInputStr(inputStr) {
inputStr = inputStr.replace(/[ÀÁÂÃÄÅàáâãäå]/g, "a");
inputStr = inputStr.replace(/[Ææ]/g, "ae");
inputStr = inputStr.replace(/[Çç]/g, "c");
inputStr = inputStr.replace(/[ÈÉÊËèéêë]/g, "e");
inputStr = inputStr.replace(/[ÌÍÎÏìíîï]/g, "i");
inputStr = inputStr.replace(/[Ññ]/g, "n");
inputStr = inputStr.replace(/[ÒÓÔÕÖòóôõö]/g, "o");
inputStr = inputStr.replace(/[ÙÚÛÜùúûü]/g, "u");
inputStr = inputStr.replace(/[Ýý]/g, "y");
inputStr = inputStr.replace(/[ß]/g, "ss");
return inputStr;
}
// Function to update list of communes (calls backend API)
function updateCommunes(search = '') {
var api = "addresses/communes?limit=15";
if (search != '') {
api+="&s="+search;
api += "&s=" + search;
}
$.ajax({
type: 'GET',
dataType:"json",
url: api,
success: function (data, status, xhr) {
if (JSON.stringify(data) !== JSON.stringify(communes)){
fetch(api, { signalCommunes })
.then(response => response.json())
.then(data => {
if (JSON.stringify(data) !== JSON.stringify(communes)) {
$("#communes").empty();
communes=data
communes = data
communes.forEach(commune => {
$("#communes").append("<option codeInsee=" + commune.codeInsee + " value='" +
commune.codeZip + ' ' + commune.nom + "'></option>");
});
}
if (communes.length == 1) {
codeInsee=communes[0].codeInsee;
codeInsee = communes[0].codeInsee;
$('#voieForm').collapse('show');
} else {
$('#voieInput').val('');
$('#voieForm').collapse('hide');
}
}
});
})
.catch(err => {
if (err.name === "AbortError") {
console.log("DEBUG: updateCommunes aborted !")
}
console.error("Error fetching communes:", err)
})
}
var voies=[]
function fillVoies(codeInsee,search='') {
var api="addresses/fantoirvoies/" + codeInsee + '?limit=15';
// Function to update list of voies (calls backend API)
function updateVoies(codeInsee, search = '') {
var api = "addresses/fantoirvoies/" + codeInsee + '?limit=15';
if (search != '') {
api+="&s="+search;
api += "&s=" + search;
}
$.ajax({
type: 'GET',
dataType:"json",
url: api,
success: function (data, status, xhr) {
if (JSON.stringify(data) !== JSON.stringify(voies)){
fetch(api, { signalVoies })
.then(response => response.json())
.then(data => {
if (JSON.stringify(data) !== JSON.stringify(voies)) {
$("#voies").empty();
voies=Object.entries(data);
let voie;
for (i in voies) {
voie = voies[i]
$("#voies").append("<option id=" + voie[1] + " value='" +
voie[0] + "'></option>");
voies = Object.entries(data);
console.log(voies)
let voie;
for (i in voies) {
voie = voies[i]
$("#voies").append("<option id=" + voie[1] + " value='" +
voie[0] + "'></option>");
}
console.log(voies)
if (voies.length == 1) {
$('#btnTestAdresse').collapse('show');
voie=voies[0].libelle[0]
voie = voies[0]
} else {
$('#btnTestAdresse').collapse('hide');
}
}
}
});
})
.catch(err => {
if (err.name === "AbortError") {
console.log("DEBUG: updateCommunes aborted !")
}
console.error("Error fetching communes:", err)
})
}
$('#methodAddress').on('show.bs.collapse', function () {
$('#communeInput').trigger('input')
@ -154,16 +210,20 @@
});
$('#communeInput').on('keyup', function () {
fillCommunes($(this).val());
controllerCommunes.abort();
inputStr = sanitizeInputStr($(this).val());
updateCommunes(inputStr);
});
$('#communeInput').on('input', function() {
$('#communeInput').on('input', function () {
if ($(this).val() === '') {
$('#voieForm').collapse('hide');
}
});
$('#voieInput').on('keyup', function () {
fillVoies(codeInsee,$(this).val());
controllerVoies.abort();
inputStr = sanitizeInputStr($(this).val());
updateVoies(codeInsee, inputStr);
});
$('#voieInput').on('input', function () {
if ($(this).val() === '') {
@ -171,7 +231,13 @@
}
});
$('#formAddressTest').submit(function(eventObj) {
console.log("SUBMIT",$('#formAddressTest'))
$('#formAddressTest').append(`<input type="hidden" class="form-control" name="codeInsee" value="${codeInsee}" />`);
return true;
});
});
</script>
</body>
</html>
</html>

View file

@ -3,7 +3,7 @@ from flask import Flask, render_template, request, escape
import json
from config.config import parse_config
from axione_api.api import query_axione_pto, parse_response
from axione_api.api import query_axione_pto, parse_response, query_axione_fantoir
from address_finder.api import AddressFinder
def load_config():
@ -54,12 +54,11 @@ def get_fantoir_voies(codeInsee):
@app.route("/test/address", methods=['POST'])
def test_address():
commune = escape(request.form['commune'])
codeInsee = escape(request.form['codeInsee'])
numeroVoie = escape(request.form['numeroVoie'])
# Trimming rivoli's key
voie = escape(request.form['voie'])[:-1]
result = query_axione_fantoir(cfg, commune, voie, numeroVoie)
# result = parse_response(query_axione_pto(cfg, pto))
result = query_axione_fantoir(cfg, codeInsee, voie, numeroVoie)
return render_template("result.html", pto="", result=result)