territories-dashboard-lib 0.1.36__py3-none-any.whl → 0.1.39b2__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.

Files changed (28) hide show
  1. territories_dashboard_lib/indicators_lib/methodo_pdf.py +6 -1
  2. territories_dashboard_lib/indicators_lib/migrations/0005_auto_20251203_1621.py +124 -0
  3. territories_dashboard_lib/indicators_lib/migrations/0006_alter_theme_action_theme_alter_theme_objectif_theme.py +23 -0
  4. territories_dashboard_lib/indicators_lib/models.py +2 -2
  5. territories_dashboard_lib/indicators_lib/query/histogram.py +7 -1
  6. territories_dashboard_lib/website_lib/conf.py +14 -0
  7. territories_dashboard_lib/website_lib/context_processors.py +3 -5
  8. territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/details/histogram.mjs +4 -1
  9. territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/details/proportions.mjs +3 -2
  10. territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/details/top10.mjs +4 -2
  11. territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/details/utils.mjs +14 -5
  12. territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/layout/header.html +1 -1
  13. territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/components/side_panel_methodo.html +1 -1
  14. territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/details/components/histogram.html +2 -1
  15. territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/details/components/no-data.html +1 -0
  16. territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/details/components/proportions.html +1 -0
  17. territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/details/components/top10.html +1 -0
  18. territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/details/map.css +50 -26
  19. territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/details/page.css +8 -0
  20. territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/themes/page.html +2 -0
  21. {territories_dashboard_lib-0.1.36.dist-info → territories_dashboard_lib-0.1.39b2.dist-info}/METADATA +1 -1
  22. {territories_dashboard_lib-0.1.36.dist-info → territories_dashboard_lib-0.1.39b2.dist-info}/RECORD +25 -24
  23. territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/react/indicatorMap.bundle.js +0 -2
  24. territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/react/sankeyGraph.bundle.js +0 -2
  25. territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/react/vendors.bundle.js +0 -2
  26. {territories_dashboard_lib-0.1.36.dist-info → territories_dashboard_lib-0.1.39b2.dist-info}/WHEEL +0 -0
  27. {territories_dashboard_lib-0.1.36.dist-info → territories_dashboard_lib-0.1.39b2.dist-info}/licenses/licence.md +0 -0
  28. {territories_dashboard_lib-0.1.36.dist-info → territories_dashboard_lib-0.1.39b2.dist-info}/top_level.txt +0 -0
@@ -6,6 +6,8 @@ from tempfile import NamedTemporaryFile
6
6
  from django.conf import settings
7
7
  from markdown import markdown
8
8
 
9
+ from territories_dashboard_lib.website_lib.conf import get_main_conf
10
+
9
11
 
10
12
  def _html_to_pdf(html_content, output_pdf_path):
11
13
  try:
@@ -36,6 +38,7 @@ def _generate_pdf_from_methodo(indicator, output_path):
36
38
  logo_path = os.path.join(settings.BASE_DIR, relative_logo_path)
37
39
  with open(logo_path, "rb") as fd:
38
40
  encoded_logo = base64.b64encode(fd.read()).decode("utf-8")
