diff --git a/packages/@sparrow-common/src/features/create-team/components/team-name/TeamName.svelte b/packages/@sparrow-common/src/features/create-team/components/team-name/TeamName.svelte index 17bbe6a49c..81bb580d78 100644 --- a/packages/@sparrow-common/src/features/create-team/components/team-name/TeamName.svelte +++ b/packages/@sparrow-common/src/features/create-team/components/team-name/TeamName.svelte @@ -24,11 +24,15 @@ */ const inputId: string = "team-name-input"; - const isOnlySpecialCharacters = (teamName: string) => { - // This regex checks if the string contains ONLY non-alphanumeric characters - return !/^(?!.*[^A-Za-z0-9]{3,})(?=.*[A-Za-z0-9])[\x20-\x7E]+$/.test( - teamName, - ); + const isValidHubName = (name: string) => { + const trimmedName = name.trim(); + // Check if empty + if (!trimmedName) return false; + // Check if contains at least one alphanumeric character + const hasAlphanumeric = /[a-zA-Z0-9]/.test(trimmedName); + // Check if contains only allowed characters (letters, digits, spaces, ., -, _) + const onlyAllowedChars = /^[a-zA-Z0-9._\- ]+$/.test(trimmedName); + return hasAlphanumeric && onlyAllowedChars; }; @@ -53,11 +57,8 @@ bind:value={teamForm.name.value} on:blur={() => { teamForm.name.isTouched = true; - teamForm.name.value = teamForm.name.value.trim(); // Trim the value on blur - if ( - teamForm.name.value && - isOnlySpecialCharacters(teamForm.name.value) - ) { + teamForm.name.value = teamForm.name.value.trim(); + if (teamForm.name.value && !isValidHubName(teamForm.name.value)) { teamForm.name.invalid = true; } else { teamForm.name.invalid = false; diff --git a/packages/@sparrow-common/src/features/create-team/constants/name.ts b/packages/@sparrow-common/src/features/create-team/constants/name.ts index 411a52f139..035ef06393 100644 --- a/packages/@sparrow-common/src/features/create-team/constants/name.ts +++ b/packages/@sparrow-common/src/features/create-team/constants/name.ts @@ -3,5 +3,5 @@ export const NAME_CONFIG = { MAX_TEXT_SIZE: 100, REQUIRED_ERROR_MESSAGE: `Please enter your hub name.`, PLACEHOLDER: `Enter your hub name`, - INVALID_ERROR_MESSAGE: `Invalid team name. Please remove unsupported characters like emojis or more than two special symbols.`, + INVALID_ERROR_MESSAGE: `Hub names can contain combination of letters, digits and these special characters (.,-,_). Please provide the hub names accordingly.`, }; diff --git a/packages/@sparrow-teams/src/features/create-workspace/components/workspace-name/WorkspaceName.svelte b/packages/@sparrow-teams/src/features/create-workspace/components/workspace-name/WorkspaceName.svelte index a34a9da3a5..ad7ab3446e 100644 --- a/packages/@sparrow-teams/src/features/create-workspace/components/workspace-name/WorkspaceName.svelte +++ b/packages/@sparrow-teams/src/features/create-workspace/components/workspace-name/WorkspaceName.svelte @@ -23,6 +23,17 @@ * Data */ const inputId: string = "team-name-input"; + + const isValidWorkspaceName = (name: string) => { + const trimmedName = name.trim(); + // Check if empty + if (!trimmedName) return false; + // Check if contains at least one alphanumeric character + const hasAlphanumeric = /[a-zA-Z0-9]/.test(trimmedName); + // Check if contains only allowed characters (letters, digits, spaces, ., -, _) + const onlyAllowedChars = /^[a-zA-Z0-9._\- ]+$/.test(trimmedName); + return hasAlphanumeric && onlyAllowedChars; + };
@@ -34,20 +45,38 @@ inputValueRequired={true} headerLabelText={NAME_CONFIG.TITLE} helpLabel={true} - isError={!workspaceForm.name.value.trim() && workspaceForm.name.isTouched} - errorMessage={NAME_CONFIG.REQUIRED_ERROR_MESSAGE} + isError={(!workspaceForm.name.value.trim() && + workspaceForm.name.isTouched) || + workspaceForm.name.invalid} + errorMessage={!workspaceForm.name.value.trim() && + workspaceForm.name.isTouched + ? NAME_CONFIG.REQUIRED_ERROR_MESSAGE + : workspaceForm.name.invalid + ? NAME_CONFIG.INVALID_ERROR_MESSAGE + : ""} > { workspaceForm.name.isTouched = true; + workspaceForm.name.value = workspaceForm.name.value.trim(); + if ( + workspaceForm.name.value && + !isValidWorkspaceName(workspaceForm.name.value) + ) { + workspaceForm.name.invalid = true; + } else { + workspaceForm.name.invalid = false; + } }} height={"36px"} id={inputId} placeholder={NAME_CONFIG.PLACEHOLDER} class="text-fs-14 bg-tertiary-300 fw-normal px-2 border-radius-4" style="outline:none;" - isError={!workspaceForm.name.value.trim() && workspaceForm.name.isTouched} + isError={(!workspaceForm.name.value.trim() && + workspaceForm.name.isTouched) || + workspaceForm.name.invalid} isEditIconRequired={false} type={"text"} placeholderColor={"var(--text-secondary-200)"} diff --git a/packages/@sparrow-teams/src/features/create-workspace/constants/name.ts b/packages/@sparrow-teams/src/features/create-workspace/constants/name.ts index 629d0437c0..62f5303780 100644 --- a/packages/@sparrow-teams/src/features/create-workspace/constants/name.ts +++ b/packages/@sparrow-teams/src/features/create-workspace/constants/name.ts @@ -2,4 +2,5 @@ export const NAME_CONFIG = { TITLE: `Workspace Name`, REQUIRED_ERROR_MESSAGE: `Workspace name cannot be empty.`, PLACEHOLDER: `Enter workspace name`, + INVALID_ERROR_MESSAGE: `Workspace names can contain combination of letters, digits and these special characters (.,-,_). Please provide the workspace names accordingly.`, }; diff --git a/packages/@sparrow-workspaces/src/features/collection-list/components/collection/Collection.svelte b/packages/@sparrow-workspaces/src/features/collection-list/components/collection/Collection.svelte index 73f8f492f2..21b7f61b76 100644 --- a/packages/@sparrow-workspaces/src/features/collection-list/components/collection/Collection.svelte +++ b/packages/@sparrow-workspaces/src/features/collection-list/components/collection/Collection.svelte @@ -4,6 +4,7 @@ import { HttpRequestDefaultNameBaseEnum } from "@sparrow/common/types/workspace/http-request-base"; import { slide } from "svelte/transition"; import { captureEvent } from "@app/utils/posthog/posthogConfig"; + import { notifications } from "@sparrow/library/ui"; export let onItemCreated: (entityType: string, args: any) => void; export let onItemDeleted: (entityType: string, args: any) => void; export let onItemRenamed: (entityType: string, args: any) => void; @@ -484,8 +485,27 @@ newCollectionName = target.value.trim(); }; + const isValidCollectionName = (name: string) => { + const trimmedName = name.trim(); + // Check if empty + if (!trimmedName) return false; + // Check if contains at least one alphanumeric character + const hasAlphanumeric = /[a-zA-Z0-9]/.test(trimmedName); + // Check if contains only allowed characters (letters, digits, spaces, ., -, _) + const onlyAllowedChars = /^[a-zA-Z0-9._\- ]+$/.test(trimmedName); + return hasAlphanumeric && onlyAllowedChars; + }; + const onRenameBlur = async () => { if (newCollectionName) { + if (!isValidCollectionName(newCollectionName)) { + notifications.error( + "Collection names can contain combination of letters, digits and these special characters (.,-,_). Please provide the collection names accordingly.", + ); + isRenaming = false; + newCollectionName = ""; + return; + } await onItemRenamed("collection", { workspaceId: collection.workspaceId, collection, diff --git a/packages/@sparrow-workspaces/src/features/collection-list/components/folder/Folder.svelte b/packages/@sparrow-workspaces/src/features/collection-list/components/folder/Folder.svelte index f594d558ad..30c55ddb8a 100644 --- a/packages/@sparrow-workspaces/src/features/collection-list/components/folder/Folder.svelte +++ b/packages/@sparrow-workspaces/src/features/collection-list/components/folder/Folder.svelte @@ -25,6 +25,7 @@ Button, Options, Tooltip, + notifications, } from "@sparrow/library/ui"; // ---- Enum, Constants and Interface @@ -387,8 +388,27 @@ newFolderName = target.value.trim(); }; + const isValidFolderName = (name: string) => { + const trimmedName = name.trim(); + // Check if empty + if (!trimmedName) return false; + // Check if contains at least one alphanumeric character + const hasAlphanumeric = /[a-zA-Z0-9]/.test(trimmedName); + // Check if contains only allowed characters (letters, digits, spaces, ., -, _) + const onlyAllowedChars = /^[a-zA-Z0-9._\- ]+$/.test(trimmedName); + return hasAlphanumeric && onlyAllowedChars; + }; + const onRenameBlur = async () => { if (newFolderName) { + if (!isValidFolderName(newFolderName)) { + notifications.error( + "Folder names can contain combination of letters, digits and these special characters (.,-,_). Please provide the folder names accordingly.", + ); + isRenaming = false; + newFolderName = ""; + return; + } await onItemRenamed("folder", { workspaceId: collection.workspaceId, collection, diff --git a/packages/@sparrow-workspaces/src/features/save-as-request/layout/SaveAsRequest.svelte b/packages/@sparrow-workspaces/src/features/save-as-request/layout/SaveAsRequest.svelte index 4474905fd8..95e550f255 100644 --- a/packages/@sparrow-workspaces/src/features/save-as-request/layout/SaveAsRequest.svelte +++ b/packages/@sparrow-workspaces/src/features/save-as-request/layout/SaveAsRequest.svelte @@ -184,6 +184,21 @@ }; const handleCreateFolder = async (folderName: string): Promise => { + const trimmedName = folderName.trim(); + // Validate folder name + if (!trimmedName) { + notifications.error("Folder name cannot be empty."); + return; + } + const hasAlphanumeric = /[a-zA-Z0-9]/.test(trimmedName); + const onlyAllowedChars = /^[a-zA-Z0-9._\- ]+$/.test(trimmedName); + if (!hasAlphanumeric || !onlyAllowedChars) { + notifications.error( + "Folder names can contain combination of letters, digits and these special characters (.,-,_). Please provide the folder names accordingly.", + ); + return; + } + createDirectoryLoader = true; const res = await onCreateFolder(workspaceMeta, path[0].id, folderName); if (res.status === "success") { @@ -201,6 +216,21 @@ }; const handleCreateCollection = async (collectionName: string) => { + const trimmedName = collectionName.trim(); + // Validate collection name + if (!trimmedName) { + notifications.error("Collection name cannot be empty."); + return; + } + const hasAlphanumeric = /[a-zA-Z0-9]/.test(trimmedName); + const onlyAllowedChars = /^[a-zA-Z0-9._\- ]+$/.test(trimmedName); + if (!hasAlphanumeric || !onlyAllowedChars) { + notifications.error( + "Collection names can contain combination of letters, digits and these special characters (.,-,_). Please provide the collection names accordingly.", + ); + return; + } + createDirectoryLoader = true; const res = await onCreateCollection(workspaceMeta, collectionName); if (res.status === "success") {