{{ liveMessage() }}
@if (isLoading()) { }{{ tr().planning.invalidInput }}
} @else if (planningOutcome()?.kind === 'PlanningConflict') {{{ tr().planning.conflict }}
} @else if (planningOutcome()?.kind === 'PlanningIncomplete') {{{ outcomeLabel(planningOutcome()!) }}
} @else if (planningOutcome()?.kind === 'Plan') {{{ tr().planning.complete }}
}{{ tr().planning.conflictingRules }}:
{{ rule.id }}
{{ tr().planning.bottleneck }}: {{ outcomeExplanation.bottleneck.message }}
{{ outcomeExplanation.reason.message }}
{{ contribution.declaredDays.length }} {{ tr().bookedDays.booked }} + {{ contribution.placementDates.length }} {{ tr().planning.explanation.leaveDays }} = {{ contribution.declaredDays.length + contribution.placementDates.length }} / {{ contribution.requested }}
@for (day of contribution.declaredDays; track day.date) { {{ displayDate(day.date) }} · {{ tr().dayTypes[day.type] }} }
{{ tr().bookedDays.fixed }}
{{ tr().planning.calculationDate }} : {{ displayDate(plan.calculationDate) }}
} @for ( contribution of plan.ifThenContributions ?? []; track contribution.ruleId + contribution.occurrence ) {{{ contribution.declaredDays.length }} {{ tr().bookedDays.booked }} + {{ contribution.placementDates.length }} {{ tr().planning.explanation.leaveDays }} = {{ contribution.requested }} / {{ contribution.requested }}
@for (day of contribution.declaredDays; track day.date) { {{ displayDate(day.date) }} · {{ tr().dayTypes[day.type] }} } @if (contribution.declaredDays.length) {{{ tr().bookedDays.fixed }}
} @if (contribution.earnedEntitlement; as earned) {{{ earned.added ? tr().planning.futureEntitlement : tr().planning.includedEntitlement }} : {{ earned.quantity }} {{ tr().dayTypes[earned.type] }}
{{ tr().planning.details.available }} {{ displayDate(earned.availableFrom) }} · {{ tr().planning.details.expires }} {{ displayDate(earned.expiryDate) }}
}{{ period.declaredDates!.length }} {{ tr().bookedDays.booked }} + {{ period.placementDates.length }} {{ tr().planning.explanation.leaveDays }} + {{ period.nonWorkingDates.length }} {{ tr().planning.explanation.freeDays }} = {{ period.duration }} {{ tr().planning.explanation.daysOff }}
{{ tr().bookedDays.fixed }}
{{ interrupted.reason.message }}
{{ tr().planning.completedStages }}: {{ interrupted.completedStages.length ? interrupted.completedStages.join(', ') : tr().planning.none }}
{{ tr().planning.uncompletedStages }}: {{ interrupted.uncompletedStages.length ? interrupted.uncompletedStages.join(', ') : tr().planning.none }}
{{ tr().planning.explanation.wholeBreak }}
{{ leaveUsed(selected) }} @if (selected.balance) { {{ tr().planning.explanation.expires }} {{ displayDate(planningDate(selected.balance.expiryDate)) }}. }
@if (selected.ruleIds.length) {{{ tr().planning.explanation.linkedRules }} @for (ruleId of selected.ruleIds; track ruleId; let last = $last) { {{ ruleLabel(ruleId) }}{{ last ? '.' : ', ' }} }
} @if (hasAtRiskContribution(selected)) {{{ tr().planning.explanation.atRiskContribution }}
} @if (selected.supporting) {{{ tr().planning.details.supporting }}
}{{ tr().planning.remaining }}: {{ selected.remainingQuantity }} {{ tr().userInput.daysSuffix }} @if (selected.remainingBalance; as remaining) { · {{ translationService.getRemainingBalanceReason( remaining, displayedPlan(), planningOutcome()?.kind === 'PlanningIncomplete' ) }} }
{{ tr().planning.details.firstDifference }}: {{ objectiveCopy(decisiveObjective).label }}
}{{ tr().planning.explanation.impactHelp }}
@if (placementChanges().length) {| {{ tr().planning.explanation.criterion }} | {{ tr().planning.explanation.withoutDay }} | {{ tr().planning.explanation.withDay }} |
|---|---|---|
| {{ change.label }}{{ change.help }} @if (change.id === decisiveObjective) { {{ tr().planning.details.firstDifference }} } | {{ change.before }} | {{ change.after }} |
{{ tr().planning.explanation.noChange }}
}{{ tr().planning.details.intro }}
{{ translationService.getRemainingBalanceReason( remaining, displayedPlan(), planningOutcome()?.kind === 'PlanningIncomplete' ) }}
}{{ tr().planning.explanationError }} {{ explanationError()!.message }}
} @if (planningOutcome() && planningOutcome()?.kind !== 'InvalidInput') {{{ tr().planning.traceLoading }}
} @else if (planningTrace(); as trace) { @if (trace.error) {{{ trace.error.message }}
}{{ tr().planning.historicalEligibilityLoading }}
} @if (historicalEligibilityError(); as error) {{{ tr().planning.historicalEligibilityError }} {{ error }}
}{{ tr().planning.dates }}: {{ decision.dates.length ? decision.dates.join(', ') : tr().planning.none }}
@if (decision.reason) {{{ tr().planning.reason }}: {{ decision.reason.message }}
}{{ candidate.reason.message }}
} @if (candidate.technicalComparison?.length) {{{ tr().planning.details .traceStageHelp }}
| {{ tr().planning .explanation .criterion }} | {{ tr().planning.before }} | {{ tr().planning.after }} |
|---|---|---|
{{
comparator.name
}}
{{
comparator.direction ===
'maximize'
? tr()
.planning
.details
.higher
: tr()
.planning
.details
.lower
}}
@if (
comparator.name ===
candidate.firstDecisiveComparator
) {
{{
tr()
.planning
.details
.firstDifference
}}
}
|
{{ comparator.before }} | {{ comparator.after }} |
{{ traceMoment() === 'before' ? tr().planning.before : tr().planning.after }}: {{ state.placements.length }} {{ tr().planning.placements }}, {{ state.earnedActivations.length }} {{ tr().planning.activations }} @for (balance of state.balances; track balance.id) { {{ balance.id }}: {{ balance.remaining }} {{ tr().planning.balanceRemaining }} {{ tr().planning.details.available }} {{ displayDate(balance.availableFrom) }} · {{ tr().planning.details.expires }} {{ displayDate(balance.expiryDate) }} }
} } } @else {{{ tr().planning.noDecisions }}
}{{ tr().planning.traceUnavailable }}
}{{ declarationEntry() ? tr().bookedDays.help : tr().planning.calendarHelp }}
@if (declarationEntry() && !calendarHorizon()) {{{ tr().settings.invalidHorizon }}
}{{ traceEffect ? tr().planning.details.traceImpactHelp : tr().planning.details.criteriaHelp }}
| {{ tr().planning.explanation.criterion }} | {{ beforeLabel }} | {{ afterLabel }} |
|---|---|---|
{{ index + 1 }}. {{ objective.label }}{{ objective.help }} |
{{ objective.before ?? tr().planning.none }} | {{ objective.value }} |
{{ tr().planning.details.auditHelp }}
{{ data | json }}
{{ tr().planning.statistics.partialPlan }}
}{{ tr().planning.statistics.help }}
{{ traceReplay() ? tr().planning.explanation.traceHelp : tr().planning.explanation.moveHelp }}
{{ tr().planning.counterfactualLoading }}
{{ tr().planning.counterfactualError }} {{ counterfactualError() }}
{{ tr().planning.comparison.dateRange }} {{ displayDate(firstDate.date) }} – {{ displayDate(analysis.results.at(-1)!.date) }}
} @if (invalidComparisonDate()) {{{ tr().planning.comparison.invalidDate }}
} @if (nearbyComparisonDates().length) {{{ tr().planning.comparison.noAlternatives }}
} @if (selectedCounterfactualResult(); as result) {{{ displayDate(result.date) }} · {{ result.status === 'eligible' ? tr().planning.comparison.available : tr().planning.comparison.unavailable }}
@if (result.status === 'ineligible') {{{ tr().planning.explanation.unavailable[ result.reason.code ] ?? result.reason.message }}
}{{ tr().planning.explanation.sameDate }}
} @else {| {{ tr().planning.explanation.criterion }} | {{ traceReplay() ? tr().planning.explanation .beforeDecision : tr().planning.explanation.currentPlan }} | {{ traceReplay() ? tr().planning.explanation .withCandidate : tr().planning.explanation.alternative }} |
|---|---|---|
| {{ change.label }} | {{ change.before }} | {{ change.after }} |
{{ tr().planning.explanation.noChange }}
} } @else {{{ tr().planning.explanation.comparisonUnavailable }}
} }{{ tr().planning.historical }}: {{ dateStatuses()[result.date]?.label ?? traceStatusLabel( result.historicalStatus ?? 'not-examined' ) }}
@if (dateStatuses()[result.date]?.reason; as historicalReason) {{{ tr().planning.reason }}: {{ historicalReason }}
} @if (dateComparison(); as comparison) {{{ tr().planning.comparison.chooseDate }}
} }