41
+ main_conf = get_main_conf()
39
42
  html = (
40
43
  """
41
44
  <!DOCTYPE html>
@@ -59,7 +62,9 @@ def _generate_pdf_from_methodo(indicator, output_path):
59
62
  + """
60
63
  </td>
61
64
  <td style="padding-left: 64px;">
62
- <div style="font-size: 30px; font-weight: 600; margin-bottom: 8px;">Tableau de bord des mobilités durables</div>
65
+ """
66
+ + f'<div style="font-size: 30px; font-weight: 600; margin-bottom: 8px;">{main_conf.title}</div>'
67
+ + """
63
68
  <div>Fiche méthodologique</div>
64
69
  </td>
65
70
  </tr>
@@ -0,0 +1,124 @@
1
+ # Generated by Django 5.2.9 on 2025-12-03 15:21
2
+
3
+ import base64
4
+ import os
5
+ import subprocess
6
+ from tempfile import NamedTemporaryFile
7
+
8
+ from django.conf import settings
9
+ from django.db import migrations
10
+ from markdown import markdown
11
+
12
+
13
+ def _html_to_pdf(html_content, output_pdf_path):
14
+ try:
15
+ process = subprocess.Popen(
16
+ [
17
+ "wkhtmltopdf",
18
+ "-",
19
+ output_pdf_path,
20
+ ], # '-' tells wkhtmltopdf to read from stdin
21
+ stdin=subprocess.PIPE,
22
+ stdout=subprocess.PIPE,
23
+ stderr=subprocess.PIPE,
24
+ )
25
+ stdout, stderr = process.communicate(input=html_content.encode("utf-8"))
26
+ if process.returncode != 0:
27
+ print("Error:", stderr.decode("utf-8"))
28
+ else:
29
+ print(f"PDF successfully created at: {output_pdf_path}")
30
+ except FileNotFoundError:
31
+ print("Error: wkhtmltopdf not found. Ensure it is installed and in your PATH.")
32
+ except Exception as e:
33
+ print(f"An error occurred: {e}")
34
+
35
+
36
+ def _generate_pdf_from_methodo(main_conf, indicator, output_path):
37
+ html = markdown(indicator.methodo)
38
+ relative_logo_path = "whitenoise_root/ministere_logo.png"
39
+ logo_path = os.path.join(settings.BASE_DIR, relative_logo_path)
40
+ with open(logo_path, "rb") as fd:
41
+ encoded_logo = base64.b64encode(fd.read()).decode("utf-8")
42
+ html = (
43
+ """
44
+ <!DOCTYPE html>
45
+ <html lang="fr">
46
+ <head>
47
+ <meta charset="UTF-8">
48
+ <title>Accents Test</title>
49
+ <style>
50
+ body {
51
+ font-family: Tahoma, Arial, sans-serif;
52
+ }
53
+ </style>
54
+ </head>
55
+ <body>
56
+ <header>
57
+ <table>
58
+ <tr>
59
+ <td>
60
+ """
61
+ + f'<img width="150px" src="data:image/png;base64,{encoded_logo}"/>'
62
+ + """
63
+ </td>
64
+ <td style="padding-left: 64px;">
65
+ """
66
+ + f'<div style="font-size: 30px; font-weight: 600; margin-bottom: 8px;">{main_conf.title}</div>'
67
+ + """
68
+ <div>Fiche méthodologique</div>
69
+ </td>
70
+ </tr>
71
+ </table>
72
+ </header>
73
+ <main>
74
+ """
75
+ + f"<h1>{indicator.title}</h1>"
76
+ + f"<p>Thématique : {indicator.sub_theme.theme.title} / {indicator.sub_theme.title}</p>"
77
+ + html
78
+ + """
79
+ </main>
80
+ </body>
81
+ </html>
82
+ """
83
+ )
84
+ _html_to_pdf(html, output_path)
85
+
86
+
87
+ def reset_methodo_file(main_conf, indicator):
88
+ # Create a temporary file for the PDF
89
+ with NamedTemporaryFile(delete=False, suffix=".pdf") as temp_file:
90
+ pdf_path = temp_file.name
91
+
92
+ # Generate the PDF
93
+ _generate_pdf_from_methodo(main_conf, indicator, pdf_path)
94
+
95
+ # Read the binary content of the generated PDF file
96
+ with open(pdf_path, "rb") as pdf_file:
97
+ pdf_content = pdf_file.read()
98
+
99
+ # Save the binary content to the BinaryField
100
+ indicator.methodo_file = pdf_content
101
+ indicator.save()
102
+
103
+ # Clean up temporary file
104
+ os.remove(pdf_path)
105
+
106
+
107
+ def reset_indicators_methodo_pdf(apps, schema_editor):
108
+ MainConf = apps.get_model("website_lib", "MainConf")
109
+ Indicator = apps.get_model("indicators_lib", "Indicator")
110
+ main_conf = MainConf.objects.first()
111
+ if main_conf:
112
+ for indicator in Indicator.objects.all():
113
+ reset_methodo_file(main_conf, indicator)
114
+
115
+
116
+ class Migration(migrations.Migration):
117
+ dependencies = [
118
+ ("indicators_lib", "0003_indicator_short_title"),
119
+ ("website_lib", "0004_mainconf_description_mainconf_social_image_url"),
120
+ ]
121
+
122
+ operations = [
123
+ migrations.RunPython(reset_indicators_methodo_pdf, migrations.RunPython.noop),
124
+ ]
@@ -0,0 +1,23 @@
1
+ # Generated by Django 5.2.6 on 2025-12-18 10:12
2
+
3
+ from django.db import migrations, models
4
+
5
+
6
+ class Migration(migrations.Migration):
7
+
8
+ dependencies = [
9
+ ('indicators_lib', '0005_auto_20251203_1621'),
10
+ ]
11
+
12
+ operations = [
13
+ migrations.AlterField(
14
+ model_name='theme',
15
+ name='action_theme',
16
+ field=models.TextField(blank=True, null=True),
17
+ ),
18
+ migrations.AlterField(
19
+ model_name='theme',
20
+ name='objectif_theme',
21
+ field=models.TextField(blank=True, null=True),
22
+ ),
23
+ ]
@@ -19,9 +19,9 @@ class Theme(CommonModel):
19
19
  name.verbose_name = "Nom (~id, URL)"
20
20
  title = models.CharField(max_length=128)
21
21
  title.verbose_name = "Titre (affiché)"
22
- objectif_theme = models.TextField(blank=True)
22
+ objectif_theme = models.TextField(blank=True, null=True)
23
23
  objectif_theme.verbose_name = "Objectif"
24
- action_theme = models.TextField(blank=True)
24
+ action_theme = models.TextField(blank=True, null=True)
25
25
  action_theme.verbose_name = "Actions"
26
26
 
27
27
  def is_displayed_on_app(self):
@@ -2,7 +2,12 @@ from .details import get_values_for_submesh_territories
2
2
 
3
3
 
4
4
  def get_territories_histogram_data(territory_values, unite):
5
- if all([t["valeur"] is None for t in territory_values]):
5
+ if all(
6
+ [
7
+ (t["valeur"] is None or (t["valeur"] > 99.99 and t["valeur"] <= 100.01))
8
+ for t in territory_values
9
+ ]
10
+ ):
6
11
  return ({}, [])
7
12
  values_for_min_max = [
8
13
  data["valeur"] for data in territory_values if data["valeur"] is not None
@@ -72,6 +77,7 @@ def get_indicator_histogram_data(indicator, territory, submesh, filters):
72
77
  territory_values = get_values_for_submesh_territories(
73
78
  indicator, submesh, territory, filters
74
79
  )
80
+ print("!!", territory_values)
75
81
  datasets_histogram_bar_chart, deciles = get_territories_histogram_data(
76
82
  territory_values, indicator.unite
77
83
  )
@@ -0,0 +1,14 @@
1
+ from territories_dashboard_lib.website_lib.models import MainConf
2
+
3
+
4
+ class MissingMainConf(Exception):
5
+ def __init__(self):
6
+ super().__init__()
7
+ self.message = "Configuration principale du site (MainConf) manquante, veuillez la créer via le backoffice ou le shell."
8
+
9
+
10
+ def get_main_conf():
11
+ main_conf = MainConf.objects.first()
12
+ if main_conf is None:
13
+ raise MissingMainConf
14
+ return main_conf
@@ -2,14 +2,12 @@ from django.conf import settings
2
2
 
3
3
  from territories_dashboard_lib.superset_lib.models import Dashboard
4
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
- )
5
+ from territories_dashboard_lib.website_lib.conf import get_main_conf
6
+ from territories_dashboard_lib.website_lib.models import NoticeBanner
9
7
 
10
8
 
11
9
  def default(request):
12
- main_conf = MainConf.objects.first()
10
+ main_conf = get_main_conf()
13
11
  notice = NoticeBanner.objects.first()
14
12
  context = {
15
13
  "ENABLE_SUPERSET": settings.ENABLE_SUPERSET,
@@ -8,7 +8,7 @@ import {
8
8
  } from "../enums.mjs";
9
9
  import { makeChart, setBackgroundInDatasets } from "../utils.mjs";
10
10
 
11
- import { addEmptyGraphMessage } from "./utils.mjs";
11
+ import { addEmptyGraphMessage, removeEmptyGraphMessage } from "./utils.mjs";
12
12
  import { formatIndicatorValue } from "../format.mjs";
13
13
 
14
14
  function getDatalabels(dataset, mesh) {
@@ -94,9 +94,12 @@ export function makeHistogramChart(indicator) {
94
94
  const { datasetsHistogramBarChart: dataset, deciles } = histogramData;
95
95
 
96
96
  const ctx = document.getElementById("histogramChart");
97
+
97
98
  if (Object.keys(dataset).length === 0) {
98
99
  addEmptyGraphMessage(ctx);
99
100
  return;
101
+ } else {
102
+ removeEmptyGraphMessage(ctx);
100
103
  }
101
104
 
102
105
  const labels = deciles.map((decile) => formatIndicatorValue(decile));
@@ -2,7 +2,7 @@ import { getIndicatorDataScript, getParams } from "../dom.mjs";
2
2
  import { getToolTip, makeChart, setBackgroundInDatasets } from "../utils.mjs";
3
3
 
4
4
  import { COLORS } from "../enums.mjs";
5
- import { addEmptyGraphMessage } from "./utils.mjs";
5
+ import { addEmptyGraphMessage, removeEmptyGraphMessage } from "./utils.mjs";
6
6
  import { formatIndicatorValue } from "../format.mjs";
7
7
 
8
8
  function getPlugins(indicator, total) {
@@ -67,6 +67,8 @@ function makeProportionsChart(indicator) {
67
67
  if (datasets.length === 0 || emptyDatasets) {
68
68
  addEmptyGraphMessage(ctx);
69
69
  return;
70
+ } else {
71
+ removeEmptyGraphMessage(ctx);
70
72
  }
71
73
 
72
74
  const total = datasets.map((d) => d.data[0]).reduce((a, b) => a + b, 0);
@@ -92,7 +94,6 @@ function makeProportionsChart(indicator) {
92
94
  },
93
95
  },
94
96
  };
95
-
96
97
  makeChart(ctx, "bar", data, options);
97
98
  }
98
99
 
@@ -1,6 +1,6 @@
1
1
  import { getToolTip, makeChart, setBackgroundInDatasets } from "../utils.mjs";
2
2
 
3
- import { addEmptyGraphMessage } from "./utils.mjs";
3
+ import { addEmptyGraphMessage, removeEmptyGraphMessage } from "./utils.mjs";
4
4
  import { formatIndicatorValue } from "../format.mjs";
5
5
  import { getIndicatorDataScript } from "../dom.mjs";
6
6
 
@@ -40,9 +40,11 @@ function makeTop10Chart(indicator) {
40
40
  datasets,
41
41
  };
42
42
 
43
- if (data.labels.length === 0) {
43
+ if (data.labels.length === 0 || datasets.length === 0) {
44
44
  addEmptyGraphMessage(ctx);
45
45
  return;
46
+ } else {
47
+ removeEmptyGraphMessage(ctx);
46
48
  }
47
49
 
48
50
  const options = {
@@ -1,8 +1,17 @@
1
1
  function addEmptyGraphMessage(ctx) {
2
- const div = document.createElement("div");
3
- div.textContent =
4
- "Il n'y a pas assez de données pour afficher le graphique.";
5
- ctx.parentNode.insertBefore(div, ctx);
2
+ const oldChart = Chart.getChart(ctx);
3
+ if (oldChart) {
4
+ oldChart.destroy();
5
+ }
6
+ const noMessageDiv =
7
+ ctx.parentElement.parentElement.querySelector(".no-data-message");
8
+ if (noMessageDiv) noMessageDiv.dataset.show = "true";
6
9
  }
7
10
 
8
- export { addEmptyGraphMessage };
11
+ function removeEmptyGraphMessage(ctx) {
12
+ const noMessageDiv =
13
+ ctx.parentElement.parentElement.querySelector(".no-data-message");
14
+ if (noMessageDiv) noMessageDiv.dataset.show = "false";
15
+ }
16
+
17
+ export { addEmptyGraphMessage, removeEmptyGraphMessage };
@@ -36,7 +36,7 @@
36
36
  <p class="fr-header__service-title">
37
37
  {{ main_conf.title }}
38
38
  {% if ENVIRONMENT != "prd" %}
39
- <span class="fr-badge fr-badge--success fr-badge--no-icon" id="fr-badge-:Rj5ikq:">{% if ENVIRONMENT == "ppd" %}PREPROD{% else %}DEV{% endif %}</span>
39
+ <span class="fr-badge fr-badge--success fr-badge--no-icon" id="fr-badge-:Rj5ikq:">{% if ENVIRONMENT == "ppd" %}PREPROD{% elif ENVIRONMENT == "ppd-beta" %}BETA{% else %}DEV{% endif %}</span>
40
40
  {% endif %}
41
41
  </p>
42
42
  </div>
@@ -24,7 +24,7 @@
24
24
  </div>
25
25
  <div class="fr-header__service">
26
26
  <p class="fr-header__service-title">
27
- Tableau de bord des mobilités durables
27
+ {{ main_conf.title }}
28
28
  </p>
29
29
  <p class="fr-header__service-tagline">Fiche méthodologique</p>
30
30
  </div>
@@ -3,10 +3,11 @@
3
3
  {% if params.mesh != params.territory_mesh and params|should_mesh_analysis:indicator %}
4
4
  <div id="histogramContainer" class="subtheme">
5
5
  <div class="fr-px-md-4w fr-px-2w fr-py-2w">
6
- {% include "territories_dashboard_lib/website/pages/indicators/components/title.html" with title="Répartition des territoires selon les valeurs de l'indicateur" key="repartition" text="Le nom des territoires s'affiche au survol ds'il y a moins de 6 territoires. Précisions : Ce graphique varie selon la maille sélectionnée." %}
6
+ {% include "territories_dashboard_lib/website/pages/indicators/components/title.html" with title="Répartition des territoires selon les valeurs de l'indicateur" key="repartition" text="Le nom des territoires s'affiche au survol s'il y a moins de 6 territoires. Précisions : Ce graphique varie selon la maille sélectionnée." %}
7
7
  <div style="width:100%; height: 400px;">
8
8
  <canvas id="histogramChart" aria-describedby="histogram-export-csv"></canvas>
9
9
  </div>
10
+ {% include "./no-data.html" %}
10
11
  {% include "./filters-reminder.html" %}
11
12
  </div>
12
13
  {% include "territories_dashboard_lib/website/pages/indicators/components/chart-buttons.html" with name="Répartition par valeurs" route="histogram" one_indicator=True tracking_objet="repartition-valeurs" %}
@@ -0,0 +1 @@
1
+ <div class="no-data-message">Il n'y a pas assez de données pour afficher le graphique.</div>
@@ -8,6 +8,7 @@
8
8
  <div style="width:100%; height: auto;">
9
9
  <canvas id="proportionsChart" aria-describedby="proportions-export-csv"></canvas>
10
10
  </div>
11
+ {% include "./no-data.html" %}
11
12
  {% include "./filters-reminder.html" %}
12
13
  </div>
13
14
  {% include "territories_dashboard_lib/website/pages/indicators/components/chart-buttons.html" with name="Répartition par dimensions" route="proportions" pattern="show" one_indicator=True tracking_objet="repartition-dimension" %}
@@ -7,6 +7,7 @@
7
7
  <div style="width:100%; height: auto;">
8
8
  <canvas id="top10Chart" aria-describedby="top-10-export-csv"></canvas>
9
9
  </div>
10
+ {% include "./no-data.html" %}
10
11
  {% include "./filters-reminder.html" %}
11
12
  </div>
12
13
  {% include "territories_dashboard_lib/website/pages/indicators/components/chart-buttons.html" with name="Top 10" route="top-10" pattern="show" one_indicator=True tracking_objet="top_10" %}
@@ -1,6 +1,6 @@
1
1
  #tdbmd-map {
2
2
  width: 100%;
3
- height: 60vh;
3
+ height: 75vh;
4
4
  position: relative;
5
5
  border: 1px solid var(--border-default-grey);
6
6
  }
@@ -12,36 +12,46 @@
12
12
  position: absolute;
13
13
  bottom: 10px;
14
14
  left: 10px;
15
- padding: 8px 16px 0px 16px;
16
- max-width: 300px;
17
- min-width: 200px;
15
+ padding: 12px 22px 8px 16px;
18
16
  background-color: white;
19
17
  border-radius: 8px;
20
18
  opacity: 94%;
19
+ display: flex;
20
+ flex-direction: row;
21
+ align-items: end;
22
+ gap: 16px;
23
+ border: 1px solid var(--border-default-grey);
24
+ font-size: 0.8rem;
21
25
  }
22
- #tdbmd-map-legend .title {
23
- margin-bottom: 8px;
24
- font-size: 0.7rem;
25
- font-weight: bold;
26
- line-height: 1.3;
26
+ #tdbmd-map-legend.tdbmd-map-legend--small {
27
+ cursor: pointer;
28
+ padding: 8px 16px;
27
29
  }
28
- #tdbmd-map-legend .indicator-scale {
29
- width: 100%;
30
- height: 20px;
31
- opacity: 80%;
30
+ .tdbmd-map-legend--close {
31
+ position: absolute;
32
+ width: 24px;
33
+ height: 24px;
34
+ cursor: pointer;
35
+ top: 2px;
36
+ right: 2px;
32
37
  }
33
- #tdbmd-map-legend .indicator-scale-values {
34
- width: 100%;
38
+ .tdbmd-map-legend--close > svg {
39
+ width: 18px;
40
+ height: 18px;
41
+ position: absolute;
42
+ top: 2px;
43
+ right: 2px;
44
+ }
45
+ #tdbmd-map-legend .tdbmd-map-legend-category {
35
46
  display: flex;
36
- justify-content: space-between;
47
+ flex-direction: row;
48
+ align-items: center;
37
49
  gap: 8px;
50
+ font-size: 0.8rem;
38
51
  }
39
- #tdbmd-map-legend .scale-minmax {
40
- max-width: 100px;
41
- text-overflow: ellipsis;
42
- overflow: hidden;
43
- white-space: nowrap;
44
- font-size: 0.7rem;
52
+ #tdbmd-map-legend .tdbmd-map-legend-category > div:first-child {
53
+ width: 32px;
54
+ height: 16px;
45
55
  }
