The overlay percentage now rises linearly to 95% at the expected wait captured at Calculate, holds there, and shows 100% only when the planner completes. Beneath the status, one line names the current planning stage (with the rule name for rule stages) and another shows the approximate remaining time, or "Taking longer than expected" once the wait is exceeded, announced once through the live status. Cancel freezes the percentage and hides both lines. PlanningCalculationService reports the stage and submitted request instead of fixed per-stage percentages; PlanningDurationService owns the wait progress on a 250 ms tick. Closes #300 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
396 lines
19 KiB
JSON
396 lines
19 KiB
JSON
{
|
||
"locale": "fr-FR",
|
||
"bookedDays": {
|
||
"enter": "Modifier les jours déjà posés",
|
||
"booked": "Déjà posé",
|
||
"help": "Choisissez CP, RTT, Autre ou Effacer, puis cliquez ou faites glisser entre deux dates, même sur plusieurs mois. Relâchez pour enregistrer ; Échap annule. Chaque jour du type choisi est retiré ; les autres prennent ce type. Week-ends et jours fériés sont ignorés. Les hachures indiquent les jours déjà posés, pris en compte au prochain calcul.",
|
||
"fixed": "Saisie utilisateur fixe, sans débit du solde restant ni décision d’optimisation.",
|
||
"removed": "Déclaration supprimée",
|
||
"erase": "Effacer",
|
||
"rangeSaved": "Jours déjà posés enregistrés : {count} ({type}).",
|
||
"rangeRemoved": "Déclarations supprimées : {count}."
|
||
},
|
||
"app": {
|
||
"title": "vac-optimizer",
|
||
"description": "Faites plus de place aux vacances.",
|
||
"skipToPlan": "Aller à votre planning"
|
||
},
|
||
"userInput": {
|
||
"title": "Configurez vos congés",
|
||
"description": "Choisissez la période à planifier, puis ajoutez chaque solde de congés et sa période de validité.",
|
||
"addVacationDay": "Ajouter un solde de congés",
|
||
"calculate": "Calculer le planning",
|
||
"durationEstimate": "Attente indicative : {range} {unit}",
|
||
"durationUnits": {
|
||
"seconds": "s",
|
||
"minutes": "min"
|
||
},
|
||
"remainingDaysWarning": "{count} jour{plural} de congé restant{plural} :",
|
||
"deleteEntry": "Supprimer l’entrée",
|
||
"chooseDate": "Expire le",
|
||
"availableDate": "Disponible à partir du",
|
||
"days": "Jours",
|
||
"type": "Type de congé",
|
||
"daySuffix": "jour",
|
||
"daysSuffix": "jours",
|
||
"expires": "exp.",
|
||
"remainingValidity": "Utilisable du {available} au {expiry}.",
|
||
"remainingHorizon": "Planning calculé du {start} au {end}.",
|
||
"remainingEarnedFrom": "Congés gagnés grâce à la règle « {rule} ».",
|
||
"remainingSuggestions": {
|
||
"available-after-horizon": "Vous pouvez prolonger la période planifiée au-delà de sa date de disponibilité, puis recalculer.",
|
||
"no-working-date": "Vérifiez la période planifiée et les dates de validité de ce solde.",
|
||
"all-dates-occupied": "Vous pouvez élargir la période si la validité le permet, ou ajuster vos jours déjà posés et vos règles, puis recalculer.",
|
||
"preserved": "Aucune action nécessaire. Pour demander son utilisation, ajoutez une règle sur une période où il est utilisable, puis recalculez.",
|
||
"calculation-incomplete": "Relancez le calcul si vous souhaitez qu’il termine la planification."
|
||
}
|
||
},
|
||
"dayTypes": {
|
||
"weekend": "Weekend",
|
||
"closedDay": "Jour Férié",
|
||
"rtt": "RTT",
|
||
"cp": "Congé Payé",
|
||
"other": "Autre",
|
||
"today": "Aujourd'hui",
|
||
"any": "N'importe"
|
||
},
|
||
"settings": {
|
||
"title": "Paramètres",
|
||
"description": "Les modifications sont enregistrées automatiquement.",
|
||
"showWeekNumbers": "Afficher les numéros de semaine",
|
||
"close": "Fermer",
|
||
"selectLanguage": "Langue",
|
||
"selectTheme": "Thème",
|
||
"themeOptions": {
|
||
"system": "Système",
|
||
"light": "Clair",
|
||
"dark": "Sombre"
|
||
},
|
||
"systemAppearance": "Apparence actuelle du système",
|
||
"planningHorizon": "Période à planifier",
|
||
"planningStart": "Date de début (incluse)",
|
||
"lastPlanningDate": "Dernière date de planification (incluse)",
|
||
"planningDatesHelp": "Choisissez vos dates, même passées. Le calendrier est mis à jour lorsque vous cliquez sur Calculer le planning.",
|
||
"invalidDate": "Saisissez deux dates calendaires valides.",
|
||
"horizonOrder": "La dernière date de planification doit être égale ou postérieure à la date de début.",
|
||
"invalidHorizon": "Corrigez les dates de planification avant de calculer."
|
||
},
|
||
"rules": {
|
||
"title": "Règles de planification",
|
||
"subtitle": "Gérer les règles d'optimisation",
|
||
"active": "actives",
|
||
"moveRuleUp": "Monter la règle",
|
||
"moveRuleDown": "Descendre la règle",
|
||
"dragRule": "Glisser pour réordonner",
|
||
"ruleMoved": "{name} : position {position} sur {count}.",
|
||
"priorityInfo": "Les règles du haut sont prioritaires. Réorganisez-les avec la poignée ou les flèches.",
|
||
"ifThenTemplate": "Si un jour férié tombe un <strong>{day}</strong>, placer <strong>{placeDays}</strong> jour(s) <strong>{placeType}</strong> <strong>{placement}</strong> et obtenir <strong>{rewardDays}</strong> jour(s) <strong>{rewardType}</strong> en bonus.",
|
||
"timeWindowTemplate": "Placer <strong>{placeDays}</strong> jour(s) <strong>{placeType}</strong> entre le <strong>{startDate}</strong> et le <strong>{endDate}</strong>.",
|
||
"editRule": "Modifier la règle",
|
||
"deleteRule": "Supprimer la règle",
|
||
"addRule": "Ajouter une règle",
|
||
"place": "Placer",
|
||
"ruleName": "Nom de la règle",
|
||
"holidayFalls": "Jour férié tombe un",
|
||
"days": "Jours",
|
||
"type": "Type",
|
||
"position": "Position",
|
||
"getBonus": "Obtenir en bonus",
|
||
"force": "Force de la règle",
|
||
"obligation": "Obligation",
|
||
"preference": "Préférence",
|
||
"startDate": "Date de début",
|
||
"endDate": "Date de fin",
|
||
"cancel": "Annuler",
|
||
"save": "Enregistrer",
|
||
"add": "Ajouter",
|
||
"addRuleButton": "Ajouter",
|
||
"newIfThenRule": "Nouvelle Règle \"Si ... Alors\"",
|
||
"newTimeWindowRule": "Nouvelle Période Imposée",
|
||
"defaultNewRuleName": "Nouvelle Règle",
|
||
"defaultNewPeriodName": "Nouvelle Période",
|
||
"daysOfWeek": {
|
||
"1": "Lundi",
|
||
"2": "Mardi",
|
||
"3": "Mercredi",
|
||
"4": "Jeudi",
|
||
"5": "Vendredi",
|
||
"6": "Samedi",
|
||
"0": "Dimanche"
|
||
},
|
||
"placement": {
|
||
"before": "Avant",
|
||
"after": "Après",
|
||
"around": "Autour",
|
||
"auto": "Auto (Meilleur choix)"
|
||
},
|
||
"optimization": {
|
||
"newRule": "Nouvelle règle d’Optimisation",
|
||
"defaultName": "Prévention des pertes",
|
||
"elementsLabel": "Éléments du planning",
|
||
"conditionsLabel": "Conditions (toutes doivent être vérifiées)",
|
||
"measureLabel": "Mesure",
|
||
"aggregationLabel": "Agrégation",
|
||
"directionLabel": "Direction",
|
||
"thresholdLabel": "Seuil de préférence en jours ouvrés",
|
||
"thresholdSummary": "seuil de préférence : {count} jours ouvrés",
|
||
"summary": "{direction} {aggregation} : {measure} — {elements}{conditions}.",
|
||
"invalidConfiguration": "Choisissez des éléments, conditions, une mesure et une agrégation compatibles, avec un seuil entier positif si nécessaire.",
|
||
"nameRequired": "Saisissez un nom de règle.",
|
||
"elements": {
|
||
"leave-balances": "Soldes de congés",
|
||
"public-holiday-weeks": "Semaines avec jour férié",
|
||
"time-off-periods": "Périodes non travaillées",
|
||
"work-sequences": "Séquences de travail",
|
||
"leave-placements": "Congés placés"
|
||
},
|
||
"conditions": {
|
||
"at-risk": "À risque d’expiration",
|
||
"complete": "Complètes",
|
||
"internal": "Internes",
|
||
"non-empty": "Non vides",
|
||
"supporting": "D’appui"
|
||
},
|
||
"measures": {
|
||
"unplaced-quantity": "Quantité non placée",
|
||
"public-holiday-week-value": "Valeur des semaines fériées",
|
||
"non-working-day-gain": "Gain de jours non travaillés",
|
||
"work-sequence-length": "Longueur des séquences de travail",
|
||
"work-sequence-deficit": "Déficit des séquences de travail",
|
||
"placement-count": "Nombre de placements"
|
||
},
|
||
"aggregations": {
|
||
"sum": "Somme",
|
||
"count": "Nombre",
|
||
"maximum": "Maximum"
|
||
},
|
||
"directions": {
|
||
"minimize": "Minimiser",
|
||
"maximize": "Maximiser"
|
||
}
|
||
}
|
||
},
|
||
"planning": {
|
||
"statistics": {
|
||
"open": "Statistiques",
|
||
"title": "Statistiques du planning",
|
||
"leaveDays": "Nouveaux jours de congé posés",
|
||
"averageWorkSequence": "Séquence de travail moyenne",
|
||
"averageTimeOffPeriod": "Période de repos moyenne",
|
||
"longestTimeOffPeriod": "Plus longue période de repos",
|
||
"weekendConnectedHolidays": "Jours fériés reliés à un week-end",
|
||
"workingDays": "jours ouvrés",
|
||
"calendarDays": "jours calendaires",
|
||
"partialPlan": "Planning partiel",
|
||
"help": "Statistiques du planning calculé. Les jours déjà posés contribuent aux périodes de repos et de travail sans consommer à nouveau les soldes.",
|
||
"earnedLeave": "Congés acquis avant consommation",
|
||
"leaveDaysUnit": "jours",
|
||
"earnedLeaveByRule": "Congés acquis par règle"
|
||
},
|
||
"calculationDate": "Date du calcul",
|
||
"futureEntitlement": "Droit futur généré",
|
||
"includedEntitlement": "Droit déjà inclus dans les soldes reportés",
|
||
"title": "Votre année optimisée",
|
||
"daysPlaced": "Jours de congé placés",
|
||
"daysGained": "Jours non travaillés gagnés",
|
||
"longestWorkSequence": "Plus longue période travaillée",
|
||
"legend": "Légende du calendrier",
|
||
"invalidInput": "Les données de planification sont invalides.",
|
||
"conflict": "Les obligations ne peuvent pas être satisfaites ensemble.",
|
||
"incomplete": "Le calcul s’est arrêté avant la fin des critères de qualité.",
|
||
"cancel": "Annuler",
|
||
"cancelling": "Annulation en cours…",
|
||
"progress": {
|
||
"stages": {
|
||
"preparation": "Préparation du calendrier",
|
||
"validation": "Vérification de vos saisies",
|
||
"obligations": "Respect des obligations",
|
||
"expiry": "Utilisation des soldes qui expirent en premier",
|
||
"dates": "Fixation des dates définitives"
|
||
},
|
||
"rule": "Application de « {rule} »",
|
||
"remaining": "Encore environ {value} {unit}",
|
||
"overrun": "Plus long que prévu"
|
||
},
|
||
"cancelled": "Calcul annulé",
|
||
"cancelledPartial": "Calcul annulé — plan partiel",
|
||
"error": "Le planificateur a rencontré une erreur inattendue.",
|
||
"complete": "Plan calculé.",
|
||
"whyPlacement": "Comprendre vos jours de congé",
|
||
"placementNavigation": "Navigation entre les explications des placements",
|
||
"placement": "Jour de congé",
|
||
"placements": "placements",
|
||
"of": "sur",
|
||
"first": "Premier placement",
|
||
"previous": "Placement précédent",
|
||
"next": "Placement suivant",
|
||
"last": "Dernier placement",
|
||
"remaining": "Jours non utilisés dans le planning final",
|
||
"balanceRemaining": "restants",
|
||
"counterfactual": "Dates alternatives",
|
||
"counterfactualLoading": "Analyse de chaque date de l’horizon…",
|
||
"counterfactualReady": "Les dates alternatives sont prêtes.",
|
||
"counterfactualError": "Les dates alternatives n’ont pas pu être calculées.",
|
||
"retryCounterfactual": "Relancer l’analyse des dates",
|
||
"eligible": "Éligible",
|
||
"ineligible": "Inéligible",
|
||
"reason": "Raison",
|
||
"explanationError": "L’explication n’a pas pu être produite.",
|
||
"conflictDetails": "Pourquoi aucun plan ne satisfait les obligations",
|
||
"conflictingRules": "Règles en conflit",
|
||
"bottleneck": "Goulot d’étranglement",
|
||
"incompleteDetails": "Étapes terminées avant l’arrêt du calcul",
|
||
"incumbentExplanation": "Cette explication concerne le meilleur plan valide trouvé ; les étapes de qualité suivantes ne sont pas terminées.",
|
||
"completedStages": "Étapes terminées",
|
||
"uncompletedStages": "Étapes interrompues ou non démarrées",
|
||
"none": "Aucun",
|
||
"currentPlacement": "Placement expliqué actuellement",
|
||
"explainedPeriod": "Période de repos expliquée",
|
||
"outsideHorizon": "Date de contexte hors de l’horizon de planification",
|
||
"calendarHelp": "Sélectionnez un jour de congé pour voir son apport au planning.",
|
||
"explanationHelp": "Découvrez votre pause et ce que chaque jour change.",
|
||
"technicalDetails": "Détails du calcul",
|
||
"compareDates": "Comparer d’autres dates",
|
||
"stopComparing": "Fermer la comparaison",
|
||
"explanation": {
|
||
"breakTitle": "Votre pause",
|
||
"leaveDays": "jours de congé posés",
|
||
"freeDays": "jours de week-end et fériés",
|
||
"daysOff": "jours de repos consécutifs",
|
||
"wholeBreak": "Ces totaux concernent toute la pause, y compris le jour sélectionné.",
|
||
"leaveUsed": "Cette date utilise 1 jour du solde « {balance} ».",
|
||
"expires": "Solde à utiliser au plus tard le",
|
||
"linkedRules": "Règles liées :",
|
||
"atRiskContribution": "Protège des congés à risque d’expiration.",
|
||
"impact": "Ce que ce jour change",
|
||
"impactHelp": "Comparez tout le planning avec et sans ce jour de congé. Les autres dates restent identiques ; seuls les totaux qui changent sont affichés.",
|
||
"criterion": "Sur tout le planning",
|
||
"withoutDay": "Sans ce jour",
|
||
"withDay": "Avec ce jour",
|
||
"noChange": "Ces totaux sont identiques. Les règles et les derniers critères de départage (expiration du solde, puis date) peuvent encore influencer le choix.",
|
||
"priorityHelp": "Les obligations sont résolues conjointement. Les préférences actives sont comparées dans l’ordre de vos règles. Seules ces règles déclenchent des placements ; l’expiration puis les dates départagent les résultats égaux.",
|
||
"tryDate": "Essayer une autre date",
|
||
"plannedDate": "Date actuellement prévue :",
|
||
"currentPlan": "Planning actuel",
|
||
"alternative": "Avec cette date",
|
||
"sameDate": "C’est la date prévue. Choisissez une autre date ci-dessus pour voir la différence.",
|
||
"moveHelp": "Essayez de déplacer ce jour. Les autres dates de congé restent identiques.",
|
||
"comparisonUnavailable": "La comparaison pour la date initiale est indisponible ; la différence ne peut donc pas être affichée.",
|
||
"objectives": {
|
||
"obligation-validity": {
|
||
"label": "Obligations non satisfaites",
|
||
"help": "Nombre de règles obligatoires non respectées. Un plan valide en compte zéro."
|
||
},
|
||
"unplaced-at-risk": {
|
||
"label": "Congés risquant d’expirer sans être utilisés",
|
||
"help": "Jours non posés expirant pendant la période planifiée. Moins, c’est mieux."
|
||
},
|
||
"preference": {
|
||
"label": "Préférence : {rule}",
|
||
"help": "Jours ou occurrences complètes, selon la règle. Plus, c’est mieux."
|
||
},
|
||
"holiday-week-value": {
|
||
"label": "Priorité des semaines avec jours fériés (points)",
|
||
"help": "Score pondéré : un férié le mercredi vaut 3, mardi/jeudi 2, lundi/vendredi 1. Plus, c’est mieux."
|
||
},
|
||
"non-working-day-gain": {
|
||
"label": "Jours de week-end et fériés dans vos pauses",
|
||
"help": "Jours de repos sans utiliser de congé. Plus, c’est mieux."
|
||
},
|
||
"longest-work-sequence": {
|
||
"label": "Maximum de jours travaillés entre congés",
|
||
"help": "Week-ends et jours fériés exclus. Moins, c’est mieux."
|
||
},
|
||
"short-sequence-deficit": {
|
||
"label": "Pénalité pour les courtes reprises du travail",
|
||
"help": "Chaque reprise de 1 à 4 jours travaillés entre congés ajoute les jours manquants pour atteindre 5. Moins, c’est mieux."
|
||
},
|
||
"supporting-placements": {
|
||
"label": "Jours utilisés sur des soldes expirant plus tard",
|
||
"help": "Congés qui pourraient être conservés au-delà de la période planifiée. Moins, c’est mieux."
|
||
},
|
||
"balance-expiry": {
|
||
"label": "Soldes expirant le plus tôt d’abord",
|
||
"help": "Départage lorsque les totaux précédents sont égaux."
|
||
},
|
||
"placement-date": {
|
||
"label": "Dates les plus proches d’abord",
|
||
"help": "Dernier départage lorsque tous les autres critères sont égaux."
|
||
},
|
||
"optimization": {
|
||
"label": "{rule}: {summary}",
|
||
"help": "Cette préférence d’optimisation évalue sa configuration enregistrée. Les préférences actives suivent l’ordre affiché ; les premières passent avant les suivantes."
|
||
}
|
||
},
|
||
"stages": {
|
||
"validation": "Vérifier les soldes et les règles",
|
||
"obligations": "Respecter les règles obligatoires",
|
||
"at-risk": "Utiliser les congés avant leur expiration",
|
||
"expiry": "Privilégier les soldes expirant bientôt",
|
||
"dates": "Privilégier les dates les plus proches"
|
||
},
|
||
"unavailable": {
|
||
"non-working": "C’est déjà un jour de repos (week-end ou jour férié). Aucun congé à poser.",
|
||
"occupied": "Un autre congé est déjà prévu ici. Choisissez un jour travaillé libre.",
|
||
"unavailable": "Ce solde de congés ne peut pas être utilisé à cette date.",
|
||
"expired": "Cette date dépasse la date d’expiration du solde.",
|
||
"type-incompatible": "Ce type de congé ne peut pas être utilisé à cette date.",
|
||
"rule-invalid": "Utiliser cette date ne respecterait pas une règle du planning.",
|
||
"invalid-optimization-configuration": "Choisissez des éléments, conditions, une mesure et une agrégation compatibles, avec un seuil entier positif si nécessaire.",
|
||
"unsupported-optimization-configuration": "Cette règle combine des éléments du planning et des mesures incompatibles."
|
||
},
|
||
"preferenceHelp": {
|
||
"time_window": "Jours de congé dans cette période souhaitée. Plus, c’est mieux.",
|
||
"if_then": "Occurrences complètes de cette règle. Plus, c’est mieux."
|
||
}
|
||
},
|
||
"details": {
|
||
"intro": "La colonne de gauche montre le planning sans ce jour de congé. Celle de droite montre le planning actuel.",
|
||
"balance": "Solde de congés",
|
||
"available": "Disponible à partir du",
|
||
"expires": "Expire le",
|
||
"criteria": "Les priorités du calcul",
|
||
"criteriaHelp": "Lisez de haut en bas : la première différence est prioritaire. Sélectionnez un critère pour comprendre son calcul.",
|
||
"firstDifference": "Première différence",
|
||
"higher": "Plus, c’est mieux",
|
||
"lower": "Moins, c’est mieux",
|
||
"tieBreaks": "Si les totaux ci-dessus sont égaux",
|
||
"audit": "Données brutes · débogage",
|
||
"auditHelp": "Valeurs, identifiants et contributions d’origine de ce calcul.",
|
||
"supporting": "Ce jour utilise des congés qui pourraient être conservés au-delà de la période planifiée pour améliorer vos pauses.",
|
||
"remainingReasons": {
|
||
"unavoidable-expiry": "Expiré le {expiry}, avant le début du planning le {start}. Il ne peut pas être posé dans cette période.",
|
||
"available-after-horizon": "Disponible seulement à partir du {available}, après la dernière date du planning, le {end}.",
|
||
"no-working-date": "Aucun jour ouvré ne se trouve à la fois dans la période planifiée et entre ses dates de disponibilité et d’expiration.",
|
||
"all-dates-occupied": "Tous les jours ouvrés où ce solde est utilisable sont déjà occupés par des congés calculés ou des jours déjà posés.",
|
||
"preserved": "Conservé pour plus tard : il expire après la période planifiée et le calcul n’a pas retenu de pose supplémentaire selon vos priorités.",
|
||
"active-priorities": "Le calcul a conservé ce solde inutilisé selon vos règles actives. Modifiez les règles ou leur ordre pour demander un autre planning.",
|
||
"calculation-incomplete": "Le calcul a été interrompu avant de terminer la planification. Sa non-utilisation n’est pas une décision définitive.",
|
||
"not-established": "La raison précise de sa non-utilisation n’a pas été établie par ce calcul."
|
||
}
|
||
},
|
||
"comparison": {
|
||
"title": "Comparer les dates",
|
||
"preview": "Simulation uniquement. Votre planning reste inchangé.",
|
||
"nearby": "Dates proches disponibles",
|
||
"noAlternatives": "Aucune autre date ne permet de poser ce jour. Vous pouvez vérifier une date pour comprendre pourquoi.",
|
||
"chooseDate": "Choisissez une date ci-dessus pour voir ce qui changerait.",
|
||
"dateRange": "Période planifiée :",
|
||
"invalidDate": "Choisissez une date valide dans la période indiquée ci-dessus.",
|
||
"changes": "Ce qui changerait",
|
||
"available": "Date disponible",
|
||
"unavailable": "Cette date ne peut pas être utilisée",
|
||
"backToPlan": "Revenir à mon planning"
|
||
}
|
||
},
|
||
"benchmark": {
|
||
"title": "Benchmark du planificateur de congés",
|
||
"instructions": "Lancez les cinq scénarios fixes et copiez le rapport obtenu.",
|
||
"run": "Lancer le benchmark",
|
||
"running": "En cours…",
|
||
"copy": "Copier le rapport"
|
||
},
|
||
"loading": "Calcul en cours...",
|
||
"weekdaysShort": ["L", "M", "M", "J", "V", "S", "D"]
|
||
}
|