CI / policy (push) Successful in 7s
CI / validate (push) Successful in 1m15s
CI / test (push) Successful in 3m18s
CI / benchmark (push) Failing after 5m53s
CI / build (push) Successful in 1m23s
CI / security (push) Successful in 7m6s
CI / policy (pull_request) Successful in 7s
CI / validate (pull_request) Successful in 1m9s
CI / build (pull_request) Successful in 43s
CI / test (pull_request) Successful in 3m19s
CI / images (push) Successful in 3m7s
CI / required (push) Successful in 2s
CI / benchmark (pull_request) Failing after 5m28s
CI / security (pull_request) Successful in 6m37s
CI / images (pull_request) Successful in 3m18s
CI / required (pull_request) Successful in 1s
185 lines
5.6 KiB
HTML
185 lines
5.6 KiB
HTML
<div class="user-input">
|
|
<header class="section-heading">
|
|
<h2 id="leave-settings-title">{{ tr().userInput.title }}</h2>
|
|
<p>{{ tr().userInput.description }}</p>
|
|
<a class="jump-to-plan" href="#planning-results-title"
|
|
>{{ tr().app.skipToPlan }} <mat-icon aria-hidden="true">arrow_downward</mat-icon></a
|
|
>
|
|
</header>
|
|
|
|
<fieldset class="planning-dates">
|
|
<legend>{{ tr().settings.planningHorizon }}</legend>
|
|
<p id="planning-dates-help">{{ tr().settings.planningDatesHelp }}</p>
|
|
<mat-form-field appearance="outline">
|
|
<mat-label>{{ tr().settings.planningStart }}</mat-label>
|
|
<input
|
|
matInput
|
|
[matDatepicker]="planningStartPicker"
|
|
name="planningStart"
|
|
required
|
|
[ngModel]="planningDates().start"
|
|
(ngModelChange)="setPlanningDate('start', $event)"
|
|
[attr.aria-invalid]="!!calendarSettings.planningHorizonError()"
|
|
[attr.aria-describedby]="
|
|
calendarSettings.planningHorizonError()
|
|
? 'planning-dates-help planning-dates-error'
|
|
: 'planning-dates-help'
|
|
"
|
|
/>
|
|
<mat-datepicker-toggle
|
|
matIconSuffix
|
|
[for]="planningStartPicker"
|
|
></mat-datepicker-toggle>
|
|
<mat-datepicker #planningStartPicker></mat-datepicker>
|
|
</mat-form-field>
|
|
<mat-form-field appearance="outline">
|
|
<mat-label>{{ tr().settings.lastPlanningDate }}</mat-label>
|
|
<input
|
|
matInput
|
|
[matDatepicker]="lastPlanningDatePicker"
|
|
name="lastPlanningDate"
|
|
required
|
|
[ngModel]="planningDates().lastPlanningDate"
|
|
(ngModelChange)="setPlanningDate('lastPlanningDate', $event)"
|
|
[attr.aria-invalid]="!!calendarSettings.planningHorizonError()"
|
|
[attr.aria-describedby]="
|
|
calendarSettings.planningHorizonError()
|
|
? 'planning-dates-help planning-dates-error'
|
|
: 'planning-dates-help'
|
|
"
|
|
/>
|
|
<mat-datepicker-toggle
|
|
matIconSuffix
|
|
[for]="lastPlanningDatePicker"
|
|
></mat-datepicker-toggle>
|
|
<mat-datepicker #lastPlanningDatePicker></mat-datepicker>
|
|
</mat-form-field>
|
|
@if (calendarSettings.planningHorizonError(); as error) {
|
|
<p id="planning-dates-error" class="validation-error" role="alert">
|
|
{{ tr().settings[error] }}
|
|
</p>
|
|
}
|
|
</fieldset>
|
|
|
|
<div class="listOfDays">
|
|
@for (day of daysOff; track day.id) {
|
|
<div class="day-input-wrapper" animate.enter="day-enter" animate.leave="day-leave">
|
|
<app-day-input
|
|
[day]="day"
|
|
(dayChange)="updateDay($index, $event)"
|
|
(deleteEntry)="removeFromList($index)"
|
|
></app-day-input>
|
|
</div>
|
|
}
|
|
<button mat-stroked-button class="add-day-button" type="button" (click)="addDay()">
|
|
<mat-icon aria-hidden="true">add</mat-icon>
|
|
{{ tr().userInput.addVacationDay }}
|
|
</button>
|
|
<div class="declaration-controls" [class.is-active]="declarationEntry()">
|
|
<button
|
|
mat-button
|
|
type="button"
|
|
class="declaration-entry-toggle"
|
|
[attr.aria-pressed]="declarationEntry()"
|
|
(click)="declarationEntry.set(!declarationEntry())"
|
|
>
|
|
<mat-icon aria-hidden="true">{{
|
|
declarationEntry() ? 'check_circle' : 'edit_calendar'
|
|
}}</mat-icon>
|
|
{{ tr().bookedDays.enter }}
|
|
</button>
|
|
@if (declarationEntry()) {
|
|
<div class="declaration-types" role="group" [attr.aria-label]="tr().userInput.type">
|
|
@for (type of declaredTypes; track type) {
|
|
<button
|
|
mat-stroked-button
|
|
type="button"
|
|
[attr.data-declared-type]="type"
|
|
[attr.aria-pressed]="declaredType() === type"
|
|
(click)="declaredType.set(type)"
|
|
>
|
|
<mat-icon class="declaration-type-check" aria-hidden="true"
|
|
>check</mat-icon
|
|
>
|
|
{{ type === 'cp' ? 'CP' : translationService.getDayTypeLabel(type) }}
|
|
</button>
|
|
}
|
|
<button
|
|
mat-stroked-button
|
|
type="button"
|
|
data-declaration-erase
|
|
[attr.aria-pressed]="declaredType() === null"
|
|
(click)="declaredType.set(null)"
|
|
>
|
|
<mat-icon aria-hidden="true">{{
|
|
declaredType() === null ? 'check' : 'backspace'
|
|
}}</mat-icon>
|
|
{{ tr().bookedDays.erase }}
|
|
</button>
|
|
</div>
|
|
}
|
|
</div>
|
|
</div>
|
|
|
|
<app-rules-panel></app-rules-panel>
|
|
|
|
@if (duration.estimate()) {
|
|
<p id="planning-duration-estimate" class="duration-estimate">{{ durationLabel() }}</p>
|
|
}
|
|
<button
|
|
mat-flat-button
|
|
class="calculate-button"
|
|
color="primary"
|
|
type="button"
|
|
[disabled]="!!calendarSettings.planningHorizonError()"
|
|
[attr.aria-describedby]="
|
|
calendarSettings.planningHorizonError()
|
|
? 'planning-dates-error'
|
|
: 'planning-duration-estimate'
|
|
"
|
|
(click)="triggerComputation()"
|
|
>
|
|
<mat-icon aria-hidden="true">auto_awesome</mat-icon>
|
|
{{ tr().userInput.calculate }}
|
|
</button>
|
|
|
|
@if (hasRemainingDays()) {
|
|
<mat-card class="warning-card" [class.is-informational]="!hasAtRiskDays()">
|
|
<mat-card-content class="warning-content">
|
|
<mat-icon [color]="hasAtRiskDays() ? 'warn' : undefined" aria-hidden="true">{{
|
|
hasAtRiskDays() ? 'warning' : 'info'
|
|
}}</mat-icon>
|
|
<div class="warning">
|
|
<p role="status">
|
|
{{
|
|
tr()
|
|
.userInput.remainingDaysWarning.replace(
|
|
'{count}',
|
|
remainingDays().toString()
|
|
)
|
|
.split('{plural}')
|
|
.join(remainingDays() > 1 ? 's' : '')
|
|
}}
|
|
</p>
|
|
<ul class="remaining-balances">
|
|
@for (day of remainingDaysDetails(); track day.id) {
|
|
<li class="remaining-day-detail">
|
|
<strong>{{ day.title }}</strong>
|
|
@if (day.earnedFrom) {
|
|
<p>{{ day.earnedFrom }}</p>
|
|
}
|
|
<p>{{ day.reason }}</p>
|
|
<p>{{ day.validity }}</p>
|
|
@if (day.suggestion) {
|
|
<p>{{ day.suggestion }}</p>
|
|
}
|
|
<p>{{ day.horizon }}</p>
|
|
</li>
|
|
}
|
|
</ul>
|
|
</div>
|
|
</mat-card-content>
|
|
</mat-card>
|
|
}
|
|
</div>
|