diff --git a/.credo.exs b/.credo.exs index 0edcce4878..354c44d44a 100644 --- a/.credo.exs +++ b/.credo.exs @@ -129,10 +129,15 @@ # Deprecated checks (these will be deleted after a grace period) # - {Credo.Check.Readability.Specs, false} + {Credo.Check.Readability.Specs, false}, # Custom checks can be created using `mix credo.gen.check`. # + + {Credo.Check.Warning.ForbiddenModule, + [ + modules: [Timex] + ]} ] } ] diff --git a/apps/shared/lib/date_time_display.ex b/apps/shared/lib/date_time_display.ex index 2b39f18931..6da044c163 100644 --- a/apps/shared/lib/date_time_display.ex +++ b/apps/shared/lib/date_time_display.ex @@ -34,7 +34,7 @@ defmodule Shared.DateTimeDisplay do def format_date(nil, _), do: "" def format_date(date, locale, iso_extended: true) do - date |> Timex.parse!("{ISO:Extended}") |> format_date(locale) + date |> TimeWrapper.parse!("{ISO:Extended}") |> format_date(locale) end @doc """ @@ -100,7 +100,7 @@ defmodule Shared.DateTimeDisplay do def format_datetime_to_paris(datetime, locale, options) when is_binary(datetime) do datetime - |> Timex.parse!("{ISO:Extended}") + |> TimeWrapper.parse!("{ISO:Extended}") |> format_datetime_to_paris(locale, options) end @@ -157,7 +157,7 @@ defmodule Shared.DateTimeDisplay do def format_time_to_paris(datetime, locale, options) when is_binary(datetime) do datetime - |> Timex.parse!("{ISO:Extended}") + |> TimeWrapper.parse!("{ISO:Extended}") |> format_time_to_paris(locale, options) end @@ -225,14 +225,11 @@ defmodule Shared.DateTimeDisplay do @spec convert_to_paris_time(DateTime.t() | NaiveDateTime.t()) :: DateTime.t() def convert_to_paris_time(%DateTime{} = dt) do - case Timex.Timezone.convert(dt, "Europe/Paris") do - %Timex.AmbiguousDateTime{after: dt} -> dt - %DateTime{} = dt -> dt - end + TimeWrapper.convert_to_paris_time(dt) end def convert_to_paris_time(%NaiveDateTime{} = ndt) do - ndt |> Timex.Timezone.convert("UTC") |> convert_to_paris_time() + ndt |> TimeWrapper.convert("UTC") |> convert_to_paris_time() end defp get_localized_datetime_format("en" = locale, options) do diff --git a/apps/shared/lib/time_wrapper.ex b/apps/shared/lib/time_wrapper.ex new file mode 100644 index 0000000000..c19d9b2385 --- /dev/null +++ b/apps/shared/lib/time_wrapper.ex @@ -0,0 +1,48 @@ +defmodule TimeWrapper do + @moduledoc """ + This module concentrates all the calls to `Timex` in a single place. + + The idea behind this module is 1. to reduce our dependency on `Timex`, and + 2. to ideally gradually replace calls by built-in Elixir `DateTime` calls, since + `Timex` filled a void in the language that has been partially filled now. + """ + + # credo:disable-for-this-file Credo.Check.Warning.ForbiddenModule + + def parse!(date_as_string, "{ISO:Extended}" = param) do + Timex.parse!(date_as_string, param) + end + + def parse!(date_as_string, "{YYYY}{0M}{0D}" = param) do + Timex.parse!(date_as_string, param) + end + + # NOTE: try not to use this, we will remove it. This is rfc2822 ; + # Plug encodes it, but there is no built-in decoder. + def parse!(datetime_as_string, "{WDshort}, {D} {Mshort} {YYYY} {h24}:{m}:{s} GMT" = param) do + Timex.parse!(datetime_as_string, param) + end + + def diff(first, second, :hours = param) do + Timex.diff(first, second, param) + end + + def now do + Timex.now() + end + + def shift(dt, months: months) do + Timex.shift(dt, months: months) + end + + def convert(dt, "UTC") do + Timex.Timezone.convert(dt, "UTC") + end + + def convert_to_paris_time(dt) do + case Timex.Timezone.convert(dt, "Europe/Paris") do + %Timex.AmbiguousDateTime{after: dt} -> dt + %DateTime{} = dt -> dt + end + end +end diff --git a/apps/shared/test/time_wrapper_test.exs b/apps/shared/test/time_wrapper_test.exs new file mode 100644 index 0000000000..9a6eff0309 --- /dev/null +++ b/apps/shared/test/time_wrapper_test.exs @@ -0,0 +1,4 @@ +defmodule TimeWrapperTest do + use ExUnit.Case, async: true + doctest TimeWrapper +end diff --git a/apps/transport/lib/db/dataset.ex b/apps/transport/lib/db/dataset.ex index 02ad3a5d8f..75a6731c67 100644 --- a/apps/transport/lib/db/dataset.ex +++ b/apps/transport/lib/db/dataset.ex @@ -154,7 +154,7 @@ defmodule DB.Dataset do @spec type_to_str_map() :: %{binary() => binary()} def type_to_str_map, do: %{ - "public-transit" => dgettext("db-dataset", "Public transit - static schedules"), + "public-transit" => dgettext("db-dataset", "Public transit"), "carpooling-areas" => dgettext("db-dataset", "Carpooling areas"), "carpooling-lines" => dgettext("db-dataset", "Carpooling lines"), "carpooling-offers" => dgettext("db-dataset", "Carpooling offers"), diff --git a/apps/transport/lib/irve/extractor.ex b/apps/transport/lib/irve/extractor.ex index 262f7b903e..ba50b62618 100644 --- a/apps/transport/lib/irve/extractor.ex +++ b/apps/transport/lib/irve/extractor.ex @@ -114,6 +114,7 @@ defmodule Transport.IRVE.Extractor do |> Enum.map(fn x -> Map.take(x, [ :dataset_id, + :http_status, :dataset_title, :dataset_organisation_name, :dataset_organisation_url, @@ -136,7 +137,7 @@ defmodule Transport.IRVE.Extractor do Transport.IRVE.Fetcher.get!(row[:url], compressed: false, decode_body: false) row - |> Map.put(:status, status) + |> Map.put(:http_status, status) |> Map.put(:index, index) |> then(fn x -> process_resource_body(x, body) end) end @@ -145,7 +146,7 @@ defmodule Transport.IRVE.Extractor do For a given resource and corresponding body, enrich data with extra stuff like estimated number of charge points. """ - def process_resource_body(%{status: 200} = row, body) do + def process_resource_body(%{http_status: 200} = row, body) do body = body |> String.split("\n") first_line = body |> hd() line_count = (body |> length) - 1 @@ -160,7 +161,7 @@ defmodule Transport.IRVE.Extractor do |> Map.put(:line_count, line_count) end - def process_body(row), do: row + def process_resource_body(row, _body), do: row @doc """ Save the outcome in the database for reporting. diff --git a/apps/transport/lib/jobs/gtfs_to_db.ex b/apps/transport/lib/jobs/gtfs_to_db.ex index 238e8a7207..2b64b38c9f 100644 --- a/apps/transport/lib/jobs/gtfs_to_db.ex +++ b/apps/transport/lib/jobs/gtfs_to_db.ex @@ -120,8 +120,8 @@ defmodule Transport.Jobs.GtfsToDB do friday: friday = r |> Map.fetch!("friday") |> String.to_integer(), saturday: saturday = r |> Map.fetch!("saturday") |> String.to_integer(), sunday: sunday = r |> Map.fetch!("sunday") |> String.to_integer(), - start_date: r |> Map.fetch!("start_date") |> Timex.parse!("{YYYY}{0M}{0D}") |> NaiveDateTime.to_date(), - end_date: r |> Map.fetch!("end_date") |> Timex.parse!("{YYYY}{0M}{0D}") |> NaiveDateTime.to_date() + start_date: r |> Map.fetch!("start_date") |> TimeWrapper.parse!("{YYYY}{0M}{0D}") |> NaiveDateTime.to_date(), + end_date: r |> Map.fetch!("end_date") |> TimeWrapper.parse!("{YYYY}{0M}{0D}") |> NaiveDateTime.to_date() } res @@ -214,7 +214,7 @@ defmodule Transport.Jobs.GtfsToDB do %{ data_import_id: data_import_id, service_id: r |> Map.fetch!("service_id"), - date: r |> Map.fetch!("date") |> Timex.parse!("{YYYY}{0M}{0D}") |> NaiveDateTime.to_date(), + date: r |> Map.fetch!("date") |> TimeWrapper.parse!("{YYYY}{0M}{0D}") |> NaiveDateTime.to_date(), exception_type: r |> Map.fetch!("exception_type") |> String.to_integer() } end) diff --git a/apps/transport/lib/jobs/oban_logger.ex b/apps/transport/lib/jobs/oban_logger.ex index ce1b3c059a..817b930954 100644 --- a/apps/transport/lib/jobs/oban_logger.ex +++ b/apps/transport/lib/jobs/oban_logger.ex @@ -1,8 +1,14 @@ defmodule Transport.Jobs.ObanLogger do @moduledoc """ - Logs the Oban job exceptions as warnings + Setup telemetry/logging for Oban. + + We: + - log job exceptions as warnings + - log Oban events related to the orchestration (notifier, queues, plugins etc.) + - we send an email when a job failed after its maximum attempt for jobs with a specific tag """ require Logger + @tag_email_on_failure "email_on_failure" @doc """ @@ -35,5 +41,22 @@ defmodule Transport.Jobs.ObanLogger do ) end - def setup, do: :telemetry.attach("oban-logger", [:oban, :job, :exception], &handle_event/4, nil) + def setup do + :telemetry.attach("oban-logger", [:oban, :job, :exception], &handle_event/4, nil) + + # Log recommended events for production. + # We leave out `job` events because job start/end can be quite noisy. + # https://hexdocs.pm/oban/preparing_for_production.html#logging + # https://hexdocs.pm/oban/Oban.Telemetry.html + # We may simplify this when + # https://github.com/oban-bg/oban/commit/13eabe3f8019e350ef979369a26f186bdf7be63e + # will be released. + events = [ + [:oban, :notifier, :switch], + [:oban, :queue, :shutdown], + [:oban, :stager, :switch] + ] + + :telemetry.attach_many("oban-default-logger", events, &Oban.Telemetry.handle_event/4, encode: true, level: :info) + end end diff --git a/apps/transport/lib/jobs/workflow.ex b/apps/transport/lib/jobs/workflow.ex index 906eec5abc..07a813af92 100644 --- a/apps/transport/lib/jobs/workflow.ex +++ b/apps/transport/lib/jobs/workflow.ex @@ -82,7 +82,7 @@ defmodule Transport.Jobs.Workflow do {:notification, :gossip, %{"success" => false, "job_id" => ^job_id} = notif} -> reason = notif |> Map.get("reason", "unknown reason") - {:error, "Job #{job_id} has failed: #{inspect(reason)}. Workflow is stopping here"} + {:error, "Job #{job_id} has failed: #{reason}. Workflow is stopping here"} end end end @@ -173,10 +173,17 @@ defmodule Transport.Jobs.Workflow do }, nil ) do + # `error` can be an error message or an `Oban.TimeoutError` exception. + # ```` + # %Oban.TimeoutError{ + # message: "Transport.Jobs.ResourceHistoryJob timed out after 1000ms", + # reason: :timeout + # } + # ``` Notifier.notify_workflow(%{meta: %{"workflow" => true}}, %{ "success" => false, "job_id" => job_id, - "reason" => error + "reason" => inspect(error) }) end diff --git a/apps/transport/lib/transport_web/live/backoffice/irve_dashboard_live.ex b/apps/transport/lib/transport_web/live/backoffice/irve_dashboard_live.ex index 25623eae92..4088708b62 100644 --- a/apps/transport/lib/transport_web/live/backoffice/irve_dashboard_live.ex +++ b/apps/transport/lib/transport_web/live/backoffice/irve_dashboard_live.ex @@ -3,7 +3,7 @@ defmodule TransportWeb.Backoffice.IRVEDashboardLive do use Phoenix.HTML import TransportWeb.Backoffice.JobsLive, only: [ensure_admin_auth_or_redirect: 3] import TransportWeb.Router.Helpers - import Helpers, only: [format_number: 1] + import Helpers, only: [format_number_maybe_nil: 2] import Ecto.Query, only: [last: 2] @impl true @@ -25,7 +25,12 @@ defmodule TransportWeb.Backoffice.IRVEDashboardLive do filtering_expression == "" || String.contains?(resource["dataset_organisation_name"] |> String.downcase(), filtering_expression) || - String.contains?(format_validity(resource["valid"]) |> inspect |> String.downcase(), filtering_expression) + String.contains?( + format_validity(resource["valid"], resource["http_status"]) + |> inspect + |> String.downcase(), + filtering_expression + ) end def assign_data(socket) do @@ -119,7 +124,9 @@ defmodule TransportWeb.Backoffice.IRVEDashboardLive do |> Enum.sort_by(fn x -> x["line_count"] end, :desc) end - def format_validity(false), do: {:safe, "KO"} - def format_validity(true), do: "OK" - def format_validity(nil), do: "Non testé" + def format_validity(false, 200), do: {:safe, "KO"} + def format_validity(true, 200), do: "OK" + def format_validity(nil, 200), do: "Non testé" + # mostly there to handle 404/500. Ignore validity and assume the resource is not reachable at all + def format_validity(_validity, http_status), do: {:safe, "KO (#{http_status})"} end diff --git a/apps/transport/lib/transport_web/live/backoffice/irve_dashboard_live.html.heex b/apps/transport/lib/transport_web/live/backoffice/irve_dashboard_live.html.heex index eef1805a15..717a4ed912 100644 --- a/apps/transport/lib/transport_web/live/backoffice/irve_dashboard_live.html.heex +++ b/apps/transport/lib/transport_web/live/backoffice/irve_dashboard_live.html.heex @@ -43,9 +43,9 @@ — <%= resource["last_modified"] |> String.slice(0..15) %> - <%= format_validity(resource["valid"]) %> + <%= format_validity(resource["valid"], resource["http_status"]) %> - <%= format_number(resource["line_count"]) %> + <%= format_number_maybe_nil(resource["line_count"], nil_result: "???") %> <% end %> diff --git a/apps/transport/lib/transport_web/live/discussions_live.ex b/apps/transport/lib/transport_web/live/discussions_live.ex index 476ecb28fe..577ef4569f 100644 --- a/apps/transport/lib/transport_web/live/discussions_live.ex +++ b/apps/transport/lib/transport_web/live/discussions_live.ex @@ -115,7 +115,7 @@ defmodule TransportWeb.DiscussionsLive do end) |> Enum.max(DateTime) - two_months_ago = DateTime.utc_now() |> Timex.shift(months: -2) + two_months_ago = DateTime.utc_now() |> TimeWrapper.shift(months: -2) DateTime.compare(two_months_ago, latest_comment_datetime) == :gt end diff --git a/apps/transport/lib/transport_web/plugs/router.ex b/apps/transport/lib/transport_web/plugs/router.ex index d1cbfb54a9..4ee9e686e6 100644 --- a/apps/transport/lib/transport_web/plugs/router.ex +++ b/apps/transport/lib/transport_web/plugs/router.ex @@ -2,7 +2,7 @@ defmodule TransportWeb.Plugs.Router do use Plug.Router plug(TransportWeb.Plugs.HealthCheck, at: "/health-check") - plug(TransportWeb.Plugs.Halt, if: {Transport.Application, :worker_only?}, message: "UP (WORKER-ONLY)") + plug(TransportWeb.Plugs.WorkerHealthcheck, if: {Transport.Application, :worker_only?}) plug(:match) plug(:dispatch) diff --git a/apps/transport/lib/transport_web/plugs/worker_healthcheck.ex b/apps/transport/lib/transport_web/plugs/worker_healthcheck.ex new file mode 100644 index 0000000000..3066e88e5f --- /dev/null +++ b/apps/transport/lib/transport_web/plugs/worker_healthcheck.ex @@ -0,0 +1,94 @@ +defmodule TransportWeb.Plugs.WorkerHealthcheck do + @moduledoc """ + A plug for the worker. + It can be conditionally enabled by passing an `:if` condition that will be evaluated. + + It displays: + - when the app was started + - the last attempt for Oban jobs + - if the system is healthy + + The system is considered healthy if the app was started recently or + if Oban attempted jobs recently. + """ + import Plug.Conn + require Logger + + @app_start_waiting_delay {20, :minute} + @oban_max_delay_since_last_attempt {60, :minute} + + def init(options), do: options + + def call(conn, opts) do + {mod, fun} = opts[:if] + + if apply(mod, fun, []) do + store_last_attempted_at_delay_metric() + status_code = if healthy_state?(), do: 200, else: 503 + + conn = + conn + |> put_resp_content_type("text/plain") + |> send_resp(status_code, """ + UP (WORKER-ONLY) + App start time: #{app_start_datetime()} + App started recently?: #{app_started_recently?()} + Oban last attempt: #{oban_last_attempted_at()} + Oban attempted jobs recently?: #{oban_attempted_jobs_recently?()} + Healthy state?: #{healthy_state?()} + """) + |> halt() + + # NOTE: Clever Cloud monitoring will better pick stuff back up + # if the app is completely down. + if !healthy_state?() do + Logger.info("Hot-fix: shutting down!!!") + # "Asynchronously and carefully stops the Erlang runtime system." + System.stop() + end + + conn + else + conn + end + end + + def store_last_attempted_at_delay_metric do + value = DateTime.diff(oban_last_attempted_at(), DateTime.utc_now(), :second) + Appsignal.add_distribution_value("oban.last_attempted_at_delay", value) + end + + def healthy_state? do + app_started_recently?() or oban_attempted_jobs_recently?() + end + + def app_started_recently? do + {delay, unit} = @app_start_waiting_delay + DateTime.diff(DateTime.utc_now(), app_start_datetime(), unit) < delay + end + + def app_start_datetime do + Transport.Cache.fetch(app_start_datetime_cache_key_name(), fn -> DateTime.utc_now() end, expire: nil) + end + + def app_start_datetime_cache_key_name, do: "#{__MODULE__}::app_start_datetime" + + def oban_attempted_jobs_recently? do + {delay, unit} = @oban_max_delay_since_last_attempt + DateTime.after?(oban_last_attempted_at(), DateTime.add(DateTime.utc_now(), -delay, unit)) + end + + def oban_last_attempted_at do + %Postgrex.Result{rows: [[delay]]} = + DB.Repo.query!(""" + SELECT MAX(attempted_at) + FROM oban_jobs + WHERE state = 'completed' + """) + + case delay do + nil -> DateTime.new!(~D[1970-01-01], ~T[00:00:00.000], "Etc/UTC") + %NaiveDateTime{} = nt -> DateTime.from_naive!(nt, "Etc/UTC") + end + end +end diff --git a/apps/transport/lib/transport_web/router.ex b/apps/transport/lib/transport_web/router.ex index 39ec8b7c28..cb9f5dfeb8 100644 --- a/apps/transport/lib/transport_web/router.ex +++ b/apps/transport/lib/transport_web/router.ex @@ -56,7 +56,6 @@ defmodule TransportWeb.Router do pipeline :reuser_space do plug(:browser) plug(:authentication_required, destination_path: "/infos_reutilisateurs") - plug(:check_reuser_space_enabled) end scope "/", OpenApiSpex.Plug do @@ -387,17 +386,6 @@ defmodule TransportWeb.Router do end end - def check_reuser_space_enabled(%Plug.Conn{} = conn, _) do - if TransportWeb.Session.display_reuser_space?(conn) do - conn - else - conn - |> put_flash(:info, dgettext("alert", "This feature is currently not available.")) - |> redirect(to: "/") - |> halt() - end - end - # Check that a secret key is passed in the URL in the `export_key` query parameter defp check_export_secret_key(%Plug.Conn{params: params} = conn, _) do export_key_value = Map.get(params, "export_key", "") diff --git a/apps/transport/lib/transport_web/session.ex b/apps/transport/lib/transport_web/session.ex index 27aebfad97..e8f73874a2 100644 --- a/apps/transport/lib/transport_web/session.ex +++ b/apps/transport/lib/transport_web/session.ex @@ -58,23 +58,6 @@ defmodule TransportWeb.Session do DB.Dataset.base_query() |> where([dataset: d], d.organization_id in ^org_ids) |> DB.Repo.exists?() end - @doc """ - A temporary helper method to determine if we should display "reuser space features". - Convenient method to find various entrypoints in the codebase: - - links and buttons to the reuser space - - follow dataset hearts (search results, dataset pages) - - reuser space - - Enable it for everybody but keep a "kill switch" to disable it quickly - by setting an environment variable and rebooting the app. - - transport.data.gouv.fr admins get access no matter what. - """ - def display_reuser_space?(%Plug.Conn{} = conn) do - feature_disabled = Application.fetch_env!(:transport, :disable_reuser_space) - admin?(conn) or not feature_disabled - end - @spec set_session_attribute_attribute(Plug.Conn.t(), binary(), boolean()) :: Plug.Conn.t() defp set_session_attribute_attribute(%Plug.Conn{} = conn, key, value) do current_user = current_user(conn) diff --git a/apps/transport/lib/transport_web/templates/dataset/_header_links.html.heex b/apps/transport/lib/transport_web/templates/dataset/_header_links.html.heex index 0515fd571d..25a3964251 100644 --- a/apps/transport/lib/transport_web/templates/dataset/_header_links.html.heex +++ b/apps/transport/lib/transport_web/templates/dataset/_header_links.html.heex @@ -3,32 +3,30 @@ <%= link("Backoffice", to: backoffice_page_path(@conn, :edit, @dataset.id)) %> · <% end %> - <%= if TransportWeb.Session.display_reuser_space?(@conn) do %> - - <%= if @current_user do %> - <%= if @is_producer do %> - <%= link(dgettext("default", "Producer space"), - to: espace_producteur_path(@conn, :edit_dataset, @dataset.id, utm_campaign: "dataset_details"), + + <%= if @current_user do %> + <%= if @is_producer do %> + <%= link(dgettext("default", "Producer space"), + to: espace_producteur_path(@conn, :edit_dataset, @dataset.id, utm_campaign: "dataset_details"), + target: "_blank" + ) %> + <% else %> + <%= if @follows_dataset do %> + <%= link(dgettext("default", "Reuser space"), + to: reuser_space_path(@conn, :datasets_edit, @dataset.id, utm_campaign: "dataset_details"), target: "_blank" ) %> <% else %> - <%= if @follows_dataset do %> - <%= link(dgettext("default", "Reuser space"), - to: reuser_space_path(@conn, :datasets_edit, @dataset.id, utm_campaign: "dataset_details"), - target: "_blank" - ) %> - <% else %> - <%= link(dgettext("default", "Reuser space"), - to: reuser_space_path(@conn, :espace_reutilisateur, utm_campaign: "dataset_details"), - target: "_blank" - ) %> - <% end %> + <%= link(dgettext("default", "Reuser space"), + to: reuser_space_path(@conn, :espace_reutilisateur, utm_campaign: "dataset_details"), + target: "_blank" + ) %> <% end %> - <% else %> - <%= link(dgettext("default", "Reuser space"), - to: page_path(@conn, :infos_reutilisateurs, utm_campaign: "dataset_details"), - target: "_blank" - ) %> <% end %> + <% else %> + <%= link(dgettext("default", "Reuser space"), + to: page_path(@conn, :infos_reutilisateurs, utm_campaign: "dataset_details"), + target: "_blank" + ) %> <% end %> diff --git a/apps/transport/lib/transport_web/templates/dataset/details.html.heex b/apps/transport/lib/transport_web/templates/dataset/details.html.heex index 10de3427b1..686432d3a2 100644 --- a/apps/transport/lib/transport_web/templates/dataset/details.html.heex +++ b/apps/transport/lib/transport_web/templates/dataset/details.html.heex @@ -239,11 +239,9 @@
- <%= if TransportWeb.Session.display_reuser_space?(@conn) do %> - <%= live_render(@conn, TransportWeb.Live.FollowDatasetLive, - session: %{"current_user" => @current_user, "dataset_id" => @dataset.id} - ) %> - <% end %> + <%= live_render(@conn, TransportWeb.Live.FollowDatasetLive, + session: %{"current_user" => @current_user, "dataset_id" => @dataset.id} + ) %> @@ -273,14 +271,6 @@ text: Dataset.type_to_str(@dataset.type), icon: icon_type_path(@dataset) ) %> - <%= if real_time_public_transit?(@dataset) do %> - <%= render("_dataset_type.html", - conn: @conn, - link: dataset_path(@conn, :index, type: "public-transit", filter: "has_realtime"), - text: dgettext("page-index", "Public transport - realtime traffic"), - icon: icon_type_path("real-time-public-transit") - ) %> - <% end %>
<%= render("_licence.html", conn: @conn, dataset: @dataset) %> diff --git a/apps/transport/lib/transport_web/templates/dataset/index.html.heex b/apps/transport/lib/transport_web/templates/dataset/index.html.heex index 4e301295fe..86a7d9e53e 100644 --- a/apps/transport/lib/transport_web/templates/dataset/index.html.heex +++ b/apps/transport/lib/transport_web/templates/dataset/index.html.heex @@ -196,9 +196,7 @@
- <%= if not is_nil(@current_user) and TransportWeb.Session.display_reuser_space?(@conn) do %> - - <% end %> + <%= unless is_nil(icon_type_path(dataset)) do %> <%= img_tag(icon_type_path(dataset), alt: dataset.type) %> <% end %> diff --git a/apps/transport/lib/transport_web/templates/layout/_header.html.heex b/apps/transport/lib/transport_web/templates/layout/_header.html.heex index 6e222369e7..3950024dfb 100644 --- a/apps/transport/lib/transport_web/templates/layout/_header.html.heex +++ b/apps/transport/lib/transport_web/templates/layout/_header.html.heex @@ -97,11 +97,9 @@ to: page_path(@conn, :espace_producteur, utm_campaign: "menu_dropdown") ) %> <% end %> - <%= if TransportWeb.Session.display_reuser_space?(@conn) do %> - <%= link(gettext("Reuser space"), - to: reuser_space_path(@conn, :espace_reutilisateur, utm_campaign: "menu_dropdown") - ) %> - <% end %> + <%= link(gettext("Reuser space"), + to: reuser_space_path(@conn, :espace_reutilisateur, utm_campaign: "menu_dropdown") + ) %> <%= dgettext("page-index", "Producer space") %> - <%= if TransportWeb.Session.display_reuser_space?(@conn) do %> - - <%= dgettext("page-index", "Reuser space") %> - - <% end %> + + <%= dgettext("page-index", "Reuser space") %> +