Fiabilise les médias et la navigation mobile
This commit is contained in:
parent
465b384c08
commit
5909f55aba
12 changed files with 266 additions and 19 deletions
|
|
@ -2,6 +2,15 @@
|
|||
|
||||
Toutes les modifications importantes du projet sont consignées ici. Le format s’inspire de [Keep a Changelog](https://keepachangelog.com/fr/1.1.0/) et le projet suit le [versionnage sémantique](https://semver.org/lang/fr/).
|
||||
|
||||
## [1.0.0-rc.17] — 2026-09-08
|
||||
|
||||
### Interface mobile et médias publics
|
||||
|
||||
- remplacement du défilement horizontal du menu principal par un menu repliable sur téléphone et tablette ;
|
||||
- maintien d’une navigation complète et accessible au clavier comme aux lecteurs d’écran ;
|
||||
- correction des permissions des nouveaux dossiers de photos publiques afin qu’ils restent lisibles par le serveur web ;
|
||||
- conservation des permissions strictes des photographies et documents privés.
|
||||
|
||||
## [1.0.0-rc.16] — 2026-09-08
|
||||
|
||||
### Mise à jour autonome
|
||||
|
|
|
|||
|
|
@ -73,3 +73,7 @@ Intégration de la modification directement dans les lignes du catalogue pour re
|
|||
## `1.0.0-rc.16` — Mise à jour autonome
|
||||
|
||||
Création d’un parcours de mise à jour commun à l’interface et à la ligne de commande, avec releases Forgejo, sauvegarde obligatoire, contrôles d’intégrité et retour arrière complet.
|
||||
|
||||
## `1.0.0-rc.17` — Utilisation mobile
|
||||
|
||||
Remplacement de la barre de navigation horizontale par un menu mobile repliable et fiabilisation des permissions appliquées aux nouvelles photos publiques.
|
||||
|
|
|
|||
|
|
@ -200,7 +200,7 @@ L’option `--apply` ne doit être utilisée qu’après lecture des rapports. L
|
|||
|
||||
## État du projet
|
||||
|
||||
La candidate actuelle est `1.0.0-rc.3`. La branche 1.0 est gelée fonctionnellement : seuls les défauts bloquants découverts pendant les validations terrain sont corrigés avant `1.0.0`.
|
||||
La candidate actuelle est `1.0.0-rc.17`. La branche 1.0 est gelée fonctionnellement : seuls les défauts bloquants découverts pendant les validations terrain sont corrigés avant `1.0.0`.
|
||||
|
||||
Le contrôle de stabilisation est disponible dans [docs/AUDIT-1.0.md](docs/AUDIT-1.0.md).
|
||||
|
||||
|
|
|
|||
2
VERSION
2
VERSION
|
|
@ -1 +1 @@
|
|||
1.0.0-rc.16
|
||||
1.0.0-rc.17
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ trait AnimalPhotoActions
|
|||
$base = $base ?: 'photo';
|
||||
$dir = __DIR__ . '/../../public/media/animals/' . $id;
|
||||
try {
|
||||
PrivateMediaService::ensure($dir, true);
|
||||
$stored = ImageService::storeUploaded($tmp, $dir, $base, 'photo');
|
||||
$filename = $stored['filename'];
|
||||
$mime = $stored['mime'];
|
||||
|
|
|
|||
|
|
@ -191,10 +191,7 @@ final class AnimalsController
|
|||
|
||||
private static function ensureAnimalMediaDir(int $animalId): void
|
||||
{
|
||||
$dir = self::animalMediaDir($animalId);
|
||||
if (!is_dir($dir)) {
|
||||
mkdir($dir, 0775, true);
|
||||
}
|
||||
PrivateMediaService::ensure(self::animalMediaDir($animalId), true);
|
||||
}
|
||||
|
||||
private static function safeFilename(string $name): string
|
||||
|
|
|
|||
|
|
@ -28,6 +28,19 @@ final class PrivateMediaService
|
|||
throw new RuntimeException(t('service.image.directory_failed'));
|
||||
}
|
||||
@chmod($dir, $mode);
|
||||
if ($public) {
|
||||
self::hardenPublicParents($dir);
|
||||
}
|
||||
}
|
||||
|
||||
private static function hardenPublicParents(string $dir): void
|
||||
{
|
||||
$mediaRoot = dirname(__DIR__, 2) . '/public/media';
|
||||
foreach ([$mediaRoot, $mediaRoot . '/animals', $dir] as $publicDir) {
|
||||
if (is_dir($publicDir)) {
|
||||
@chmod($publicDir, 0755);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function moveVisibility(int $animalId, string $filename, bool $toPublic): void
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
/** Barre de navigation et recherche globale. */
|
||||
?>
|
||||
<header class="navbar navbar-expand-md d-print-none">
|
||||
<header class="navbar navbar-expand-lg d-print-none">
|
||||
<div class="container-xl">
|
||||
<div class="topbar-surface d-flex align-items-center justify-content-between w-100">
|
||||
<a class="navbar-brand d-flex flex-row align-items-center py-0"
|
||||
|
|
@ -16,7 +16,15 @@
|
|||
</span>
|
||||
</a>
|
||||
|
||||
<div class="navbar-nav flex-row order-md-last">
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse"
|
||||
data-bs-target="#globinoursMainNavigation" aria-controls="globinoursMainNavigation"
|
||||
aria-expanded="false" aria-label="<?= h(t('nav.open_menu')) ?>">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
|
||||
<nav class="collapse navbar-collapse topbar-menu" id="globinoursMainNavigation"
|
||||
aria-label="<?= h(t('nav.main')) ?>">
|
||||
<div class="navbar-nav flex-row order-md-last ms-md-auto">
|
||||
<span class="search-trigger-wrap"><button class="search-trigger" type="button" data-bs-toggle="modal"
|
||||
data-bs-target="#globalSearchModal"
|
||||
title="<?= h(t('search.open')) ?> — <?= h(t('search.shortcut')) ?>"
|
||||
|
|
@ -125,6 +133,7 @@
|
|||
</div>
|
||||
|
||||
</div>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
|
|
|||
|
|
@ -31,9 +31,10 @@
|
|||
<div class="col-lg-6">
|
||||
<section class="card h-100">
|
||||
<div class="card-body">
|
||||
<span class="badge bg-blue-lt mb-2">1.0.0-rc.16</span>
|
||||
<h3>Mises à jour autonomes</h3>
|
||||
<p class="text-muted">Installation vérifiée depuis Forgejo, sauvegarde obligatoire et retour automatique du code et des données en cas d’échec.</p>
|
||||
<span class="badge bg-blue-lt mb-2">1.0.0-rc.17</span>
|
||||
<h3>Utilisation mobile</h3>
|
||||
<p class="text-muted">Navigation repliable sur les petits écrans et publication fiable des nouvelles
|
||||
photographies, y compris depuis l’application Android.</p>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,218 @@
|
|||
html{scroll-padding-top:1rem}img{max-width:100%}.table-responsive{overscroll-behavior-inline:contain}.nav-tabs{flex-wrap:nowrap;overflow-x:auto;overflow-y:hidden;-webkit-overflow-scrolling:touch;scrollbar-width:thin}.nav-tabs .nav-link{white-space:nowrap}.modal-dialog-scrollable{max-height:calc(100dvh - 1rem)}
|
||||
@media(max-width:991.98px){.page>.navbar{padding:.5rem}.topbar-surface{height:auto;min-height:72px;padding:.55rem;gap:.5rem}.topbar-surface>.navbar-brand{flex:0 0 auto}.topbar-surface>.navbar-nav{min-width:0;overflow-x:auto;overscroll-behavior-inline:contain;padding-bottom:.2rem}.topbar-surface>.navbar-nav>.btn,.topbar-surface>.navbar-nav>.dropdown{flex:0 0 auto}.page-header{padding-top:.5rem}.page-body{margin-top:.75rem}.settings-section-nav{flex-wrap:nowrap!important;overflow-x:auto;padding-bottom:.35rem}.footer-surface{align-items:flex-start!important}.page-title{font-size:1.15rem}}
|
||||
@media(max-width:767.98px){body,.page{background-attachment:scroll}.container-xl{padding-left:.75rem;padding-right:.75rem}.topbar-surface .navbar-brand img{width:42px;height:44px}.topbar-surface .navbar-brand span span:last-child{display:none}.topbar-surface>.navbar-nav{gap:.25rem}.topbar-surface>.navbar-nav>.btn{min-width:44px;height:46px;padding:.45rem;white-space:nowrap;margin-right:.25rem!important}.settings-trigger{width:46px;height:46px;margin-right:0!important}.settings-dropdown .dropdown-menu{position:fixed!important;inset:auto .75rem .75rem .75rem!important;width:auto!important;max-height:75dvh;overflow-y:auto;transform:none!important}.settings-menu-columns{grid-template-columns:1fr}.settings-menu-column{padding:.15rem .35rem}.settings-menu-column+.settings-menu-column{border-left:0;border-top:1px solid rgba(98,105,118,.16);margin-top:.65rem;padding-top:.65rem;padding-left:.35rem}.card-header,.card-body,.card-footer{padding-left:.85rem;padding-right:.85rem}.btn{min-height:44px}.btn-sm{min-height:40px}input.form-control,select.form-select,textarea.form-control{font-size:16px}.modal-dialog{margin:.5rem}.modal-content{max-height:calc(100dvh - 1rem)}.modal-body{overflow-y:auto}.footer-meta{gap:.65rem!important}.paw-footer{height:80px;flex-basis:80px}}
|
||||
@media(max-width:420px){.topbar-surface .navbar-brand span{display:none}.topbar-surface .navbar-brand img{margin-right:0!important}.footer-surface{font-size:.9rem}}
|
||||
@media(display-mode:standalone){body{padding-top:env(safe-area-inset-top);padding-bottom:env(safe-area-inset-bottom)}.page>.navbar{position:sticky;top:env(safe-area-inset-top);background:#f7f3eb;z-index:1050}}
|
||||
html {
|
||||
scroll-padding-top: 1rem;
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.table-responsive {
|
||||
overscroll-behavior-inline: contain;
|
||||
}
|
||||
|
||||
.nav-tabs {
|
||||
flex-wrap: nowrap;
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
scrollbar-width: thin;
|
||||
}
|
||||
|
||||
.nav-tabs .nav-link {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.modal-dialog-scrollable {
|
||||
max-height: calc(100dvh - 1rem);
|
||||
}
|
||||
|
||||
@media (max-width: 991.98px) {
|
||||
.page > .navbar {
|
||||
padding: .5rem;
|
||||
}
|
||||
|
||||
.topbar-surface {
|
||||
flex-wrap: wrap;
|
||||
height: auto;
|
||||
min-height: 72px;
|
||||
padding: .55rem;
|
||||
gap: .5rem;
|
||||
}
|
||||
|
||||
.topbar-surface > .navbar-brand {
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.topbar-menu {
|
||||
flex-basis: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.topbar-menu > .navbar-nav {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
width: 100%;
|
||||
gap: .5rem;
|
||||
padding-top: .5rem;
|
||||
}
|
||||
|
||||
.topbar-menu .btn {
|
||||
justify-content: flex-start;
|
||||
width: 100%;
|
||||
margin-right: 0 !important;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
.topbar-menu .search-trigger-wrap,
|
||||
.topbar-menu .settings-dropdown {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.topbar-menu .search-trigger,
|
||||
.topbar-menu .settings-trigger {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
min-height: 44px;
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
.page-header {
|
||||
padding-top: .5rem;
|
||||
}
|
||||
|
||||
.page-body {
|
||||
margin-top: .75rem;
|
||||
}
|
||||
|
||||
.settings-section-nav {
|
||||
flex-wrap: nowrap !important;
|
||||
overflow-x: auto;
|
||||
padding-bottom: .35rem;
|
||||
}
|
||||
|
||||
.footer-surface {
|
||||
align-items: flex-start !important;
|
||||
}
|
||||
|
||||
.page-title {
|
||||
font-size: 1.15rem;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 767.98px) {
|
||||
body,
|
||||
.page {
|
||||
background-attachment: scroll;
|
||||
}
|
||||
|
||||
.container-xl {
|
||||
padding-left: .75rem;
|
||||
padding-right: .75rem;
|
||||
}
|
||||
|
||||
.topbar-surface .navbar-brand img {
|
||||
width: 42px;
|
||||
height: 44px;
|
||||
}
|
||||
|
||||
.topbar-surface .navbar-brand span span:last-child {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.settings-dropdown .dropdown-menu {
|
||||
position: fixed !important;
|
||||
inset: auto .75rem .75rem .75rem !important;
|
||||
width: auto !important;
|
||||
max-height: 75dvh;
|
||||
overflow-y: auto;
|
||||
transform: none !important;
|
||||
}
|
||||
|
||||
.settings-menu-columns {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.settings-menu-column {
|
||||
padding: .15rem .35rem;
|
||||
}
|
||||
|
||||
.settings-menu-column + .settings-menu-column {
|
||||
margin-top: .65rem;
|
||||
padding-top: .65rem;
|
||||
padding-left: .35rem;
|
||||
border-top: 1px solid rgba(98, 105, 118, .16);
|
||||
border-left: 0;
|
||||
}
|
||||
|
||||
.card-header,
|
||||
.card-body,
|
||||
.card-footer {
|
||||
padding-left: .85rem;
|
||||
padding-right: .85rem;
|
||||
}
|
||||
|
||||
.btn {
|
||||
min-height: 44px;
|
||||
}
|
||||
|
||||
.btn-sm {
|
||||
min-height: 40px;
|
||||
}
|
||||
|
||||
input.form-control,
|
||||
select.form-select,
|
||||
textarea.form-control {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.modal-dialog {
|
||||
margin: .5rem;
|
||||
}
|
||||
|
||||
.modal-content {
|
||||
max-height: calc(100dvh - 1rem);
|
||||
}
|
||||
|
||||
.modal-body {
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.footer-meta {
|
||||
gap: .65rem !important;
|
||||
}
|
||||
|
||||
.paw-footer {
|
||||
height: 80px;
|
||||
flex-basis: 80px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 420px) {
|
||||
.topbar-surface .navbar-brand span {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.topbar-surface .navbar-brand img {
|
||||
margin-right: 0 !important;
|
||||
}
|
||||
|
||||
.footer-surface {
|
||||
font-size: .9rem;
|
||||
}
|
||||
}
|
||||
|
||||
@media (display-mode: standalone) {
|
||||
body {
|
||||
padding-top: env(safe-area-inset-top);
|
||||
padding-bottom: env(safe-area-inset-bottom);
|
||||
}
|
||||
|
||||
.page > .navbar {
|
||||
position: sticky;
|
||||
top: env(safe-area-inset-top);
|
||||
z-index: 1050;
|
||||
background: #f7f3eb;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ return [
|
|||
'settings.public_site'=>'Public website','common.title'=>'Title','common.text'=>'Text','public_site.unavailable'=>'Website unavailable','public_site.unavailable_help'=>'The public website is not available yet.','public_site.not_found'=>'Page not found','public_site.animals'=>'Our animals','public_site.contact'=>'Contact','public_site.home'=>'Home','public_site.donation'=>'Donations','public_site.navigation'=>'Main navigation','public_site.powered_by'=>'Powered by','public_site.rna'=>'RNA registration','public_site.siret'=>'SIRET','public_site.map_title'=>'Find us','public_site.map_marker'=>'Association address','public_site.discover'=>'Meet the animals','public_site.latest_animals'=>'Looking for a family','public_site.no_animals'=>'No animal is currently published in this category.','public_site.all_species'=>'All species','public_site.sterilized'=>'Sterilised','public_site.age_unknown'=>'Age not provided','public_site.months'=>':count months','public_site.years'=>':count year(s)','public_site.years_months'=>':years year(s) and :months months','public_site.back_animals'=>'Back to animals','public_site.age'=>'Age','public_site.breed'=>'Breed','public_site.coat'=>'Coat','public_site.dogs'=>'Dog-friendly','public_site.cats'=>'Cat-friendly','public_site.children'=>'Child-friendly','public_site.clean'=>'House-trained','public_site.ask_adoption'=>'Contact us about adoption','public_site.make_donation'=>'Make a donation',
|
||||
'public_site.settings_title'=>'Settings — Public website','public_site.settings_heading'=>'Public mini-site','public_site.settings_intro'=>'A lightweight website powered only by information deliberately made public.','public_site.preview'=>'View website','public_site.saved'=>'Public website settings were saved.','public_site.activation_style'=>'Activation and appearance','public_site.enable'=>'Enable public website','public_site.enable_help'=>'When disabled, no public page or animal profile can be viewed.','public_site.theme'=>'Visual theme','public_site.theme_warm'=>'Warm','public_site.theme_nature'=>'Natural','public_site.theme_minimal'=>'Minimal','public_site.free_page'=>'Free-form page','public_site.show_free_page'=>'Show this page in the menu','public_site.donation_url'=>'Donation platform link','public_site.contact_reuse'=>'Address, phone number, email, and logo come from the association’s general settings.','public_site.invalid_url'=>'One of the entered links is invalid.','public_site.publish_animal'=>'Publish this animal on the mini-site','public_site.publish_animal_help'=>'The profile will only be visible when the animal is also available for adoption. Only public photos and the text below are used.','public_site.public_description'=>'Public description','public_site.public_description_example'=>'Personality, habits, and the kind of family they need…',
|
||||
'common.open'=>'Open','settings.lab_references'=>'Lab references','medical_document.menu_prescription'=>'Prescription','medical_document.menu_analysis'=>'Lab results','lab_reference.title'=>'Settings — Lab references','lab_reference.heading'=>'Lab reference ranges','lab_reference.intro'=>'Ranges by analyser and species used to prefill lab reports and interpret their charts.','lab_reference.saved'=>'Lab reference ranges were saved.','lab_reference.priority_title'=>'Local reference takes priority.','lab_reference.priority_help'=>'If your analyser or clinic prints different ranges, enter them here: they take precedence over manufacturer values. An empty bound does not trigger colour interpretation.','lab_reference.manufacturer_ranges'=>'Initial manufacturer ranges; all values remain editable.','lab_reference.code'=>'Code','lab_reference.source'=>'Source / note','lab_reference.invalid'=>'Invalid reference data: check labels, units, and bounds.',
|
||||
'nav.dashboard'=>'Dashboard','nav.animals'=>'Animals','nav.directory'=>'Directory','nav.care_round'=>'Care rounds','nav.statistics'=>'Statistics','nav.administrative'=>'Administration','nav.grants'=>'Grants',
|
||||
'nav.main'=>'Main navigation','nav.open_menu'=>'Open menu','nav.dashboard'=>'Dashboard','nav.animals'=>'Animals','nav.directory'=>'Directory','nav.care_round'=>'Care rounds','nav.statistics'=>'Statistics','nav.administrative'=>'Administration','nav.grants'=>'Grants',
|
||||
'account.settings'=>'Account and settings','account.settings_heading'=>'Settings','account.logout'=>'Log out',
|
||||
'settings.general'=>'General','settings.users'=>'Users','settings.permissions'=>'Roles and permissions','settings.species'=>'Species','settings.pricing'=>'Pricing','settings.backups'=>'Backups','settings.audit'=>'Audit log','settings.asm3'=>'ASM3 migration','settings.data'=>'Data and demo',
|
||||
'settings.general_title'=>'General settings','settings.general_intro'=>'Association identity and shared Globinours rules.','settings.language'=>'Application language','settings.language_help'=>'Default interface language. French is used as a fallback whenever a translation is missing.','settings.save'=>'Save settings',
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ return [
|
|||
'settings.public_site'=>'Site public','common.title'=>'Titre','common.text'=>'Texte','public_site.unavailable'=>'Site indisponible','public_site.unavailable_help'=>'Le site public n’est pas encore disponible.','public_site.not_found'=>'Page introuvable','public_site.animals'=>'Nos animaux','public_site.contact'=>'Contact','public_site.home'=>'Accueil','public_site.donation'=>'Dons','public_site.navigation'=>'Navigation principale','public_site.powered_by'=>'Propulsé par','public_site.rna'=>'RNA','public_site.siret'=>'SIRET','public_site.map_title'=>'Nous trouver','public_site.map_marker'=>'Adresse de l’association','public_site.discover'=>'Découvrir les animaux','public_site.latest_animals'=>'Ils cherchent une famille','public_site.no_animals'=>'Aucun animal n’est actuellement publié dans cette catégorie.','public_site.all_species'=>'Toutes les espèces','public_site.sterilized'=>'Stérilisé','public_site.age_unknown'=>'Âge non renseigné','public_site.months'=>':count mois','public_site.years'=>':count an(s)','public_site.years_months'=>':years an(s) et :months mois','public_site.back_animals'=>'Retour aux animaux','public_site.age'=>'Âge','public_site.breed'=>'Race','public_site.coat'=>'Robe','public_site.dogs'=>'OK chiens','public_site.cats'=>'OK chats','public_site.children'=>'OK enfants','public_site.clean'=>'Propre','public_site.ask_adoption'=>'Nous contacter pour son adoption','public_site.make_donation'=>'Faire un don',
|
||||
'public_site.settings_title'=>'Paramètres — Site public','public_site.settings_heading'=>'Mini-site public','public_site.settings_intro'=>'Un site léger alimenté uniquement par les informations volontairement publiées.','public_site.preview'=>'Voir le site','public_site.saved'=>'La configuration du site public a été enregistrée.','public_site.activation_style'=>'Activation et apparence','public_site.enable'=>'Activer le site public','public_site.enable_help'=>'Lorsqu’il est désactivé, aucune page publique ni fiche animale n’est consultable.','public_site.theme'=>'Thème visuel','public_site.theme_warm'=>'Chaleureux','public_site.theme_nature'=>'Naturel','public_site.theme_minimal'=>'Minimal','public_site.free_page'=>'Page libre','public_site.show_free_page'=>'Afficher cette page dans le menu','public_site.donation_url'=>'Lien vers la plateforme de don','public_site.contact_reuse'=>'L’adresse, le téléphone, l’e-mail et le logo viennent des paramètres généraux de l’association.','public_site.invalid_url'=>'Un des liens saisis est invalide.','public_site.publish_animal'=>'Publier cet animal sur le mini-site','public_site.publish_animal_help'=>'La fiche ne sera visible que si l’animal est également disponible à l’adoption. Seules les photos publiques et le texte ci-dessous seront utilisés.','public_site.public_description'=>'Présentation publique','public_site.public_description_example'=>'Son caractère, ses habitudes et la famille qu’il recherche…',
|
||||
'common.open'=>'Ouvrir','settings.lab_references'=>'Références biologiques','medical_document.menu_prescription'=>'Ordonnance','medical_document.menu_analysis'=>'Résultats d’analyses','lab_reference.title'=>'Paramètres — Références biologiques','lab_reference.heading'=>'Références biologiques','lab_reference.intro'=>'Intervalles par analyseur et par espèce utilisés pour préremplir les analyses et interpréter leurs courbes.','lab_reference.saved'=>'Les références biologiques ont été enregistrées.','lab_reference.priority_title'=>'Référence locale prioritaire.','lab_reference.priority_help'=>'Si votre analyseur ou votre clinique imprime des bornes différentes, reportez-les ici : elles priment sur les valeurs constructeur. Une borne vide ne déclenche aucune interprétation colorée.','lab_reference.manufacturer_ranges'=>'Valeurs initiales issues des intervalles constructeur ; elles restent modifiables.','lab_reference.code'=>'Code','lab_reference.source'=>'Source / remarque','lab_reference.invalid'=>'Référentiel invalide : vérifiez les libellés, unités et bornes.',
|
||||
'nav.dashboard'=>'Tableau de bord','nav.animals'=>'Animaux','nav.directory'=>'Annuaire','nav.care_round'=>'Tournée','nav.statistics'=>'Statistiques','nav.administrative'=>'Administratif','nav.grants'=>'Subventions',
|
||||
'nav.main'=>'Navigation principale','nav.open_menu'=>'Ouvrir le menu','nav.dashboard'=>'Tableau de bord','nav.animals'=>'Animaux','nav.directory'=>'Annuaire','nav.care_round'=>'Tournée','nav.statistics'=>'Statistiques','nav.administrative'=>'Administratif','nav.grants'=>'Subventions',
|
||||
'account.settings'=>'Compte et paramètres','account.settings_heading'=>'Paramètres','account.logout'=>'Déconnexion',
|
||||
'settings.general'=>'Général','settings.users'=>'Utilisateurs','settings.permissions'=>'Rôles et permissions','settings.species'=>'Espèces','settings.pricing'=>'Tarifs','settings.backups'=>'Sauvegardes','settings.audit'=>'Journal d’audit','settings.asm3'=>'Migration ASM3','settings.data'=>'Données et démo',
|
||||
'settings.general_title'=>'Paramètres généraux','settings.general_intro'=>'Identité de l’association et règles communes de Globinours.','settings.language'=>'Langue de l’application','settings.language_help'=>'Langue générale de l’interface. Le français reste utilisé lorsqu’une traduction manque.','settings.save'=>'Enregistrer les paramètres',
|
||||
|
|
|
|||
Loading…
Reference in a new issue