diff --git a/taxonomy-editor-frontend/src/pages/editentry/ListAllEntryProperties.tsx b/taxonomy-editor-frontend/src/pages/editentry/ListAllEntryProperties.tsx
index 0d4267e2..065ca295 100644
--- a/taxonomy-editor-frontend/src/pages/editentry/ListAllEntryProperties.tsx
+++ b/taxonomy-editor-frontend/src/pages/editentry/ListAllEntryProperties.tsx
@@ -1,4 +1,4 @@
-import { Box, Grid, Paper, Typography } from "@mui/material";
+import { Alert, Box, Grid, Paper, Snackbar, Typography } from "@mui/material";
import MaterialTable, { MTableToolbar } from "@material-table/core";
import { useState } from "react";
import ISO6391, { LanguageCode } from "iso-639-1";
@@ -68,22 +68,37 @@ const ListAllEntryProperties = ({ nodeObject, setNodeObject }) => {
const LanguageCodes = ISO6391.getAllCodes();
- const validatePropertyName = (propertyName:string) : boolean => {
+ const validatePropertyName = (propertyName: string): boolean => {
// Every property name should be in the form property_name:lang_code
if (propertyName) {
- const [, langCode] = propertyName.split(':');
+ const [, langCode] = propertyName.split(":");
if (!LanguageCodes.includes(langCode as LanguageCode)) {
- return false;
+ return false;
}
// Property name should not include special caracters
const pattern = /^[a-zA-Z0-9_]+:[a-zA-Z0-9_]+$/;
if (!pattern.test(propertyName)) {
- return false;
+ return false;
}
return true;
}
return false;
- }
+ };
+
+ const isPropertyNameUnique = (
+ propertyName: string,
+ otherProperties: RenderedPropertyType[]
+ ): boolean => {
+ for (const prop of otherProperties) {
+ if (prop.propertyName === propertyName) return false;
+ }
+ return true;
+ };
+
+ const [errorMessage, setErrorMessage] = useState("");
+ const handleCloseErrorSnackbar = () => {
+ setErrorMessage("");
+ };
return (
@@ -92,25 +107,41 @@ const ListAllEntryProperties = ({ nodeObject, setNodeObject }) => {
validatePropertyName(rowData.propertyName) ? true : { isValid: false, helperText: 'Property name should not contain special caracters and should follow the format : property_name:lang_code' } , },
+ {
+ title: "Name",
+ field: "propertyName",
+ validate: (rowData) =>
+ validatePropertyName(rowData.propertyName)
+ ? true
+ : {
+ isValid: false,
+ helperText:
+ "Property name should not contain special caracters and should follow the format : property_name:lang_code",
+ },
+ },
{ title: "Value", field: "propertyValue" },
]}
editable={{
onRowAdd: (newRow: RowType) =>
- new Promise((resolve) => {
- // Add new property to rendered rows
- const updatedRows = [
- ...data,
- { id: Math.random().toString(), ...newRow },
- ];
- setData(updatedRows);
+ new Promise((resolve, reject) => {
+ if (!isPropertyNameUnique(newRow.propertyName, data)) {
+ setErrorMessage(`${newRow.propertyName} already exists`);
+ reject();
+ } else {
+ // Add new property to rendered rows
+ const updatedRows = [
+ ...data,
+ { id: Math.random().toString(), ...newRow },
+ ];
+ setData(updatedRows);
- // Add new key-value pair of a property in nodeObject
- changePropertyData(
- normalizeNameToDb(newRow.propertyName),
- newRow.propertyValue
- );
- resolve();
+ // Add new key-value pair of a property in nodeObject
+ changePropertyData(
+ normalizeNameToDb(newRow.propertyName),
+ newRow.propertyValue
+ );
+ resolve();
+ }
}),
onRowDelete: (selectedRow: RenderedPropertyType) =>
new Promise((resolve, reject) => {
@@ -130,21 +161,34 @@ const ListAllEntryProperties = ({ nodeObject, setNodeObject }) => {
oldRow: RenderedPropertyType
) =>
new Promise((resolve, reject) => {
- // Update row in rendered rows
- const updatedRows = data.map((el) =>
- el.id === oldRow.id ? updatedRow : el
- );
- setData(updatedRows);
- // Updation takes place by deletion + addition
- // If property name has been changed, previous key should be removed from nodeObject
- updatedRow.propertyName !== oldRow.propertyName &&
- deletePropertyData(oldRow.propertyName);
- // Add new property to nodeObject
- changePropertyData(
- normalizeNameToDb(updatedRow.propertyName),
- updatedRow.propertyValue
- );
- resolve();
+ const index = data.findIndex((row) => row.id === updatedRow.id);
+ const otherProperties = [...data];
+ otherProperties.splice(index, 1);
+ if (
+ !isPropertyNameUnique(
+ updatedRow.propertyName,
+ otherProperties
+ )
+ ) {
+ setErrorMessage(`${updatedRow.propertyName} already exists`);
+ reject();
+ } else {
+ // Update row in rendered rows
+ const updatedRows = data.map((el) =>
+ el.id === oldRow.id ? updatedRow : el
+ );
+ setData(updatedRows);
+ // Updation takes place by deletion + addition
+ // If property name has been changed, previous key should be removed from nodeObject
+ updatedRow.propertyName !== oldRow.propertyName &&
+ deletePropertyData(oldRow.propertyName);
+ // Add new property to nodeObject
+ changePropertyData(
+ normalizeNameToDb(updatedRow.propertyName),
+ updatedRow.propertyValue
+ );
+ resolve();
+ }
}),
}}
options={{
@@ -176,6 +220,21 @@ const ListAllEntryProperties = ({ nodeObject, setNodeObject }) => {
}}
/>
+
+
+ {errorMessage}
+
+
);
};