From 2e7d1bf8eea15f9fc1ceeacaf5a3787e5dfc66ab Mon Sep 17 00:00:00 2001 From: maliming Date: Fri, 28 Jul 2023 11:40:49 +0800 Subject: [PATCH 01/39] Add `AbpIdentityUserValidator`. --- .../AspNetCore/AbpIdentityAspNetCoreModule.cs | 3 +- .../Volo/Abp/Identity/Localization/ar.json | 1 + .../Volo/Abp/Identity/Localization/cs.json | 1 + .../Volo/Abp/Identity/Localization/de.json | 1 + .../Volo/Abp/Identity/Localization/el.json | 1 + .../Volo/Abp/Identity/Localization/en-GB.json | 1 + .../Volo/Abp/Identity/Localization/en.json | 1 + .../Volo/Abp/Identity/Localization/es.json | 1 + .../Volo/Abp/Identity/Localization/fa.json | 1 + .../Volo/Abp/Identity/Localization/fi.json | 1 + .../Volo/Abp/Identity/Localization/fr.json | 1 + .../Volo/Abp/Identity/Localization/hi.json | 1 + .../Volo/Abp/Identity/Localization/hr.json | 1 + .../Volo/Abp/Identity/Localization/hu.json | 1 + .../Volo/Abp/Identity/Localization/is.json | 1 + .../Volo/Abp/Identity/Localization/it.json | 1 + .../Volo/Abp/Identity/Localization/nl.json | 1 + .../Volo/Abp/Identity/Localization/pl-PL.json | 1 + .../Volo/Abp/Identity/Localization/pt-BR.json | 1 + .../Volo/Abp/Identity/Localization/ro-RO.json | 1 + .../Volo/Abp/Identity/Localization/ru.json | 1 + .../Volo/Abp/Identity/Localization/sk.json | 1 + .../Volo/Abp/Identity/Localization/sl.json | 1 + .../Volo/Abp/Identity/Localization/tr.json | 1 + .../Volo/Abp/Identity/Localization/vi.json | 1 + .../Abp/Identity/Localization/zh-Hans.json | 1 + .../Abp/Identity/Localization/zh-Hant.json | 1 + .../Abp/Identity/AbpIdentityUserValidator.cs | 48 +++++++++++++++++++ .../AbpIdentityUserValidator_Tests.cs | 36 ++++++++++++++ 29 files changed, 112 insertions(+), 1 deletion(-) create mode 100644 modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/AbpIdentityUserValidator.cs create mode 100644 modules/identity/test/Volo.Abp.Identity.AspNetCore.Tests/Volo/Abp/Identity/AspNetCore/AbpIdentityUserValidator_Tests.cs diff --git a/modules/identity/src/Volo.Abp.Identity.AspNetCore/Volo/Abp/Identity/AspNetCore/AbpIdentityAspNetCoreModule.cs b/modules/identity/src/Volo.Abp.Identity.AspNetCore/Volo/Abp/Identity/AspNetCore/AbpIdentityAspNetCoreModule.cs index 93d8a52ee7..974f81a201 100644 --- a/modules/identity/src/Volo.Abp.Identity.AspNetCore/Volo/Abp/Identity/AspNetCore/AbpIdentityAspNetCoreModule.cs +++ b/modules/identity/src/Volo.Abp.Identity.AspNetCore/Volo/Abp/Identity/AspNetCore/AbpIdentityAspNetCoreModule.cs @@ -16,7 +16,8 @@ public class AbpIdentityAspNetCoreModule : AbpModule builder .AddDefaultTokenProviders() .AddTokenProvider(LinkUserTokenProviderConsts.LinkUserTokenProviderName) - .AddSignInManager(); + .AddSignInManager() + .AddUserValidator(); }); } diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ar.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ar.json index 490bd611df..7985177c6e 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ar.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ar.json @@ -48,6 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "اسم الدور '{0}' غير صالح.", "Volo.Abp.Identity:InvalidToken": "غير صالح token.", "Volo.Abp.Identity:InvalidUserName": "اسم المستخدم '{0}' غير صالح ، يمكن أن يحتوي على أحرف أو أرقام فقط.", + "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "لااسم المستخدم '{0}' غير صالح ، لا يمكنك استخدام البريد الإلكتروني لمستخدم آخر كاسم المستخدم الخاص بك.", "Volo.Abp.Identity:LoginAlreadyAssociated": "يوجد مستخدم لديه معلومات تسجيل الدخول هذه بالفعل.", "Volo.Abp.Identity:PasswordMismatch": "كلمة مرور غير صحيحة.", "Volo.Abp.Identity:PasswordRequiresDigit": "يجب أن تحتوي كلمات المرور على رقم واحد على الأقل ('0' - '9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/cs.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/cs.json index 7f2ddde421..db8eef485f 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/cs.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/cs.json @@ -48,6 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "Role '{0}' je neplatná.", "Volo.Abp.Identity:InvalidToken": "Neplatný token.", "Volo.Abp.Identity:InvalidUserName": "Uživatelské jméno '{0}' je neplatné, může obsahovat pouze písmena a číslice.", + "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "Uživatelské jméno '{0}' je neplatné, Nemůžete použít email jiného uživatele jako své uživatelské jméno.", "Volo.Abp.Identity:LoginAlreadyAssociated": "Uživatel s tímto přihlášením již existuje.", "Volo.Abp.Identity:PasswordMismatch": "Chybné heslo.", "Volo.Abp.Identity:PasswordRequiresDigit": "Hesla musí obsahovat alespoň jednu číslici ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/de.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/de.json index 69f2e9e9b2..10b056e9da 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/de.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/de.json @@ -48,6 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "Der Rollenname '{0}' ist ungültig.", "Volo.Abp.Identity:InvalidToken": "Ungültiger Token.", "Volo.Abp.Identity:InvalidUserName": "Der Benutzername '{0}' ist ungültig und darf nur Buchstaben oder Ziffern enthalten.", + "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "Der Benutzername '{0}' ist ungültig, Sie können nicht die E-Mail-Adresse eines anderen Benutzers als Ihren Benutzernamen verwenden.", "Volo.Abp.Identity:LoginAlreadyAssociated": "Ein Benutzer mit diesem Login existiert bereits.", "Volo.Abp.Identity:PasswordMismatch": "Falsches Passwort.", "Volo.Abp.Identity:PasswordRequiresDigit": "Passwörter müssen mindestens eine Ziffer haben ('0' - '9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/el.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/el.json index 765d85ce09..f2cf0e2d81 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/el.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/el.json @@ -47,6 +47,7 @@ "Volo.Abp.Identity:InvalidRoleName": "Το όνομα ρόλου '{0}' δεν είναι έγκυρο.", "Volo.Abp.Identity:InvalidToken": "Μη έγκυρο διακριτικό.", "Volo.Abp.Identity:InvalidUserName": "Το όνομα χρήστη '{0}' δεν είναι έγκυρο, μπορεί να περιέχει μόνο γράμματα ή ψηφία.", + "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "Το όνομα χρήστη '{0}' δεν είναι έγκυρο, Δεν μπορείτε να χρησιμοποιήσετε το email ενός άλλου χρήστη ως όνομα χρήστη.", "Volo.Abp.Identity:LoginAlreadyAssociated": "Ένας χρήστης με αυτήν τη σύνδεση υπάρχει ήδη.", "Volo.Abp.Identity:PasswordMismatch": "Λάθος κωδικός.", "Volo.Abp.Identity:PasswordRequiresDigit": "Οι κωδικοί πρόσβασης πρέπει να έχουν τουλάχιστον ένα ψηφίο ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/en-GB.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/en-GB.json index adebfa33e8..5a94e0f816 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/en-GB.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/en-GB.json @@ -47,6 +47,7 @@ "Volo.Abp.Identity:InvalidRoleName": "Role name '{0}' is invalid.", "Volo.Abp.Identity:InvalidToken": "Invalid token.", "Volo.Abp.Identity:InvalidUserName": "Username '{0}' is invalid, it should only contain letters or digits.", + "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "Username '{0}' is invalid, You cannot use another user's email as your Username.", "Volo.Abp.Identity:LoginAlreadyAssociated": "A user with this login already exists.", "Volo.Abp.Identity:PasswordMismatch": "Incorrect password.", "Volo.Abp.Identity:PasswordRequiresDigit": "Passwords must have at least one digit ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/en.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/en.json index 724ec04300..738156140e 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/en.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/en.json @@ -48,6 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "Role name '{0}' is invalid.", "Volo.Abp.Identity:InvalidToken": "Invalid token.", "Volo.Abp.Identity:InvalidUserName": "Username '{0}' is invalid, can only contain letters or digits.", + "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "Username '{0}' is invalid, You cannot use another user's email as your Username.", "Volo.Abp.Identity:LoginAlreadyAssociated": "A user with this login already exists.", "Volo.Abp.Identity:PasswordMismatch": "Incorrect password.", "Volo.Abp.Identity:PasswordRequiresDigit": "Passwords must have at least one digit ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/es.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/es.json index 06c279ec73..3e0cbe0abc 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/es.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/es.json @@ -48,6 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "El nombre de rol '{0}' no es válido.", "Volo.Abp.Identity:InvalidToken": "token no válido", "Volo.Abp.Identity:InvalidUserName": "Nombre de usuario '{0}' no es válido. Sólo puede contener letras o dígitos", + "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "Nombre de usuario '{0}' no es válido. No puedes usar el e-mail de otro usuario como tu nombre de usuario.", "Volo.Abp.Identity:LoginAlreadyAssociated": "Usuario con este inicio de sesión en uso.", "Volo.Abp.Identity:PasswordMismatch": "Contraseña incorrecta.", "Volo.Abp.Identity:PasswordRequiresDigit": "Contraseñas deben tener al menos un dígito ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/fa.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/fa.json index 7a89cebc87..a0c1f743f9 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/fa.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/fa.json @@ -47,6 +47,7 @@ "Volo.Abp.Identity:InvalidRoleName": "عنوان نقش/وظیفه {0} نامعتبر است.", "Volo.Abp.Identity:InvalidToken": "گذرواژه وارد شده معتبر نیست.", "Volo.Abp.Identity:InvalidUserName": "نام کاربری '{0}' نامعتبر است، نام کاربری فقط می تواند شامل حروف یا ارقام باشد.", + "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "شما نمی توانید از ایمیل کاربر دیگری به عنوان نام کاربری خود استفاده کنید.", "Volo.Abp.Identity:LoginAlreadyAssociated": "یک کاربر با این نام کاربری از قبل موجود می باشد.", "Volo.Abp.Identity:PasswordMismatch": "گذرواژه اشتباه است.", "Volo.Abp.Identity:PasswordRequiresDigit": "گذرواژه ها باید حداقل یک رقم داشته باشند ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/fi.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/fi.json index d74257414a..ad4032eeb6 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/fi.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/fi.json @@ -48,6 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "Roolin nimi {0} on virheellinen.", "Volo.Abp.Identity:InvalidToken": "Virheellinen tunnus.", "Volo.Abp.Identity:InvalidUserName": "Käyttäjätunnus {0} on virheellinen, voi sisältää vain kirjaimia tai numeroita.", + "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "Käyttäjätunnus {0} on virheellinen, Et voi käyttää toisen käyttäjän sähköpostiosoitetta käyttäjänimenä.", "Volo.Abp.Identity:LoginAlreadyAssociated": "Käyttäjä, jolla on tämä sisäänkirjautuminen, on jo olemassa.", "Volo.Abp.Identity:PasswordMismatch": "Väärä salasana.", "Volo.Abp.Identity:PasswordRequiresDigit": "Salasanoissa on oltava vähintään yksi numero ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/fr.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/fr.json index 80a5f90a10..b4fe67f76b 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/fr.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/fr.json @@ -48,6 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "Le nom de rôle '{0}' n’est pas valide.", "Volo.Abp.Identity:InvalidToken": "Jeton non valide.", "Volo.Abp.Identity:InvalidUserName": "Le nom d’utilisateur '{0}' n’est pas valide, ne peut contenir que des lettres ou des chiffres.", + "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "Le nom d’utilisateur '{0}' n’est pas valide,Vous ne pouvez pas utiliser l’e-mail d’un autre utilisateur comme nom d’utilisateur.", "Volo.Abp.Identity:LoginAlreadyAssociated": "Un utilisateur avec cette connexion existe déjà.", "Volo.Abp.Identity:PasswordMismatch": "Mot de passe incorrect.", "Volo.Abp.Identity:PasswordRequiresDigit": "Les mots de passe doivent avoir au moins un chiffre ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/hi.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/hi.json index e01e4c8e25..c6717ed5ac 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/hi.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/hi.json @@ -48,6 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "भूमिका नाम '{0}' अमान्य है।", "Volo.Abp.Identity:InvalidToken": "अमान्य टोकन।", "Volo.Abp.Identity:InvalidUserName": "उपयोगकर्ता नाम '{0}' अमान्य है, इसमें केवल अक्षर या अंक हो सकते हैं।", + "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "उपयोगकर्ता नाम '{0}' अमान्य है, आप दूसरे उपयोगकर्ता का ईमेल नाम उपयोग नहीं कर सकते।", "Volo.Abp.Identity:LoginAlreadyAssociated": "इस लॉगिन वाला उपयोगकर्ता पहले से मौजूद है।", "Volo.Abp.Identity:PasswordMismatch": "गलत पासवर्ड।", "Volo.Abp.Identity:PasswordRequiresDigit": "पासवर्ड में कम से कम एक अंक ('0'-'9') होना चाहिए।", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/hr.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/hr.json index a31715fc16..4890e944ea 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/hr.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/hr.json @@ -48,6 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "Naziv uloge '{0}' nije valjan.", "Volo.Abp.Identity:InvalidToken": "Pogrešan token.", "Volo.Abp.Identity:InvalidUserName": "Korisničko ime '{0}' nije važeće, može sadržavati samo slova ili znamenke.", + "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "Korisničko ime '{0}' nije važeće, Ne možete koristiti e-poštu drugog korisnika kao svoje korisničko ime.", "Volo.Abp.Identity:LoginAlreadyAssociated": "Korisnik s ovom prijavom već postoji.", "Volo.Abp.Identity:PasswordMismatch": "Netočna lozinka.", "Volo.Abp.Identity:PasswordRequiresDigit": "Lozinke moraju imati najmanje jednu znamenku ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/hu.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/hu.json index 8c658c9e89..2bbfeddcbf 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/hu.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/hu.json @@ -48,6 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "'{0}' szerepkör név érvénytelen.", "Volo.Abp.Identity:InvalidToken": "Érvénytelen token.", "Volo.Abp.Identity:InvalidUserName": "'{0}' felhasználónév érvénytelen, csak betűket és számokat tartalmazhat.", + "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "'{0}' felhasználónév érvénytelen, Nem használhatja más felhasználó email címét felhasználónévként.", "Volo.Abp.Identity:LoginAlreadyAssociated": "Az ilyen bejelentkezéssel rendelkező felhasználó már létezik.", "Volo.Abp.Identity:PasswordMismatch": "Érvénytelen jelszó.", "Volo.Abp.Identity:PasswordRequiresDigit": "A jelszavaknak legalább egy számjegyet kell rendelkezniük ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/is.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/is.json index c0bb4af19a..15a741a268 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/is.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/is.json @@ -48,6 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "Hlutverkanafnið '{0}' er ógilt.", "Volo.Abp.Identity:InvalidToken": "Ógilt token.", "Volo.Abp.Identity:InvalidUserName": "Notandanafnið '{0}' er ógilt, getur aðeins innihaldið bókstafi eða tölustafi.", + "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "Notandanafnið '{0}' er ógilt, Þú getur ekki notað netfang annars notanda sem notendanafn.", "Volo.Abp.Identity:LoginAlreadyAssociated": "Notandi með þessa innskráningu er þegar til.", "Volo.Abp.Identity:PasswordMismatch": "Rangt lykilorð.", "Volo.Abp.Identity:PasswordRequiresDigit": "Lykilorð verða að hafa að minnsta kosti einn staf ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/it.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/it.json index 513def4b52..eaf566930b 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/it.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/it.json @@ -48,6 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "Il nome del ruolo '{0}' non è valido.", "Volo.Abp.Identity:InvalidToken": "Token non valido.", "Volo.Abp.Identity:InvalidUserName": "Il nome utente '{0}' non è valido, può contenere solo lettere o cifre.", + "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "Il nome utente '{0}' non è valido, Non puoi utilizzare l'email di un altro utente come nome utente.", "Volo.Abp.Identity:LoginAlreadyAssociated": "Esiste già un utente con questo account.", "Volo.Abp.Identity:PasswordMismatch": "Password errata.", "Volo.Abp.Identity:PasswordRequiresDigit": "La password deve contenere almeno una cifra ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/nl.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/nl.json index 472935418b..79ee163cd2 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/nl.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/nl.json @@ -48,6 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "Rol naam '{0}' is ongeldig.", "Volo.Abp.Identity:InvalidToken": "Ongeldig token.", "Volo.Abp.Identity:InvalidUserName": "Gebruikersnaam '{0}' is ongeldig, mag alleen letters of cijfers bevatten.", + "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "Gebruikersnaam '{0}' is ongeldig, U kunt het e-mailadres van een andere gebruiker niet als uw gebruikersnaam gebruiken.", "Volo.Abp.Identity:LoginAlreadyAssociated": "Er bestaat al een gebruiker met deze login.", "Volo.Abp.Identity:PasswordMismatch": "Incorrect wachtwoord.", "Volo.Abp.Identity:PasswordRequiresDigit": "Wachtwoorden moeten minimaal één cijfer bevatten ('0' - '9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/pl-PL.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/pl-PL.json index 377c792ddf..36297c453a 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/pl-PL.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/pl-PL.json @@ -48,6 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "Rola '{0}' jest niepoprawna.", "Volo.Abp.Identity:InvalidToken": "Niepoprawny token.", "Volo.Abp.Identity:InvalidUserName": "Nazwa użytkownika '{0}' jest niepoprawna, może zawierać tylko litery i cyfry.", + "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "Nazwa użytkownika '{0}' jest niepoprawna, Nie możesz użyć adresu e-mail innego użytkownika jako swojej nazwy użytkownika.", "Volo.Abp.Identity:LoginAlreadyAssociated": "Użytkownik o tym loginie już istnieje.", "Volo.Abp.Identity:PasswordMismatch": "Niepoprawne hasło.", "Volo.Abp.Identity:PasswordRequiresDigit": "Hasło musi zawierać przynajmniej jedną cyfrę ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/pt-BR.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/pt-BR.json index c8807d2792..22936d80b1 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/pt-BR.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/pt-BR.json @@ -48,6 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "Perfil '{0}' inválido.", "Volo.Abp.Identity:InvalidToken": "Token inválido.", "Volo.Abp.Identity:InvalidUserName": "Usuário '{0}' é inválido, somente pode conter letras ou números.", + "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "Usuário '{0}' é inválido, Você não pode usar o e-mail de outro usuário como seu nome de usuário.", "Volo.Abp.Identity:LoginAlreadyAssociated": "Um usuário com este login já existe.", "Volo.Abp.Identity:PasswordMismatch": "Senha incorreta.", "Volo.Abp.Identity:PasswordRequiresDigit": "Senhas devem possuir pelo menos um dígito ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ro-RO.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ro-RO.json index d86eb4f1fa..ec0e22eb39 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ro-RO.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ro-RO.json @@ -48,6 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "Numele de rol '{0}' este invalid.", "Volo.Abp.Identity:InvalidToken": "Invalid token.", "Volo.Abp.Identity:InvalidUserName": "Numele de utilizator '{0}' este invalid, poate conţine doar litere şi cifre.", + "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "Numele de utilizator '{0}' este invalid, Nu puteţi folosi adresa de email a altui utilizator ca nume de utilizator.", "Volo.Abp.Identity:LoginAlreadyAssociated": "Un utilizator cu această autentificare există deja.", "Volo.Abp.Identity:PasswordMismatch": "Parolă incorectă.", "Volo.Abp.Identity:PasswordRequiresDigit": "Parolele trebuie să conţină cel puţin o cifră ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ru.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ru.json index 73fd937af0..d584a5ac3d 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ru.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ru.json @@ -48,6 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "Имя роли '{0}' недопустимо.", "Volo.Abp.Identity:InvalidToken": "Недопустимый маркер.", "Volo.Abp.Identity:InvalidUserName": "Имя пользователя '{0}' недопустимо и может содержать только буквы или цифры.", + "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "Имя пользователя '{0}' недопустимо Вы не можете использовать электронную почту другого пользователя в качестве своего имени пользователя.", "Volo.Abp.Identity:LoginAlreadyAssociated": "Пользователь с таким логином уже существует.", "Volo.Abp.Identity:PasswordMismatch": "Неверный пароль.", "Volo.Abp.Identity:PasswordRequiresDigit": "Пароль должен содержать по крайней мере одну цифру.", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/sk.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/sk.json index 83eb3850ad..7083f2f494 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/sk.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/sk.json @@ -48,6 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "Názov roly '{0}' je neplatný.", "Volo.Abp.Identity:InvalidToken": "Neplatný token.", "Volo.Abp.Identity:InvalidUserName": "Používateľské meno '{0}' je neplatné, môže obsahovať len písmená alebo číslice.", + "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "Používateľské meno '{0}' je neplatné, Nemôžete použiť email iného používateľa ako svoje používateľské meno.", "Volo.Abp.Identity:LoginAlreadyAssociated": "Používateľ s týmto prihlasovacím menom už existuje.", "Volo.Abp.Identity:PasswordMismatch": "Nesprávne heslo.", "Volo.Abp.Identity:PasswordRequiresDigit": "Heslá musia obsahovať aspoň jednu číslicu ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/sl.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/sl.json index caa60a2d71..ce58ebdcf6 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/sl.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/sl.json @@ -48,6 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "Naziv vloge '{0}' ni veljaven.", "Volo.Abp.Identity:InvalidToken": "Neveljaven žeton.", "Volo.Abp.Identity:InvalidUserName": "Uporabniško ime '{0}' ni veljavno, vsebuje lahko le črke in številke.", + "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "Uporabniško ime '{0}' ni veljavno, Ne morete uporabiti e-poštnega naslova drugega uporabnika kot svojega uporabniškega imena.", "Volo.Abp.Identity:LoginAlreadyAssociated": "Uporabnik s to prijavo že obstaja.", "Volo.Abp.Identity:PasswordMismatch": "Nepravilno geslo.", "Volo.Abp.Identity:PasswordRequiresDigit": "Gesla morajo imeti vsaj eno številko ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/tr.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/tr.json index c8957dc3e7..83e21f3c58 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/tr.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/tr.json @@ -48,6 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "'{0}' rol ismi geçersizdir.", "Volo.Abp.Identity:InvalidToken": "Geçersiz token.", "Volo.Abp.Identity:InvalidUserName": "'{0}' kullanıcı adı geçersiz, sadece harf ve rakamlardan oluşmalı.", + "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "'{0}' kullanıcı adı geçersiz, Başka bir kullanıcının e-posta adresini kullanıcı adı olarak kullanamazsınız.", "Volo.Abp.Identity:LoginAlreadyAssociated": "Bu giriş bilgilerine sahip bir kullanıcı zaten var.", "Volo.Abp.Identity:PasswordMismatch": "Hatalı şifre.", "Volo.Abp.Identity:PasswordRequiresDigit": "Şifre en az bir sayı içermeli ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/vi.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/vi.json index 05dbe248a0..f17fcbfe0d 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/vi.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/vi.json @@ -48,6 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "Tên người dùng '{0}' Không hợp lệ.", "Volo.Abp.Identity:InvalidToken": "Token không hợp lệ.", "Volo.Abp.Identity:InvalidUserName": "Tên người dùng '{0}' không hợp lệ, chỉ có thể chứa chữ cái hoặc chữ số.", + "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "Tên người dùng '{0}' không hợp lệ, Bạn không thể sử dụng email của người dùng khác làm tên người dùng của mình.", "Volo.Abp.Identity:LoginAlreadyAssociated": "Một người dùng có thông tin đăng nhập này đã tồn tại.", "Volo.Abp.Identity:PasswordMismatch": "Mật khẩu không đúng.", "Volo.Abp.Identity:PasswordRequiresDigit": "Mật khẩu phải có ít nhất một chữ số ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/zh-Hans.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/zh-Hans.json index 095f5cef2f..df0183aa3f 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/zh-Hans.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/zh-Hans.json @@ -48,6 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "角色名 '{0}' 无效.", "Volo.Abp.Identity:InvalidToken": "token无效.", "Volo.Abp.Identity:InvalidUserName": "用户名 '{0}' 无效, 只能包含字母或数字.", + "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "用户名 '{0}' 无效, 不能使用其他用户的邮箱作为你的用户名.", "Volo.Abp.Identity:LoginAlreadyAssociated": "此登录名的用户已存在.", "Volo.Abp.Identity:PasswordMismatch": "密码错误.", "Volo.Abp.Identity:PasswordRequiresDigit": "密码至少包含一位数字 ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/zh-Hant.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/zh-Hant.json index 936ad985f6..1a88eb9c37 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/zh-Hant.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/zh-Hant.json @@ -48,6 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "角色名 '{0}' 無效.", "Volo.Abp.Identity:InvalidToken": "token無效.", "Volo.Abp.Identity:InvalidUserName": "使用者名稱 '{0}' 無效, 只能包含字母或數字.", + "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "使用者名稱 '{0}' 無效, 不能使用其他使用者的電子信箱作為你的使用者名稱.", "Volo.Abp.Identity:LoginAlreadyAssociated": "此登入名的使用者已存在.", "Volo.Abp.Identity:PasswordMismatch": "密碼錯誤.", "Volo.Abp.Identity:PasswordRequiresDigit": "密碼至少包含一位數字 ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/AbpIdentityUserValidator.cs b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/AbpIdentityUserValidator.cs new file mode 100644 index 0000000000..e4b7217037 --- /dev/null +++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/AbpIdentityUserValidator.cs @@ -0,0 +1,48 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Identity; +using Microsoft.Extensions.Localization; +using Volo.Abp.Identity.Localization; + +namespace Volo.Abp.Identity +{ + public class AbpIdentityUserValidator : IUserValidator + { + protected IStringLocalizer Localizer { get; } + + public AbpIdentityUserValidator(IStringLocalizer localizer) + { + Localizer = localizer; + } + + public virtual async Task ValidateAsync(UserManager manager, IdentityUser user) + { + var describer = new IdentityErrorDescriber(); + + Check.NotNull(manager, nameof(manager)); + Check.NotNull(user, nameof(user)); + + var errors = new List(); + + var userName = await manager.GetUserNameAsync(user); + if (userName == null) + { + errors.Add(describer.InvalidUserName(null)); + } + else + { + var owner = await manager.FindByEmailAsync(userName); + if (owner != null && !string.Equals(await manager.GetUserIdAsync(owner), await manager.GetUserIdAsync(user))) + { + errors.Add(new IdentityError + { + Code = "InvalidUserName", + Description = Localizer["Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername", userName] + }); + } + } + + return errors.Count > 0 ? IdentityResult.Failed(errors.ToArray()) : IdentityResult.Success; + } + } +} diff --git a/modules/identity/test/Volo.Abp.Identity.AspNetCore.Tests/Volo/Abp/Identity/AspNetCore/AbpIdentityUserValidator_Tests.cs b/modules/identity/test/Volo.Abp.Identity.AspNetCore.Tests/Volo/Abp/Identity/AspNetCore/AbpIdentityUserValidator_Tests.cs new file mode 100644 index 0000000000..105ce166d8 --- /dev/null +++ b/modules/identity/test/Volo.Abp.Identity.AspNetCore.Tests/Volo/Abp/Identity/AspNetCore/AbpIdentityUserValidator_Tests.cs @@ -0,0 +1,36 @@ +using System; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.Extensions.Localization; +using Shouldly; +using Volo.Abp.Identity.Localization; +using Xunit; + +namespace Volo.Abp.Identity.AspNetCore; + +public class AbpIdentityUserValidator_Tests : AbpIdentityAspNetCoreTestBase +{ + private readonly IdentityUserManager _identityUserManager; + private readonly IStringLocalizer Localizer; + + public AbpIdentityUserValidator_Tests() + { + _identityUserManager = GetRequiredService(); + Localizer = GetRequiredService>(); + } + + [Fact] + public async Task Test() + { + var user1 = new IdentityUser(Guid.NewGuid(), "user1", "user1@volosoft.com"); + var identityResult = await _identityUserManager.CreateAsync(user1); + identityResult.Succeeded.ShouldBeTrue(); + + var user2 = new IdentityUser(Guid.NewGuid(), "user1@volosoft.com", "user2@volosoft.com"); + identityResult = await _identityUserManager.CreateAsync(user2); + identityResult.Succeeded.ShouldBeFalse(); + identityResult.Errors.Count().ShouldBe(1); + identityResult.Errors.First().Code.ShouldBe("InvalidUserName"); + identityResult.Errors.First().Description.ShouldBe(Localizer["Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername", "user1@volosoft.com"]); + } +} From 1420b53e262b7b7e80007952c9714c9e384cbe99 Mon Sep 17 00:00:00 2001 From: maliming Date: Fri, 28 Jul 2023 11:42:25 +0800 Subject: [PATCH 02/39] Update AbpIdentityUserValidator_Tests.cs --- .../Abp/Identity/AspNetCore/AbpIdentityUserValidator_Tests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/identity/test/Volo.Abp.Identity.AspNetCore.Tests/Volo/Abp/Identity/AspNetCore/AbpIdentityUserValidator_Tests.cs b/modules/identity/test/Volo.Abp.Identity.AspNetCore.Tests/Volo/Abp/Identity/AspNetCore/AbpIdentityUserValidator_Tests.cs index 105ce166d8..ac20b4894c 100644 --- a/modules/identity/test/Volo.Abp.Identity.AspNetCore.Tests/Volo/Abp/Identity/AspNetCore/AbpIdentityUserValidator_Tests.cs +++ b/modules/identity/test/Volo.Abp.Identity.AspNetCore.Tests/Volo/Abp/Identity/AspNetCore/AbpIdentityUserValidator_Tests.cs @@ -20,7 +20,7 @@ public class AbpIdentityUserValidator_Tests : AbpIdentityAspNetCoreTestBase } [Fact] - public async Task Test() + public async Task Can_Not_Use_Another_Users_Email_As_Your_Username_Test() { var user1 = new IdentityUser(Guid.NewGuid(), "user1", "user1@volosoft.com"); var identityResult = await _identityUserManager.CreateAsync(user1); From aa2a6020089f7d04a21da302a3fb46cc9245de5c Mon Sep 17 00:00:00 2001 From: maliming Date: Fri, 28 Jul 2023 12:55:44 +0800 Subject: [PATCH 03/39] Update localization texts. --- .../Volo/Abp/Identity/Localization/ar.json | 2 +- .../Volo/Abp/Identity/Localization/cs.json | 2 +- .../Volo/Abp/Identity/Localization/de.json | 2 +- .../Volo/Abp/Identity/Localization/el.json | 2 +- .../Volo/Abp/Identity/Localization/en-GB.json | 2 +- .../Volo/Abp/Identity/Localization/en.json | 2 +- .../Volo/Abp/Identity/Localization/es.json | 2 +- .../Volo/Abp/Identity/Localization/fa.json | 2 +- .../Volo/Abp/Identity/Localization/fi.json | 2 +- .../Volo/Abp/Identity/Localization/fr.json | 2 +- .../Volo/Abp/Identity/Localization/hi.json | 2 +- .../Volo/Abp/Identity/Localization/hr.json | 2 +- .../Volo/Abp/Identity/Localization/hu.json | 2 +- .../Volo/Abp/Identity/Localization/is.json | 2 +- .../Volo/Abp/Identity/Localization/it.json | 2 +- .../Volo/Abp/Identity/Localization/nl.json | 2 +- .../Volo/Abp/Identity/Localization/pl-PL.json | 2 +- .../Volo/Abp/Identity/Localization/pt-BR.json | 2 +- .../Volo/Abp/Identity/Localization/ro-RO.json | 2 +- .../Volo/Abp/Identity/Localization/ru.json | 2 +- .../Volo/Abp/Identity/Localization/sk.json | 2 +- .../Volo/Abp/Identity/Localization/sl.json | 2 +- .../Volo/Abp/Identity/Localization/tr.json | 2 +- .../Volo/Abp/Identity/Localization/vi.json | 2 +- .../Volo/Abp/Identity/Localization/zh-Hans.json | 2 +- .../Volo/Abp/Identity/Localization/zh-Hant.json | 2 +- .../Volo/Abp/Identity/AbpIdentityUserValidator.cs | 2 +- 27 files changed, 27 insertions(+), 27 deletions(-) diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ar.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ar.json index 7985177c6e..39c55dfb7c 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ar.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ar.json @@ -48,7 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "اسم الدور '{0}' غير صالح.", "Volo.Abp.Identity:InvalidToken": "غير صالح token.", "Volo.Abp.Identity:InvalidUserName": "اسم المستخدم '{0}' غير صالح ، يمكن أن يحتوي على أحرف أو أرقام فقط.", - "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "لااسم المستخدم '{0}' غير صالح ، لا يمكنك استخدام البريد الإلكتروني لمستخدم آخر كاسم المستخدم الخاص بك.", + "InvalidUserName": "لااسم المستخدم '{0}' غير صالح .", "Volo.Abp.Identity:LoginAlreadyAssociated": "يوجد مستخدم لديه معلومات تسجيل الدخول هذه بالفعل.", "Volo.Abp.Identity:PasswordMismatch": "كلمة مرور غير صحيحة.", "Volo.Abp.Identity:PasswordRequiresDigit": "يجب أن تحتوي كلمات المرور على رقم واحد على الأقل ('0' - '9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/cs.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/cs.json index db8eef485f..87d0b79066 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/cs.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/cs.json @@ -48,7 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "Role '{0}' je neplatná.", "Volo.Abp.Identity:InvalidToken": "Neplatný token.", "Volo.Abp.Identity:InvalidUserName": "Uživatelské jméno '{0}' je neplatné, může obsahovat pouze písmena a číslice.", - "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "Uživatelské jméno '{0}' je neplatné, Nemůžete použít email jiného uživatele jako své uživatelské jméno.", + "InvalidUserName": "Uživatelské jméno '{0}' je neplatné.", "Volo.Abp.Identity:LoginAlreadyAssociated": "Uživatel s tímto přihlášením již existuje.", "Volo.Abp.Identity:PasswordMismatch": "Chybné heslo.", "Volo.Abp.Identity:PasswordRequiresDigit": "Hesla musí obsahovat alespoň jednu číslici ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/de.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/de.json index 10b056e9da..841752f211 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/de.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/de.json @@ -48,7 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "Der Rollenname '{0}' ist ungültig.", "Volo.Abp.Identity:InvalidToken": "Ungültiger Token.", "Volo.Abp.Identity:InvalidUserName": "Der Benutzername '{0}' ist ungültig und darf nur Buchstaben oder Ziffern enthalten.", - "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "Der Benutzername '{0}' ist ungültig, Sie können nicht die E-Mail-Adresse eines anderen Benutzers als Ihren Benutzernamen verwenden.", + "InvalidUserName": "Der Benutzername '{0}' ist ungültig.", "Volo.Abp.Identity:LoginAlreadyAssociated": "Ein Benutzer mit diesem Login existiert bereits.", "Volo.Abp.Identity:PasswordMismatch": "Falsches Passwort.", "Volo.Abp.Identity:PasswordRequiresDigit": "Passwörter müssen mindestens eine Ziffer haben ('0' - '9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/el.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/el.json index f2cf0e2d81..9316a29d39 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/el.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/el.json @@ -47,7 +47,7 @@ "Volo.Abp.Identity:InvalidRoleName": "Το όνομα ρόλου '{0}' δεν είναι έγκυρο.", "Volo.Abp.Identity:InvalidToken": "Μη έγκυρο διακριτικό.", "Volo.Abp.Identity:InvalidUserName": "Το όνομα χρήστη '{0}' δεν είναι έγκυρο, μπορεί να περιέχει μόνο γράμματα ή ψηφία.", - "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "Το όνομα χρήστη '{0}' δεν είναι έγκυρο, Δεν μπορείτε να χρησιμοποιήσετε το email ενός άλλου χρήστη ως όνομα χρήστη.", + "InvalidUserName": "Το όνομα χρήστη '{0}' δεν είναι έγκυρο.", "Volo.Abp.Identity:LoginAlreadyAssociated": "Ένας χρήστης με αυτήν τη σύνδεση υπάρχει ήδη.", "Volo.Abp.Identity:PasswordMismatch": "Λάθος κωδικός.", "Volo.Abp.Identity:PasswordRequiresDigit": "Οι κωδικοί πρόσβασης πρέπει να έχουν τουλάχιστον ένα ψηφίο ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/en-GB.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/en-GB.json index 5a94e0f816..15e534ea67 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/en-GB.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/en-GB.json @@ -47,7 +47,7 @@ "Volo.Abp.Identity:InvalidRoleName": "Role name '{0}' is invalid.", "Volo.Abp.Identity:InvalidToken": "Invalid token.", "Volo.Abp.Identity:InvalidUserName": "Username '{0}' is invalid, it should only contain letters or digits.", - "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "Username '{0}' is invalid, You cannot use another user's email as your Username.", + "InvalidUserName": "Username '{0}' is invalid.", "Volo.Abp.Identity:LoginAlreadyAssociated": "A user with this login already exists.", "Volo.Abp.Identity:PasswordMismatch": "Incorrect password.", "Volo.Abp.Identity:PasswordRequiresDigit": "Passwords must have at least one digit ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/en.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/en.json index 738156140e..6de7c220e2 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/en.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/en.json @@ -48,7 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "Role name '{0}' is invalid.", "Volo.Abp.Identity:InvalidToken": "Invalid token.", "Volo.Abp.Identity:InvalidUserName": "Username '{0}' is invalid, can only contain letters or digits.", - "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "Username '{0}' is invalid, You cannot use another user's email as your Username.", + "InvalidUserName": "Username '{0}' is invalid.", "Volo.Abp.Identity:LoginAlreadyAssociated": "A user with this login already exists.", "Volo.Abp.Identity:PasswordMismatch": "Incorrect password.", "Volo.Abp.Identity:PasswordRequiresDigit": "Passwords must have at least one digit ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/es.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/es.json index 3e0cbe0abc..c70078845c 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/es.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/es.json @@ -48,7 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "El nombre de rol '{0}' no es válido.", "Volo.Abp.Identity:InvalidToken": "token no válido", "Volo.Abp.Identity:InvalidUserName": "Nombre de usuario '{0}' no es válido. Sólo puede contener letras o dígitos", - "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "Nombre de usuario '{0}' no es válido. No puedes usar el e-mail de otro usuario como tu nombre de usuario.", + "InvalidUserName": "Nombre de usuario '{0}' no es válido.", "Volo.Abp.Identity:LoginAlreadyAssociated": "Usuario con este inicio de sesión en uso.", "Volo.Abp.Identity:PasswordMismatch": "Contraseña incorrecta.", "Volo.Abp.Identity:PasswordRequiresDigit": "Contraseñas deben tener al menos un dígito ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/fa.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/fa.json index a0c1f743f9..f349f080af 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/fa.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/fa.json @@ -47,7 +47,7 @@ "Volo.Abp.Identity:InvalidRoleName": "عنوان نقش/وظیفه {0} نامعتبر است.", "Volo.Abp.Identity:InvalidToken": "گذرواژه وارد شده معتبر نیست.", "Volo.Abp.Identity:InvalidUserName": "نام کاربری '{0}' نامعتبر است، نام کاربری فقط می تواند شامل حروف یا ارقام باشد.", - "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "شما نمی توانید از ایمیل کاربر دیگری به عنوان نام کاربری خود استفاده کنید.", + "InvalidUserName": "ام کاربری '{0}' نامعتبر است", "Volo.Abp.Identity:LoginAlreadyAssociated": "یک کاربر با این نام کاربری از قبل موجود می باشد.", "Volo.Abp.Identity:PasswordMismatch": "گذرواژه اشتباه است.", "Volo.Abp.Identity:PasswordRequiresDigit": "گذرواژه ها باید حداقل یک رقم داشته باشند ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/fi.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/fi.json index ad4032eeb6..6b133481e7 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/fi.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/fi.json @@ -48,7 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "Roolin nimi {0} on virheellinen.", "Volo.Abp.Identity:InvalidToken": "Virheellinen tunnus.", "Volo.Abp.Identity:InvalidUserName": "Käyttäjätunnus {0} on virheellinen, voi sisältää vain kirjaimia tai numeroita.", - "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "Käyttäjätunnus {0} on virheellinen, Et voi käyttää toisen käyttäjän sähköpostiosoitetta käyttäjänimenä.", + "InvalidUserName": "Käyttäjätunnus {0} on virheellinen.", "Volo.Abp.Identity:LoginAlreadyAssociated": "Käyttäjä, jolla on tämä sisäänkirjautuminen, on jo olemassa.", "Volo.Abp.Identity:PasswordMismatch": "Väärä salasana.", "Volo.Abp.Identity:PasswordRequiresDigit": "Salasanoissa on oltava vähintään yksi numero ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/fr.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/fr.json index b4fe67f76b..c9d1bfba7b 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/fr.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/fr.json @@ -48,7 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "Le nom de rôle '{0}' n’est pas valide.", "Volo.Abp.Identity:InvalidToken": "Jeton non valide.", "Volo.Abp.Identity:InvalidUserName": "Le nom d’utilisateur '{0}' n’est pas valide, ne peut contenir que des lettres ou des chiffres.", - "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "Le nom d’utilisateur '{0}' n’est pas valide,Vous ne pouvez pas utiliser l’e-mail d’un autre utilisateur comme nom d’utilisateur.", + "InvalidUserName": "Le nom d’utilisateur '{0}' n’est pas valide.", "Volo.Abp.Identity:LoginAlreadyAssociated": "Un utilisateur avec cette connexion existe déjà.", "Volo.Abp.Identity:PasswordMismatch": "Mot de passe incorrect.", "Volo.Abp.Identity:PasswordRequiresDigit": "Les mots de passe doivent avoir au moins un chiffre ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/hi.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/hi.json index c6717ed5ac..7155c3bf58 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/hi.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/hi.json @@ -48,7 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "भूमिका नाम '{0}' अमान्य है।", "Volo.Abp.Identity:InvalidToken": "अमान्य टोकन।", "Volo.Abp.Identity:InvalidUserName": "उपयोगकर्ता नाम '{0}' अमान्य है, इसमें केवल अक्षर या अंक हो सकते हैं।", - "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "उपयोगकर्ता नाम '{0}' अमान्य है, आप दूसरे उपयोगकर्ता का ईमेल नाम उपयोग नहीं कर सकते।", + "InvalidUserName": "उपयोगकर्ता नाम '{0}' अमान्य है", "Volo.Abp.Identity:LoginAlreadyAssociated": "इस लॉगिन वाला उपयोगकर्ता पहले से मौजूद है।", "Volo.Abp.Identity:PasswordMismatch": "गलत पासवर्ड।", "Volo.Abp.Identity:PasswordRequiresDigit": "पासवर्ड में कम से कम एक अंक ('0'-'9') होना चाहिए।", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/hr.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/hr.json index 4890e944ea..cdea4c02f5 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/hr.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/hr.json @@ -48,7 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "Naziv uloge '{0}' nije valjan.", "Volo.Abp.Identity:InvalidToken": "Pogrešan token.", "Volo.Abp.Identity:InvalidUserName": "Korisničko ime '{0}' nije važeće, može sadržavati samo slova ili znamenke.", - "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "Korisničko ime '{0}' nije važeće, Ne možete koristiti e-poštu drugog korisnika kao svoje korisničko ime.", + "InvalidUserName": "Korisničko ime '{0}' nije važeće.", "Volo.Abp.Identity:LoginAlreadyAssociated": "Korisnik s ovom prijavom već postoji.", "Volo.Abp.Identity:PasswordMismatch": "Netočna lozinka.", "Volo.Abp.Identity:PasswordRequiresDigit": "Lozinke moraju imati najmanje jednu znamenku ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/hu.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/hu.json index 2bbfeddcbf..fc72ed1e0f 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/hu.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/hu.json @@ -48,7 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "'{0}' szerepkör név érvénytelen.", "Volo.Abp.Identity:InvalidToken": "Érvénytelen token.", "Volo.Abp.Identity:InvalidUserName": "'{0}' felhasználónév érvénytelen, csak betűket és számokat tartalmazhat.", - "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "'{0}' felhasználónév érvénytelen, Nem használhatja más felhasználó email címét felhasználónévként.", + "InvalidUserName": "'{0}' felhasználónév érvénytelen.", "Volo.Abp.Identity:LoginAlreadyAssociated": "Az ilyen bejelentkezéssel rendelkező felhasználó már létezik.", "Volo.Abp.Identity:PasswordMismatch": "Érvénytelen jelszó.", "Volo.Abp.Identity:PasswordRequiresDigit": "A jelszavaknak legalább egy számjegyet kell rendelkezniük ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/is.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/is.json index 15a741a268..a30d47f4c0 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/is.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/is.json @@ -48,7 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "Hlutverkanafnið '{0}' er ógilt.", "Volo.Abp.Identity:InvalidToken": "Ógilt token.", "Volo.Abp.Identity:InvalidUserName": "Notandanafnið '{0}' er ógilt, getur aðeins innihaldið bókstafi eða tölustafi.", - "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "Notandanafnið '{0}' er ógilt, Þú getur ekki notað netfang annars notanda sem notendanafn.", + "InvalidUserName": "Notandanafnið '{0}' er ógilt.", "Volo.Abp.Identity:LoginAlreadyAssociated": "Notandi með þessa innskráningu er þegar til.", "Volo.Abp.Identity:PasswordMismatch": "Rangt lykilorð.", "Volo.Abp.Identity:PasswordRequiresDigit": "Lykilorð verða að hafa að minnsta kosti einn staf ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/it.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/it.json index eaf566930b..67a0cbeb36 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/it.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/it.json @@ -48,7 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "Il nome del ruolo '{0}' non è valido.", "Volo.Abp.Identity:InvalidToken": "Token non valido.", "Volo.Abp.Identity:InvalidUserName": "Il nome utente '{0}' non è valido, può contenere solo lettere o cifre.", - "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "Il nome utente '{0}' non è valido, Non puoi utilizzare l'email di un altro utente come nome utente.", + "InvalidUserName": "Il nome utente '{0}' non è valido.", "Volo.Abp.Identity:LoginAlreadyAssociated": "Esiste già un utente con questo account.", "Volo.Abp.Identity:PasswordMismatch": "Password errata.", "Volo.Abp.Identity:PasswordRequiresDigit": "La password deve contenere almeno una cifra ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/nl.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/nl.json index 79ee163cd2..139fa50107 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/nl.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/nl.json @@ -48,7 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "Rol naam '{0}' is ongeldig.", "Volo.Abp.Identity:InvalidToken": "Ongeldig token.", "Volo.Abp.Identity:InvalidUserName": "Gebruikersnaam '{0}' is ongeldig, mag alleen letters of cijfers bevatten.", - "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "Gebruikersnaam '{0}' is ongeldig, U kunt het e-mailadres van een andere gebruiker niet als uw gebruikersnaam gebruiken.", + "InvalidUserName": "Gebruikersnaam '{0}' is ongeldig.", "Volo.Abp.Identity:LoginAlreadyAssociated": "Er bestaat al een gebruiker met deze login.", "Volo.Abp.Identity:PasswordMismatch": "Incorrect wachtwoord.", "Volo.Abp.Identity:PasswordRequiresDigit": "Wachtwoorden moeten minimaal één cijfer bevatten ('0' - '9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/pl-PL.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/pl-PL.json index 36297c453a..dabf2655c4 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/pl-PL.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/pl-PL.json @@ -48,7 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "Rola '{0}' jest niepoprawna.", "Volo.Abp.Identity:InvalidToken": "Niepoprawny token.", "Volo.Abp.Identity:InvalidUserName": "Nazwa użytkownika '{0}' jest niepoprawna, może zawierać tylko litery i cyfry.", - "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "Nazwa użytkownika '{0}' jest niepoprawna, Nie możesz użyć adresu e-mail innego użytkownika jako swojej nazwy użytkownika.", + "InvalidUserName": "Nazwa użytkownika '{0}' jest niepoprawna.", "Volo.Abp.Identity:LoginAlreadyAssociated": "Użytkownik o tym loginie już istnieje.", "Volo.Abp.Identity:PasswordMismatch": "Niepoprawne hasło.", "Volo.Abp.Identity:PasswordRequiresDigit": "Hasło musi zawierać przynajmniej jedną cyfrę ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/pt-BR.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/pt-BR.json index 22936d80b1..999a9f19bd 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/pt-BR.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/pt-BR.json @@ -48,7 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "Perfil '{0}' inválido.", "Volo.Abp.Identity:InvalidToken": "Token inválido.", "Volo.Abp.Identity:InvalidUserName": "Usuário '{0}' é inválido, somente pode conter letras ou números.", - "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "Usuário '{0}' é inválido, Você não pode usar o e-mail de outro usuário como seu nome de usuário.", + "InvalidUserName": "Usuário '{0}' é inválido.", "Volo.Abp.Identity:LoginAlreadyAssociated": "Um usuário com este login já existe.", "Volo.Abp.Identity:PasswordMismatch": "Senha incorreta.", "Volo.Abp.Identity:PasswordRequiresDigit": "Senhas devem possuir pelo menos um dígito ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ro-RO.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ro-RO.json index ec0e22eb39..573331d4f3 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ro-RO.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ro-RO.json @@ -48,7 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "Numele de rol '{0}' este invalid.", "Volo.Abp.Identity:InvalidToken": "Invalid token.", "Volo.Abp.Identity:InvalidUserName": "Numele de utilizator '{0}' este invalid, poate conţine doar litere şi cifre.", - "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "Numele de utilizator '{0}' este invalid, Nu puteţi folosi adresa de email a altui utilizator ca nume de utilizator.", + "InvalidUserName": "Numele de utilizator '{0}' este invalid.", "Volo.Abp.Identity:LoginAlreadyAssociated": "Un utilizator cu această autentificare există deja.", "Volo.Abp.Identity:PasswordMismatch": "Parolă incorectă.", "Volo.Abp.Identity:PasswordRequiresDigit": "Parolele trebuie să conţină cel puţin o cifră ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ru.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ru.json index d584a5ac3d..7bd8da5955 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ru.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ru.json @@ -48,7 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "Имя роли '{0}' недопустимо.", "Volo.Abp.Identity:InvalidToken": "Недопустимый маркер.", "Volo.Abp.Identity:InvalidUserName": "Имя пользователя '{0}' недопустимо и может содержать только буквы или цифры.", - "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "Имя пользователя '{0}' недопустимо Вы не можете использовать электронную почту другого пользователя в качестве своего имени пользователя.", + "InvalidUserName": "Имя пользователя '{0}' недопустимо.", "Volo.Abp.Identity:LoginAlreadyAssociated": "Пользователь с таким логином уже существует.", "Volo.Abp.Identity:PasswordMismatch": "Неверный пароль.", "Volo.Abp.Identity:PasswordRequiresDigit": "Пароль должен содержать по крайней мере одну цифру.", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/sk.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/sk.json index 7083f2f494..520377210d 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/sk.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/sk.json @@ -48,7 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "Názov roly '{0}' je neplatný.", "Volo.Abp.Identity:InvalidToken": "Neplatný token.", "Volo.Abp.Identity:InvalidUserName": "Používateľské meno '{0}' je neplatné, môže obsahovať len písmená alebo číslice.", - "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "Používateľské meno '{0}' je neplatné, Nemôžete použiť email iného používateľa ako svoje používateľské meno.", + "InvalidUserName": "Používateľské meno '{0}' je neplatné.", "Volo.Abp.Identity:LoginAlreadyAssociated": "Používateľ s týmto prihlasovacím menom už existuje.", "Volo.Abp.Identity:PasswordMismatch": "Nesprávne heslo.", "Volo.Abp.Identity:PasswordRequiresDigit": "Heslá musia obsahovať aspoň jednu číslicu ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/sl.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/sl.json index ce58ebdcf6..0fec5bbd4d 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/sl.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/sl.json @@ -48,7 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "Naziv vloge '{0}' ni veljaven.", "Volo.Abp.Identity:InvalidToken": "Neveljaven žeton.", "Volo.Abp.Identity:InvalidUserName": "Uporabniško ime '{0}' ni veljavno, vsebuje lahko le črke in številke.", - "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "Uporabniško ime '{0}' ni veljavno, Ne morete uporabiti e-poštnega naslova drugega uporabnika kot svojega uporabniškega imena.", + "InvalidUserName": "Uporabniško ime '{0}' ni veljavno.", "Volo.Abp.Identity:LoginAlreadyAssociated": "Uporabnik s to prijavo že obstaja.", "Volo.Abp.Identity:PasswordMismatch": "Nepravilno geslo.", "Volo.Abp.Identity:PasswordRequiresDigit": "Gesla morajo imeti vsaj eno številko ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/tr.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/tr.json index 83e21f3c58..6a8b5f04c7 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/tr.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/tr.json @@ -48,7 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "'{0}' rol ismi geçersizdir.", "Volo.Abp.Identity:InvalidToken": "Geçersiz token.", "Volo.Abp.Identity:InvalidUserName": "'{0}' kullanıcı adı geçersiz, sadece harf ve rakamlardan oluşmalı.", - "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "'{0}' kullanıcı adı geçersiz, Başka bir kullanıcının e-posta adresini kullanıcı adı olarak kullanamazsınız.", + "InvalidUserName": "'{0}' kullanıcı adı geçersiz.", "Volo.Abp.Identity:LoginAlreadyAssociated": "Bu giriş bilgilerine sahip bir kullanıcı zaten var.", "Volo.Abp.Identity:PasswordMismatch": "Hatalı şifre.", "Volo.Abp.Identity:PasswordRequiresDigit": "Şifre en az bir sayı içermeli ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/vi.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/vi.json index f17fcbfe0d..c649637b4d 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/vi.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/vi.json @@ -48,7 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "Tên người dùng '{0}' Không hợp lệ.", "Volo.Abp.Identity:InvalidToken": "Token không hợp lệ.", "Volo.Abp.Identity:InvalidUserName": "Tên người dùng '{0}' không hợp lệ, chỉ có thể chứa chữ cái hoặc chữ số.", - "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "Tên người dùng '{0}' không hợp lệ, Bạn không thể sử dụng email của người dùng khác làm tên người dùng của mình.", + "InvalidUserName": "Tên người dùng '{0}' không hợp lệ.", "Volo.Abp.Identity:LoginAlreadyAssociated": "Một người dùng có thông tin đăng nhập này đã tồn tại.", "Volo.Abp.Identity:PasswordMismatch": "Mật khẩu không đúng.", "Volo.Abp.Identity:PasswordRequiresDigit": "Mật khẩu phải có ít nhất một chữ số ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/zh-Hans.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/zh-Hans.json index df0183aa3f..165ba09b41 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/zh-Hans.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/zh-Hans.json @@ -48,7 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "角色名 '{0}' 无效.", "Volo.Abp.Identity:InvalidToken": "token无效.", "Volo.Abp.Identity:InvalidUserName": "用户名 '{0}' 无效, 只能包含字母或数字.", - "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "用户名 '{0}' 无效, 不能使用其他用户的邮箱作为你的用户名.", + "InvalidUserName": "用户名 '{0}' 无效.", "Volo.Abp.Identity:LoginAlreadyAssociated": "此登录名的用户已存在.", "Volo.Abp.Identity:PasswordMismatch": "密码错误.", "Volo.Abp.Identity:PasswordRequiresDigit": "密码至少包含一位数字 ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/zh-Hant.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/zh-Hant.json index 1a88eb9c37..d12c44890a 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/zh-Hant.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/zh-Hant.json @@ -48,7 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "角色名 '{0}' 無效.", "Volo.Abp.Identity:InvalidToken": "token無效.", "Volo.Abp.Identity:InvalidUserName": "使用者名稱 '{0}' 無效, 只能包含字母或數字.", - "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "使用者名稱 '{0}' 無效, 不能使用其他使用者的電子信箱作為你的使用者名稱.", + "InvalidUserName": "使用者名稱 '{0}' 無效.", "Volo.Abp.Identity:LoginAlreadyAssociated": "此登入名的使用者已存在.", "Volo.Abp.Identity:PasswordMismatch": "密碼錯誤.", "Volo.Abp.Identity:PasswordRequiresDigit": "密碼至少包含一位數字 ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/AbpIdentityUserValidator.cs b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/AbpIdentityUserValidator.cs index e4b7217037..c7507c6e36 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/AbpIdentityUserValidator.cs +++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/AbpIdentityUserValidator.cs @@ -37,7 +37,7 @@ namespace Volo.Abp.Identity errors.Add(new IdentityError { Code = "InvalidUserName", - Description = Localizer["Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername", userName] + Description = Localizer["InvalidUserName", userName] }); } } From f231792aefa6ec785686e79cb8cf00f8f3093b06 Mon Sep 17 00:00:00 2001 From: maliming Date: Fri, 28 Jul 2023 14:02:12 +0800 Subject: [PATCH 04/39] Update AbpIdentityUserValidator_Tests.cs --- .../Abp/Identity/AspNetCore/AbpIdentityUserValidator_Tests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/identity/test/Volo.Abp.Identity.AspNetCore.Tests/Volo/Abp/Identity/AspNetCore/AbpIdentityUserValidator_Tests.cs b/modules/identity/test/Volo.Abp.Identity.AspNetCore.Tests/Volo/Abp/Identity/AspNetCore/AbpIdentityUserValidator_Tests.cs index ac20b4894c..ef9cfb53d3 100644 --- a/modules/identity/test/Volo.Abp.Identity.AspNetCore.Tests/Volo/Abp/Identity/AspNetCore/AbpIdentityUserValidator_Tests.cs +++ b/modules/identity/test/Volo.Abp.Identity.AspNetCore.Tests/Volo/Abp/Identity/AspNetCore/AbpIdentityUserValidator_Tests.cs @@ -31,6 +31,6 @@ public class AbpIdentityUserValidator_Tests : AbpIdentityAspNetCoreTestBase identityResult.Succeeded.ShouldBeFalse(); identityResult.Errors.Count().ShouldBe(1); identityResult.Errors.First().Code.ShouldBe("InvalidUserName"); - identityResult.Errors.First().Description.ShouldBe(Localizer["Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername", "user1@volosoft.com"]); + identityResult.Errors.First().Description.ShouldBe(Localizer["InvalidUserName", "user1@volosoft.com"]); } } From 9c6529e93f0e11e4a555264cb21f8ed694949456 Mon Sep 17 00:00:00 2001 From: Sinan997 Date: Fri, 28 Jul 2023 14:59:40 +0300 Subject: [PATCH 05/39] show password directive test and document --- docs/en/UI/Angular/Show-Password-Directive.md | 52 +++++++++++++++ .../Angular/images/showPasswordDirective1.png | Bin 0 -> 3707 bytes .../Angular/images/showPasswordDirective2.png | Bin 0 -> 3932 bytes .../lib/tests/show-password-directive.spec.ts | 59 ++++++++++++++++++ 4 files changed, 111 insertions(+) create mode 100644 docs/en/UI/Angular/Show-Password-Directive.md create mode 100644 docs/en/UI/Angular/images/showPasswordDirective1.png create mode 100644 docs/en/UI/Angular/images/showPasswordDirective2.png create mode 100644 npm/ng-packs/packages/core/src/lib/tests/show-password-directive.spec.ts diff --git a/docs/en/UI/Angular/Show-Password-Directive.md b/docs/en/UI/Angular/Show-Password-Directive.md new file mode 100644 index 0000000000..db54bcdd76 --- /dev/null +++ b/docs/en/UI/Angular/Show-Password-Directive.md @@ -0,0 +1,52 @@ +# Show Password Directive + +In password input, text can be shown easily via changing input type attribute to `text`. To make this even easier, you can use the `ShowPasswordDirective` which has been exposed by the `@abp/ng.core` package. + + +## Getting Started + +In order to use the `ShowPasswordDirective` in an HTML template, the **`CoreModule`** should be imported into your module like this: + +```ts +// ... +import { CoreModule } from '@abp/ng.core'; + +@NgModule({ + //... + imports: [..., CoreModule], +}) +export class MyFeatureModule {} +``` + +## Usage + +The `ShowPasswordDirective` is very easy to use. The directive's selector is **`abpShowPassword`**. By adding the `abpShowPassword` attribute to an input element, you can activate the `ShowPasswordDirective` for the input element. + +See an example usage: + +```ts +@Component({ + selector: 'test-component', + standalone: true, + template: ` +
+ + + icon +
+ ` +}) +export class TestComponent{ + showPassword = false; +} +``` + +The `abpShowPassword` attribute has been added to the `` element. Click icon to activate the `ShowPasswordDirective`. + +See the result: + +![Show Password directive](./images/showPasswordDirective1.png) + +To see password input click icon. + +![Show Password directive](./images/showPasswordDirective2.png) \ No newline at end of file diff --git a/docs/en/UI/Angular/images/showPasswordDirective1.png b/docs/en/UI/Angular/images/showPasswordDirective1.png new file mode 100644 index 0000000000000000000000000000000000000000..7b64be2b5f14c8e8affb7849331f0f5398188193 GIT binary patch literal 3707 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 YNubRLytJp=IDz)l)k46FG%?Tr1J+;SK>z>% literal 0 HcmV?d00001 diff --git a/docs/en/UI/Angular/images/showPasswordDirective2.png b/docs/en/UI/Angular/images/showPasswordDirective2.png new file mode 100644 index 0000000000000000000000000000000000000000..43199ffeaa2b1a813743599a1f74137404254ee0 GIT binary patch literal 3932 zcma)9c{r5c+aIzg+4mt!mWYsb)W|+)rYPB$3`(|;ol(-*X~w=Q5h457cP4u=XzW`m zG)N5D-pBWP|NOr1?{}{2dCqyx@|^qr-1j;6{fW8**So;L%K!p_F2MA)jX@wv7|^~; zM+3ZjGvwDnpo{b{?OXT!vwqE@JPEtm_-*kf;t{K<#)AlHnHH)73MMRNmwXoN`BRSd zjJid*^c_*jD+F7X50*?Z{x&|tx+PTL>je5@AKtn zGBQ$M)L5St=%BwP1k={m7Nv?1JsW0b#{gg2ns@$n@QqAiWrtn&qv&3{$cKry0t|tv ze<#!J674F&hczG_cHecZKa2?Vv9qB&xOIXorJnD}(os#xmi)7IjHA4cLv*~5no^FP zGc5(`N$y9*_p;L%ZM=<+v$MGEKK#!?uP{(j$Lw~l#p;UuavKV95!~ZWmlT6joJlD> z$JNT_Qlrke4 z#)_Yn70TN^TyvmC)^Pk@KXSX~BQOx^mjCC0>|NzR0Yg&e?H6)keas6B6XUK|$es1H z{=daJ<1bd)L#*K^D0g9*9Ue}2H8Tg}=X>`f>W(>BSPp!n+7pqTDe^S%4az0h{@i_j ziRN4|n$pvOa{#rt(nvn9a?;h5HoC9Y7SKXzZDi-UN;|hn!)uFZ^X?TkIHZ$&C8IrcW zR?Nk_`s>2G5Ap2E5#{1fY3=lTy-T}iKO)YIC{qT22E(=Xk5yBI(_=qIcRpx*HN`s@ zgw^PGEj(T4?j^c1$`R}-_v@ceOq1-1OL7~k_u${0l))NZMHKR(zZpeIOP@(@uBY|X zVc}@Lr!z=&3Q||8wTHISPtKmdJDvx2obSb*0W-eG;jy`%L-+0Kq6c0+J&_U;Pf-?E z-(rnkGR8CeA;*ZSCPf1!o(P^m>f98-;8yM|Y?$F8*jiuj)dZ-Hg`w&+`PajNI$e3e zY9DaP)rAHQrQX{JhfY^69$ZTGDpcvq7MeC-O&3x;R=D7Qi4C7Kenc8^w}6)B|J=?@ zUlY_Cd;LI#8=7e;rV>@9WZZNU^uYS3hcs}OUQ2hTg1EbWJmDke*nTR%NFKdDp{q%L zy;v=5!|+K`t5T$yQzY*!I2_0<|-C>kG;c(dcVp z(TqlO0p`9T7PYBDKjUd*PHU5Y?Ld_j)EcHin{~53wNYwU|Ll0j`m;J6XF=T4jYhZT z`rf}Sj_(I&1_T9N03Y9*Rpv=bO!QpUM8vnOxxj-@ets(zuTeSQwVd(T#pR$s|NWwf zT()~b?PP|*He(YHibn`imrdOG;giQhV3BhLQk*Zq=qe;m_y9knGb%Xxn^Fb;b;VdQ(E z3FPY^w5EYng2pI+XyEiv))ZOkupf7q0|Itl&1O7C^3~$QQ{R==?|1l69og4LZADE3 zz9nyGmL+YDME9qDnm49R(@*!~qQ@&$I}M4sB-B4vGw#?^lp+QX>h?AhHNuuHO{?=+ z3uV3J#z*IEm-zpQHw{$MMz#cw$luDQ&rm77-Crn}Qj$FzCmU?843yBt<_uDSDC?EW zNeu9qEXIb;&t}31c14H%>|vWQFV9HZp>?`F-jn{DGy# zlfE&7#9Ytk2z$TGyy}rPzfM32J1^~Z`(%xsrn3|#s06AH)+s^a1BlX@SjH0vLQpW5 zc`V1_ubsZuQzp!Ee#4%`oDF^ymhH)=9JhX~5ctUZV~}N$YK7%-YM#JZ)XDoMvZpxL z9@`W;SdhlMM+hA*LZK^hj`9%Il;u;uj0MF$Bint6VXBL$&|UKNnzVYEWl7Rus@WcU zDe~~kr}TO-g(1l7Y5Av~X9-|KMuG>tb9*HM2S>e0o9U4>i?t11!tdM?*hyty_-UxB zV9gHA)G-)|a+qV7xX~KcoDDK}o!RVkKXEacCs`SP=W6dpVlGbD$xe;P|AuAT-um6m z>%z46?h+vE^Ka8tR2psQf_JDH#PABYI=aQI*JAr68^%?}V6IP?XxU#vn|gP}d�Y zx-=@ZKc@!UqB`SJS~_LXdsHc4kZavv)ya!NHN1YKx6!>ZL-8~2tgiLj$XwO;4d2+Ksk1Ka;xH8ZN3$6e-$NX3jNU>tlZ zQ4zb%Z~F#Oi;t_uFmlS1clM@ox8~DtyNp??q?Cu(Xb)zGy7Z^s^et7LP>40(j182Xjlu#7K|v}%u{U_&hCCOuTzgM(&s4_1Dys#{!414iZG}UF zRtzUsc~Bwr2Tv%xid7ipPLnh_+eL~+d5`xk2Sth5AnE!(hE}yJ!+aT;ZLP6uYij*D zbzLN3D@5sfNarK*@l%u8<)YY0E=vA9q@SeD0C;6`e`|bY+04es{Pt$PDj?TpQoAHP zXy$qVjjqNEx*xE=Xm>@vuh~?0_nhxW{%~$XG=^&x^VRqkiIvN7R?wrg zTzvfy_EjOQFRI&LO2WND!LRfj1XeKBj@k!(CvOurCEpU9JLJE_hfD=qAyAzsIyc0^ z4@3L|TWVLk)(@+Ot-L6{*95L@FA*&?Nbmf`fV;x0N84Rro^t8dk#JgaWlUxwaV%;fdRt0cIzjw`v++JMTNJ4&gZ?)2xP51m8SQ0zHm4)Tx?@- z0(r*{RmS0|)%iX4&dH^HY$4bhpC!NdSN23hRBMzJQjZRIB#sHu%eQD-=1|qZ2G!>e zuLZ}vf)=KGlM*lus(N3Guv5)=>zrJfd8@U2sSm% zKB@rOC=pkc*ftja%s}aUVOoc!?#~nfvXb~~vgW41dv7xPnU~3UX|Yn*hh`ddurcuu z?0ACavM=9b^v=n|URTK8?g9;p4*OufzOD7}+a+uZvA*ryo#!$cL-8U#v6~u_93+pM)@PVZhFKZ?&J1|(k3;aqTJif) zzhlq?Y(8)P8uAn(3JuK_L>c zjJq2d-D*_}tcU$l1>Wa%dN{rM+>Wqk(j~bD8R|G1jnw z`MCDZ@=)!+hCZ(R+0XZYB}6O%R#6?^v1)HWf0l`?81T6Y=mI@<6$%@5_J|p#eM>ps zI0gei1J*AznP~g#y!88)hlExH-%K4&(IGm@;fLbnm$?apyjeuv#aT08qHrpvk3CLO z?bVO3Dlf9ZH8@4`fkg-d?DP0r + + + `, + imports:[ShowPasswordDirective] +}) +class TestComponent { + showPassword:boolean = false +} + +describe('ShowPasswordDirective',()=>{ + let fixture: ComponentFixture;; + let des : DebugElement[]; + let desAll : DebugElement[]; + let bareInput; + + beforeEach(()=>{ + fixture = TestBed.configureTestingModule({ + imports: [ TestComponent ] + }).createComponent(TestComponent) + + fixture.detectChanges(); // initial binding + + // all elements with an attached HighlightDirective + des = fixture.debugElement.queryAll(By.directive(ShowPasswordDirective)); + + // all inputs includes nondirective + desAll = fixture.debugElement.queryAll(By.all()); + + // the input without the ShowPasswordDirective + bareInput = fixture.debugElement.query(By.css('input:not([abpShowPassword])')); + }) + + // color tests + it('should have three input has ShowPasswordDirective elements', () => { + expect(des.length).toBe(3); + }); + + test.each([[0,'text'],[1,'password'],[2,'text'],[3,'password']])('%p. input type must be %p)', (index,inpType) => { + const inputType = desAll[index].nativeElement.type; + expect(inputType).toBe(inpType); + }); + + it('should have three input has ShowPasswordDirective elements', () => { + let input = des[2].nativeElement + expect(input.type).toBe('password') + fixture.componentInstance.showPassword = true + fixture.detectChanges() + expect(input.type).toBe('text') + }); + }); \ No newline at end of file From 11f03b26ed02e28850e3e14081a37e607ec3ee1d Mon Sep 17 00:00:00 2001 From: Sinan997 Date: Sun, 30 Jul 2023 23:48:51 +0300 Subject: [PATCH 06/39] capsLock doc and test --- .../src/lib/tests/capsLock.directive.spec.ts | 58 +++++++++++++++++++ .../lib/tests/show-password-directive.spec.ts | 2 +- 2 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 npm/ng-packs/packages/core/src/lib/tests/capsLock.directive.spec.ts diff --git a/npm/ng-packs/packages/core/src/lib/tests/capsLock.directive.spec.ts b/npm/ng-packs/packages/core/src/lib/tests/capsLock.directive.spec.ts new file mode 100644 index 0000000000..17d50ba697 --- /dev/null +++ b/npm/ng-packs/packages/core/src/lib/tests/capsLock.directive.spec.ts @@ -0,0 +1,58 @@ +import { Component, DebugElement } from '@angular/core' +import { ComponentFixture, TestBed } from '@angular/core/testing' +import { TrackCapsLockDirective } from '../directives'; +import { By } from '@angular/platform-browser'; + +@Component({ + standalone:true, + template: ` + + `, + imports:[TrackCapsLockDirective] +}) +class TestComponent { + capsLock:boolean = false +} + +describe('TrackCapsLockDirective',()=>{ + let fixture: ComponentFixture;; + let des : DebugElement[]; + + beforeEach(()=>{ + fixture = TestBed.configureTestingModule({ + imports: [ TestComponent ] + }).createComponent(TestComponent); + + fixture.detectChanges(); + + des = fixture.debugElement.queryAll(By.directive(TrackCapsLockDirective)); + }); + + // tests + test.each(['keydown','keyup'])('is %p works when press capslock and is emit status', (eventName) => { + const event = new KeyboardEvent(eventName, { + key: 'CapsLock', + modifierCapsLock: true + }); + window.dispatchEvent(event); + fixture.detectChanges(); + expect(fixture.componentInstance.capsLock).toBe(true) + }); + + test.each(['keydown','keyup'])('is %p detect the change capslock is emit status', (eventName) => { + const trueEvent = new KeyboardEvent(eventName, { + key: 'CapsLock', + modifierCapsLock: true + }); + window.dispatchEvent(trueEvent); + fixture.detectChanges(); + expect(fixture.componentInstance.capsLock).toBe(true) + const falseEvent = new KeyboardEvent(eventName, { + key: 'CapsLock', + modifierCapsLock: false + }); + window.dispatchEvent(falseEvent); + fixture.detectChanges(); + expect(fixture.componentInstance.capsLock).toBe(false) + }); + }); \ No newline at end of file diff --git a/npm/ng-packs/packages/core/src/lib/tests/show-password-directive.spec.ts b/npm/ng-packs/packages/core/src/lib/tests/show-password-directive.spec.ts index 6b07997bc9..e1e9750995 100644 --- a/npm/ng-packs/packages/core/src/lib/tests/show-password-directive.spec.ts +++ b/npm/ng-packs/packages/core/src/lib/tests/show-password-directive.spec.ts @@ -39,7 +39,7 @@ describe('ShowPasswordDirective',()=>{ bareInput = fixture.debugElement.query(By.css('input:not([abpShowPassword])')); }) - // color tests + // tests it('should have three input has ShowPasswordDirective elements', () => { expect(des.length).toBe(3); }); From 3257c24d74186ebf1d62452b5b8e752c0201c726 Mon Sep 17 00:00:00 2001 From: Sinan997 Date: Sun, 30 Jul 2023 23:49:52 +0300 Subject: [PATCH 07/39] capsLock doc and test --- docs/en/UI/Angular/CapsLock.directive.md | 52 ++++++++++++++++++ .../UI/Angular/images/CapsLockDirective1.png | Bin 0 -> 2224 bytes .../UI/Angular/images/CapsLockDirective2.png | Bin 0 -> 4274 bytes 3 files changed, 52 insertions(+) create mode 100644 docs/en/UI/Angular/CapsLock.directive.md create mode 100644 docs/en/UI/Angular/images/CapsLockDirective1.png create mode 100644 docs/en/UI/Angular/images/CapsLockDirective2.png diff --git a/docs/en/UI/Angular/CapsLock.directive.md b/docs/en/UI/Angular/CapsLock.directive.md new file mode 100644 index 0000000000..4b92d61124 --- /dev/null +++ b/docs/en/UI/Angular/CapsLock.directive.md @@ -0,0 +1,52 @@ +# Show Password Directive + +In password inputs,You may want to show if Caps Lock is on. To make this even easier, you can use the `TrackCapsLockDirective` which has been exposed by the `@abp/ng.core` package. + + +## Getting Started + +In order to use the `TrackCapsLockDirective` in an HTML template, the **`CoreModule`** should be imported into your module like this: + +```ts +// ... +import { CoreModule } from '@abp/ng.core'; + +@NgModule({ + //... + imports: [..., CoreModule], +}) +export class MyFeatureModule {} +``` + +## Usage + +The `TrackCapsLockDirective` is very easy to use. The directive's selector is **`abpCapsLock`**. By adding the `abpCapsLock` event to an element, you can track the status of Caps Lock. U can use this to warn user + +See an example usage: + +```ts +@Component({ + selector: 'test-component', + standalone: true, + template: ` +
+ + + icon +
+ ` +}) +export class TestComponent{ + capsLock = false; +} +``` + +The `abpCapsLock` event has been added to the `` element. Press Caps Lock to activate the `TrackCapsLockDirective`. + +See the result: + +![Show Password directive](./images/CapsLockDirective1.png) + +To see Caps Lock icon press Caps Lock. + +![Show Password directive](./images/CapsLockDirective2.png) \ No newline at end of file diff --git a/docs/en/UI/Angular/images/CapsLockDirective1.png b/docs/en/UI/Angular/images/CapsLockDirective1.png new file mode 100644 index 0000000000000000000000000000000000000000..2f143d755fd2d331beed42c8ce9c361cb8aeaa0b GIT binary patch literal 2224 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 U>BitD2Pwepw$-gl!+XE~7Z`*$lmGw# literal 0 HcmV?d00001 From 45a544b0108d8aa8f0083dc092083c669f5e9a17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sinan=20=C3=96zt=C3=BCrk?= <72804437+Sinan997@users.noreply.github.com> Date: Mon, 31 Jul 2023 10:48:56 +0300 Subject: [PATCH 08/39] Update CapsLock.directive.md --- docs/en/UI/Angular/CapsLock.directive.md | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/docs/en/UI/Angular/CapsLock.directive.md b/docs/en/UI/Angular/CapsLock.directive.md index 4b92d61124..a21057490c 100644 --- a/docs/en/UI/Angular/CapsLock.directive.md +++ b/docs/en/UI/Angular/CapsLock.directive.md @@ -5,15 +5,17 @@ In password inputs,You may want to show if Caps Lock is on. To make this even ea ## Getting Started -In order to use the `TrackCapsLockDirective` in an HTML template, the **`CoreModule`** should be imported into your module like this: +`TrackCapsLockDirective` is standalone. In order to use the `TrackCapsLockDirective` in an HTML template, import it to related module or your standalone component: ```ts -// ... -import { CoreModule } from '@abp/ng.core'; +import { TrackCapsLockDirective } from '@abp/ng.core'; @NgModule({ //... - imports: [..., CoreModule], + imports: [ + ..., + TrackCapsLockDirective + ], }) export class MyFeatureModule {} ``` @@ -25,6 +27,8 @@ The `TrackCapsLockDirective` is very easy to use. The directive's selector is ** See an example usage: ```ts +import { TrackCapsLockDirective } from '@abp/ng.core' + @Component({ selector: 'test-component', standalone: true, @@ -34,7 +38,8 @@ See an example usage: icon - ` + `, + imports: [ TrackCapsLockDirective ] }) export class TestComponent{ capsLock = false; @@ -49,4 +54,4 @@ See the result: To see Caps Lock icon press Caps Lock. -![Show Password directive](./images/CapsLockDirective2.png) \ No newline at end of file +![Show Password directive](./images/CapsLockDirective2.png) From 383222a9ee7b6e9699228e9b71ffa16044ef309b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sinan=20=C3=96zt=C3=BCrk?= <72804437+Sinan997@users.noreply.github.com> Date: Mon, 31 Jul 2023 10:51:53 +0300 Subject: [PATCH 09/39] Update CapsLock.directive.md --- docs/en/UI/Angular/CapsLock.directive.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/en/UI/Angular/CapsLock.directive.md b/docs/en/UI/Angular/CapsLock.directive.md index a21057490c..24bef39cdc 100644 --- a/docs/en/UI/Angular/CapsLock.directive.md +++ b/docs/en/UI/Angular/CapsLock.directive.md @@ -1,6 +1,6 @@ -# Show Password Directive +# Caps Lock Directive -In password inputs,You may want to show if Caps Lock is on. To make this even easier, you can use the `TrackCapsLockDirective` which has been exposed by the `@abp/ng.core` package. +In password inputs, You may want to show if Caps Lock is on. To make this even easier, you can use the `TrackCapsLockDirective` which has been exposed by the `@abp/ng.core` package. ## Getting Started From f96f71576b4318b4a58bf85b2355432d8819d55b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sinan=20=C3=96zt=C3=BCrk?= <72804437+Sinan997@users.noreply.github.com> Date: Mon, 31 Jul 2023 10:58:53 +0300 Subject: [PATCH 10/39] Update Show-Password-Directive.md --- docs/en/UI/Angular/Show-Password-Directive.md | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/docs/en/UI/Angular/Show-Password-Directive.md b/docs/en/UI/Angular/Show-Password-Directive.md index db54bcdd76..6c3cbe4f45 100644 --- a/docs/en/UI/Angular/Show-Password-Directive.md +++ b/docs/en/UI/Angular/Show-Password-Directive.md @@ -4,16 +4,17 @@ In password input, text can be shown easily via changing input type attribute to ## Getting Started - -In order to use the `ShowPasswordDirective` in an HTML template, the **`CoreModule`** should be imported into your module like this: +`ShowPasswordDirective` is standalone. In order to use the `ShowPasswordDirective` in an HTML template, import it to related module or your standalone component: ```ts -// ... -import { CoreModule } from '@abp/ng.core'; +import { ShowPasswordDirective } from '@abp/ng.core'; @NgModule({ //... - imports: [..., CoreModule], + imports: [ + ..., + ShowPasswordDirective + ], }) export class MyFeatureModule {} ``` @@ -25,6 +26,7 @@ The `ShowPasswordDirective` is very easy to use. The directive's selector is **` See an example usage: ```ts +import { ShowPasswordDirective } from '@abp/ng.core'; @Component({ selector: 'test-component', standalone: true, @@ -34,7 +36,8 @@ See an example usage: icon - ` + `, + imports: [ShowPasswordDirective] }) export class TestComponent{ showPassword = false; @@ -49,4 +52,4 @@ See the result: To see password input click icon. -![Show Password directive](./images/showPasswordDirective2.png) \ No newline at end of file +![Show Password directive](./images/showPasswordDirective2.png) From 6e4cd54f2a675685511d4a4fb4c213e0c75db37f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sinan=20=C3=96zt=C3=BCrk?= <72804437+Sinan997@users.noreply.github.com> Date: Mon, 31 Jul 2023 11:21:13 +0300 Subject: [PATCH 11/39] Update CapsLock.directive.md --- docs/en/UI/Angular/CapsLock.directive.md | 29 +++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/docs/en/UI/Angular/CapsLock.directive.md b/docs/en/UI/Angular/CapsLock.directive.md index 24bef39cdc..1e1021bdd4 100644 --- a/docs/en/UI/Angular/CapsLock.directive.md +++ b/docs/en/UI/Angular/CapsLock.directive.md @@ -7,11 +7,16 @@ In password inputs, You may want to show if Caps Lock is on. To make this even e `TrackCapsLockDirective` is standalone. In order to use the `TrackCapsLockDirective` in an HTML template, import it to related module or your standalone component: +**Importing to NgModule** ```ts import { TrackCapsLockDirective } from '@abp/ng.core'; @NgModule({ //... + declarations: [ + ..., + TestComponent + ], imports: [ ..., TrackCapsLockDirective @@ -22,15 +27,33 @@ export class MyFeatureModule {} ## Usage -The `TrackCapsLockDirective` is very easy to use. The directive's selector is **`abpCapsLock`**. By adding the `abpCapsLock` event to an element, you can track the status of Caps Lock. U can use this to warn user +The `TrackCapsLockDirective` is very easy to use. The directive's selector is **`abpCapsLock`**. By adding the `abpCapsLock` event to an element, you can track the status of Caps Lock. You can use this to warn user. See an example usage: +**NgModule Component usage** +```ts +@Component({ + selector: 'test-component', + template: ` +
+ + + icon +
+ ` +}) +export class TestComponent{ + capsLock = false; +} +``` + +**Standalone Component usage** ```ts import { TrackCapsLockDirective } from '@abp/ng.core' @Component({ - selector: 'test-component', + selector: 'standalone-component', standalone: true, template: `
@@ -41,7 +64,7 @@ import { TrackCapsLockDirective } from '@abp/ng.core' `, imports: [ TrackCapsLockDirective ] }) -export class TestComponent{ +export class StandaloneComponent{ capsLock = false; } ``` From 14b103668b267e96160cac8a7cd831f743a35efa Mon Sep 17 00:00:00 2001 From: maliming Date: Mon, 31 Jul 2023 16:38:00 +0800 Subject: [PATCH 12/39] Add `IAbpAccessTokenProvider`. --- .../MauiBlazor/IAbpMauiAccessTokenProvider.cs | 8 ----- .../MauiBlazorAbpAccessTokenProvider.cs | 14 ++++++++ ...delRemoteServiceHttpClientAuthenticator.cs | 24 +++---------- .../NullAbpMauiAccessTokenProvider.cs | 13 ------- .../AbpHttpClientIdentityModelWebModule.cs | 8 +++-- .../Web/HttpContextAbpAccessTokenProvider.cs | 29 ++++++++++++++++ ...delRemoteServiceHttpClientAuthenticator.cs | 23 ++++--------- ...delRemoteServiceHttpClientAuthenticator.cs | 34 ++++--------------- .../WebAssemblyAbpAccessTokenProvider.cs | 34 +++++++++++++++++++ .../Authentication/IAbpAccessTokenProvider.cs | 8 +++++ .../NullAbpAccessTokenProvider.cs | 12 +++++++ 11 files changed, 120 insertions(+), 87 deletions(-) delete mode 100644 framework/src/Volo.Abp.Http.Client.IdentityModel.MauiBlazor/Volo/Abp/Http/Client/IdentityModel/MauiBlazor/IAbpMauiAccessTokenProvider.cs create mode 100644 framework/src/Volo.Abp.Http.Client.IdentityModel.MauiBlazor/Volo/Abp/Http/Client/IdentityModel/MauiBlazor/MauiBlazorAbpAccessTokenProvider.cs delete mode 100644 framework/src/Volo.Abp.Http.Client.IdentityModel.MauiBlazor/Volo/Abp/Http/Client/IdentityModel/MauiBlazor/NullAbpMauiAccessTokenProvider.cs create mode 100644 framework/src/Volo.Abp.Http.Client.IdentityModel.Web/Volo/Abp/Http/Client/IdentityModel/Web/HttpContextAbpAccessTokenProvider.cs create mode 100644 framework/src/Volo.Abp.Http.Client.IdentityModel.WebAssembly/Volo/Abp/Http/Client/IdentityModel/WebAssembly/WebAssemblyAbpAccessTokenProvider.cs create mode 100644 framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/Authentication/IAbpAccessTokenProvider.cs create mode 100644 framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/Authentication/NullAbpAccessTokenProvider.cs diff --git a/framework/src/Volo.Abp.Http.Client.IdentityModel.MauiBlazor/Volo/Abp/Http/Client/IdentityModel/MauiBlazor/IAbpMauiAccessTokenProvider.cs b/framework/src/Volo.Abp.Http.Client.IdentityModel.MauiBlazor/Volo/Abp/Http/Client/IdentityModel/MauiBlazor/IAbpMauiAccessTokenProvider.cs deleted file mode 100644 index 0c257b090c..0000000000 --- a/framework/src/Volo.Abp.Http.Client.IdentityModel.MauiBlazor/Volo/Abp/Http/Client/IdentityModel/MauiBlazor/IAbpMauiAccessTokenProvider.cs +++ /dev/null @@ -1,8 +0,0 @@ -using System.Threading.Tasks; - -namespace Volo.Abp.Http.Client.IdentityModel.MauiBlazor; - -public interface IAbpMauiAccessTokenProvider -{ - Task GetAccessTokenAsync(); -} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Http.Client.IdentityModel.MauiBlazor/Volo/Abp/Http/Client/IdentityModel/MauiBlazor/MauiBlazorAbpAccessTokenProvider.cs b/framework/src/Volo.Abp.Http.Client.IdentityModel.MauiBlazor/Volo/Abp/Http/Client/IdentityModel/MauiBlazor/MauiBlazorAbpAccessTokenProvider.cs new file mode 100644 index 0000000000..8afbcbafed --- /dev/null +++ b/framework/src/Volo.Abp.Http.Client.IdentityModel.MauiBlazor/Volo/Abp/Http/Client/IdentityModel/MauiBlazor/MauiBlazorAbpAccessTokenProvider.cs @@ -0,0 +1,14 @@ +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Http.Client.Authentication; + +namespace Volo.Abp.Http.Client.IdentityModel.MauiBlazor; + +[Dependency(ReplaceServices = true)] +public class MauiBlazorAbpAccessTokenProvider : IAbpAccessTokenProvider, ITransientDependency +{ + public virtual Task GetTokenAsync() + { + return Task.FromResult(null as string); + } +} diff --git a/framework/src/Volo.Abp.Http.Client.IdentityModel.MauiBlazor/Volo/Abp/Http/Client/IdentityModel/MauiBlazor/MauiIBlazorIdentityModelRemoteServiceHttpClientAuthenticator.cs b/framework/src/Volo.Abp.Http.Client.IdentityModel.MauiBlazor/Volo/Abp/Http/Client/IdentityModel/MauiBlazor/MauiIBlazorIdentityModelRemoteServiceHttpClientAuthenticator.cs index ba36de1d77..b1277373fa 100644 --- a/framework/src/Volo.Abp.Http.Client.IdentityModel.MauiBlazor/Volo/Abp/Http/Client/IdentityModel/MauiBlazor/MauiIBlazorIdentityModelRemoteServiceHttpClientAuthenticator.cs +++ b/framework/src/Volo.Abp.Http.Client.IdentityModel.MauiBlazor/Volo/Abp/Http/Client/IdentityModel/MauiBlazor/MauiIBlazorIdentityModelRemoteServiceHttpClientAuthenticator.cs @@ -1,8 +1,5 @@ -using System; -using System.Threading.Tasks; +using System.Threading.Tasks; using IdentityModel.Client; -using JetBrains.Annotations; -using Microsoft.Extensions.DependencyInjection; using Volo.Abp.DependencyInjection; using Volo.Abp.Http.Client.Authentication; using Volo.Abp.IdentityModel; @@ -12,22 +9,21 @@ namespace Volo.Abp.Http.Client.IdentityModel.MauiBlazor; [Dependency(ReplaceServices = true)] public class MauiBlazorIdentityModelRemoteServiceHttpClientAuthenticator : IdentityModelRemoteServiceHttpClientAuthenticator { - [CanBeNull] - protected IAbpMauiAccessTokenProvider AbpMauiAccessTokenProvider { get; } + protected IAbpAccessTokenProvider AccessTokenProvider { get; } public MauiBlazorIdentityModelRemoteServiceHttpClientAuthenticator( IIdentityModelAuthenticationService identityModelAuthenticationService, - IServiceProvider serviceProvider) + IAbpAccessTokenProvider abpAccessTokenProvider) : base(identityModelAuthenticationService) { - AbpMauiAccessTokenProvider = serviceProvider.GetService(); + AccessTokenProvider = abpAccessTokenProvider; } public async override Task Authenticate(RemoteServiceHttpClientAuthenticateContext context) { if (context.RemoteService.GetUseCurrentAccessToken() != false) { - var accessToken = await GetAccessTokenFromAccessTokenProviderOrNullAsync(); + var accessToken = await AccessTokenProvider.GetTokenAsync(); if (accessToken != null) { context.Request.SetBearerToken(accessToken); @@ -37,14 +33,4 @@ public class MauiBlazorIdentityModelRemoteServiceHttpClientAuthenticator : Ident await base.Authenticate(context); } - - protected virtual async Task GetAccessTokenFromAccessTokenProviderOrNullAsync() - { - if (AbpMauiAccessTokenProvider == null) - { - return null; - } - - return await AbpMauiAccessTokenProvider.GetAccessTokenAsync(); - } } diff --git a/framework/src/Volo.Abp.Http.Client.IdentityModel.MauiBlazor/Volo/Abp/Http/Client/IdentityModel/MauiBlazor/NullAbpMauiAccessTokenProvider.cs b/framework/src/Volo.Abp.Http.Client.IdentityModel.MauiBlazor/Volo/Abp/Http/Client/IdentityModel/MauiBlazor/NullAbpMauiAccessTokenProvider.cs deleted file mode 100644 index ae6ecd949f..0000000000 --- a/framework/src/Volo.Abp.Http.Client.IdentityModel.MauiBlazor/Volo/Abp/Http/Client/IdentityModel/MauiBlazor/NullAbpMauiAccessTokenProvider.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System.Threading.Tasks; -using Volo.Abp.DependencyInjection; - -namespace Volo.Abp.Http.Client.IdentityModel.MauiBlazor; - -[Dependency(TryRegister = true)] -public class NullAbpMauiAccessTokenProvider : IAbpMauiAccessTokenProvider -{ - public Task GetAccessTokenAsync() - { - return Task.FromResult(null as string); - } -} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Http.Client.IdentityModel.Web/Volo/Abp/Http/Client/IdentityModel/Web/AbpHttpClientIdentityModelWebModule.cs b/framework/src/Volo.Abp.Http.Client.IdentityModel.Web/Volo/Abp/Http/Client/IdentityModel/Web/AbpHttpClientIdentityModelWebModule.cs index 44959fbb82..1478193bf6 100644 --- a/framework/src/Volo.Abp.Http.Client.IdentityModel.Web/Volo/Abp/Http/Client/IdentityModel/Web/AbpHttpClientIdentityModelWebModule.cs +++ b/framework/src/Volo.Abp.Http.Client.IdentityModel.Web/Volo/Abp/Http/Client/IdentityModel/Web/AbpHttpClientIdentityModelWebModule.cs @@ -1,4 +1,5 @@ -using Volo.Abp.Modularity; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.Modularity; namespace Volo.Abp.Http.Client.IdentityModel.Web; @@ -7,5 +8,8 @@ namespace Volo.Abp.Http.Client.IdentityModel.Web; )] public class AbpHttpClientIdentityModelWebModule : AbpModule { - + public override void ConfigureServices(ServiceConfigurationContext context) + { + context.Services.AddHttpContextAccessor(); + } } diff --git a/framework/src/Volo.Abp.Http.Client.IdentityModel.Web/Volo/Abp/Http/Client/IdentityModel/Web/HttpContextAbpAccessTokenProvider.cs b/framework/src/Volo.Abp.Http.Client.IdentityModel.Web/Volo/Abp/Http/Client/IdentityModel/Web/HttpContextAbpAccessTokenProvider.cs new file mode 100644 index 0000000000..97d88bd3b0 --- /dev/null +++ b/framework/src/Volo.Abp.Http.Client.IdentityModel.Web/Volo/Abp/Http/Client/IdentityModel/Web/HttpContextAbpAccessTokenProvider.cs @@ -0,0 +1,29 @@ +using System.Threading.Tasks; +using Microsoft.AspNetCore.Authentication; +using Microsoft.AspNetCore.Http; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Http.Client.Authentication; + +namespace Volo.Abp.Http.Client.IdentityModel.Web; + +[Dependency(ReplaceServices = true)] +public class HttpContextAbpAccessTokenProvider : IAbpAccessTokenProvider, ITransientDependency +{ + protected IHttpContextAccessor HttpContextAccessor { get; } + + public HttpContextAbpAccessTokenProvider(IHttpContextAccessor httpContextAccessor) + { + HttpContextAccessor = httpContextAccessor; + } + + public virtual async Task GetTokenAsync() + { + var httpContext = HttpContextAccessor?.HttpContext; + if (httpContext == null) + { + return null; + } + + return await httpContext.GetTokenAsync("access_token"); + } +} diff --git a/framework/src/Volo.Abp.Http.Client.IdentityModel.Web/Volo/Abp/Http/Client/IdentityModel/Web/HttpContextIdentityModelRemoteServiceHttpClientAuthenticator.cs b/framework/src/Volo.Abp.Http.Client.IdentityModel.Web/Volo/Abp/Http/Client/IdentityModel/Web/HttpContextIdentityModelRemoteServiceHttpClientAuthenticator.cs index 6ae44a0943..364134348b 100644 --- a/framework/src/Volo.Abp.Http.Client.IdentityModel.Web/Volo/Abp/Http/Client/IdentityModel/Web/HttpContextIdentityModelRemoteServiceHttpClientAuthenticator.cs +++ b/framework/src/Volo.Abp.Http.Client.IdentityModel.Web/Volo/Abp/Http/Client/IdentityModel/Web/HttpContextIdentityModelRemoteServiceHttpClientAuthenticator.cs @@ -1,7 +1,5 @@ using System.Threading.Tasks; using IdentityModel.Client; -using Microsoft.AspNetCore.Authentication; -using Microsoft.AspNetCore.Http; using Volo.Abp.DependencyInjection; using Volo.Abp.Http.Client.Authentication; using Volo.Abp.IdentityModel; @@ -11,19 +9,21 @@ namespace Volo.Abp.Http.Client.IdentityModel.Web; [Dependency(ReplaceServices = true)] public class HttpContextIdentityModelRemoteServiceHttpClientAuthenticator : IdentityModelRemoteServiceHttpClientAuthenticator { - public IHttpContextAccessor HttpContextAccessor { get; set; } + protected IAbpAccessTokenProvider AccessTokenProvider { get; } public HttpContextIdentityModelRemoteServiceHttpClientAuthenticator( - IIdentityModelAuthenticationService identityModelAuthenticationService) + IIdentityModelAuthenticationService identityModelAuthenticationService, + IAbpAccessTokenProvider accessTokenProvider) : base(identityModelAuthenticationService) { + AccessTokenProvider = accessTokenProvider; } - public override async Task Authenticate(RemoteServiceHttpClientAuthenticateContext context) + public async override Task Authenticate(RemoteServiceHttpClientAuthenticateContext context) { if (context.RemoteService.GetUseCurrentAccessToken() != false) { - var accessToken = await GetAccessTokenFromHttpContextOrNullAsync(); + var accessToken = await AccessTokenProvider.GetTokenAsync(); if (accessToken != null) { context.Request.SetBearerToken(accessToken); @@ -33,15 +33,4 @@ public class HttpContextIdentityModelRemoteServiceHttpClientAuthenticator : Iden await base.Authenticate(context); } - - protected virtual async Task GetAccessTokenFromHttpContextOrNullAsync() - { - var httpContext = HttpContextAccessor?.HttpContext; - if (httpContext == null) - { - return null; - } - - return await httpContext.GetTokenAsync("access_token"); - } } diff --git a/framework/src/Volo.Abp.Http.Client.IdentityModel.WebAssembly/Volo/Abp/Http/Client/IdentityModel/WebAssembly/AccessTokenProviderIdentityModelRemoteServiceHttpClientAuthenticator.cs b/framework/src/Volo.Abp.Http.Client.IdentityModel.WebAssembly/Volo/Abp/Http/Client/IdentityModel/WebAssembly/AccessTokenProviderIdentityModelRemoteServiceHttpClientAuthenticator.cs index 846cc6f3a3..c16317e376 100644 --- a/framework/src/Volo.Abp.Http.Client.IdentityModel.WebAssembly/Volo/Abp/Http/Client/IdentityModel/WebAssembly/AccessTokenProviderIdentityModelRemoteServiceHttpClientAuthenticator.cs +++ b/framework/src/Volo.Abp.Http.Client.IdentityModel.WebAssembly/Volo/Abp/Http/Client/IdentityModel/WebAssembly/AccessTokenProviderIdentityModelRemoteServiceHttpClientAuthenticator.cs @@ -1,9 +1,5 @@ -using System; -using System.Threading.Tasks; +using System.Threading.Tasks; using IdentityModel.Client; -using JetBrains.Annotations; -using Microsoft.AspNetCore.Components.WebAssembly.Authentication; -using Microsoft.Extensions.DependencyInjection; using Volo.Abp.DependencyInjection; using Volo.Abp.Http.Client.Authentication; using Volo.Abp.IdentityModel; @@ -14,22 +10,21 @@ namespace Volo.Abp.Http.Client.IdentityModel.WebAssembly; public class AccessTokenProviderIdentityModelRemoteServiceHttpClientAuthenticator : IdentityModelRemoteServiceHttpClientAuthenticator { - [CanBeNull] - protected IAccessTokenProvider AccessTokenProvider { get; } + protected IAbpAccessTokenProvider AccessTokenProvider { get; } public AccessTokenProviderIdentityModelRemoteServiceHttpClientAuthenticator( IIdentityModelAuthenticationService identityModelAuthenticationService, - IServiceProvider serviceProvider) + IAbpAccessTokenProvider accessTokenProvider) : base(identityModelAuthenticationService) { - AccessTokenProvider = serviceProvider.GetService(); + AccessTokenProvider = accessTokenProvider; } - public override async Task Authenticate(RemoteServiceHttpClientAuthenticateContext context) + public async override Task Authenticate(RemoteServiceHttpClientAuthenticateContext context) { if (context.RemoteService.GetUseCurrentAccessToken() != false) { - var accessToken = await GetAccessTokenFromAccessTokenProviderOrNullAsync(); + var accessToken = await AccessTokenProvider.GetTokenAsync(); if (accessToken != null) { context.Request.SetBearerToken(accessToken); @@ -39,21 +34,4 @@ public class AccessTokenProviderIdentityModelRemoteServiceHttpClientAuthenticato await base.Authenticate(context); } - - protected virtual async Task GetAccessTokenFromAccessTokenProviderOrNullAsync() - { - if (AccessTokenProvider == null) - { - return null; - } - - var result = await AccessTokenProvider.RequestAccessToken(); - if (result.Status != AccessTokenResultStatus.Success) - { - return null; - } - - result.TryGetToken(out var token); - return token.Value; - } } diff --git a/framework/src/Volo.Abp.Http.Client.IdentityModel.WebAssembly/Volo/Abp/Http/Client/IdentityModel/WebAssembly/WebAssemblyAbpAccessTokenProvider.cs b/framework/src/Volo.Abp.Http.Client.IdentityModel.WebAssembly/Volo/Abp/Http/Client/IdentityModel/WebAssembly/WebAssemblyAbpAccessTokenProvider.cs new file mode 100644 index 0000000000..d0a68cdb7c --- /dev/null +++ b/framework/src/Volo.Abp.Http.Client.IdentityModel.WebAssembly/Volo/Abp/Http/Client/IdentityModel/WebAssembly/WebAssemblyAbpAccessTokenProvider.cs @@ -0,0 +1,34 @@ +using System.Threading.Tasks; +using Microsoft.AspNetCore.Components.WebAssembly.Authentication; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Http.Client.Authentication; + +namespace Volo.Abp.Http.Client.IdentityModel.WebAssembly; + +[Dependency(ReplaceServices = true)] +public class WebAssemblyAbpAccessTokenProvider : IAbpAccessTokenProvider, ITransientDependency +{ + protected IAccessTokenProvider AccessTokenProvider { get; } + + public WebAssemblyAbpAccessTokenProvider(IAccessTokenProvider accessTokenProvider) + { + AccessTokenProvider = accessTokenProvider; + } + + public virtual async Task GetTokenAsync() + { + if (AccessTokenProvider == null) + { + return null; + } + + var result = await AccessTokenProvider.RequestAccessToken(); + if (result.Status != AccessTokenResultStatus.Success) + { + return null; + } + + result.TryGetToken(out var token); + return token.Value; + } +} diff --git a/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/Authentication/IAbpAccessTokenProvider.cs b/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/Authentication/IAbpAccessTokenProvider.cs new file mode 100644 index 0000000000..a4e9e650e3 --- /dev/null +++ b/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/Authentication/IAbpAccessTokenProvider.cs @@ -0,0 +1,8 @@ +using System.Threading.Tasks; + +namespace Volo.Abp.Http.Client.Authentication; + +public interface IAbpAccessTokenProvider +{ + Task GetTokenAsync(); +} diff --git a/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/Authentication/NullAbpAccessTokenProvider.cs b/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/Authentication/NullAbpAccessTokenProvider.cs new file mode 100644 index 0000000000..6bd7e6344b --- /dev/null +++ b/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/Authentication/NullAbpAccessTokenProvider.cs @@ -0,0 +1,12 @@ +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.Http.Client.Authentication; + +public class NullAbpAccessTokenProvider : IAbpAccessTokenProvider, ITransientDependency +{ + public Task GetTokenAsync() + { + return Task.FromResult(null as string); + } +} From 3daec5dd224a7169027b402b2d0613e49e64c021 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sinan=20=C3=96zt=C3=BCrk?= <72804437+Sinan997@users.noreply.github.com> Date: Mon, 31 Jul 2023 12:22:36 +0300 Subject: [PATCH 13/39] Update Show-Password-Directive.md --- docs/en/UI/Angular/Show-Password-Directive.md | 26 +++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/docs/en/UI/Angular/Show-Password-Directive.md b/docs/en/UI/Angular/Show-Password-Directive.md index 6c3cbe4f45..c19c8073bd 100644 --- a/docs/en/UI/Angular/Show-Password-Directive.md +++ b/docs/en/UI/Angular/Show-Password-Directive.md @@ -6,11 +6,16 @@ In password input, text can be shown easily via changing input type attribute to ## Getting Started `ShowPasswordDirective` is standalone. In order to use the `ShowPasswordDirective` in an HTML template, import it to related module or your standalone component: +**Importing to NgModule** ```ts import { ShowPasswordDirective } from '@abp/ng.core'; @NgModule({ //... + declarations: [ + ..., + TestComponent + ], imports: [ ..., ShowPasswordDirective @@ -25,10 +30,27 @@ The `ShowPasswordDirective` is very easy to use. The directive's selector is **` See an example usage: +**NgModule Component usage** ```ts -import { ShowPasswordDirective } from '@abp/ng.core'; @Component({ selector: 'test-component', + template: ` +
+ + + icon +
+ ` +}) +export class TestComponent{ + showPassword = false; +} +``` +**Standalone Component usage** +```ts +import { ShowPasswordDirective } from '@abp/ng.core'; +@Component({ + selector: 'standalone-component', standalone: true, template: `
@@ -39,7 +61,7 @@ import { ShowPasswordDirective } from '@abp/ng.core'; `, imports: [ShowPasswordDirective] }) -export class TestComponent{ +export class StandaloneComponent{ showPassword = false; } ``` From 8197eb1289a1c935c5e32b5f0fcf481e0c420293 Mon Sep 17 00:00:00 2001 From: Sinan997 Date: Mon, 31 Jul 2023 12:57:37 +0300 Subject: [PATCH 14/39] settings tab re-order --- .../src/lib/providers/feature-management-settings.provider.ts | 2 +- .../config/src/lib/providers/setting-tab.provider.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/npm/ng-packs/packages/feature-management/src/lib/providers/feature-management-settings.provider.ts b/npm/ng-packs/packages/feature-management/src/lib/providers/feature-management-settings.provider.ts index 2d7664bb46..30d6701d4b 100644 --- a/npm/ng-packs/packages/feature-management/src/lib/providers/feature-management-settings.provider.ts +++ b/npm/ng-packs/packages/feature-management/src/lib/providers/feature-management-settings.provider.ts @@ -17,7 +17,7 @@ export function configureSettingTabs(settingtabs: SettingTabsService) { settingtabs.add([ { name: eFeatureManagementTabNames.FeatureManagement, - order: 104, + order: 120, requiredPolicy: 'FeatureManagement.ManageHostFeatures', component: FeatureManagementTabComponent, }, diff --git a/npm/ng-packs/packages/setting-management/config/src/lib/providers/setting-tab.provider.ts b/npm/ng-packs/packages/setting-management/config/src/lib/providers/setting-tab.provider.ts index f05104c177..91a31f70cc 100644 --- a/npm/ng-packs/packages/setting-management/config/src/lib/providers/setting-tab.provider.ts +++ b/npm/ng-packs/packages/setting-management/config/src/lib/providers/setting-tab.provider.ts @@ -17,7 +17,7 @@ export function configureSettingTabs(settingTabs: SettingTabsService) { settingTabs.add([ { name: eSettingManamagementSettingTabNames.EmailSettingGroup, - order: 100, + order: 110, requiredPolicy: 'SettingManagement.Emailing', component: EmailSettingGroupComponent, }, From 9b778069fdcc7e1079d40ddcba55b3758ca028ab Mon Sep 17 00:00:00 2001 From: Sinan997 Date: Mon, 31 Jul 2023 17:50:39 +0300 Subject: [PATCH 15/39] re-setting order to default value and new sorting compare function --- .../core/src/lib/services/routes.service.ts | 22 +++++++++++++++---- .../feature-management-settings.provider.ts | 2 +- .../src/lib/providers/setting-tab.provider.ts | 2 +- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/npm/ng-packs/packages/core/src/lib/services/routes.service.ts b/npm/ng-packs/packages/core/src/lib/services/routes.service.ts index 329d2a370c..ec8ee4c4e5 100644 --- a/npm/ng-packs/packages/core/src/lib/services/routes.service.ts +++ b/npm/ng-packs/packages/core/src/lib/services/routes.service.ts @@ -12,6 +12,7 @@ import { } from '../utils/tree-utils'; import { ConfigStateService } from './config-state.service'; import { PermissionService } from './permission.service'; +import { LocalizationService } from './localization.service'; // eslint-disable-next-line @typescript-eslint/ban-types export abstract class AbstractTreeService { @@ -158,14 +159,26 @@ export abstract class AbstractNavTreeService { private subscription: Subscription; private permissionService: PermissionService; + private localizationService: LocalizationService readonly id = 'name'; readonly parentId = 'parentName'; readonly hide = (item: T) => item.invisible || !this.isGranted(item); readonly sort = (a: T, b: T) => { - if (!Number.isInteger(a.order)) return 1; - if (!Number.isInteger(b.order)) return -1; - - return (a.order as number) - (b.order as number); + const aName = this.localizationService.instant(a.name); + const bName = this.localizationService.instant(b.name); + const aNumber = a.order; + const bNumber = b.order; + + if (!Number.isInteger(aNumber)) return 1; + if (!Number.isInteger(bNumber)) return -1; + + if (aNumber > bNumber) return 1 + if (aNumber < bNumber) return -1 + + if ( aName > bName ) return 1; + if ( aName < bName ) return -1; + + return 0 }; constructor(protected injector: Injector) { @@ -175,6 +188,7 @@ export abstract class AbstractNavTreeService .createOnUpdateStream(state => state) .subscribe(() => this.refresh()); this.permissionService = injector.get(PermissionService); + this.localizationService = injector.get(LocalizationService); this.othersGroup = injector.get(OTHERS_GROUP); } diff --git a/npm/ng-packs/packages/feature-management/src/lib/providers/feature-management-settings.provider.ts b/npm/ng-packs/packages/feature-management/src/lib/providers/feature-management-settings.provider.ts index 30d6701d4b..64bbfb9932 100644 --- a/npm/ng-packs/packages/feature-management/src/lib/providers/feature-management-settings.provider.ts +++ b/npm/ng-packs/packages/feature-management/src/lib/providers/feature-management-settings.provider.ts @@ -17,7 +17,7 @@ export function configureSettingTabs(settingtabs: SettingTabsService) { settingtabs.add([ { name: eFeatureManagementTabNames.FeatureManagement, - order: 120, + order: 100, requiredPolicy: 'FeatureManagement.ManageHostFeatures', component: FeatureManagementTabComponent, }, diff --git a/npm/ng-packs/packages/setting-management/config/src/lib/providers/setting-tab.provider.ts b/npm/ng-packs/packages/setting-management/config/src/lib/providers/setting-tab.provider.ts index 91a31f70cc..f05104c177 100644 --- a/npm/ng-packs/packages/setting-management/config/src/lib/providers/setting-tab.provider.ts +++ b/npm/ng-packs/packages/setting-management/config/src/lib/providers/setting-tab.provider.ts @@ -17,7 +17,7 @@ export function configureSettingTabs(settingTabs: SettingTabsService) { settingTabs.add([ { name: eSettingManamagementSettingTabNames.EmailSettingGroup, - order: 110, + order: 100, requiredPolicy: 'SettingManagement.Emailing', component: EmailSettingGroupComponent, }, From 939f116ebcfe01dc2e2fb90ddaefbb783d2fb30a Mon Sep 17 00:00:00 2001 From: Sinan997 Date: Tue, 1 Aug 2023 12:14:00 +0300 Subject: [PATCH 16/39] moving logic to compare func --- .../packages/core/src/lib/services/routes.service.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/npm/ng-packs/packages/core/src/lib/services/routes.service.ts b/npm/ng-packs/packages/core/src/lib/services/routes.service.ts index ec8ee4c4e5..5f05eaa8ab 100644 --- a/npm/ng-packs/packages/core/src/lib/services/routes.service.ts +++ b/npm/ng-packs/packages/core/src/lib/services/routes.service.ts @@ -164,6 +164,10 @@ export abstract class AbstractNavTreeService readonly parentId = 'parentName'; readonly hide = (item: T) => item.invisible || !this.isGranted(item); readonly sort = (a: T, b: T) => { + return this.compareFunc(a,b) + }; + + readonly compareFunc = (a: T, b: T) => { const aName = this.localizationService.instant(a.name); const bName = this.localizationService.instant(b.name); const aNumber = a.order; @@ -179,7 +183,7 @@ export abstract class AbstractNavTreeService if ( aName < bName ) return -1; return 0 - }; + } constructor(protected injector: Injector) { super(); From b2008832025e0dd742f42e493dea9f6988322ea2 Mon Sep 17 00:00:00 2001 From: Masum ULU Date: Tue, 1 Aug 2023 14:30:13 +0300 Subject: [PATCH 17/39] Update NavItem model for toolbar --- .../packages/theme-shared/src/lib/models/nav-item.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/npm/ng-packs/packages/theme-shared/src/lib/models/nav-item.ts b/npm/ng-packs/packages/theme-shared/src/lib/models/nav-item.ts index 706eb1cb6c..c673bc74e2 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/models/nav-item.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/models/nav-item.ts @@ -1,8 +1,17 @@ import { Injector, Type } from '@angular/core'; import { Observable, of } from 'rxjs'; +export interface Badge { + count?: number | Observable; + color?: string; + icon?: string; +} + export class NavItem { id?: string | number; + name?: string; + description?: string; + badge?: Badge; component?: Type; html?: string; action?: () => void; From b84412409633c1d29454953e4f821a18423a172c Mon Sep 17 00:00:00 2001 From: Galip Tolga Erdem Date: Tue, 1 Aug 2023 17:02:46 -0400 Subject: [PATCH 18/39] Added Distributed Events section --- docs/en/Modules/Tenant-Management.md | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/docs/en/Modules/Tenant-Management.md b/docs/en/Modules/Tenant-Management.md index e12b6fc7a6..0d43c5e31e 100644 --- a/docs/en/Modules/Tenant-Management.md +++ b/docs/en/Modules/Tenant-Management.md @@ -48,6 +48,33 @@ The Features action opens a modal to enable/disable/set [features](../Features.m *Manage Host features* button is used to set features for the host side, if you use the features of your application also in the host side. +## Distributed Events + +This module defines the following ETOs (Event Transfer Objects) to allow you to subscribe to changes on the entities of the module; + +- `TenantEto` is published on changes done on an `Tenant` entity. + +**Example: Get notified when a new tenant has been created** + +``` +public class MyHandler : + IDistributedEventHandler>, + ITransientDependency +{ + public async Task HandleEventAsync(EntityCreatedEto eventData) + { + TenantEto tenant = eventData.Entity; + // TODO: ... + } +} +``` + + + +`TenantEto` is configured to automatically publish the events. You should configure yourself for the others. See the [Distributed Event Bus document](https://github.com/abpframework/abp/blob/rel-7.3/docs/en/Distributed-Event-Bus.md) to learn details of the pre-defined events. + +> Subscribing to the distributed events is especially useful for distributed scenarios (like microservice architecture). If you are building a monolithic application, or listening events in the same process that runs the Tenant Management Module, then subscribing to the [local events](https://github.com/abpframework/abp/blob/rel-7.3/docs/en/Local-Event-Bus.md) can be more efficient and easier. + ## Internals This section can be used as a reference if you want to [customize](../Customizing-Application-Modules-Guide.md) this module without changing [its source code](https://github.com/abpframework/abp/tree/dev/modules/tenant-management). From 2302230e56b1ef92171cd3512f7b7d446c7af61b Mon Sep 17 00:00:00 2001 From: maliming Date: Wed, 2 Aug 2023 09:18:27 +0800 Subject: [PATCH 19/39] Depends on `AbpBackgroundJobsModule` in the `DemoAppSharedModule`. Resolve #17250 --- .../DemoAppSharedModule.cs | 2 +- .../Volo.Abp.BackgroundJobs.DemoApp.Shared.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.Shared/DemoAppSharedModule.cs b/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.Shared/DemoAppSharedModule.cs index 193e87b528..ad002a5e18 100644 --- a/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.Shared/DemoAppSharedModule.cs +++ b/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.Shared/DemoAppSharedModule.cs @@ -5,7 +5,7 @@ using Volo.Abp.Modularity; namespace Volo.Abp.BackgroundJobs.DemoApp.Shared { [DependsOn( - typeof(AbpBackgroundJobsAbstractionsModule) + typeof(AbpBackgroundJobsModule) )] public class DemoAppSharedModule : AbpModule { diff --git a/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.Shared/Volo.Abp.BackgroundJobs.DemoApp.Shared.csproj b/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.Shared/Volo.Abp.BackgroundJobs.DemoApp.Shared.csproj index e6a08dbd02..d8ff12e3f8 100644 --- a/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.Shared/Volo.Abp.BackgroundJobs.DemoApp.Shared.csproj +++ b/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.Shared/Volo.Abp.BackgroundJobs.DemoApp.Shared.csproj @@ -8,7 +8,7 @@ - + From 71a61a895d7d1f9c1fcaee390c4ceee1d20f5157 Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Wed, 2 Aug 2023 11:27:39 +0800 Subject: [PATCH 20/39] Order setting tabs --- .../SettingManagement/SettingManagement.razor.cs | 2 +- .../SettingComponentCreationContext.cs | 13 +++++++++++++ .../SettingComponentGroup.cs | 7 ++++++- .../Settings/EmailingPageContributor.cs | 3 ++- .../Settings/TimeZonePageContributor.cs | 3 ++- .../SettingPageContributorManager.cs | 1 + .../SettingManagement/SettingPageCreationContext.cs | 13 +++++++++++++ .../Pages/SettingManagement/SettingPageGroup.cs | 7 ++++++- .../Settings/EmailingPageContributor.cs | 3 ++- .../Settings/TimeZonePageContributor.cs | 3 ++- 10 files changed, 48 insertions(+), 7 deletions(-) diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/Pages/SettingManagement/SettingManagement.razor.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/Pages/SettingManagement/SettingManagement.razor.cs index 1422d67873..47a956a028 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/Pages/SettingManagement/SettingManagement.razor.cs +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/Pages/SettingManagement/SettingManagement.razor.cs @@ -39,7 +39,7 @@ public partial class SettingManagement { await contributor.ConfigureAsync(SettingComponentCreationContext); } - + SettingComponentCreationContext.Normalize(); SettingItemRenders.Clear(); SelectedGroup = GetNormalizedString(SettingComponentCreationContext.Groups.First().Id); diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/SettingComponentCreationContext.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/SettingComponentCreationContext.cs index dfba0564f2..d016fb66ce 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/SettingComponentCreationContext.cs +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/SettingComponentCreationContext.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using Volo.Abp.DependencyInjection; namespace Volo.Abp.SettingManagement.Blazor; @@ -16,4 +17,16 @@ public class SettingComponentCreationContext : IServiceProviderAccessor Groups = new List(); } + + public void Normalize() + { + Order(); + } + + private void Order() + { + var orderedItems = Groups.OrderBy(item => item.Order).ToArray(); + Groups.Clear(); + Groups.AddRange(orderedItems); + } } diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/SettingComponentGroup.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/SettingComponentGroup.cs index bf4bbf2a22..0577f38b76 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/SettingComponentGroup.cs +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/SettingComponentGroup.cs @@ -5,6 +5,8 @@ namespace Volo.Abp.SettingManagement.Blazor; public class SettingComponentGroup { + public const int DefaultOrder = 1000; + public string Id { get => _id; set => _id = Check.NotNullOrWhiteSpace(value, nameof(Id)); @@ -24,12 +26,15 @@ public class SettingComponentGroup private Type _componentType; public object Parameter { get; set; } + + public int Order { get; set; } - public SettingComponentGroup([NotNull] string id, [NotNull] string displayName, [NotNull] Type componentType, object parameter = null) + public SettingComponentGroup([NotNull] string id, [NotNull] string displayName, [NotNull] Type componentType, object parameter = null, int order = DefaultOrder) { Id = id; DisplayName = displayName; ComponentType = componentType; Parameter = parameter; + Order = order; } } diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/Settings/EmailingPageContributor.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/Settings/EmailingPageContributor.cs index aec58c8ca8..13cdc2acde 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/Settings/EmailingPageContributor.cs +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/Settings/EmailingPageContributor.cs @@ -23,7 +23,8 @@ public class EmailingPageContributor : ISettingComponentContributor new SettingComponentGroup( "Volo.Abp.SettingManagement", l["Menu:Emailing"], - typeof(EmailSettingGroupViewComponent) + typeof(EmailSettingGroupViewComponent), + order : 3 ) ); } diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/Settings/TimeZonePageContributor.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/Settings/TimeZonePageContributor.cs index 6effd64494..a23a32cb53 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/Settings/TimeZonePageContributor.cs +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/Settings/TimeZonePageContributor.cs @@ -20,7 +20,8 @@ public class TimeZonePageContributor : ISettingComponentContributor new SettingComponentGroup( "Volo.Abp.TimeZone", l["Menu:TimeZone"], - typeof(TimeZoneSettingGroupViewComponent) + typeof(TimeZoneSettingGroupViewComponent), + order : 4 ) ); } diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/SettingPageContributorManager.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/SettingPageContributorManager.cs index 9b08236cae..83f5d53fa5 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/SettingPageContributorManager.cs +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/SettingPageContributorManager.cs @@ -37,6 +37,7 @@ public class SettingPageContributorManager : IScopedDependency { await contributor.ConfigureAsync(context); } + context.Normalize(); return context; } diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/SettingPageCreationContext.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/SettingPageCreationContext.cs index c929fef16d..51490e4e63 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/SettingPageCreationContext.cs +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/SettingPageCreationContext.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using Volo.Abp.DependencyInjection; namespace Volo.Abp.SettingManagement.Web.Pages.SettingManagement; @@ -16,4 +17,16 @@ public class SettingPageCreationContext : IServiceProviderAccessor Groups = new List(); } + + public void Normalize() + { + Order(); + } + + private void Order() + { + var orderedItems = Groups.OrderBy(item => item.Order).ToArray(); + Groups.Clear(); + Groups.AddRange(orderedItems); + } } diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/SettingPageGroup.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/SettingPageGroup.cs index 2dbc6eb4de..65aceb554c 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/SettingPageGroup.cs +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/SettingPageGroup.cs @@ -5,6 +5,8 @@ namespace Volo.Abp.SettingManagement.Web.Pages.SettingManagement; public class SettingPageGroup { + public const int DefaultOrder = 1000; + public string Id { get => _id; set => _id = Check.NotNullOrWhiteSpace(value, nameof(Id)); @@ -24,12 +26,15 @@ public class SettingPageGroup private Type _componentType; public object Parameter { get; set; } + + public int Order { get; set; } - public SettingPageGroup([NotNull] string id, [NotNull] string displayName, [NotNull] Type componentType, object parameter = null) + public SettingPageGroup([NotNull] string id, [NotNull] string displayName, [NotNull] Type componentType, object parameter = null, int order = DefaultOrder) { Id = id; DisplayName = displayName; ComponentType = componentType; Parameter = parameter; + Order = order; } } diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Settings/EmailingPageContributor.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Settings/EmailingPageContributor.cs index 5096404a11..0c369f12ff 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Settings/EmailingPageContributor.cs +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Settings/EmailingPageContributor.cs @@ -23,7 +23,8 @@ public class EmailingPageContributor : SettingPageContributorBase new SettingPageGroup( "Volo.Abp.EmailSetting", l["Menu:Emailing"], - typeof(EmailSettingGroupViewComponent) + typeof(EmailSettingGroupViewComponent), + order : 3 ) ); return Task.CompletedTask; diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Settings/TimeZonePageContributor.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Settings/TimeZonePageContributor.cs index 696d1204da..21c35baccc 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Settings/TimeZonePageContributor.cs +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Settings/TimeZonePageContributor.cs @@ -25,7 +25,8 @@ public class TimeZonePageContributor : SettingPageContributorBase new SettingPageGroup( "Volo.Abp.TimeZone", l["Menu:TimeZone"], - typeof(TimeZoneSettingGroupViewComponent) + typeof(TimeZoneSettingGroupViewComponent), + order : 4 ) ); } From 0d107364be1c0c8066b14fef2da0a0b499438578 Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Wed, 2 Aug 2023 11:58:25 +0800 Subject: [PATCH 21/39] Update document --- docs/en/Modules/Setting-Management.md | 6 ++++-- docs/zh-Hans/Modules/Setting-Management.md | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/docs/en/Modules/Setting-Management.md b/docs/en/Modules/Setting-Management.md index 354fbdd539..e26c7c806e 100644 --- a/docs/en/Modules/Setting-Management.md +++ b/docs/en/Modules/Setting-Management.md @@ -177,7 +177,8 @@ public class BookStoreSettingPageContributor : ISettingPageContributor new SettingPageGroup( "Volo.Abp.MySettingGroup", "MySettingGroup", - typeof(MySettingGroupViewComponent) + typeof(MySettingGroupViewComponent), + order : 1 ) ); @@ -240,7 +241,8 @@ public class BookStoreSettingComponentContributor : ISettingComponentContributor new SettingComponentGroup( "Volo.Abp.MySettingGroup", "MySettingGroup", - typeof(MySettingGroupComponent) + typeof(MySettingGroupComponent), + order : 1 ) ); diff --git a/docs/zh-Hans/Modules/Setting-Management.md b/docs/zh-Hans/Modules/Setting-Management.md index 242553c2c9..cf52d588a2 100644 --- a/docs/zh-Hans/Modules/Setting-Management.md +++ b/docs/zh-Hans/Modules/Setting-Management.md @@ -146,7 +146,8 @@ public class BookStoreSettingPageContributor : ISettingPageContributor new SettingPageGroup( "Volo.Abp.MySettingGroup", "MySettingGroup", - typeof(MySettingGroupViewComponent) + typeof(MySettingGroupViewComponent), + order : 1 ) ); @@ -209,7 +210,8 @@ public class BookStoreSettingComponentContributor : ISettingComponentContributor new SettingComponentGroup( "Volo.Abp.MySettingGroup", "MySettingGroup", - typeof(MySettingGroupComponent) + typeof(MySettingGroupComponent), + order : 1 ) ); From b5b2cfb07ed2954d4211c9e9fa1c53733a096c72 Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Wed, 2 Aug 2023 12:45:41 +0800 Subject: [PATCH 22/39] improve --- .../SettingComponentCreationContext.cs | 2 +- .../Volo.Abp.SettingManagement.Blazor/SettingComponentGroup.cs | 2 +- .../Settings/EmailingPageContributor.cs | 3 +-- .../Settings/TimeZonePageContributor.cs | 3 +-- .../Pages/SettingManagement/SettingPageCreationContext.cs | 2 +- .../Settings/EmailingPageContributor.cs | 3 +-- .../Settings/TimeZonePageContributor.cs | 3 +-- 7 files changed, 7 insertions(+), 11 deletions(-) diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/SettingComponentCreationContext.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/SettingComponentCreationContext.cs index d016fb66ce..ff386cc260 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/SettingComponentCreationContext.cs +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/SettingComponentCreationContext.cs @@ -25,7 +25,7 @@ public class SettingComponentCreationContext : IServiceProviderAccessor private void Order() { - var orderedItems = Groups.OrderBy(item => item.Order).ToArray(); + var orderedItems = Groups.OrderBy(item => item.Order).ThenBy(item => item.DisplayName).ToArray(); Groups.Clear(); Groups.AddRange(orderedItems); } diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/SettingComponentGroup.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/SettingComponentGroup.cs index 0577f38b76..7b1aca36aa 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/SettingComponentGroup.cs +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/SettingComponentGroup.cs @@ -5,7 +5,7 @@ namespace Volo.Abp.SettingManagement.Blazor; public class SettingComponentGroup { - public const int DefaultOrder = 1000; + public const int DefaultOrder = 1; public string Id { get => _id; diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/Settings/EmailingPageContributor.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/Settings/EmailingPageContributor.cs index 13cdc2acde..aec58c8ca8 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/Settings/EmailingPageContributor.cs +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/Settings/EmailingPageContributor.cs @@ -23,8 +23,7 @@ public class EmailingPageContributor : ISettingComponentContributor new SettingComponentGroup( "Volo.Abp.SettingManagement", l["Menu:Emailing"], - typeof(EmailSettingGroupViewComponent), - order : 3 + typeof(EmailSettingGroupViewComponent) ) ); } diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/Settings/TimeZonePageContributor.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/Settings/TimeZonePageContributor.cs index a23a32cb53..6effd64494 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/Settings/TimeZonePageContributor.cs +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/Settings/TimeZonePageContributor.cs @@ -20,8 +20,7 @@ public class TimeZonePageContributor : ISettingComponentContributor new SettingComponentGroup( "Volo.Abp.TimeZone", l["Menu:TimeZone"], - typeof(TimeZoneSettingGroupViewComponent), - order : 4 + typeof(TimeZoneSettingGroupViewComponent) ) ); } diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/SettingPageCreationContext.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/SettingPageCreationContext.cs index 51490e4e63..957342592d 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/SettingPageCreationContext.cs +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/SettingPageCreationContext.cs @@ -25,7 +25,7 @@ public class SettingPageCreationContext : IServiceProviderAccessor private void Order() { - var orderedItems = Groups.OrderBy(item => item.Order).ToArray(); + var orderedItems = Groups.OrderBy(item => item.Order).ThenBy(item => item.DisplayName).ToArray(); Groups.Clear(); Groups.AddRange(orderedItems); } diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Settings/EmailingPageContributor.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Settings/EmailingPageContributor.cs index 0c369f12ff..5096404a11 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Settings/EmailingPageContributor.cs +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Settings/EmailingPageContributor.cs @@ -23,8 +23,7 @@ public class EmailingPageContributor : SettingPageContributorBase new SettingPageGroup( "Volo.Abp.EmailSetting", l["Menu:Emailing"], - typeof(EmailSettingGroupViewComponent), - order : 3 + typeof(EmailSettingGroupViewComponent) ) ); return Task.CompletedTask; diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Settings/TimeZonePageContributor.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Settings/TimeZonePageContributor.cs index 21c35baccc..696d1204da 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Settings/TimeZonePageContributor.cs +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Settings/TimeZonePageContributor.cs @@ -25,8 +25,7 @@ public class TimeZonePageContributor : SettingPageContributorBase new SettingPageGroup( "Volo.Abp.TimeZone", l["Menu:TimeZone"], - typeof(TimeZoneSettingGroupViewComponent), - order : 4 + typeof(TimeZoneSettingGroupViewComponent) ) ); } From daa151108b4e3ae1db4a6a7dfeb7a0b2c7e414ff Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Wed, 2 Aug 2023 12:48:10 +0800 Subject: [PATCH 23/39] Update SettingComponentGroup.cs --- .../Volo.Abp.SettingManagement.Blazor/SettingComponentGroup.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/SettingComponentGroup.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/SettingComponentGroup.cs index 7b1aca36aa..0577f38b76 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/SettingComponentGroup.cs +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/SettingComponentGroup.cs @@ -5,7 +5,7 @@ namespace Volo.Abp.SettingManagement.Blazor; public class SettingComponentGroup { - public const int DefaultOrder = 1; + public const int DefaultOrder = 1000; public string Id { get => _id; From 132f2741f475f43a56a4a70f05aabead5e57e6c9 Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Wed, 2 Aug 2023 13:25:49 +0800 Subject: [PATCH 24/39] Update SettingPageCreationContext --- .../SettingComponentCreationContext.cs | 6 ++---- .../Pages/SettingManagement/SettingPageCreationContext.cs | 6 ++---- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/SettingComponentCreationContext.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/SettingComponentCreationContext.cs index ff386cc260..390110430c 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/SettingComponentCreationContext.cs +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/SettingComponentCreationContext.cs @@ -9,7 +9,7 @@ public class SettingComponentCreationContext : IServiceProviderAccessor { public IServiceProvider ServiceProvider { get; } - public List Groups { get; } + public List Groups { get; private set; } public SettingComponentCreationContext(IServiceProvider serviceProvider) { @@ -25,8 +25,6 @@ public class SettingComponentCreationContext : IServiceProviderAccessor private void Order() { - var orderedItems = Groups.OrderBy(item => item.Order).ThenBy(item => item.DisplayName).ToArray(); - Groups.Clear(); - Groups.AddRange(orderedItems); + Groups = Groups.OrderBy(item => item.Order).ThenBy(item => item.DisplayName).ToList(); } } diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/SettingPageCreationContext.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/SettingPageCreationContext.cs index 957342592d..d620ced0b9 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/SettingPageCreationContext.cs +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/SettingPageCreationContext.cs @@ -9,7 +9,7 @@ public class SettingPageCreationContext : IServiceProviderAccessor { public IServiceProvider ServiceProvider { get; } - public List Groups { get; } + public List Groups { get; private set; } public SettingPageCreationContext(IServiceProvider serviceProvider) { @@ -25,8 +25,6 @@ public class SettingPageCreationContext : IServiceProviderAccessor private void Order() { - var orderedItems = Groups.OrderBy(item => item.Order).ThenBy(item => item.DisplayName).ToArray(); - Groups.Clear(); - Groups.AddRange(orderedItems); + Groups = Groups.OrderBy(item => item.Order).ThenBy(item => item.DisplayName).ToList(); } } From 2f112e136726e7340727f704da3d6567f73ebfe1 Mon Sep 17 00:00:00 2001 From: Sinan997 Date: Wed, 2 Aug 2023 13:54:32 +0300 Subject: [PATCH 25/39] SORT_COMPARE_FUNC injection token added --- .../packages/core/src/lib/core.module.ts | 5 ++++ .../core/src/lib/services/routes.service.ts | 24 +++-------------- .../core/src/lib/tokens/compare-func.token.ts | 27 +++++++++++++++++++ 3 files changed, 35 insertions(+), 21 deletions(-) create mode 100644 npm/ng-packs/packages/core/src/lib/tokens/compare-func.token.ts diff --git a/npm/ng-packs/packages/core/src/lib/core.module.ts b/npm/ng-packs/packages/core/src/lib/core.module.ts index c2d497ae7b..c4f7c78fa7 100644 --- a/npm/ng-packs/packages/core/src/lib/core.module.ts +++ b/npm/ng-packs/packages/core/src/lib/core.module.ts @@ -38,6 +38,7 @@ import { SafeHtmlPipe } from './pipes/safe-html.pipe'; import { QUEUE_MANAGER } from './tokens/queue.token'; import { DefaultQueueManager } from './utils/queue'; import { IncludeLocalizationResourcesProvider } from './providers/include-localization-resources.provider'; +import { SORT_COMPARE_FUNC, compareFuncFactory } from './tokens/compare-func.token'; /** * BaseCoreModule is the module that holds @@ -176,6 +177,10 @@ export class CoreModule { useValue: localizationContributor(options.localizations), deps: [LocalizationService], }, + { + provide: SORT_COMPARE_FUNC, + useFactory: compareFuncFactory + }, { provide: QUEUE_MANAGER, useClass: DefaultQueueManager, diff --git a/npm/ng-packs/packages/core/src/lib/services/routes.service.ts b/npm/ng-packs/packages/core/src/lib/services/routes.service.ts index 5f05eaa8ab..c3a1ffe07f 100644 --- a/npm/ng-packs/packages/core/src/lib/services/routes.service.ts +++ b/npm/ng-packs/packages/core/src/lib/services/routes.service.ts @@ -12,7 +12,7 @@ import { } from '../utils/tree-utils'; import { ConfigStateService } from './config-state.service'; import { PermissionService } from './permission.service'; -import { LocalizationService } from './localization.service'; +import { SORT_COMPARE_FUNC } from '../tokens/compare-func.token'; // eslint-disable-next-line @typescript-eslint/ban-types export abstract class AbstractTreeService { @@ -159,7 +159,7 @@ export abstract class AbstractNavTreeService { private subscription: Subscription; private permissionService: PermissionService; - private localizationService: LocalizationService + private compareFunc; readonly id = 'name'; readonly parentId = 'parentName'; readonly hide = (item: T) => item.invisible || !this.isGranted(item); @@ -167,24 +167,6 @@ export abstract class AbstractNavTreeService return this.compareFunc(a,b) }; - readonly compareFunc = (a: T, b: T) => { - const aName = this.localizationService.instant(a.name); - const bName = this.localizationService.instant(b.name); - const aNumber = a.order; - const bNumber = b.order; - - if (!Number.isInteger(aNumber)) return 1; - if (!Number.isInteger(bNumber)) return -1; - - if (aNumber > bNumber) return 1 - if (aNumber < bNumber) return -1 - - if ( aName > bName ) return 1; - if ( aName < bName ) return -1; - - return 0 - } - constructor(protected injector: Injector) { super(); const configState = this.injector.get(ConfigStateService); @@ -192,8 +174,8 @@ export abstract class AbstractNavTreeService .createOnUpdateStream(state => state) .subscribe(() => this.refresh()); this.permissionService = injector.get(PermissionService); - this.localizationService = injector.get(LocalizationService); this.othersGroup = injector.get(OTHERS_GROUP); + this.compareFunc = injector.get(SORT_COMPARE_FUNC); } protected isGranted({ requiredPolicy }: T): boolean { diff --git a/npm/ng-packs/packages/core/src/lib/tokens/compare-func.token.ts b/npm/ng-packs/packages/core/src/lib/tokens/compare-func.token.ts new file mode 100644 index 0000000000..bf66ec2b54 --- /dev/null +++ b/npm/ng-packs/packages/core/src/lib/tokens/compare-func.token.ts @@ -0,0 +1,27 @@ +import { InjectionToken, inject } from '@angular/core'; +import { LocalizationService } from '../services'; + +export const SORT_COMPARE_FUNC = new InjectionToken< 0 | 1 | -1 >('SORT_COMPARE_FUNC'); + +export function compareFuncFactory() { + const localizationService = inject(LocalizationService) + const fn = (a,b) => { + const aName = localizationService.instant(a.name); + const bName = localizationService.instant(b.name); + const aNumber = a.order; + const bNumber = b.order; + + if (!Number.isInteger(aNumber)) return 1; + if (!Number.isInteger(bNumber)) return -1; + + if (aNumber > bNumber) return 1 + if (aNumber < bNumber) return -1 + + if ( aName > bName ) return 1; + if ( aName < bName ) return -1; + + return 0 + } + + return fn +} \ No newline at end of file From 272580aeeb59fc46a835c521bd9c6d0b32043ea6 Mon Sep 17 00:00:00 2001 From: maliming Date: Thu, 3 Aug 2023 12:57:31 +0800 Subject: [PATCH 26/39] Update AbpHostingHostBuilderExtensions.cs Close #17261 --- .../Extensions/Hosting/AbpHostingHostBuilderExtensions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/src/Volo.Abp.Core/Microsoft/Extensions/Hosting/AbpHostingHostBuilderExtensions.cs b/framework/src/Volo.Abp.Core/Microsoft/Extensions/Hosting/AbpHostingHostBuilderExtensions.cs index 767fa43f1d..09f6ed9bed 100644 --- a/framework/src/Volo.Abp.Core/Microsoft/Extensions/Hosting/AbpHostingHostBuilderExtensions.cs +++ b/framework/src/Volo.Abp.Core/Microsoft/Extensions/Hosting/AbpHostingHostBuilderExtensions.cs @@ -15,7 +15,7 @@ public static class AbpHostingHostBuilderExtensions return hostBuilder.ConfigureAppConfiguration((_, builder) => { builder.AddJsonFile( - path: AppSettingsSecretJsonPath, + path: path, optional: optional, reloadOnChange: reloadOnChange ); From b7ebe0121d3c4f04ab3dd88ec810eaced6585954 Mon Sep 17 00:00:00 2001 From: minhtaile2712 Date: Thu, 3 Aug 2023 12:17:10 +0700 Subject: [PATCH 27/39] Correct links Correct links to valid branch (`dev` instead of `master`). --- docs/en/Modules/Index.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/en/Modules/Index.md b/docs/en/Modules/Index.md index d5037665f0..5e280268e7 100644 --- a/docs/en/Modules/Index.md +++ b/docs/en/Modules/Index.md @@ -4,8 +4,8 @@ ABP is a **modular application framework** which consists of dozens of **NuGet & There are **two types of modules.** They don't have any structural difference but are categorized by functionality and purpose: -* [**Framework modules**](https://github.com/abpframework/abp/tree/master/framework/src): These are **core modules of the framework** like caching, emailing, theming, security, serialization, validation, EF Core integration, MongoDB integration... etc. They do not have application/business functionalities but makes your daily development easier by providing common infrastructure, integration and abstractions. -* [**Application modules**](https://github.com/abpframework/abp/tree/master/modules): These modules implement specific application/business functionalities like blogging, document management, identity management, tenant management... etc. They generally have their own entities, services, APIs and UI components. +* [**Framework modules**](https://github.com/abpframework/abp/tree/dev/framework/src): These are **core modules of the framework** like caching, emailing, theming, security, serialization, validation, EF Core integration, MongoDB integration... etc. They do not have application/business functionalities but makes your daily development easier by providing common infrastructure, integration and abstractions. +* [**Application modules**](https://github.com/abpframework/abp/tree/dev/modules): These modules implement specific application/business functionalities like blogging, document management, identity management, tenant management... etc. They generally have their own entities, services, APIs and UI components. ## Open Source Application Modules @@ -29,4 +29,4 @@ See [the GitHub repository](https://github.com/abpframework/abp/tree/dev/modules ## Commercial Application Modules -[ABP Commercial](https://commercial.abp.io/) license provides **additional pre-built application modules** on top of the ABP framework. See the [module list](https://commercial.abp.io/modules) provided by the ABP Commercial. \ No newline at end of file +[ABP Commercial](https://commercial.abp.io/) license provides **additional pre-built application modules** on top of the ABP framework. See the [module list](https://commercial.abp.io/modules) provided by the ABP Commercial. From d9170bb3a1455d9278623026fd476721f0ed93a0 Mon Sep 17 00:00:00 2001 From: Sinan997 Date: Thu, 3 Aug 2023 09:53:55 +0300 Subject: [PATCH 28/39] update --- docs/en/UI/Angular/CapsLock.directive.md | 6 +++--- .../packages/core/src/lib/tests/capsLock.directive.spec.ts | 1 - .../core/src/lib/tests/show-password-directive.spec.ts | 6 +----- 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/docs/en/UI/Angular/CapsLock.directive.md b/docs/en/UI/Angular/CapsLock.directive.md index 1e1021bdd4..64a3fc42ca 100644 --- a/docs/en/UI/Angular/CapsLock.directive.md +++ b/docs/en/UI/Angular/CapsLock.directive.md @@ -39,7 +39,7 @@ See an example usage:
- icon + icon
` }) @@ -59,10 +59,10 @@ import { TrackCapsLockDirective } from '@abp/ng.core'
- icon + icon
`, - imports: [ TrackCapsLockDirective ] + imports: [TrackCapsLockDirective] }) export class StandaloneComponent{ capsLock = false; diff --git a/npm/ng-packs/packages/core/src/lib/tests/capsLock.directive.spec.ts b/npm/ng-packs/packages/core/src/lib/tests/capsLock.directive.spec.ts index 17d50ba697..3182dfa2dd 100644 --- a/npm/ng-packs/packages/core/src/lib/tests/capsLock.directive.spec.ts +++ b/npm/ng-packs/packages/core/src/lib/tests/capsLock.directive.spec.ts @@ -28,7 +28,6 @@ describe('TrackCapsLockDirective',()=>{ des = fixture.debugElement.queryAll(By.directive(TrackCapsLockDirective)); }); - // tests test.each(['keydown','keyup'])('is %p works when press capslock and is emit status', (eventName) => { const event = new KeyboardEvent(eventName, { key: 'CapsLock', diff --git a/npm/ng-packs/packages/core/src/lib/tests/show-password-directive.spec.ts b/npm/ng-packs/packages/core/src/lib/tests/show-password-directive.spec.ts index e1e9750995..8babb472c4 100644 --- a/npm/ng-packs/packages/core/src/lib/tests/show-password-directive.spec.ts +++ b/npm/ng-packs/packages/core/src/lib/tests/show-password-directive.spec.ts @@ -27,19 +27,15 @@ describe('ShowPasswordDirective',()=>{ imports: [ TestComponent ] }).createComponent(TestComponent) - fixture.detectChanges(); // initial binding + fixture.detectChanges(); - // all elements with an attached HighlightDirective des = fixture.debugElement.queryAll(By.directive(ShowPasswordDirective)); - // all inputs includes nondirective desAll = fixture.debugElement.queryAll(By.all()); - // the input without the ShowPasswordDirective bareInput = fixture.debugElement.query(By.css('input:not([abpShowPassword])')); }) - // tests it('should have three input has ShowPasswordDirective elements', () => { expect(des.length).toBe(3); }); From 8d02cf83ef0873da98919ee6b2de95e274cc2d8e Mon Sep 17 00:00:00 2001 From: Sinan997 Date: Tue, 1 Aug 2023 08:12:01 +0300 Subject: [PATCH 29/39] decreasing margin for form prop --- .../extensible-form/extensible-form-prop.component.html | 2 +- .../extensible-form/extensible-form-prop.component.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/npm/ng-packs/packages/theme-shared/extensions/src/lib/components/extensible-form/extensible-form-prop.component.html b/npm/ng-packs/packages/theme-shared/extensions/src/lib/components/extensible-form/extensible-form-prop.component.html index 26dcbf1297..2f16d5d905 100644 --- a/npm/ng-packs/packages/theme-shared/extensions/src/lib/components/extensible-form/extensible-form-prop.component.html +++ b/npm/ng-packs/packages/theme-shared/extensions/src/lib/components/extensible-form/extensible-form-prop.component.html @@ -7,7 +7,7 @@ -
+
[]> = of([]); From f178443b737dbc7b50853b24cf8ffac3c8e0471c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Thu, 3 Aug 2023 10:02:16 +0300 Subject: [PATCH 30/39] Update docs-nav.json --- docs/en/docs-nav.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/en/docs-nav.json b/docs/en/docs-nav.json index c6c07d9a7c..08046fa664 100644 --- a/docs/en/docs-nav.json +++ b/docs/en/docs-nav.json @@ -1522,6 +1522,10 @@ } ] }, + { + "text": "API Documentation", + "path": "{ApiDocumentationUrl}" + }, { "text": "Contribution Guide", "path": "Contribution/Index.md" From 5c066c5b3f6fcbad97149b44d065ae7a9fb1870b Mon Sep 17 00:00:00 2001 From: Sinan997 Date: Fri, 28 Jul 2023 14:59:40 +0300 Subject: [PATCH 31/39] show password directive test and document --- docs/en/UI/Angular/Show-Password-Directive.md | 52 +++++++++++++++ .../Angular/images/showPasswordDirective1.png | Bin 0 -> 3707 bytes .../Angular/images/showPasswordDirective2.png | Bin 0 -> 3932 bytes .../lib/tests/show-password-directive.spec.ts | 59 ++++++++++++++++++ 4 files changed, 111 insertions(+) create mode 100644 docs/en/UI/Angular/Show-Password-Directive.md create mode 100644 docs/en/UI/Angular/images/showPasswordDirective1.png create mode 100644 docs/en/UI/Angular/images/showPasswordDirective2.png create mode 100644 npm/ng-packs/packages/core/src/lib/tests/show-password-directive.spec.ts diff --git a/docs/en/UI/Angular/Show-Password-Directive.md b/docs/en/UI/Angular/Show-Password-Directive.md new file mode 100644 index 0000000000..db54bcdd76 --- /dev/null +++ b/docs/en/UI/Angular/Show-Password-Directive.md @@ -0,0 +1,52 @@ +# Show Password Directive + +In password input, text can be shown easily via changing input type attribute to `text`. To make this even easier, you can use the `ShowPasswordDirective` which has been exposed by the `@abp/ng.core` package. + + +## Getting Started + +In order to use the `ShowPasswordDirective` in an HTML template, the **`CoreModule`** should be imported into your module like this: + +```ts +// ... +import { CoreModule } from '@abp/ng.core'; + +@NgModule({ + //... + imports: [..., CoreModule], +}) +export class MyFeatureModule {} +``` + +## Usage + +The `ShowPasswordDirective` is very easy to use. The directive's selector is **`abpShowPassword`**. By adding the `abpShowPassword` attribute to an input element, you can activate the `ShowPasswordDirective` for the input element. + +See an example usage: + +```ts +@Component({ + selector: 'test-component', + standalone: true, + template: ` +
+ + + icon +
+ ` +}) +export class TestComponent{ + showPassword = false; +} +``` + +The `abpShowPassword` attribute has been added to the `` element. Click icon to activate the `ShowPasswordDirective`. + +See the result: + +![Show Password directive](./images/showPasswordDirective1.png) + +To see password input click icon. + +![Show Password directive](./images/showPasswordDirective2.png) \ No newline at end of file diff --git a/docs/en/UI/Angular/images/showPasswordDirective1.png b/docs/en/UI/Angular/images/showPasswordDirective1.png new file mode 100644 index 0000000000000000000000000000000000000000..7b64be2b5f14c8e8affb7849331f0f5398188193 GIT binary patch literal 3707 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 YNubRLytJp=IDz)l)k46FG%?Tr1J+;SK>z>% literal 0 HcmV?d00001 diff --git a/docs/en/UI/Angular/images/showPasswordDirective2.png b/docs/en/UI/Angular/images/showPasswordDirective2.png new file mode 100644 index 0000000000000000000000000000000000000000..43199ffeaa2b1a813743599a1f74137404254ee0 GIT binary patch literal 3932 zcma)9c{r5c+aIzg+4mt!mWYsb)W|+)rYPB$3`(|;ol(-*X~w=Q5h457cP4u=XzW`m zG)N5D-pBWP|NOr1?{}{2dCqyx@|^qr-1j;6{fW8**So;L%K!p_F2MA)jX@wv7|^~; zM+3ZjGvwDnpo{b{?OXT!vwqE@JPEtm_-*kf;t{K<#)AlHnHH)73MMRNmwXoN`BRSd zjJid*^c_*jD+F7X50*?Z{x&|tx+PTL>je5@AKtn zGBQ$M)L5St=%BwP1k={m7Nv?1JsW0b#{gg2ns@$n@QqAiWrtn&qv&3{$cKry0t|tv ze<#!J674F&hczG_cHecZKa2?Vv9qB&xOIXorJnD}(os#xmi)7IjHA4cLv*~5no^FP zGc5(`N$y9*_p;L%ZM=<+v$MGEKK#!?uP{(j$Lw~l#p;UuavKV95!~ZWmlT6joJlD> z$JNT_Qlrke4 z#)_Yn70TN^TyvmC)^Pk@KXSX~BQOx^mjCC0>|NzR0Yg&e?H6)keas6B6XUK|$es1H z{=daJ<1bd)L#*K^D0g9*9Ue}2H8Tg}=X>`f>W(>BSPp!n+7pqTDe^S%4az0h{@i_j ziRN4|n$pvOa{#rt(nvn9a?;h5HoC9Y7SKXzZDi-UN;|hn!)uFZ^X?TkIHZ$&C8IrcW zR?Nk_`s>2G5Ap2E5#{1fY3=lTy-T}iKO)YIC{qT22E(=Xk5yBI(_=qIcRpx*HN`s@ zgw^PGEj(T4?j^c1$`R}-_v@ceOq1-1OL7~k_u${0l))NZMHKR(zZpeIOP@(@uBY|X zVc}@Lr!z=&3Q||8wTHISPtKmdJDvx2obSb*0W-eG;jy`%L-+0Kq6c0+J&_U;Pf-?E z-(rnkGR8CeA;*ZSCPf1!o(P^m>f98-;8yM|Y?$F8*jiuj)dZ-Hg`w&+`PajNI$e3e zY9DaP)rAHQrQX{JhfY^69$ZTGDpcvq7MeC-O&3x;R=D7Qi4C7Kenc8^w}6)B|J=?@ zUlY_Cd;LI#8=7e;rV>@9WZZNU^uYS3hcs}OUQ2hTg1EbWJmDke*nTR%NFKdDp{q%L zy;v=5!|+K`t5T$yQzY*!I2_0<|-C>kG;c(dcVp z(TqlO0p`9T7PYBDKjUd*PHU5Y?Ld_j)EcHin{~53wNYwU|Ll0j`m;J6XF=T4jYhZT z`rf}Sj_(I&1_T9N03Y9*Rpv=bO!QpUM8vnOxxj-@ets(zuTeSQwVd(T#pR$s|NWwf zT()~b?PP|*He(YHibn`imrdOG;giQhV3BhLQk*Zq=qe;m_y9knGb%Xxn^Fb;b;VdQ(E z3FPY^w5EYng2pI+XyEiv))ZOkupf7q0|Itl&1O7C^3~$QQ{R==?|1l69og4LZADE3 zz9nyGmL+YDME9qDnm49R(@*!~qQ@&$I}M4sB-B4vGw#?^lp+QX>h?AhHNuuHO{?=+ z3uV3J#z*IEm-zpQHw{$MMz#cw$luDQ&rm77-Crn}Qj$FzCmU?843yBt<_uDSDC?EW zNeu9qEXIb;&t}31c14H%>|vWQFV9HZp>?`F-jn{DGy# zlfE&7#9Ytk2z$TGyy}rPzfM32J1^~Z`(%xsrn3|#s06AH)+s^a1BlX@SjH0vLQpW5 zc`V1_ubsZuQzp!Ee#4%`oDF^ymhH)=9JhX~5ctUZV~}N$YK7%-YM#JZ)XDoMvZpxL z9@`W;SdhlMM+hA*LZK^hj`9%Il;u;uj0MF$Bint6VXBL$&|UKNnzVYEWl7Rus@WcU zDe~~kr}TO-g(1l7Y5Av~X9-|KMuG>tb9*HM2S>e0o9U4>i?t11!tdM?*hyty_-UxB zV9gHA)G-)|a+qV7xX~KcoDDK}o!RVkKXEacCs`SP=W6dpVlGbD$xe;P|AuAT-um6m z>%z46?h+vE^Ka8tR2psQf_JDH#PABYI=aQI*JAr68^%?}V6IP?XxU#vn|gP}d�Y zx-=@ZKc@!UqB`SJS~_LXdsHc4kZavv)ya!NHN1YKx6!>ZL-8~2tgiLj$XwO;4d2+Ksk1Ka;xH8ZN3$6e-$NX3jNU>tlZ zQ4zb%Z~F#Oi;t_uFmlS1clM@ox8~DtyNp??q?Cu(Xb)zGy7Z^s^et7LP>40(j182Xjlu#7K|v}%u{U_&hCCOuTzgM(&s4_1Dys#{!414iZG}UF zRtzUsc~Bwr2Tv%xid7ipPLnh_+eL~+d5`xk2Sth5AnE!(hE}yJ!+aT;ZLP6uYij*D zbzLN3D@5sfNarK*@l%u8<)YY0E=vA9q@SeD0C;6`e`|bY+04es{Pt$PDj?TpQoAHP zXy$qVjjqNEx*xE=Xm>@vuh~?0_nhxW{%~$XG=^&x^VRqkiIvN7R?wrg zTzvfy_EjOQFRI&LO2WND!LRfj1XeKBj@k!(CvOurCEpU9JLJE_hfD=qAyAzsIyc0^ z4@3L|TWVLk)(@+Ot-L6{*95L@FA*&?Nbmf`fV;x0N84Rro^t8dk#JgaWlUxwaV%;fdRt0cIzjw`v++JMTNJ4&gZ?)2xP51m8SQ0zHm4)Tx?@- z0(r*{RmS0|)%iX4&dH^HY$4bhpC!NdSN23hRBMzJQjZRIB#sHu%eQD-=1|qZ2G!>e zuLZ}vf)=KGlM*lus(N3Guv5)=>zrJfd8@U2sSm% zKB@rOC=pkc*ftja%s}aUVOoc!?#~nfvXb~~vgW41dv7xPnU~3UX|Yn*hh`ddurcuu z?0ACavM=9b^v=n|URTK8?g9;p4*OufzOD7}+a+uZvA*ryo#!$cL-8U#v6~u_93+pM)@PVZhFKZ?&J1|(k3;aqTJif) zzhlq?Y(8)P8uAn(3JuK_L>c zjJq2d-D*_}tcU$l1>Wa%dN{rM+>Wqk(j~bD8R|G1jnw z`MCDZ@=)!+hCZ(R+0XZYB}6O%R#6?^v1)HWf0l`?81T6Y=mI@<6$%@5_J|p#eM>ps zI0gei1J*AznP~g#y!88)hlExH-%K4&(IGm@;fLbnm$?apyjeuv#aT08qHrpvk3CLO z?bVO3Dlf9ZH8@4`fkg-d?DP0r + + + `, + imports:[ShowPasswordDirective] +}) +class TestComponent { + showPassword:boolean = false +} + +describe('ShowPasswordDirective',()=>{ + let fixture: ComponentFixture;; + let des : DebugElement[]; + let desAll : DebugElement[]; + let bareInput; + + beforeEach(()=>{ + fixture = TestBed.configureTestingModule({ + imports: [ TestComponent ] + }).createComponent(TestComponent) + + fixture.detectChanges(); // initial binding + + // all elements with an attached HighlightDirective + des = fixture.debugElement.queryAll(By.directive(ShowPasswordDirective)); + + // all inputs includes nondirective + desAll = fixture.debugElement.queryAll(By.all()); + + // the input without the ShowPasswordDirective + bareInput = fixture.debugElement.query(By.css('input:not([abpShowPassword])')); + }) + + // color tests + it('should have three input has ShowPasswordDirective elements', () => { + expect(des.length).toBe(3); + }); + + test.each([[0,'text'],[1,'password'],[2,'text'],[3,'password']])('%p. input type must be %p)', (index,inpType) => { + const inputType = desAll[index].nativeElement.type; + expect(inputType).toBe(inpType); + }); + + it('should have three input has ShowPasswordDirective elements', () => { + let input = des[2].nativeElement + expect(input.type).toBe('password') + fixture.componentInstance.showPassword = true + fixture.detectChanges() + expect(input.type).toBe('text') + }); + }); \ No newline at end of file From b61cd17d3167653b0f0a84b9717769bcafffa1f6 Mon Sep 17 00:00:00 2001 From: Sinan997 Date: Sun, 30 Jul 2023 23:48:51 +0300 Subject: [PATCH 32/39] capsLock doc and test --- .../src/lib/tests/capsLock.directive.spec.ts | 58 +++++++++++++++++++ .../lib/tests/show-password-directive.spec.ts | 2 +- 2 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 npm/ng-packs/packages/core/src/lib/tests/capsLock.directive.spec.ts diff --git a/npm/ng-packs/packages/core/src/lib/tests/capsLock.directive.spec.ts b/npm/ng-packs/packages/core/src/lib/tests/capsLock.directive.spec.ts new file mode 100644 index 0000000000..17d50ba697 --- /dev/null +++ b/npm/ng-packs/packages/core/src/lib/tests/capsLock.directive.spec.ts @@ -0,0 +1,58 @@ +import { Component, DebugElement } from '@angular/core' +import { ComponentFixture, TestBed } from '@angular/core/testing' +import { TrackCapsLockDirective } from '../directives'; +import { By } from '@angular/platform-browser'; + +@Component({ + standalone:true, + template: ` + + `, + imports:[TrackCapsLockDirective] +}) +class TestComponent { + capsLock:boolean = false +} + +describe('TrackCapsLockDirective',()=>{ + let fixture: ComponentFixture;; + let des : DebugElement[]; + + beforeEach(()=>{ + fixture = TestBed.configureTestingModule({ + imports: [ TestComponent ] + }).createComponent(TestComponent); + + fixture.detectChanges(); + + des = fixture.debugElement.queryAll(By.directive(TrackCapsLockDirective)); + }); + + // tests + test.each(['keydown','keyup'])('is %p works when press capslock and is emit status', (eventName) => { + const event = new KeyboardEvent(eventName, { + key: 'CapsLock', + modifierCapsLock: true + }); + window.dispatchEvent(event); + fixture.detectChanges(); + expect(fixture.componentInstance.capsLock).toBe(true) + }); + + test.each(['keydown','keyup'])('is %p detect the change capslock is emit status', (eventName) => { + const trueEvent = new KeyboardEvent(eventName, { + key: 'CapsLock', + modifierCapsLock: true + }); + window.dispatchEvent(trueEvent); + fixture.detectChanges(); + expect(fixture.componentInstance.capsLock).toBe(true) + const falseEvent = new KeyboardEvent(eventName, { + key: 'CapsLock', + modifierCapsLock: false + }); + window.dispatchEvent(falseEvent); + fixture.detectChanges(); + expect(fixture.componentInstance.capsLock).toBe(false) + }); + }); \ No newline at end of file diff --git a/npm/ng-packs/packages/core/src/lib/tests/show-password-directive.spec.ts b/npm/ng-packs/packages/core/src/lib/tests/show-password-directive.spec.ts index 6b07997bc9..e1e9750995 100644 --- a/npm/ng-packs/packages/core/src/lib/tests/show-password-directive.spec.ts +++ b/npm/ng-packs/packages/core/src/lib/tests/show-password-directive.spec.ts @@ -39,7 +39,7 @@ describe('ShowPasswordDirective',()=>{ bareInput = fixture.debugElement.query(By.css('input:not([abpShowPassword])')); }) - // color tests + // tests it('should have three input has ShowPasswordDirective elements', () => { expect(des.length).toBe(3); }); From 9f10aeb148b89aa86245f9f6b59464661877a2ab Mon Sep 17 00:00:00 2001 From: Sinan997 Date: Sun, 30 Jul 2023 23:49:52 +0300 Subject: [PATCH 33/39] capsLock doc and test --- docs/en/UI/Angular/CapsLock.directive.md | 52 ++++++++++++++++++ .../UI/Angular/images/CapsLockDirective1.png | Bin 0 -> 2224 bytes .../UI/Angular/images/CapsLockDirective2.png | Bin 0 -> 4274 bytes 3 files changed, 52 insertions(+) create mode 100644 docs/en/UI/Angular/CapsLock.directive.md create mode 100644 docs/en/UI/Angular/images/CapsLockDirective1.png create mode 100644 docs/en/UI/Angular/images/CapsLockDirective2.png diff --git a/docs/en/UI/Angular/CapsLock.directive.md b/docs/en/UI/Angular/CapsLock.directive.md new file mode 100644 index 0000000000..4b92d61124 --- /dev/null +++ b/docs/en/UI/Angular/CapsLock.directive.md @@ -0,0 +1,52 @@ +# Show Password Directive + +In password inputs,You may want to show if Caps Lock is on. To make this even easier, you can use the `TrackCapsLockDirective` which has been exposed by the `@abp/ng.core` package. + + +## Getting Started + +In order to use the `TrackCapsLockDirective` in an HTML template, the **`CoreModule`** should be imported into your module like this: + +```ts +// ... +import { CoreModule } from '@abp/ng.core'; + +@NgModule({ + //... + imports: [..., CoreModule], +}) +export class MyFeatureModule {} +``` + +## Usage + +The `TrackCapsLockDirective` is very easy to use. The directive's selector is **`abpCapsLock`**. By adding the `abpCapsLock` event to an element, you can track the status of Caps Lock. U can use this to warn user + +See an example usage: + +```ts +@Component({ + selector: 'test-component', + standalone: true, + template: ` +
+ + + icon +
+ ` +}) +export class TestComponent{ + capsLock = false; +} +``` + +The `abpCapsLock` event has been added to the `` element. Press Caps Lock to activate the `TrackCapsLockDirective`. + +See the result: + +![Show Password directive](./images/CapsLockDirective1.png) + +To see Caps Lock icon press Caps Lock. + +![Show Password directive](./images/CapsLockDirective2.png) \ No newline at end of file diff --git a/docs/en/UI/Angular/images/CapsLockDirective1.png b/docs/en/UI/Angular/images/CapsLockDirective1.png new file mode 100644 index 0000000000000000000000000000000000000000..2f143d755fd2d331beed42c8ce9c361cb8aeaa0b GIT binary patch literal 2224 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 U>BitD2Pwepw$-gl!+XE~7Z`*$lmGw# literal 0 HcmV?d00001 From 4fd8dbc49a32c2ab665e9a28429c5ef530f81049 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sinan=20=C3=96zt=C3=BCrk?= <72804437+Sinan997@users.noreply.github.com> Date: Mon, 31 Jul 2023 10:48:56 +0300 Subject: [PATCH 34/39] Update CapsLock.directive.md --- docs/en/UI/Angular/CapsLock.directive.md | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/docs/en/UI/Angular/CapsLock.directive.md b/docs/en/UI/Angular/CapsLock.directive.md index 4b92d61124..a21057490c 100644 --- a/docs/en/UI/Angular/CapsLock.directive.md +++ b/docs/en/UI/Angular/CapsLock.directive.md @@ -5,15 +5,17 @@ In password inputs,You may want to show if Caps Lock is on. To make this even ea ## Getting Started -In order to use the `TrackCapsLockDirective` in an HTML template, the **`CoreModule`** should be imported into your module like this: +`TrackCapsLockDirective` is standalone. In order to use the `TrackCapsLockDirective` in an HTML template, import it to related module or your standalone component: ```ts -// ... -import { CoreModule } from '@abp/ng.core'; +import { TrackCapsLockDirective } from '@abp/ng.core'; @NgModule({ //... - imports: [..., CoreModule], + imports: [ + ..., + TrackCapsLockDirective + ], }) export class MyFeatureModule {} ``` @@ -25,6 +27,8 @@ The `TrackCapsLockDirective` is very easy to use. The directive's selector is ** See an example usage: ```ts +import { TrackCapsLockDirective } from '@abp/ng.core' + @Component({ selector: 'test-component', standalone: true, @@ -34,7 +38,8 @@ See an example usage: icon
- ` + `, + imports: [ TrackCapsLockDirective ] }) export class TestComponent{ capsLock = false; @@ -49,4 +54,4 @@ See the result: To see Caps Lock icon press Caps Lock. -![Show Password directive](./images/CapsLockDirective2.png) \ No newline at end of file +![Show Password directive](./images/CapsLockDirective2.png) From cd5867a3f8bd78fdd3b401384554a4934f04a445 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sinan=20=C3=96zt=C3=BCrk?= <72804437+Sinan997@users.noreply.github.com> Date: Mon, 31 Jul 2023 10:51:53 +0300 Subject: [PATCH 35/39] Update CapsLock.directive.md --- docs/en/UI/Angular/CapsLock.directive.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/en/UI/Angular/CapsLock.directive.md b/docs/en/UI/Angular/CapsLock.directive.md index a21057490c..24bef39cdc 100644 --- a/docs/en/UI/Angular/CapsLock.directive.md +++ b/docs/en/UI/Angular/CapsLock.directive.md @@ -1,6 +1,6 @@ -# Show Password Directive +# Caps Lock Directive -In password inputs,You may want to show if Caps Lock is on. To make this even easier, you can use the `TrackCapsLockDirective` which has been exposed by the `@abp/ng.core` package. +In password inputs, You may want to show if Caps Lock is on. To make this even easier, you can use the `TrackCapsLockDirective` which has been exposed by the `@abp/ng.core` package. ## Getting Started From 00c41f56698e2bdb84b27bc36b2255ea3be0cf50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sinan=20=C3=96zt=C3=BCrk?= <72804437+Sinan997@users.noreply.github.com> Date: Mon, 31 Jul 2023 10:58:53 +0300 Subject: [PATCH 36/39] Update Show-Password-Directive.md --- docs/en/UI/Angular/Show-Password-Directive.md | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/docs/en/UI/Angular/Show-Password-Directive.md b/docs/en/UI/Angular/Show-Password-Directive.md index db54bcdd76..6c3cbe4f45 100644 --- a/docs/en/UI/Angular/Show-Password-Directive.md +++ b/docs/en/UI/Angular/Show-Password-Directive.md @@ -4,16 +4,17 @@ In password input, text can be shown easily via changing input type attribute to ## Getting Started - -In order to use the `ShowPasswordDirective` in an HTML template, the **`CoreModule`** should be imported into your module like this: +`ShowPasswordDirective` is standalone. In order to use the `ShowPasswordDirective` in an HTML template, import it to related module or your standalone component: ```ts -// ... -import { CoreModule } from '@abp/ng.core'; +import { ShowPasswordDirective } from '@abp/ng.core'; @NgModule({ //... - imports: [..., CoreModule], + imports: [ + ..., + ShowPasswordDirective + ], }) export class MyFeatureModule {} ``` @@ -25,6 +26,7 @@ The `ShowPasswordDirective` is very easy to use. The directive's selector is **` See an example usage: ```ts +import { ShowPasswordDirective } from '@abp/ng.core'; @Component({ selector: 'test-component', standalone: true, @@ -34,7 +36,8 @@ See an example usage: icon
- ` + `, + imports: [ShowPasswordDirective] }) export class TestComponent{ showPassword = false; @@ -49,4 +52,4 @@ See the result: To see password input click icon. -![Show Password directive](./images/showPasswordDirective2.png) \ No newline at end of file +![Show Password directive](./images/showPasswordDirective2.png) From 1659274d7cfc7d70be56f5f921167aa6d3f760f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sinan=20=C3=96zt=C3=BCrk?= <72804437+Sinan997@users.noreply.github.com> Date: Mon, 31 Jul 2023 11:21:13 +0300 Subject: [PATCH 37/39] Update CapsLock.directive.md --- docs/en/UI/Angular/CapsLock.directive.md | 29 +++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/docs/en/UI/Angular/CapsLock.directive.md b/docs/en/UI/Angular/CapsLock.directive.md index 24bef39cdc..1e1021bdd4 100644 --- a/docs/en/UI/Angular/CapsLock.directive.md +++ b/docs/en/UI/Angular/CapsLock.directive.md @@ -7,11 +7,16 @@ In password inputs, You may want to show if Caps Lock is on. To make this even e `TrackCapsLockDirective` is standalone. In order to use the `TrackCapsLockDirective` in an HTML template, import it to related module or your standalone component: +**Importing to NgModule** ```ts import { TrackCapsLockDirective } from '@abp/ng.core'; @NgModule({ //... + declarations: [ + ..., + TestComponent + ], imports: [ ..., TrackCapsLockDirective @@ -22,15 +27,33 @@ export class MyFeatureModule {} ## Usage -The `TrackCapsLockDirective` is very easy to use. The directive's selector is **`abpCapsLock`**. By adding the `abpCapsLock` event to an element, you can track the status of Caps Lock. U can use this to warn user +The `TrackCapsLockDirective` is very easy to use. The directive's selector is **`abpCapsLock`**. By adding the `abpCapsLock` event to an element, you can track the status of Caps Lock. You can use this to warn user. See an example usage: +**NgModule Component usage** +```ts +@Component({ + selector: 'test-component', + template: ` +
+ + + icon +
+ ` +}) +export class TestComponent{ + capsLock = false; +} +``` + +**Standalone Component usage** ```ts import { TrackCapsLockDirective } from '@abp/ng.core' @Component({ - selector: 'test-component', + selector: 'standalone-component', standalone: true, template: `
@@ -41,7 +64,7 @@ import { TrackCapsLockDirective } from '@abp/ng.core' `, imports: [ TrackCapsLockDirective ] }) -export class TestComponent{ +export class StandaloneComponent{ capsLock = false; } ``` From 2372ce0f29cefaada74ec2b1a8eda306f39ecf87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sinan=20=C3=96zt=C3=BCrk?= <72804437+Sinan997@users.noreply.github.com> Date: Mon, 31 Jul 2023 12:22:36 +0300 Subject: [PATCH 38/39] Update Show-Password-Directive.md --- docs/en/UI/Angular/Show-Password-Directive.md | 26 +++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/docs/en/UI/Angular/Show-Password-Directive.md b/docs/en/UI/Angular/Show-Password-Directive.md index 6c3cbe4f45..c19c8073bd 100644 --- a/docs/en/UI/Angular/Show-Password-Directive.md +++ b/docs/en/UI/Angular/Show-Password-Directive.md @@ -6,11 +6,16 @@ In password input, text can be shown easily via changing input type attribute to ## Getting Started `ShowPasswordDirective` is standalone. In order to use the `ShowPasswordDirective` in an HTML template, import it to related module or your standalone component: +**Importing to NgModule** ```ts import { ShowPasswordDirective } from '@abp/ng.core'; @NgModule({ //... + declarations: [ + ..., + TestComponent + ], imports: [ ..., ShowPasswordDirective @@ -25,10 +30,27 @@ The `ShowPasswordDirective` is very easy to use. The directive's selector is **` See an example usage: +**NgModule Component usage** ```ts -import { ShowPasswordDirective } from '@abp/ng.core'; @Component({ selector: 'test-component', + template: ` +
+ + + icon +
+ ` +}) +export class TestComponent{ + showPassword = false; +} +``` +**Standalone Component usage** +```ts +import { ShowPasswordDirective } from '@abp/ng.core'; +@Component({ + selector: 'standalone-component', standalone: true, template: `
@@ -39,7 +61,7 @@ import { ShowPasswordDirective } from '@abp/ng.core'; `, imports: [ShowPasswordDirective] }) -export class TestComponent{ +export class StandaloneComponent{ showPassword = false; } ``` From 65512dd433bc9b0e4e237f8a2736e9677e98f168 Mon Sep 17 00:00:00 2001 From: Sinan997 Date: Thu, 3 Aug 2023 09:53:55 +0300 Subject: [PATCH 39/39] update --- docs/en/UI/Angular/CapsLock.directive.md | 6 +++--- .../packages/core/src/lib/tests/capsLock.directive.spec.ts | 1 - .../core/src/lib/tests/show-password-directive.spec.ts | 6 +----- 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/docs/en/UI/Angular/CapsLock.directive.md b/docs/en/UI/Angular/CapsLock.directive.md index 1e1021bdd4..64a3fc42ca 100644 --- a/docs/en/UI/Angular/CapsLock.directive.md +++ b/docs/en/UI/Angular/CapsLock.directive.md @@ -39,7 +39,7 @@ See an example usage:
- icon + icon
` }) @@ -59,10 +59,10 @@ import { TrackCapsLockDirective } from '@abp/ng.core'
- icon + icon
`, - imports: [ TrackCapsLockDirective ] + imports: [TrackCapsLockDirective] }) export class StandaloneComponent{ capsLock = false; diff --git a/npm/ng-packs/packages/core/src/lib/tests/capsLock.directive.spec.ts b/npm/ng-packs/packages/core/src/lib/tests/capsLock.directive.spec.ts index 17d50ba697..3182dfa2dd 100644 --- a/npm/ng-packs/packages/core/src/lib/tests/capsLock.directive.spec.ts +++ b/npm/ng-packs/packages/core/src/lib/tests/capsLock.directive.spec.ts @@ -28,7 +28,6 @@ describe('TrackCapsLockDirective',()=>{ des = fixture.debugElement.queryAll(By.directive(TrackCapsLockDirective)); }); - // tests test.each(['keydown','keyup'])('is %p works when press capslock and is emit status', (eventName) => { const event = new KeyboardEvent(eventName, { key: 'CapsLock', diff --git a/npm/ng-packs/packages/core/src/lib/tests/show-password-directive.spec.ts b/npm/ng-packs/packages/core/src/lib/tests/show-password-directive.spec.ts index e1e9750995..8babb472c4 100644 --- a/npm/ng-packs/packages/core/src/lib/tests/show-password-directive.spec.ts +++ b/npm/ng-packs/packages/core/src/lib/tests/show-password-directive.spec.ts @@ -27,19 +27,15 @@ describe('ShowPasswordDirective',()=>{ imports: [ TestComponent ] }).createComponent(TestComponent) - fixture.detectChanges(); // initial binding + fixture.detectChanges(); - // all elements with an attached HighlightDirective des = fixture.debugElement.queryAll(By.directive(ShowPasswordDirective)); - // all inputs includes nondirective desAll = fixture.debugElement.queryAll(By.all()); - // the input without the ShowPasswordDirective bareInput = fixture.debugElement.query(By.css('input:not([abpShowPassword])')); }) - // tests it('should have three input has ShowPasswordDirective elements', () => { expect(des.length).toBe(3); });