From 15487b0a50ecd42204562028c3675aa39259c47d Mon Sep 17 00:00:00 2001 From: Ushran Gouhar <43915259+ugouhar@users.noreply.github.com> Date: Tue, 23 Sep 2025 11:45:31 +0530 Subject: [PATCH] Issues/22729/bug fix avatar initial (#23499) * fix(ui): fix avatar inital * Add the fallback value * Add support for unicode characters --- .../ui/src/utils/CommonUtils.test.ts | 49 +++++++++++++++++++ .../resources/ui/src/utils/CommonUtils.tsx | 13 ++++- 2 files changed, 61 insertions(+), 1 deletion(-) diff --git a/openmetadata-ui/src/main/resources/ui/src/utils/CommonUtils.test.ts b/openmetadata-ui/src/main/resources/ui/src/utils/CommonUtils.test.ts index 07693bc67b7..cac6107ea82 100644 --- a/openmetadata-ui/src/main/resources/ui/src/utils/CommonUtils.test.ts +++ b/openmetadata-ui/src/main/resources/ui/src/utils/CommonUtils.test.ts @@ -13,6 +13,7 @@ import { filterSelectOptions, + getFirstAlphanumeric, getTableFQNFromColumnFQN, isLinearGradient, } from './CommonUtils'; @@ -120,4 +121,52 @@ describe('Tests for CommonUtils', () => { expect(isLinearGradient('')).toBe(false); }); }); + + describe('getFirstAlphanumeric', () => { + it('should return the first alphabet from name containing only alphabets', () => { + const firstAlphabet = getFirstAlphanumeric('John Doe'); + + expect(firstAlphabet).toBe('j'); + }); + + it('should return the first alphanumeric character from name containing both alphabets and numbers', () => { + let firstAlphabet = getFirstAlphanumeric('3John Doe'); + + expect(firstAlphabet).toBe('3'); + + firstAlphabet = getFirstAlphanumeric('John3 Doe'); + + expect(firstAlphabet).toBe('j'); + }); + + it('should return the first alphanumeric character from name containing special characters', () => { + let firstAlphabet = getFirstAlphanumeric('[Software Engineer] John Doe'); + + expect(firstAlphabet).toBe('s'); + + firstAlphabet = getFirstAlphanumeric('(Product Manager] Jane Doe'); + + expect(firstAlphabet).toBe('p'); + }); + + it('should fallback to the first character if there is no alphanumeric character found', () => { + const firstAlphabet = getFirstAlphanumeric('][/)([*'); + + expect(firstAlphabet).toBe(']'); + }); + + it('should return the first alphabet from name when it is not in english language', () => { + let firstAlphabet = getFirstAlphanumeric('🚀Éclair'); + + expect(firstAlphabet).toBe('é'); + + firstAlphabet = getFirstAlphanumeric('ชานนท์'); + + expect(firstAlphabet).toBe('ช'); + + firstAlphabet = getFirstAlphanumeric('ño'); + + expect(firstAlphabet).toBe('ñ'); + }); + }); }); diff --git a/openmetadata-ui/src/main/resources/ui/src/utils/CommonUtils.tsx b/openmetadata-ui/src/main/resources/ui/src/utils/CommonUtils.tsx index 6a0807e20b9..13ff9b8ef00 100644 --- a/openmetadata-ui/src/main/resources/ui/src/utils/CommonUtils.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/utils/CommonUtils.tsx @@ -403,8 +403,19 @@ export const getNameFromFQN = (fqn: string): string => { return arr[arr.length - 1]; }; +export const getFirstAlphanumeric = (name: string): string => { + /** + * \p{L} → matches any kind of letter from any language (Latin, Cyrillic, Chinese, etc.). + * \p{N} → matches any kind of numeric digit (Arabic-Indic, Roman numerals, etc.). + * u flag → required for Unicode property escapes to work. + */ + const match = name.match(/[\p{L}\p{N}]/u); + + return match ? match[0].toLowerCase() : name.charAt(0).toLowerCase(); +}; + export const getRandomColor = (name: string) => { - const firstAlphabet = name.charAt(0).toLowerCase(); + const firstAlphabet = getFirstAlphanumeric(name); // Convert the user's name to a numeric value let nameValue = 0; for (let i = 0; i < name.length; i++) {