46
56
  #map-sidebar {
47
57
  position: absolute;
@@ -136,12 +146,17 @@
136
146
  margin-bottom: 16px;
137
147
  }
138
148
  #map-sidebar[data-open="false"] {
139
- width: 32px;
149
+ width: 0px;
140
150
  }
141
- #map-sidebar[data-open="false"] #collapse span:before {
142
- transform: scaleX(1);
151
+ #map-sidebar[data-open="false"] #collapse {
152
+ display: none;
153
+ }
154
+ #layers-checkboxes-legend {
155
+ font-weight: bold;
156
+ }
157
+ .sidebar-filters label {
158
+ font-size: 0.8rem;
143
159
  }
144
-
145
160
  #map-buttons {
146
161
  position: absolute;
147
162
  z-index: 1;
@@ -306,3 +321,12 @@
306
321
  #map-help-details-summary {
307
322
  font-size: 0.8rem;
308
323
  }
324
+ #map-loader {
325
+ position: absolute;
326
+ bottom: 8px;
327
+ right: 8px;
328
+ font-size: 0.6rem;
329
+ background-color: rgba(255, 255, 255, 0.9);
330
+ padding: 8px 16px 0px 16px;
331
+ border-radius: 4px;
332
+ }
@@ -11,3 +11,11 @@
11
11
  pointer-events: none;
