From c0b54f6e84b6bc12c0106b74d952f032e614f7ea Mon Sep 17 00:00:00 2001 From: JustinKol <144163838+JustinKol@users.noreply.github.com> Date: Thu, 1 Feb 2024 12:51:23 -0500 Subject: [PATCH] Added TableAPI whitespace check and trim values (#1731) * Added TableAPI whitespace check and trim values * Reverted value is not required unless Row or PrimaryKey * Prettier Run * Add full whitespace check on Keys * Prettier formatting * Fixed type * Added whitespace check for tabs, vertical tabs, formfeeds, line breaks, etc * Fixed logic --- .../Panes/Tables/AddTableEntityPanel.tsx | 33 ++++++++++++++++--- .../Panes/Tables/EditTableEntityPanel.tsx | 16 +++++++-- 2 files changed, 43 insertions(+), 6 deletions(-) diff --git a/src/Explorer/Panes/Tables/AddTableEntityPanel.tsx b/src/Explorer/Panes/Tables/AddTableEntityPanel.tsx index c9d9bda10..1f23a60bc 100644 --- a/src/Explorer/Panes/Tables/AddTableEntityPanel.tsx +++ b/src/Explorer/Panes/Tables/AddTableEntityPanel.tsx @@ -1,5 +1,6 @@ import { IDropdownOption, Image, Label, Stack, Text, TextField } from "@fluentui/react"; import { useBoolean } from "@fluentui/react-hooks"; +import { logConsoleError } from "Utils/NotificationConsoleUtils"; import React, { FunctionComponent, useEffect, useState } from "react"; import * as _ from "underscore"; import AddPropertyIcon from "../../../../images/Add-property.svg"; @@ -97,9 +98,19 @@ export const AddTableEntityPanel: FunctionComponent = /* Add new entity attribute */ const onSubmit = async (): Promise => { for (let i = 0; i < entities.length; i++) { - const { property, type } = entities[i]; - if (property === "" || property === undefined) { - setFormError(`Property name cannot be empty. Please enter a property name`); + const { property, type, value } = entities[i]; + if ((property === "PartitionKey" && value === "") || (property === "RowKey" && value === "")) { + logConsoleError(`${property} cannot be empty. Please input a value for ${property}`); + setFormError(`${property} cannot be empty. Please input a value for ${property}`); + return; + } + + if ( + (property === "PartitionKey" && containsAnyWhiteSpace(value) === true) || + (property === "RowKey" && containsAnyWhiteSpace(value) === true) + ) { + logConsoleError(`${property} cannot have whitespace. Please input a value for ${property} without whitespace`); + setFormError(`${property} cannot have whitespace. Please input a value for ${property} without whitespace`); return; } @@ -107,6 +118,8 @@ export const AddTableEntityPanel: FunctionComponent = setFormError(`Property type cannot be empty. Please select a type from the dropdown for property ${property}`); return; } + + setFormError(""); } setIsExecuting(true); @@ -127,6 +140,13 @@ export const AddTableEntityPanel: FunctionComponent = } }; + const containsAnyWhiteSpace = (entityValue: string) => { + if (/\s/.test(entityValue)) { + return true; + } + return false; + }; + const tryInsertNewHeaders = (viewModel: TableEntityListViewModel, newEntity: Entities.ITableEntity): boolean => { let newHeaders: string[] = []; const keys = Object.keys(newEntity); @@ -182,9 +202,14 @@ export const AddTableEntityPanel: FunctionComponent = const entityChange = (value: string | Date, indexOfInput: number, key: string): void => { const cloneEntities: EntityRowType[] = [...entities]; if (key === "property") { - cloneEntities[indexOfInput].property = value.toString(); + cloneEntities[indexOfInput].property = value.toString().trim(); } else if (key === "time") { cloneEntities[indexOfInput].entityTimeValue = value.toString(); + } else if ( + cloneEntities[indexOfInput].property === "PartitionKey" || + cloneEntities[indexOfInput].property === "RowKey" + ) { + cloneEntities[indexOfInput].value = value.toString().trim(); } else { cloneEntities[indexOfInput].value = value.toString(); } diff --git a/src/Explorer/Panes/Tables/EditTableEntityPanel.tsx b/src/Explorer/Panes/Tables/EditTableEntityPanel.tsx index be2f982e0..e59fceee9 100644 --- a/src/Explorer/Panes/Tables/EditTableEntityPanel.tsx +++ b/src/Explorer/Panes/Tables/EditTableEntityPanel.tsx @@ -1,5 +1,6 @@ import { IDropdownOption, Image, Label, Stack, Text, TextField } from "@fluentui/react"; import { useBoolean } from "@fluentui/react-hooks"; +import { logConsoleError } from "Utils/NotificationConsoleUtils"; import React, { FunctionComponent, useEffect, useState } from "react"; import * as _ from "underscore"; import AddPropertyIcon from "../../../../images/Add-property.svg"; @@ -190,7 +191,7 @@ export const EditTableEntityPanel: FunctionComponent const onSubmit = async (): Promise => { for (let i = 0; i < entities.length; i++) { - const { property, type } = entities[i]; + const { property, type, value } = entities[i]; if (property === "" || property === undefined) { setFormError(`Property name cannot be empty. Please enter a property name`); return; @@ -200,6 +201,17 @@ export const EditTableEntityPanel: FunctionComponent setFormError(`Property type cannot be empty. Please select a type from the dropdown for property ${property}`); return; } + + if ( + (property === "PartitionKey" && value === "") || + (property === "PartitionKey" && value === undefined) || + (property === "RowKey" && value === "") || + (property === "RowKey" && value === undefined) + ) { + logConsoleError(`${property} cannot be empty. Please input a value for ${property}`); + setFormError(`${property} cannot be empty. Please input a value for ${property}`); + return; + } } setIsExecuting(true); @@ -359,7 +371,7 @@ export const EditTableEntityPanel: FunctionComponent selectedKey={entity.type} entityPropertyPlaceHolder={detailedHelp} entityValuePlaceholder={entity.entityValuePlaceholder} - entityValue={entity.value?.toString()} + entityValue={entity.value.toString()} isEntityTypeDate={entity.isEntityTypeDate} entityTimeValue={entity.entityTimeValue} isEntityValueDisable={entity.isEntityValueDisable}