From 3cf435a0797f94c08019f9c479b9f56077ca0562 Mon Sep 17 00:00:00 2001 From: Giddh's Black Tiger Date: Mon, 20 Apr 2026 18:34:42 +0530 Subject: [PATCH] refactor: standardize name and company name validation patterns across components - Replace minlength validator with pattern validator for company name field - Update company name error message to reflect pattern requirements - Rename UPDATE_REGEX to COMPANY_NAME_REGEX for clarity - Update NAME_REGEX pattern to enforce 3-50 character names starting with letter - Remove unused FULL_NAME_REGEX from regex library - Import and apply NAME_REGEX consistently across user-profile, user-management, and add --- .../organization-details.component.html | 5 +++-- .../organization-details.component.ts | 4 ++-- .../add-user-dialog.component.ts | 3 ++- .../user-management.component.ts | 21 ++++++++++++++----- .../user-profile/user-profile.component.ts | 4 ++-- libs/regex/src/index.ts | 5 ++--- 6 files changed, 27 insertions(+), 15 deletions(-) diff --git a/apps/36-blocks-widget/src/app/otp/organization-details/organization-details.component.html b/apps/36-blocks-widget/src/app/otp/organization-details/organization-details.component.html index 7e37d9c9..a2b72ea9 100644 --- a/apps/36-blocks-widget/src/app/otp/organization-details/organization-details.component.html +++ b/apps/36-blocks-widget/src/app/otp/organization-details/organization-details.component.html @@ -191,10 +191,11 @@