12
12
  font-size: 12px;
13
13
  }
14
+
15
+ .no-data-message {
16
+ display: none;
17
+ }
18
+
19
+ .no-data-message[data-show="true"] {
20
+ display: block;
21
+ }
@@ -41,6 +41,7 @@
41
41
  <div>
42
42
  <div class="fr-pr-md-4w fr-pl-md-4w fr-pr-2w fr-pl-2w fr-mt-4w">
43
43
  <h1>{{ theme.title }}</h1>
44
+ {% if theme.objectif_theme is not None and theme.action_theme is not None %}
44
45
  <div class="fr-grid-row">
45
46
  <div class="fr-col-12 fr-col-md-6">
46
47
  <p class="fr-text--sm fr-mb-0">
@@ -55,6 +56,7 @@
55
56
  <p class="fr-text--sm">{{ theme.action_theme }}</p>
56
57
  </div>
57
58
  </div>
59
+ {% endif %}
58
60
  </div>
59
61
  {% for sub_theme in sub_themes %}
60
62
  <section
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: territories-dashboard-lib
3
- Version: 0.1.36
3
+ Version: 0.1.39b2
4
4
  Summary: Librairie pour la visualisation d'indicateurs territoriaux.
5
5
  Author-email: Bastien <bastien@prune.sh>
6
6
  Classifier: Programming Language :: Python :: 3