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 @@
-
+