Edit Organization

} @else if ( organizationForm.get('companyName')?.touched && - organizationForm.get('companyName')?.hasError('minlength') + organizationForm.get('companyName')?.hasError('pattern') ) { } diff --git a/apps/36-blocks-widget/src/app/otp/organization-details/organization-details.component.ts b/apps/36-blocks-widget/src/app/otp/organization-details/organization-details.component.ts index 9f924943..bb994cda 100644 --- a/apps/36-blocks-widget/src/app/otp/organization-details/organization-details.component.ts +++ b/apps/36-blocks-widget/src/app/otp/organization-details/organization-details.component.ts @@ -25,7 +25,7 @@ import { BaseComponent } from 'libs/ui/base-component/src/lib/base-component/bas import { OtpService } from '../service/otp.service'; import { WidgetThemeService } from '../service/widget-theme.service'; import { finalize, takeUntil } from 'rxjs'; -import { EMAIL_REGEX } from '@proxy/regex'; +import { COMPANY_NAME_REGEX, EMAIL_REGEX } from '@proxy/regex'; @Component({ selector: 'organization-details', @@ -43,7 +43,7 @@ export class OrganizationDetailsComponent extends BaseComponent implements OnIni readonly isDark = computed(() => this.themeService.isDark$()); public organizationForm = new FormGroup({ - companyName: new FormControl('', [Validators.required, Validators.minLength(3)]), + companyName: new FormControl('', [Validators.required, Validators.pattern(COMPANY_NAME_REGEX)]), email: new FormControl('', [Validators.required, Validators.pattern(EMAIL_REGEX)]), phoneNumber: new FormControl('', [Validators.pattern(/^$|^[0-9]{10,15}$/)]), timezone: new FormControl(''), diff --git a/apps/36-blocks-widget/src/app/otp/user-management/add-user-dialog.component.ts b/apps/36-blocks-widget/src/app/otp/user-management/add-user-dialog.component.ts index cc0396c7..d872b2da 100644 --- a/apps/36-blocks-widget/src/app/otp/user-management/add-user-dialog.component.ts +++ b/apps/36-blocks-widget/src/app/otp/user-management/add-user-dialog.component.ts @@ -21,6 +21,7 @@ import { WidgetTheme } from '@proxy/constant'; import { WidgetDialogRef } from '../service/widget-dialog.service'; import { ToastService } from '../service/toast.service'; import { ToastComponent } from '../service/toast.component'; +import { NAME_REGEX } from '@proxy/regex'; /** * Standalone Add-User dialog. @@ -179,7 +180,7 @@ export class AddUserDialogComponent implements OnInit, OnDestroy { ngOnInit(): void { this.form = this.fb.group({ - name: ['', [Validators.required, Validators.pattern(/^[\p{L}\s'-]+$/u)]], + name: ['', [Validators.required, Validators.pattern(NAME_REGEX)]], email: ['', [Validators.required, Validators.email]], mobileNumber: ['', [Validators.pattern(/^(\+?[1-9]\d{1,14}|[0-9]{10})$/)]], role: [''], diff --git a/apps/36-blocks-widget/src/app/otp/user-management/user-management.component.ts b/apps/36-blocks-widget/src/app/otp/user-management/user-management.component.ts index f0e3586e..99913dbd 100644 --- a/apps/36-blocks-widget/src/app/otp/user-management/user-management.component.ts +++ b/apps/36-blocks-widget/src/app/otp/user-management/user-management.component.ts @@ -21,7 +21,7 @@ import { CommonModule } from '@angular/common'; import { ToastService } from '../service/toast.service'; import { ToastComponent } from '../service/toast.component'; import { WidgetTheme } from '@proxy/constant'; -import { UPDATE_REGEX } from '@proxy/regex'; +import { NAME_REGEX } from '@proxy/regex'; import { FormsModule, ReactiveFormsModule, FormBuilder, FormGroup, Validators } from '@angular/forms'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { Actions, ofType } from '@ngrx/effects'; @@ -42,6 +42,7 @@ import { updateRoleData, updateUserPermissionData, updateUserRoleData, + deleteUserData, } from '../store/selectors'; import { isEqual } from 'lodash-es'; import { WidgetThemeService } from '../service/widget-theme.service'; @@ -276,6 +277,17 @@ export class UserManagementComponent implements OnInit, AfterViewInit, OnDestroy } }); + this.store + .pipe(select(deleteUserData), distinctUntilChanged(isEqual), takeUntilDestroyed(this.destroyRef)) + .subscribe((res) => { + if (res) { + this.getCompanyUsers(); + const message = res?.data?.message || res?.message || 'User removed successfully.'; + this.toastService.success(message); + this.cdr.markForCheck(); + } + }); + this.actions$ .pipe( ofType( @@ -286,7 +298,8 @@ export class UserManagementComponent implements OnInit, AfterViewInit, OnDestroy otpActions.addUserError, otpActions.updateCompanyUserError, otpActions.updateUserRoleError, - otpActions.updateUserPermissionError + otpActions.updateUserPermissionError, + otpActions.deleteUserError ), takeUntilDestroyed(this.destroyRef) ) @@ -310,7 +323,7 @@ export class UserManagementComponent implements OnInit, AfterViewInit, OnDestroy }); this.addUserForm = this.fb.group({ - name: ['', [Validators.required, Validators.pattern(UPDATE_REGEX)]], + name: ['', [Validators.required, Validators.pattern(NAME_REGEX)]], email: ['', [Validators.required, Validators.email]], mobileNumber: ['', [Validators.pattern(/^(\+?[1-9]\d{1,14}|[0-9]{10})$/)]], role: [''], @@ -400,8 +413,6 @@ export class UserManagementComponent implements OnInit, AfterViewInit, OnDestroy public confirmDelete(): void { if (this.pendingDeleteUser) { const userId = (this.pendingDeleteUser as any).user_id; - this.userData = this.userData.filter((u: any) => u.user_id !== userId); - this.totalUsers = Math.max(0, this.totalUsers - 1); this.store.dispatch(otpActions.deleteUser({ companyId: userId, authToken: this.userToken() })); } this.cancelDelete(); diff --git a/apps/36-blocks-widget/src/app/otp/user-profile/user-profile.component.ts b/apps/36-blocks-widget/src/app/otp/user-profile/user-profile.component.ts index 3cc4e39e..8b67f0de 100644 --- a/apps/36-blocks-widget/src/app/otp/user-profile/user-profile.component.ts +++ b/apps/36-blocks-widget/src/app/otp/user-profile/user-profile.component.ts @@ -36,7 +36,7 @@ import { } from '../store/selectors'; import { BaseComponent } from '@proxy/ui/base-component'; import { isEqual } from 'lodash-es'; -import { UPDATE_REGEX } from '@proxy/regex'; +import { NAME_REGEX } from '@proxy/regex'; import { WidgetTheme } from '@proxy/constant'; import { WidgetThemeService } from '../service/widget-theme.service'; @Component({ @@ -88,7 +88,7 @@ export class UserProfileComponent extends BaseComponent implements OnInit, After // authToken: string = ''; clientForm = new FormGroup({ - name: new FormControl('', [Validators.required, Validators.pattern(UPDATE_REGEX)]), + name: new FormControl('', [Validators.required, Validators.pattern(NAME_REGEX)]), mobile: new FormControl({ value: '', disabled: true }), email: new FormControl({ value: '', disabled: true }), }); diff --git a/libs/regex/src/index.ts b/libs/regex/src/index.ts index 9211fee4..07552932 100644 --- a/libs/regex/src/index.ts +++ b/libs/regex/src/index.ts @@ -64,9 +64,8 @@ export const CAMPAIGN_NAME_REGEX = /^[a-zA-Z0-9][a-zA-Z0-9_\s]+$/; export const ALPHANUMERIC_WITH_DASH_CAPS_AND_STARTS_WITH_ALPHABET_REGEX = /^[A-Za-z][A-Za-z0-9\-\_]*$/; export const PERMISSION_NAME_REGEX = /^[a-zA-Z0-9_\s]+$/; export const NON_ASCII_PRINTABLE_CHARACTERS_REGEX = /[^\t\r\n\x20-\x7E]/; -export const FULL_NAME_REGEX = /^([\w])+\s+([\w\s])+$/i; export const PASSWORD_REGEX = /(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[\W_]).*/; // Should Contain at least one lowercase letter, one uppercase letter, one number and one symbol -export const NAME_REGEX = /^([a-zA-Z]+\s)*[a-zA-Z]+$/i; +export const NAME_REGEX = /^[a-zA-Z][a-zA-Z\s]{2,49}$/; export const EMAIL_OR_MOBILE_REGEX = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$|^[0-9]{7,15}$/; -export const UPDATE_REGEX = /^[a-zA-Z0-9][a-zA-Z0-9_\s]+$/; +export const COMPANY_NAME_REGEX = /^[a-zA-Z0-9][a-zA-Z0-9_\s]+$/;