diff --git a/frontend/Exence/src/app/private/profile/profile.component.html b/frontend/Exence/src/app/private/profile/profile.component.html index d7fa7be..bc3afc0 100644 --- a/frontend/Exence/src/app/private/profile/profile.component.html +++ b/frontend/Exence/src/app/private/profile/profile.component.html @@ -44,7 +44,7 @@

Profile data

@let nameControl = userDataForm.controls.username; Username - + @@ -54,7 +54,7 @@

Profile data

@let emailControl = userDataForm.controls.email; Email - + diff --git a/frontend/Exence/src/app/private/profile/profile.component.ts b/frontend/Exence/src/app/private/profile/profile.component.ts index e90dd90..710e3da 100644 --- a/frontend/Exence/src/app/private/profile/profile.component.ts +++ b/frontend/Exence/src/app/private/profile/profile.component.ts @@ -15,21 +15,23 @@ import { UserService } from '../../shared/user/user.service'; import { ValidatorComponent } from '../../shared/validator/validator.component'; import { ExtraValidators } from '../../shared/validators'; import { SessionsListComponent } from '../session/sessions-list/sessions-list.component'; +import { AutoTrimDirective } from "src/app/shared/auto-trim.directive"; @Component({ selector: 'ex-profile', templateUrl: './profile.component.html', styleUrl: './profile.component.scss', imports: [ - ReactiveFormsModule, - MatFormFieldModule, - MatInputModule, - MatDividerModule, - ButtonComponent, - InputClearButtonComponent, - SessionsListComponent, - ValidatorComponent, - ], + ReactiveFormsModule, + MatFormFieldModule, + MatInputModule, + MatDividerModule, + ButtonComponent, + InputClearButtonComponent, + SessionsListComponent, + ValidatorComponent, + AutoTrimDirective +], }) export class ProfileComponent { private readonly fb = inject(NonNullableFormBuilder); diff --git a/frontend/Exence/src/app/private/transactions-and-categories/create-category-dialog/create-category-dialog.component.html b/frontend/Exence/src/app/private/transactions-and-categories/create-category-dialog/create-category-dialog.component.html index 60b8f22..2d33055 100644 --- a/frontend/Exence/src/app/private/transactions-and-categories/create-category-dialog/create-category-dialog.component.html +++ b/frontend/Exence/src/app/private/transactions-and-categories/create-category-dialog/create-category-dialog.component.html @@ -9,6 +9,7 @@

New category

Name @@ -76,6 +77,5 @@

New category

\ No newline at end of file diff --git a/frontend/Exence/src/app/private/transactions-and-categories/create-category-dialog/create-category-dialog.component.ts b/frontend/Exence/src/app/private/transactions-and-categories/create-category-dialog/create-category-dialog.component.ts index 73ed26d..5604b20 100644 --- a/frontend/Exence/src/app/private/transactions-and-categories/create-category-dialog/create-category-dialog.component.ts +++ b/frontend/Exence/src/app/private/transactions-and-categories/create-category-dialog/create-category-dialog.component.ts @@ -13,23 +13,25 @@ import { ButtonComponent } from '../../../shared/button/button.component'; import { InputClearButtonComponent } from '../../../shared/input-clear-button/input-clear-button.component'; import { ValidatorComponent } from '../../../shared/validator/validator.component'; import { CategoryService } from '../../category.service'; +import { AutoTrimDirective } from "src/app/shared/auto-trim.directive"; @Component({ selector: 'ex-create-category-dialog', templateUrl: './create-category-dialog.component.html', styleUrl: './create-category-dialog.component.scss', imports: [ - ReactiveFormsModule, - MatFormFieldModule, - MatInputModule, - MatCardModule, - MatMenuModule, - MatIconModule, - PickerComponent, - InputClearButtonComponent, - ButtonComponent, - ValidatorComponent, - ], + ReactiveFormsModule, + MatFormFieldModule, + MatInputModule, + MatCardModule, + MatMenuModule, + MatIconModule, + PickerComponent, + InputClearButtonComponent, + ButtonComponent, + ValidatorComponent, + AutoTrimDirective +], }) export class CreateCategoryDialogComponent { private readonly dialogRef = inject(MatDialogRef); diff --git a/frontend/Exence/src/app/private/transactions-and-categories/create-transaction-dialog/create-transaction-dialog.component.html b/frontend/Exence/src/app/private/transactions-and-categories/create-transaction-dialog/create-transaction-dialog.component.html index c32befe..1c9875b 100644 --- a/frontend/Exence/src/app/private/transactions-and-categories/create-transaction-dialog/create-transaction-dialog.component.html +++ b/frontend/Exence/src/app/private/transactions-and-categories/create-transaction-dialog/create-transaction-dialog.component.html @@ -9,6 +9,7 @@

New transaction

Title @@ -79,7 +80,7 @@

New transaction

@let noteControl = form.controls.note; Note - + diff --git a/frontend/Exence/src/app/private/transactions-and-categories/create-transaction-dialog/create-transaction-dialog.component.ts b/frontend/Exence/src/app/private/transactions-and-categories/create-transaction-dialog/create-transaction-dialog.component.ts index 83fdfa8..67ae080 100644 --- a/frontend/Exence/src/app/private/transactions-and-categories/create-transaction-dialog/create-transaction-dialog.component.ts +++ b/frontend/Exence/src/app/private/transactions-and-categories/create-transaction-dialog/create-transaction-dialog.component.ts @@ -16,6 +16,7 @@ import { InputClearButtonComponent } from '../../../shared/input-clear-button/in import { ValidatorComponent } from '../../../shared/validator/validator.component'; import { CategoryService } from '../../category.service'; import { TransactionService } from '../transaction.service'; +import { AutoTrimDirective } from "src/app/shared/auto-trim.directive"; export interface CreateTransactionDialogData { type?: TransactionType; @@ -27,16 +28,17 @@ export interface CreateTransactionDialogData { templateUrl: './create-transaction-dialog.component.html', styleUrl: './create-transaction-dialog.component.scss', imports: [ - ReactiveFormsModule, - MatFormFieldModule, - MatInputModule, - MatCardModule, - MatSelectModule, MatDatepickerModule, - MatCheckboxModule, - InputClearButtonComponent, - ButtonComponent, - ValidatorComponent, - ], + ReactiveFormsModule, + MatFormFieldModule, + MatInputModule, + MatCardModule, + MatSelectModule, MatDatepickerModule, + MatCheckboxModule, + InputClearButtonComponent, + ButtonComponent, + ValidatorComponent, + AutoTrimDirective +], }) export class CreateTransactionDialogComponent extends BaseComponent implements OnInit { private readonly dialogRef = inject(MatDialogRef); diff --git a/frontend/Exence/src/app/public/forgot-password/forgot-password.component.html b/frontend/Exence/src/app/public/forgot-password/forgot-password.component.html index af73be0..f3c4ef0 100644 --- a/frontend/Exence/src/app/public/forgot-password/forgot-password.component.html +++ b/frontend/Exence/src/app/public/forgot-password/forgot-password.component.html @@ -16,7 +16,7 @@

Forgot password?

Email - + diff --git a/frontend/Exence/src/app/public/forgot-password/forgot-password.component.ts b/frontend/Exence/src/app/public/forgot-password/forgot-password.component.ts index fc9e948..e8a5b7b 100644 --- a/frontend/Exence/src/app/public/forgot-password/forgot-password.component.ts +++ b/frontend/Exence/src/app/public/forgot-password/forgot-password.component.ts @@ -15,22 +15,24 @@ import { NavigationService } from '../../shared/navigation/navigation.service'; import { SnackbarService } from '../../shared/snackbar/snackbar.service'; import { ExtraValidators } from '../../shared/validators'; import { ValidatorComponent } from '../../shared/validator/validator.component'; +import { AutoTrimDirective } from "src/app/shared/auto-trim.directive"; @Component({ selector: 'ex-forgot-password', templateUrl: './forgot-password.component.html', styleUrl: './forgot-password.component.scss', imports: [ - MatFormFieldModule, - MatInputModule, - ButtonComponent, - ReactiveFormsModule, - MatCardModule, - MatIconModule, - InputClearButtonComponent, - RouterLink, - ValidatorComponent, - ] + MatFormFieldModule, + MatInputModule, + ButtonComponent, + ReactiveFormsModule, + MatCardModule, + MatIconModule, + InputClearButtonComponent, + RouterLink, + ValidatorComponent, + AutoTrimDirective +] }) export class ForgotPasswordComponent extends BaseComponent { private readonly fb = inject(NonNullableFormBuilder); diff --git a/frontend/Exence/src/app/public/login/login.component.html b/frontend/Exence/src/app/public/login/login.component.html index c0c0d8a..a174eea 100644 --- a/frontend/Exence/src/app/public/login/login.component.html +++ b/frontend/Exence/src/app/public/login/login.component.html @@ -20,6 +20,7 @@

Log in to your account

matInput [formControl]="emailControl" type="email" + autoTrim /> diff --git a/frontend/Exence/src/app/public/login/login.component.ts b/frontend/Exence/src/app/public/login/login.component.ts index 43bb72e..ac7a3c0 100644 --- a/frontend/Exence/src/app/public/login/login.component.ts +++ b/frontend/Exence/src/app/public/login/login.component.ts @@ -15,23 +15,25 @@ import { NavigationService } from '../../shared/navigation/navigation.service'; import { CurrentUserService } from '../../shared/user/current-user.service'; import { ValidatorComponent } from '../../shared/validator/validator.component'; import { ExtraValidators } from '../../shared/validators'; +import { AutoTrimDirective } from "src/app/shared/auto-trim.directive"; @Component({ selector: 'ex-login', templateUrl: './login.component.html', styleUrl: './login.component.scss', imports: [ - MatFormFieldModule, - MatInputModule, - ReactiveFormsModule, - MatButtonModule, - RouterModule, - MatCardModule, - MatIconModule, - InputClearButtonComponent, - ButtonComponent, - ValidatorComponent, - ], + MatFormFieldModule, + MatInputModule, + ReactiveFormsModule, + MatButtonModule, + RouterModule, + MatCardModule, + MatIconModule, + InputClearButtonComponent, + ButtonComponent, + ValidatorComponent, + AutoTrimDirective +], }) export class LoginComponent extends BaseComponent { private readonly fb = inject(NonNullableFormBuilder); diff --git a/frontend/Exence/src/app/public/registration/registration.component.html b/frontend/Exence/src/app/public/registration/registration.component.html index ac7eaa3..e8eb5a0 100644 --- a/frontend/Exence/src/app/public/registration/registration.component.html +++ b/frontend/Exence/src/app/public/registration/registration.component.html @@ -19,7 +19,7 @@

Create an Account

@let nameControl = form.controls.username; Username - + @@ -28,7 +28,7 @@

Create an Account

@let emailControl = form.controls.email; Email - + diff --git a/frontend/Exence/src/app/public/registration/registration.component.ts b/frontend/Exence/src/app/public/registration/registration.component.ts index 11e5441..a190883 100644 --- a/frontend/Exence/src/app/public/registration/registration.component.ts +++ b/frontend/Exence/src/app/public/registration/registration.component.ts @@ -15,23 +15,25 @@ import { ExtraValidators } from '../../shared/validators'; import { AuthService } from '../../shared/auth/auth.service'; import { SnackbarService } from '../../shared/snackbar/snackbar.service'; import { ValidatorComponent } from '../../shared/validator/validator.component'; +import { AutoTrimDirective } from "src/app/shared/auto-trim.directive"; @Component({ selector: 'ex-registration', templateUrl: './registration.component.html', styleUrl: './registration.component.scss', imports: [ - MatCardModule, - MatIconModule, - ReactiveFormsModule, - MatFormFieldModule, - MatInput, - ButtonComponent, - InputClearButtonComponent, - RouterLink, - MatTooltipModule, - ValidatorComponent, - ] + MatCardModule, + MatIconModule, + ReactiveFormsModule, + MatFormFieldModule, + MatInput, + ButtonComponent, + InputClearButtonComponent, + RouterLink, + MatTooltipModule, + ValidatorComponent, + AutoTrimDirective +] }) export class RegistrationComponent extends BaseComponent { private readonly fb = inject(NonNullableFormBuilder); diff --git a/frontend/Exence/src/app/shared/auto-trim.directive.ts b/frontend/Exence/src/app/shared/auto-trim.directive.ts new file mode 100644 index 0000000..6d5d9d8 --- /dev/null +++ b/frontend/Exence/src/app/shared/auto-trim.directive.ts @@ -0,0 +1,25 @@ +import { Directive, inject } from "@angular/core"; +import { ControlValueAccessor, NgControl } from "@angular/forms"; + +@Directive({ + selector: '[autoTrim]', + standalone: true +}) +export class AutoTrimDirective { + private control = inject(NgControl); + + constructor() { + trimValueAccessor(this.control.valueAccessor!); + } +} + +function trimValueAccessor(valueAccessor: ControlValueAccessor) { + const original = valueAccessor.registerOnChange; + + // overrides angular's formControl updation function to first validate strings + valueAccessor.registerOnChange = (fn: (_: unknown) => void) => { + return original.call(valueAccessor, (value: unknown) => { + return fn(typeof value === 'string' ? value.replace(/\s+/g, ' ').trim() : value); + }); + } +} \ No newline at end of file diff --git a/frontend/Exence/src/app/shared/data-table/data-table.component.html b/frontend/Exence/src/app/shared/data-table/data-table.component.html index 41c9cb5..045c01e 100644 --- a/frontend/Exence/src/app/shared/data-table/data-table.component.html +++ b/frontend/Exence/src/app/shared/data-table/data-table.component.html @@ -145,13 +145,13 @@

- +