Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
[control]="form.controls.originalAmount"
[label]="'debts.create.originalAmount'"
[min]="1"
[step]="amountStep()"
/>

@let currencyControl = form.controls.currency;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import { EnumValuePipe } from '../../../shared/pipes/enum-value.pipe';
import { TranslatePipe } from '../../../shared/pipes/translate.pipe';
import { SelectAutoFocusDirective } from '../../../shared/select-auto-focus.directive';
import { TranslationCode } from '../../../shared/i18n/translation-types';
import { localizeCurrency, toRawValueSignal } from '../../../shared/util/utils';
import { getAmountStep, localizeCurrency, toRawValueSignal } from '../../../shared/util/utils';
import { ValidatorComponent } from '../../../shared/validator/validator.component';
import { CategoryService } from '../../transactions-and-categories/category.service';
import { MatDialogClose } from '@angular/material/dialog';
Expand Down Expand Up @@ -77,6 +77,8 @@ export class CreateDebtDialogComponent extends DialogComponent<DebtType | undefi
});

private readonly searchText = toRawValueSignal(this.form.controls.category.controls.searchText);
private readonly currencyValue = toRawValueSignal(this.form.controls.currency);
amountStep = computed(() => getAmountStep(1, this.currencyValue()));

filteredCategories = computed(() => {
const search = this.searchText();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@
[control]="paymentForm.controls.amount"
[label]="'debts.paymentAmount'"
[min]="0.01"
[step]="amountStep()"
/>
<ex-button
filled
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import { EnumValuePipe } from '../../../shared/pipes/enum-value.pipe';
import { TranslatePipe } from '../../../shared/pipes/translate.pipe';
import { SelectAutoFocusDirective } from '../../../shared/select-auto-focus.directive';
import { TranslationCode } from '../../../shared/i18n/translation-types';
import { localizeCurrency, toRawValueSignal } from '../../../shared/util/utils';
import { getAmountStep, localizeCurrency, toRawValueSignal } from '../../../shared/util/utils';
import { ValidatorComponent } from '../../../shared/validator/validator.component';
import { CategoryService } from '../../transactions-and-categories/category.service';
import { DebtModel } from '../debt-list/debt-list.component';
Expand Down Expand Up @@ -64,6 +64,7 @@ export class EditDebtDialogComponent extends DialogComponent<EditDebtDialogData,
private readonly translocoService = inject(TranslocoService);

data = this.dialogRef.value;
amountStep = computed(() => getAmountStep(1, this.data.debt.currency));

debtTypes = DebtType;
debtStatuses = DebtStatus;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,14 @@
[control]="form.controls.targetAmount"
[label]="'goals.create.targetAmount'"
[min]="1"
[step]="amountStep()"
/>
<ex-amount-stepper
class="mb-3"
[control]="form.controls.initialAmount"
[label]="'goals.create.initialAmount'"
[min]="0"
[step]="amountStep()"
/>
</div>
@if (form.hasError('initialAmountMax')) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import { InputClearButtonComponent } from '../../../shared/input-clear-button/in
import { EnumValuePipe } from '../../../shared/pipes/enum-value.pipe';
import { TranslatePipe } from '../../../shared/pipes/translate.pipe';
import { SelectAutoFocusDirective } from '../../../shared/select-auto-focus.directive';
import { localizeCurrency, toRawValueSignal } from '../../../shared/util/utils';
import { getAmountStep, localizeCurrency, toRawValueSignal } from '../../../shared/util/utils';
import { ValidatorComponent } from '../../../shared/validator/validator.component';
import { ExtraValidators } from '../../../shared/validators';
import { CategoryService } from '../../transactions-and-categories/category.service';
Expand Down Expand Up @@ -76,6 +76,8 @@ export class CreateGoalDialogComponent extends DialogComponent<undefined, GoalCr
);

private readonly searchText = toRawValueSignal(this.form.controls.category.controls.searchText);
private readonly currencyValue = toRawValueSignal(this.form.controls.currency);
amountStep = computed(() => getAmountStep(1, this.currencyValue()));

filteredCategories = computed(() => {
const search = this.searchText();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,18 @@
</mat-form-field>

<div class="d-flex flex-column flex-sm-row gap-3">
<ex-amount-stepper [control]="form.controls.targetAmount" [label]="'goals.edit.targetAmount'" [min]="1" />
<ex-amount-stepper [control]="form.controls.currentAmount" [label]="'goals.edit.currentAmount'" [min]="0" />
<ex-amount-stepper
[control]="form.controls.targetAmount"
[label]="'goals.edit.targetAmount'"
[min]="1"
[step]="amountStep()"
/>
<ex-amount-stepper
[control]="form.controls.currentAmount"
[label]="'goals.edit.currentAmount'"
[min]="0"
[step]="amountStep()"
/>
</div>
@if (form.hasError('fieldNotLessThan')) {
<mat-error>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import { InputClearButtonComponent } from '../../../shared/input-clear-button/in
import { EnumValuePipe } from '../../../shared/pipes/enum-value.pipe';
import { TranslatePipe } from '../../../shared/pipes/translate.pipe';
import { SelectAutoFocusDirective } from '../../../shared/select-auto-focus.directive';
import { localizeCurrency, toRawValueSignal } from '../../../shared/util/utils';
import { getAmountStep, localizeCurrency, toRawValueSignal } from '../../../shared/util/utils';
import { ValidatorComponent } from '../../../shared/validator/validator.component';
import { ExtraValidators } from '../../../shared/validators';
import { CategoryService } from '../../transactions-and-categories/category.service';
Expand Down Expand Up @@ -60,6 +60,7 @@ export class EditGoalDialogComponent extends DialogComponent<EditGoalDialogData,
private readonly translocoService = inject(TranslocoService);

data = this.dialogRef.value;
amountStep = computed(() => getAmountStep(1, this.data.goal.currency));

currencies = SupportedCurrency;
goalStatuses = GoalStatus;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
[control]="form.controls.amount"
[label]="'investments.create.amount'"
[min]="0.01"
[step]="amountStep()"
/>

@let currencyControl = form.controls.currency;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Component, DestroyRef, inject, signal } from '@angular/core';
import { Component, computed, DestroyRef, inject, signal } from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { NonNullableFormBuilder, ReactiveFormsModule, Validators } from '@angular/forms';
import { MatAutocompleteModule, MatAutocompleteSelectedEvent } from '@angular/material/autocomplete';
Expand All @@ -22,6 +22,7 @@ import { InputClearButtonComponent } from '../../../shared/input-clear-button/in
import { EnumValuePipe } from '../../../shared/pipes/enum-value.pipe';
import { TranslatePipe } from '../../../shared/pipes/translate.pipe';
import { TranslationCode } from '../../../shared/i18n/translation-types';
import { getAmountStep, toRawValueSignal } from '../../../shared/util/utils';
import { ValidatorComponent } from '../../../shared/validator/validator.component';

export interface CreateInvestmentDialogData {
Expand Down Expand Up @@ -74,6 +75,9 @@ export class CreateInvestmentDialogComponent extends DialogComponent<
note: this.fb.control<string>('', [Validators.maxLength(500)]),
});

private currencyValue = toRawValueSignal(this.form.controls.currency);
amountStep = computed(() => getAmountStep(1, this.currencyValue()));

filteredAssets = signal<{ name: string; type: InvestmentType }[]>([]);

constructor() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
[control]="form.controls.amount"
[label]="'investments.edit.amount'"
[min]="0.01"
[step]="amountStep()"
/>

@let noteControl = form.controls.note;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Component, DestroyRef, inject, signal } from '@angular/core';
import { Component, computed, DestroyRef, inject, signal } from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { NonNullableFormBuilder, ReactiveFormsModule, Validators } from '@angular/forms';
import { MatAutocompleteModule, MatAutocompleteSelectedEvent } from '@angular/material/autocomplete';
Expand All @@ -21,6 +21,7 @@ import { InputClearButtonComponent } from '../../../shared/input-clear-button/in
import { EnumValuePipe } from '../../../shared/pipes/enum-value.pipe';
import { TranslatePipe } from '../../../shared/pipes/translate.pipe';
import { TranslationCode } from '../../../shared/i18n/translation-types';
import { getAmountStep } from '../../../shared/util/utils';
import { ValidatorComponent } from '../../../shared/validator/validator.component';

export interface EditInvestmentDialogData {
Expand Down Expand Up @@ -55,6 +56,7 @@ export class EditInvestmentDialogComponent extends DialogComponent<EditInvestmen

investmentTypes = InvestmentType;
data = this.dialogRef.value;
amountStep = computed(() => getAmountStep(1, this.data.investment.currency));

form = this.fb.group({
asset: this.fb.control<string>(this.data.investment.asset, [Validators.required, Validators.maxLength(100)]),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,12 @@

<div class="d-flex flex-column flex-sm-row align-items-sm-start gap-3">
@let amountControl = form.controls.amount;
<ex-amount-stepper [control]="amountControl" label="transaction.create.amount" [min]="1" />
<ex-amount-stepper
[control]="amountControl"
label="transaction.create.amount"
[min]="1"
[step]="amountStep()"
/>
@let dateControl = form.controls.date;
<mat-form-field
[matTooltip]="'recurring.featureDisabledByRecurring' | translate"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ import { EnumValuePipe } from '../../../shared/pipes/enum-value.pipe';
import { OrdinalPipe } from '../../../shared/pipes/ordinal.pipe';
import { TranslatePipe } from '../../../shared/pipes/translate.pipe';
import { SelectAutoFocusDirective } from '../../../shared/select-auto-focus.directive';
import { localizeCurrency, toRawValueSignal } from '../../../shared/util/utils';
import { getAmountStep, localizeCurrency, toRawValueSignal } from '../../../shared/util/utils';
import { ValidatorComponent } from '../../../shared/validator/validator.component';
import { ExtraValidators } from '../../../shared/validators';
import { CategoryService } from '../category.service';
Expand Down Expand Up @@ -161,6 +161,8 @@ export class CreateTransactionDialogComponent extends DialogWithBaseComponent<
private dateValue = toRawValueSignal(this.form.controls.date);
private currencyValue = toRawValueSignal(this.form.controls.currency);

amountStep = computed(() => getAmountStep(1, this.currencyValue()));

recurringDateFilter = computed((): DateFilterFn<Date | null> => {
const frequency = this.frequencyValue();
const dayOfWeek = this.dayOfWeekValue();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,12 @@

<div class="d-flex flex-column flex-md-row align-items-md-start gap-3">
@let amountControl = form.controls.amount;
<ex-amount-stepper [control]="amountControl" label="transaction.edit.amount" [min]="1" />
<ex-amount-stepper
[control]="amountControl"
label="transaction.edit.amount"
[min]="1"
[step]="amountStep()"
/>
@let dateControl = form.controls.date;
<mat-form-field>
<mat-label>{{ 'transaction.edit.date' | translate }}</mat-label>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import { InputClearButtonComponent } from '../../../shared/input-clear-button/in
import { EnumValuePipe } from '../../../shared/pipes/enum-value.pipe';
import { TranslatePipe } from '../../../shared/pipes/translate.pipe';
import { SelectAutoFocusDirective } from '../../../shared/select-auto-focus.directive';
import { localizeCurrency, toRawValueSignal } from '../../../shared/util/utils';
import { getAmountStep, localizeCurrency, toRawValueSignal } from '../../../shared/util/utils';
import { ValidatorComponent } from '../../../shared/validator/validator.component';
import { CategoryService } from '../category.service';
import { ExchangeRateRequest, ExchangeRateService } from '../../../shared/exchange-rate.service';
Expand Down Expand Up @@ -102,6 +102,8 @@ export class EditTransactionDialogComponent extends DialogComponent<
private currencyValue = toRawValueSignal(this.form.controls.currency);
private selectedType = toRawValueSignal(this.form.controls.type);

amountStep = computed(() => getAmountStep(1, this.currencyValue()));

private categories = signal<CategoryGet[]>([]);

filteredCategories = computed(() => {
Expand Down
16 changes: 16 additions & 0 deletions frontend/Exence/src/app/shared/util/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,22 @@ import { TransactionFilter } from '../../data-model/modules/transaction/Transact
import { TransactionType } from '../../data-model/modules/transaction/TransactionType';
import { SupportedCurrency } from '../../data-model/modules/user-settings/SupportedCurrency';

const CURRENCY_STEP_MULTIPLIERS: Record<SupportedCurrency, number> = {
[SupportedCurrency.HUF]: 100,
[SupportedCurrency.EUR]: 1,
[SupportedCurrency.USD]: 1,
[SupportedCurrency.CAD]: 1,
[SupportedCurrency.GBP]: 1,
[SupportedCurrency.CHF]: 1,
[SupportedCurrency.PLN]: 1,
[SupportedCurrency.CZK]: 5,
[SupportedCurrency.RON]: 1,
};

export function getAmountStep(eurAmount: number, currency: SupportedCurrency): number {
return eurAmount * CURRENCY_STEP_MULTIPLIERS[currency];
}

export function toRawValueSignal<T>(control: AbstractControl<unknown, T>): Signal<T> {
return toSignal(control.valueChanges.pipe(map(() => control.getRawValue() as T)), {
initialValue: control.getRawValue() as T,
Expand Down
Loading