territories-dashboard-lib 0.1.0__py3-none-any.whl → 0.1.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of territories-dashboard-lib might be problematic. Click here for more details.
- territories_dashboard_lib/commons/__init__.py +0 -0
- territories_dashboard_lib/commons/decorators.py +36 -0
- territories_dashboard_lib/commons/models.py +9 -0
- territories_dashboard_lib/geo_lib/__init__.py +0 -0
- territories_dashboard_lib/geo_lib/admin.py +64 -0
- territories_dashboard_lib/geo_lib/enums.py +7 -0
- territories_dashboard_lib/geo_lib/migrations/0001_initial.py +51 -0
- territories_dashboard_lib/geo_lib/migrations/__init__.py +0 -0
- territories_dashboard_lib/geo_lib/models.py +58 -0
- territories_dashboard_lib/geo_lib/urls.py +27 -0
- territories_dashboard_lib/geo_lib/views.py +239 -0
- territories_dashboard_lib/indicators_lib/__init__.py +0 -0
- territories_dashboard_lib/indicators_lib/admin.py +140 -0
- territories_dashboard_lib/indicators_lib/enums.py +59 -0
- territories_dashboard_lib/indicators_lib/export.py +29 -0
- territories_dashboard_lib/indicators_lib/format.py +34 -0
- territories_dashboard_lib/indicators_lib/methodo_pdf.py +99 -0
- territories_dashboard_lib/indicators_lib/migrations/0001_initial.py +138 -0
- territories_dashboard_lib/indicators_lib/migrations/__init__.py +0 -0
- territories_dashboard_lib/indicators_lib/models.py +230 -0
- territories_dashboard_lib/indicators_lib/payloads.py +54 -0
- territories_dashboard_lib/indicators_lib/query/commons.py +223 -0
- territories_dashboard_lib/indicators_lib/query/comparison.py +70 -0
- territories_dashboard_lib/indicators_lib/query/details.py +64 -0
- territories_dashboard_lib/indicators_lib/query/histogram.py +82 -0
- territories_dashboard_lib/indicators_lib/query/indicator_card.py +102 -0
- territories_dashboard_lib/indicators_lib/query/top_10.py +100 -0
- territories_dashboard_lib/indicators_lib/query/utils.py +20 -0
- territories_dashboard_lib/indicators_lib/refresh_filters.py +17 -0
- territories_dashboard_lib/indicators_lib/table.py +154 -0
- territories_dashboard_lib/indicators_lib/urls.py +97 -0
- territories_dashboard_lib/indicators_lib/views.py +490 -0
- territories_dashboard_lib/superset_lib/__init__.py +0 -0
- territories_dashboard_lib/superset_lib/admin.py +22 -0
- territories_dashboard_lib/superset_lib/guest_token.py +64 -0
- territories_dashboard_lib/superset_lib/logic.py +67 -0
- territories_dashboard_lib/superset_lib/migrations/0001_initial.py +45 -0
- territories_dashboard_lib/superset_lib/migrations/__init__.py +0 -0
- territories_dashboard_lib/superset_lib/models.py +52 -0
- territories_dashboard_lib/superset_lib/serializers.py +10 -0
- territories_dashboard_lib/superset_lib/urls.py +10 -0
- territories_dashboard_lib/superset_lib/views.py +19 -0
- territories_dashboard_lib/tracking_lib/__init__.py +0 -0
- territories_dashboard_lib/tracking_lib/enums.py +7 -0
- territories_dashboard_lib/tracking_lib/logic.py +78 -0
- territories_dashboard_lib/tracking_lib/migrations/0001_initial.py +45 -0
- territories_dashboard_lib/tracking_lib/migrations/__init__.py +0 -0
- territories_dashboard_lib/tracking_lib/models.py +79 -0
- territories_dashboard_lib/website_lib/__init__.py +0 -0
- territories_dashboard_lib/website_lib/admin.py +40 -0
- territories_dashboard_lib/website_lib/context_processors.py +27 -0
- territories_dashboard_lib/website_lib/forms.py +47 -0
- territories_dashboard_lib/website_lib/migrations/0001_initial.py +91 -0
- territories_dashboard_lib/website_lib/migrations/__init__.py +0 -0
- territories_dashboard_lib/website_lib/models.py +148 -0
- territories_dashboard_lib/website_lib/navigation.py +124 -0
- territories_dashboard_lib/website_lib/params.py +268 -0
- territories_dashboard_lib/website_lib/serializers.py +105 -0
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/css/website.css +956 -0
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/chart.js +13 -0
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/chartjs-plugin-datalabels.js +1 -0
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/html2canvas.js +20 -0
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/comparaison/data.mjs +62 -0
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/comparaison/history.mjs +98 -0
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/comparaison/main-values.mjs +30 -0
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/comparaison/page.mjs +105 -0
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/comparaison/territory-chart.mjs +141 -0
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/details/data.mjs +59 -0
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/details/histogram.mjs +130 -0
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/details/map.mjs +25 -0
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/details/page.mjs +96 -0
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/details/proportions.mjs +77 -0
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/details/sankey.mjs +27 -0
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/details/table.mjs +229 -0
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/details/top10.mjs +76 -0
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/details/utils.mjs +8 -0
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/dom.mjs +92 -0
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/enums.mjs +104 -0
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/export-graph.mjs +15 -0
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/export.mjs +20 -0
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/filters.mjs +159 -0
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/format.mjs +54 -0
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/side_panel.mjs +103 -0
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/theme/history.mjs +89 -0
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/theme/main-value.mjs +22 -0
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/theme/page.mjs +162 -0
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/theme/statistics.mjs +42 -0
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/utils.mjs +93 -0
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/static/page.mjs +35 -0
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/patternomaly.js +1452 -0
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/react18.js +31 -0
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/reactdom18.js +267 -0
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/supersetEmbed.js +355 -0
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/react/indicatorMap.bundle.js +2 -0
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/react/sankeyGraph.bundle.js +2 -0
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/react/vendors-node_modules_mapbox-gl_dist_mapbox-gl_js.bundle.js +2 -0
- territories_dashboard_lib/website_lib/static_content.py +20 -0
- territories_dashboard_lib/website_lib/templates/admin/indicators_lib/indicator/change_form.html +8 -0
- territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/404.html +10 -0
- territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/500.html +10 -0
- territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/layout/base.html +42 -0
- territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/layout/base.js +47 -0
- territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/layout/footer.html +96 -0
- territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/layout/header.html +101 -0
- territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/layout/header.js +102 -0
- territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/comparaison/[theme]/components/indicateur-card.html +48 -0
- territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/comparaison/[theme]/page.html +52 -0
- territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/components/chart-buttons.html +29 -0
- territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/components/geo_params.html +71 -0
- territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/components/indicator-card.html +52 -0
- territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/components/loader.html +28 -0
- territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/components/side_panel.html +27 -0
- territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/components/side_panel_geo.html +80 -0
- territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/components/side_panel_geo.js +85 -0
- territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/components/side_panel_methodo.html +45 -0
- territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/components/side_panel_methodo.js +19 -0
- territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/components/themes-list.html +9 -0
- territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/components/themes-nav.html +33 -0
- territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/components/title.html +28 -0
- territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/details/components/filters-reminder.html +19 -0
- territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/details/components/table.html +123 -0
- territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/details/page.html +166 -0
- territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/themes/components/extremum.html +15 -0
- territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/themes/components/indicateur-card.html +76 -0
- territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/themes/page.html +66 -0
- territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/lexique/page.html +17 -0
- territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/page.html +14 -0
- territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/sitemap/page.html +71 -0
- territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/static/page.html +16 -0
- territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/superset/page.html +55 -0
- territories_dashboard_lib/website_lib/templatetags/htmlparams.py +75 -0
- territories_dashboard_lib/website_lib/templatetags/other_filters.py +30 -0
- territories_dashboard_lib/website_lib/views.py +212 -0
- {territories_dashboard_lib-0.1.0.dist-info → territories_dashboard_lib-0.1.2.dist-info}/METADATA +1 -1
- territories_dashboard_lib-0.1.2.dist-info/RECORD +138 -0
- territories_dashboard_lib-0.1.0.dist-info/RECORD +0 -5
- {territories_dashboard_lib-0.1.0.dist-info → territories_dashboard_lib-0.1.2.dist-info}/WHEEL +0 -0
- {territories_dashboard_lib-0.1.0.dist-info → territories_dashboard_lib-0.1.2.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
from django.db import models
|
|
2
|
+
|
|
3
|
+
from territories_dashboard_lib.commons.models import CommonModel
|
|
4
|
+
from territories_dashboard_lib.indicators_lib.enums import MeshLevel
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Dashboard(CommonModel):
|
|
8
|
+
superset_id = models.TextField(
|
|
9
|
+
unique=True,
|
|
10
|
+
verbose_name="Embed ID de Superset",
|
|
11
|
+
help_text="Un utilisateur administrateur de l'instance Superset doit accéder aux paramètres du dashboard et cliquer sur 'embed dashboard' pour récupérer cet ID nécessaire à la connexion avec l'instance Superset.",
|
|
12
|
+
)
|
|
13
|
+
short_name = models.TextField(
|
|
14
|
+
unique=True,
|
|
15
|
+
verbose_name="Nom court",
|
|
16
|
+
help_text="Pour l'URL, ne mettre que des lettres minuscules sans accents et des tirets",
|
|
17
|
+
)
|
|
18
|
+
label = models.TextField(
|
|
19
|
+
unique=True,
|
|
20
|
+
verbose_name="Label",
|
|
21
|
+
help_text="Nom du dashboard à afficher dans la liste.",
|
|
22
|
+
)
|
|
23
|
+
order = models.IntegerField(
|
|
24
|
+
default=1,
|
|
25
|
+
verbose_name="Numéro d'ordre",
|
|
26
|
+
help_text="Numéro d'ordre dans la dropdown de sélection, les dashboards sont triés du plus petit numéro au plus grand.",
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
def __str__(self):
|
|
30
|
+
return self.label
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class Filter(CommonModel):
|
|
34
|
+
dashboard = models.ForeignKey(
|
|
35
|
+
Dashboard, on_delete=models.CASCADE, related_name="filters"
|
|
36
|
+
)
|
|
37
|
+
superset_id = models.TextField(
|
|
38
|
+
null=True,
|
|
39
|
+
blank=True,
|
|
40
|
+
help_text="ID du native filter du territoire, qui permettra d'initialiser les filtres du dasbhoard au territoire sélectionné dans l'application. Pour le récupérer c'est un petit parcours du combattant : aller sur le dashboard dans superset, cliquer sur modifier le dashboard, cliquer sur les trois petits points, puis sur modifier les propriétés. Cliquer sur avancé, copier le json et le coller dans un site comme : https://jsonformatter.curiousconcept.com/ pour mieux le voir. Chercher 'global_chart_configuration' puis 'native_filter_configuration'. Chercher le native filter lié au choix du territoire. Copier l'id qui dans son nom, le nom est de la forme NATIVE_FILTER-ID. Promis, c'est le plus simple que j'ai trouvé !",
|
|
41
|
+
)
|
|
42
|
+
superset_col = models.TextField(
|
|
43
|
+
null=True,
|
|
44
|
+
blank=True,
|
|
45
|
+
help_text="Nom de la colonne en base de données liée au filtre sur le territoire. Pour trouver le nom faire les mêmes étapes que pour geo_filter_id et chercher 'column' dans les paramètres json du native filter.",
|
|
46
|
+
)
|
|
47
|
+
mesh = models.TextField(
|
|
48
|
+
choices=MeshLevel.choices,
|
|
49
|
+
null=True,
|
|
50
|
+
blank=True,
|
|
51
|
+
help_text="Maille du territoire sur lequel s'effectue le filtre.",
|
|
52
|
+
)
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
from django.urls import path
|
|
2
|
+
|
|
3
|
+
from .views import dashboards_view, guest_token_view
|
|
4
|
+
|
|
5
|
+
app_name = "superset-api"
|
|
6
|
+
|
|
7
|
+
urlpatterns = [
|
|
8
|
+
path("guest-token/", guest_token_view, name="guest-token"),
|
|
9
|
+
path("dashboards/", dashboards_view, name="dashboards"),
|
|
10
|
+
]
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
from django.http import HttpResponse, JsonResponse
|
|
2
|
+
from django.views.decorators.http import require_GET
|
|
3
|
+
|
|
4
|
+
from .guest_token import get_guest_token
|
|
5
|
+
from .models import Dashboard
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
@require_GET
|
|
9
|
+
def guest_token_view(request):
|
|
10
|
+
dashboard_id = request.GET.get("dashboard")
|
|
11
|
+
guest_token = get_guest_token(dashboard_id)
|
|
12
|
+
return HttpResponse(guest_token)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@require_GET
|
|
16
|
+
def dashboards_view(request):
|
|
17
|
+
dashboards = Dashboard.objects.order_by("order", "label")
|
|
18
|
+
data = [{"label": d.label, "superset_id": d.superset_id} for d in dashboards]
|
|
19
|
+
return JsonResponse(data, safe=False)
|
|
File without changes
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import uuid
|
|
2
|
+
from datetime import timedelta
|
|
3
|
+
from typing import TYPE_CHECKING, Union
|
|
4
|
+
|
|
5
|
+
from django.http import HttpRequest, HttpResponse
|
|
6
|
+
from django.urls import resolve
|
|
7
|
+
|
|
8
|
+
from territories_dashboard_lib.tracking_lib.enums import TRACKING_COOKIE_NAME, EventType
|
|
9
|
+
from territories_dashboard_lib.tracking_lib.models import Event, Page
|
|
10
|
+
|
|
11
|
+
if TYPE_CHECKING:
|
|
12
|
+
from territories_dashboard_lib.indicators_lib.models import Indicator, Theme
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def get_or_set_tracking_cookie(request: HttpRequest, response: HttpResponse) -> str:
|
|
16
|
+
tracking_cookie = request.COOKIES.get(TRACKING_COOKIE_NAME)
|
|
17
|
+
if tracking_cookie is None:
|
|
18
|
+
tracking_cookie = str(uuid.uuid4())
|
|
19
|
+
response.set_cookie(
|
|
20
|
+
key=TRACKING_COOKIE_NAME,
|
|
21
|
+
value=tracking_cookie,
|
|
22
|
+
max_age=timedelta(days=365),
|
|
23
|
+
)
|
|
24
|
+
return tracking_cookie
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def track_page(
|
|
28
|
+
*,
|
|
29
|
+
request: HttpRequest,
|
|
30
|
+
response: HttpResponse,
|
|
31
|
+
params=None,
|
|
32
|
+
indicator: Union["Indicator", None] = None,
|
|
33
|
+
theme: Union["Theme", None] = None,
|
|
34
|
+
):
|
|
35
|
+
if params is None:
|
|
36
|
+
params = {}
|
|
37
|
+
try:
|
|
38
|
+
cookie = get_or_set_tracking_cookie(request, response)
|
|
39
|
+
match = resolve(request.path)
|
|
40
|
+
view_name = match.view_name
|
|
41
|
+
Page.objects.create(
|
|
42
|
+
cookie=cookie,
|
|
43
|
+
territory_id=params.get("territory_id"),
|
|
44
|
+
territory_mesh=params.get("territory_mesh"),
|
|
45
|
+
submesh=params.get("mesh"),
|
|
46
|
+
cmp_territory_id=params.get("cmp_territory_id"),
|
|
47
|
+
cmp_territory_mesh=params.get("cmp_territory_mesh"),
|
|
48
|
+
indicator=indicator.id if indicator else None,
|
|
49
|
+
indicator_name=indicator.name if indicator else None,
|
|
50
|
+
theme=theme.id if theme else None,
|
|
51
|
+
theme_name=theme.name if theme else None,
|
|
52
|
+
url=request.get_full_path(),
|
|
53
|
+
view=view_name,
|
|
54
|
+
)
|
|
55
|
+
except Exception as e:
|
|
56
|
+
print("error while tracking indicator view")
|
|
57
|
+
print(e)
|
|
58
|
+
return response
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def track_event(
|
|
62
|
+
*, request: HttpRequest, response: HttpResponse, event_name=EventType, data
|
|
63
|
+
):
|
|
64
|
+
try:
|
|
65
|
+
cookie = get_or_set_tracking_cookie(request, response)
|
|
66
|
+
match = resolve(request.path)
|
|
67
|
+
view_name = match.view_name
|
|
68
|
+
Event.objects.create(
|
|
69
|
+
cookie=cookie,
|
|
70
|
+
name=event_name,
|
|
71
|
+
data=data,
|
|
72
|
+
url=request.get_full_path(),
|
|
73
|
+
view=view_name,
|
|
74
|
+
)
|
|
75
|
+
except Exception as e:
|
|
76
|
+
print("error while tracking event")
|
|
77
|
+
print(e)
|
|
78
|
+
return response
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Generated by Django 5.2.3 on 2025-06-18 13:03
|
|
2
|
+
|
|
3
|
+
from django.db import migrations, models
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Migration(migrations.Migration):
|
|
7
|
+
|
|
8
|
+
initial = True
|
|
9
|
+
|
|
10
|
+
dependencies = [
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
operations = [
|
|
14
|
+
migrations.CreateModel(
|
|
15
|
+
name='Event',
|
|
16
|
+
fields=[
|
|
17
|
+
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
|
18
|
+
('created_at', models.DateTimeField(auto_now_add=True)),
|
|
19
|
+
('cookie', models.TextField(help_text="Un cookie sans durée d'expiration est placé dans chaque nouvelle session, il possède une valeur aléatoire qui permet de tracer le navigateur du visiteur entre plusieurs visites.")),
|
|
20
|
+
('name', models.TextField(choices=[('download', 'Download')])),
|
|
21
|
+
('data', models.JSONField(blank=True, null=True)),
|
|
22
|
+
('url', models.TextField(help_text='URL brut de la page')),
|
|
23
|
+
('view', models.TextField(help_text='Nom de la vue dans Django')),
|
|
24
|
+
],
|
|
25
|
+
),
|
|
26
|
+
migrations.CreateModel(
|
|
27
|
+
name='Page',
|
|
28
|
+
fields=[
|
|
29
|
+
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
|
30
|
+
('created_at', models.DateTimeField(auto_now_add=True)),
|
|
31
|
+
('cookie', models.TextField(help_text="Un cookie sans durée d'expiration est placé dans chaque nouvelle session, il possède une valeur aléatoire qui permet de tracer le navigateur du visiteur entre plusieurs visites.")),
|
|
32
|
+
('territory_id', models.TextField(blank=True, help_text='ID du territoire principal sélectionné.', null=True)),
|
|
33
|
+
('territory_mesh', models.TextField(blank=True, choices=[('fr', 'National'), ('reg', 'Region'), ('dep', 'Department'), ('epci', 'Epci'), ('com', 'Town')], help_text='Maille du territoire principal sélectionné.', null=True)),
|
|
34
|
+
('submesh', models.TextField(blank=True, choices=[('fr', 'National'), ('reg', 'Region'), ('dep', 'Department'), ('epci', 'Epci'), ('com', 'Town')], help_text="Maille d'analyse sélectionnée.", null=True)),
|
|
35
|
+
('cmp_territory_id', models.TextField(blank=True, help_text="ID du territoire de comparaison, null s'il ne s'agit pas de la page comparaison.", null=True)),
|
|
36
|
+
('cmp_territory_mesh', models.TextField(blank=True, choices=[('fr', 'National'), ('reg', 'Region'), ('dep', 'Department'), ('epci', 'Epci'), ('com', 'Town')], help_text="Maille du territoire de comparaison, null s'il ne s'agit pas de la page comparaison.", null=True)),
|
|
37
|
+
('indicator', models.IntegerField(blank=True, help_text="ID de l'indicateur de la page détails, null s'il ne s'agit pas de la page détails, utile pour faire des jointures.", null=True)),
|
|
38
|
+
('indicator_name', models.TextField(blank=True, help_text="Nom de l'indicateur de la page détails, null s'il ne s'agit pas de la page détails, utile pour une analyse rapide.", null=True)),
|
|
39
|
+
('theme', models.IntegerField(blank=True, help_text='ID du thème de la page, utile pour faire des jointures.', null=True)),
|
|
40
|
+
('theme_name', models.TextField(blank=True, help_text='Nom du thème de la page, utile pour une analyse rapide.', null=True)),
|
|
41
|
+
('url', models.TextField(help_text='URL brut de la page')),
|
|
42
|
+
('view', models.TextField(help_text='Nom de la vue dans Django')),
|
|
43
|
+
],
|
|
44
|
+
),
|
|
45
|
+
]
|
|
File without changes
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
from django.db import models
|
|
2
|
+
|
|
3
|
+
from territories_dashboard_lib.indicators_lib.enums import MeshLevel
|
|
4
|
+
from territories_dashboard_lib.tracking_lib.enums import EventType
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Page(models.Model):
|
|
8
|
+
"""
|
|
9
|
+
Une vue correspond à l'ouverture d'une des pages de l'application.
|
|
10
|
+
À chaque changement de paramètre (territoire, maille, territoire de comparaison) une nouvelle vue est enregistrée.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
created_at = models.DateTimeField(auto_now_add=True)
|
|
14
|
+
cookie = models.TextField(
|
|
15
|
+
help_text="Un cookie sans durée d'expiration est placé dans chaque nouvelle session, il possède une valeur aléatoire qui permet de tracer le navigateur du visiteur entre plusieurs visites."
|
|
16
|
+
)
|
|
17
|
+
territory_id = models.TextField(
|
|
18
|
+
help_text="ID du territoire principal sélectionné.", null=True, blank=True
|
|
19
|
+
)
|
|
20
|
+
territory_mesh = models.TextField(
|
|
21
|
+
choices=MeshLevel.choices,
|
|
22
|
+
help_text="Maille du territoire principal sélectionné.",
|
|
23
|
+
null=True,
|
|
24
|
+
blank=True,
|
|
25
|
+
)
|
|
26
|
+
submesh = models.TextField(
|
|
27
|
+
choices=MeshLevel.choices,
|
|
28
|
+
help_text="Maille d'analyse sélectionnée.",
|
|
29
|
+
null=True,
|
|
30
|
+
blank=True,
|
|
31
|
+
)
|
|
32
|
+
cmp_territory_id = models.TextField(
|
|
33
|
+
null=True,
|
|
34
|
+
blank=True,
|
|
35
|
+
help_text="ID du territoire de comparaison, null s'il ne s'agit pas de la page comparaison.",
|
|
36
|
+
)
|
|
37
|
+
cmp_territory_mesh = models.TextField(
|
|
38
|
+
choices=MeshLevel.choices,
|
|
39
|
+
null=True,
|
|
40
|
+
blank=True,
|
|
41
|
+
help_text="Maille du territoire de comparaison, null s'il ne s'agit pas de la page comparaison.",
|
|
42
|
+
)
|
|
43
|
+
indicator = models.IntegerField(
|
|
44
|
+
null=True,
|
|
45
|
+
blank=True,
|
|
46
|
+
help_text="ID de l'indicateur de la page détails, null s'il ne s'agit pas de la page détails, utile pour faire des jointures.",
|
|
47
|
+
)
|
|
48
|
+
indicator_name = models.TextField(
|
|
49
|
+
null=True,
|
|
50
|
+
blank=True,
|
|
51
|
+
help_text="Nom de l'indicateur de la page détails, null s'il ne s'agit pas de la page détails, utile pour une analyse rapide.",
|
|
52
|
+
)
|
|
53
|
+
theme = models.IntegerField(
|
|
54
|
+
help_text="ID du thème de la page, utile pour faire des jointures.",
|
|
55
|
+
null=True,
|
|
56
|
+
blank=True,
|
|
57
|
+
)
|
|
58
|
+
theme_name = models.TextField(
|
|
59
|
+
help_text="Nom du thème de la page, utile pour une analyse rapide.",
|
|
60
|
+
null=True,
|
|
61
|
+
blank=True,
|
|
62
|
+
)
|
|
63
|
+
url = models.TextField(help_text="URL brut de la page")
|
|
64
|
+
view = models.TextField(help_text="Nom de la vue dans Django")
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
class Event(models.Model):
|
|
68
|
+
"""
|
|
69
|
+
Tracking des autres événements de l'application
|
|
70
|
+
"""
|
|
71
|
+
|
|
72
|
+
created_at = models.DateTimeField(auto_now_add=True)
|
|
73
|
+
cookie = models.TextField(
|
|
74
|
+
help_text="Un cookie sans durée d'expiration est placé dans chaque nouvelle session, il possède une valeur aléatoire qui permet de tracer le navigateur du visiteur entre plusieurs visites."
|
|
75
|
+
)
|
|
76
|
+
name = models.TextField(choices=EventType.choices)
|
|
77
|
+
data = models.JSONField(null=True, blank=True)
|
|
78
|
+
url = models.TextField(help_text="URL brut de la page")
|
|
79
|
+
view = models.TextField(help_text="Nom de la vue dans Django")
|
|
File without changes
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
from django.contrib import admin
|
|
2
|
+
|
|
3
|
+
from territories_dashboard_lib.website_lib.forms import (
|
|
4
|
+
GlossaryItemAdminForm,
|
|
5
|
+
LandingPageAdminForm,
|
|
6
|
+
MainConfAdminForm,
|
|
7
|
+
StaticPageAdminForm,
|
|
8
|
+
)
|
|
9
|
+
from territories_dashboard_lib.website_lib.models import (
|
|
10
|
+
GlossaryItem,
|
|
11
|
+
LandingPage,
|
|
12
|
+
MainConf,
|
|
13
|
+
NoticeBanner,
|
|
14
|
+
StaticPage,
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@admin.register(MainConf)
|
|
19
|
+
class MainConfAdmin(admin.ModelAdmin):
|
|
20
|
+
form = MainConfAdminForm
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@admin.register(GlossaryItem)
|
|
24
|
+
class GlossaryItemAdmin(admin.ModelAdmin):
|
|
25
|
+
form = GlossaryItemAdminForm
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@admin.register(LandingPage)
|
|
29
|
+
class LandingPageAdminForm(admin.ModelAdmin):
|
|
30
|
+
form = LandingPageAdminForm
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
@admin.register(StaticPage)
|
|
34
|
+
class StaticPageAdminForm(admin.ModelAdmin):
|
|
35
|
+
form = StaticPageAdminForm
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
@admin.register(NoticeBanner)
|
|
39
|
+
class NoticeBannerAdmin(admin.ModelAdmin):
|
|
40
|
+
list_display = ("title", "created_at")
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
from django.conf import settings
|
|
2
|
+
|
|
3
|
+
from territories_dashboard_lib.superset_lib.models import Dashboard
|
|
4
|
+
from territories_dashboard_lib.superset_lib.serializers import serialize_dashboard
|
|
5
|
+
from territories_dashboard_lib.website_lib.models import (
|
|
6
|
+
MainConf,
|
|
7
|
+
NoticeBanner,
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def default(request):
|
|
12
|
+
main_conf = MainConf.objects.first()
|
|
13
|
+
notice = NoticeBanner.objects.first()
|
|
14
|
+
context = {
|
|
15
|
+
"ENABLE_SUPERSET": settings.ENABLE_SUPERSET,
|
|
16
|
+
"ANALYTICS_ID": settings.ANALYTICS_ID,
|
|
17
|
+
"ENVIRONMENT": settings.ENVIRONMENT,
|
|
18
|
+
"view_name": request.resolver_match.view_name,
|
|
19
|
+
"main_conf": main_conf,
|
|
20
|
+
"notice": notice,
|
|
21
|
+
"dashboards": [
|
|
22
|
+
serialize_dashboard(d)
|
|
23
|
+
for d in Dashboard.objects.all().order_by("order", "label")
|
|
24
|
+
],
|
|
25
|
+
"version": settings.VERSION,
|
|
26
|
+
}
|
|
27
|
+
return context
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
from django import forms
|
|
2
|
+
from django.forms import Textarea
|
|
3
|
+
|
|
4
|
+
from territories_dashboard_lib.website_lib.models import (
|
|
5
|
+
GlossaryItem,
|
|
6
|
+
LandingPage,
|
|
7
|
+
MainConf,
|
|
8
|
+
StaticPage,
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class MainConfAdminForm(forms.ModelForm):
|
|
13
|
+
class Meta:
|
|
14
|
+
model = MainConf
|
|
15
|
+
fields = "__all__"
|
|
16
|
+
widgets = {
|
|
17
|
+
"title": Textarea(attrs={"rows": 1, "cols": 30}),
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class GlossaryItemAdminForm(forms.ModelForm):
|
|
22
|
+
class Meta:
|
|
23
|
+
model = GlossaryItem
|
|
24
|
+
fields = "__all__"
|
|
25
|
+
widgets = {
|
|
26
|
+
"word": Textarea(attrs={"rows": 1, "cols": 30}),
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class LandingPageAdminForm(forms.ModelForm):
|
|
31
|
+
class Meta:
|
|
32
|
+
model = LandingPage
|
|
33
|
+
fields = "__all__"
|
|
34
|
+
widgets = {
|
|
35
|
+
"title": Textarea(attrs={"rows": 1, "cols": 30}),
|
|
36
|
+
"button_link": Textarea(attrs={"rows": 1, "cols": 30}),
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class StaticPageAdminForm(forms.ModelForm):
|
|
41
|
+
class Meta:
|
|
42
|
+
model = StaticPage
|
|
43
|
+
fields = "__all__"
|
|
44
|
+
widgets = {
|
|
45
|
+
"name": Textarea(attrs={"rows": 1, "cols": 30}),
|
|
46
|
+
"url": Textarea(attrs={"rows": 1, "cols": 30}),
|
|
47
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# Generated by Django 5.2.3 on 2025-06-18 13:09
|
|
2
|
+
|
|
3
|
+
import martor.models
|
|
4
|
+
from django.db import migrations, models
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Migration(migrations.Migration):
|
|
8
|
+
|
|
9
|
+
initial = True
|
|
10
|
+
|
|
11
|
+
dependencies = [
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
operations = [
|
|
15
|
+
migrations.CreateModel(
|
|
16
|
+
name='GlossaryItem',
|
|
17
|
+
fields=[
|
|
18
|
+
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
|
19
|
+
('created_at', models.DateTimeField(auto_now_add=True)),
|
|
20
|
+
('updated_at', models.DateTimeField(auto_now=True)),
|
|
21
|
+
('word', models.TextField(verbose_name='Mot')),
|
|
22
|
+
('definition', models.TextField(verbose_name='Définition')),
|
|
23
|
+
],
|
|
24
|
+
options={
|
|
25
|
+
'verbose_name': 'Définition',
|
|
26
|
+
'verbose_name_plural': 'Page Lexique',
|
|
27
|
+
'ordering': ['word'],
|
|
28
|
+
},
|
|
29
|
+
),
|
|
30
|
+
migrations.CreateModel(
|
|
31
|
+
name='LandingPage',
|
|
32
|
+
fields=[
|
|
33
|
+
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
|
34
|
+
('created_at', models.DateTimeField(auto_now_add=True)),
|
|
35
|
+
('updated_at', models.DateTimeField(auto_now=True)),
|
|
36
|
+
('title', models.TextField(verbose_name='Titre')),
|
|
37
|
+
('body', martor.models.MartorField(verbose_name='Contenu')),
|
|
38
|
+
('button_link', models.TextField(help_text='Au format markdown, par exemple : <br/><br/>[découvrir les indicateurs](/indicateurs/)', verbose_name='Lien du bouton')),
|
|
39
|
+
],
|
|
40
|
+
options={
|
|
41
|
+
'verbose_name': "Page d'accueil",
|
|
42
|
+
'verbose_name_plural': "Page d'accueil",
|
|
43
|
+
},
|
|
44
|
+
),
|
|
45
|
+
migrations.CreateModel(
|
|
46
|
+
name='MainConf',
|
|
47
|
+
fields=[
|
|
48
|
+
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
|
49
|
+
('created_at', models.DateTimeField(auto_now_add=True)),
|
|
50
|
+
('updated_at', models.DateTimeField(auto_now=True)),
|
|
51
|
+
('title', models.TextField(default='Tableau de bord', verbose_name='Titre principal du site')),
|
|
52
|
+
('entity', models.TextField(default='', help_text="Renseigner le nom de l'entité au même format que le logo officiel en respectant les mises à la ligne.", verbose_name='Entité qui possède le site')),
|
|
53
|
+
('header_navigation', models.TextField(default='', help_text='Navigation du header, mettre les liens au format markdown avec un slash à la fin du lien, mettre une ligne vide entre chaque rubrique. <br/><br/>\n \n Une rubrique peut contenir un seul lien, ou bien plusiers, dans ce cas la rubrique sera sous forme de dropdown et il faut mettre un titre en premier. <br/><br/>Par exemple : <br/>\n <br/><br/>\n [Accueil](/accueil/)\n <br/><br/>\n [Indicateurs territoriaux](/indicateurs/)\n <br/><br/>\n À propos\n [Présentation](/presentation/)\n [Journal des versions](/journal/)\n ', verbose_name='Navigation')),
|
|
54
|
+
('footer_navigation', models.TextField(default='', help_text='Navigation du footer, mettre les liens au format markdown, un par ligne. <br/><br/>\n Si le lien est interne, commencer et terminer le lien par un slash comme "/accueil/"<br/><br/>\n Par exemple : <br/><br/>\n [Plan du site](/plan-site/)<br/>\n [Accessibilité](/accessibilite/)<br/>\n [Mentions légales](/mentions-legales/) <br/>\n ', verbose_name='Navigation')),
|
|
55
|
+
],
|
|
56
|
+
options={
|
|
57
|
+
'verbose_name': 'Configuration principale',
|
|
58
|
+
'verbose_name_plural': 'Configurations principales',
|
|
59
|
+
},
|
|
60
|
+
),
|
|
61
|
+
migrations.CreateModel(
|
|
62
|
+
name='NoticeBanner',
|
|
63
|
+
fields=[
|
|
64
|
+
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
|
65
|
+
('created_at', models.DateTimeField(auto_now_add=True)),
|
|
66
|
+
('updated_at', models.DateTimeField(auto_now=True)),
|
|
67
|
+
('title', models.CharField(max_length=64, verbose_name='Titre')),
|
|
68
|
+
('description', models.CharField(max_length=255, verbose_name='Description')),
|
|
69
|
+
('link_href', models.CharField(blank=True, help_text="Le lien doit être un lien interne et commencer et terminer par '/', par exemple '/journal/", max_length=255, null=True, verbose_name='Lien')),
|
|
70
|
+
('link_text', models.CharField(blank=True, help_text='à remplir seulement si un lien est spécifié', max_length=64, null=True, verbose_name='Intitulé du lien')),
|
|
71
|
+
],
|
|
72
|
+
options={
|
|
73
|
+
'ordering': ['-created_at'],
|
|
74
|
+
},
|
|
75
|
+
),
|
|
76
|
+
migrations.CreateModel(
|
|
77
|
+
name='StaticPage',
|
|
78
|
+
fields=[
|
|
79
|
+
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
|
80
|
+
('created_at', models.DateTimeField(auto_now_add=True)),
|
|
81
|
+
('updated_at', models.DateTimeField(auto_now=True)),
|
|
82
|
+
('name', models.TextField(verbose_name='Nom de la page')),
|
|
83
|
+
('url', models.TextField(help_text="En minuscule avec des espaces remplacés par des traits '-'.<br/>Par exemple : <br/><br/> indicateurs <br/> mentions-legales", verbose_name='Url de la page')),
|
|
84
|
+
('body', martor.models.MartorField(verbose_name='Contenu')),
|
|
85
|
+
],
|
|
86
|
+
options={
|
|
87
|
+
'verbose_name': 'Page Statique',
|
|
88
|
+
'verbose_name_plural': 'Pages Statiques',
|
|
89
|
+
},
|
|
90
|
+
),
|
|
91
|
+
]
|
|
File without changes
|