diff --git a/JeMPI_Apps/JeMPI_UI/src/hooks/useAppConfig.tsx b/JeMPI_Apps/JeMPI_UI/src/hooks/useAppConfig.tsx
index 3493eac0f..054891cb7 100644
--- a/JeMPI_Apps/JeMPI_UI/src/hooks/useAppConfig.tsx
+++ b/JeMPI_Apps/JeMPI_UI/src/hooks/useAppConfig.tsx
@@ -39,25 +39,23 @@ export const AppConfigProvider = ({
refetchOnWindowFocus: false
})
const availableFields: DisplayField[] = useMemo(() => {
- return (fields || [])
- .filter(({ scope }) =>
- scope.some(path => {
- return matchPath(
- {
- path: path
- },
- location.pathname
- )
- })
- )
- .map(field => {
- return {
+ try {
+ if (!fields || !Array.isArray(fields)) return []
+
+ return fields
+ .filter(({ scope }) =>
+ scope?.some(path => matchPath({ path }, location.pathname))
+ )
+ .map(field => ({
...field,
formatValue: getFieldValueFormatter(field.fieldType),
isValid: (value: unknown) => isInputValid(value, field?.validation),
getValue: valueGetter
- }
- })
+ }))
+ } catch (error) {
+ console.error('Error processing available fields:', error)
+ return []
+ }
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [fields, location])
diff --git a/JeMPI_Apps/JeMPI_UI/src/pages/settings/Settings.tsx b/JeMPI_Apps/JeMPI_UI/src/pages/settings/Settings.tsx
index 431e4c1c1..ee678105f 100644
--- a/JeMPI_Apps/JeMPI_UI/src/pages/settings/Settings.tsx
+++ b/JeMPI_Apps/JeMPI_UI/src/pages/settings/Settings.tsx
@@ -15,9 +15,11 @@ import { generateId } from 'utils/helpers'
import Probabilistic from './probabilistic/Probabilistic'
import { useConfig } from 'hooks/useConfig'
import { useSnackbar } from 'notistack'
+import { useConfiguration } from 'hooks/useUIConfiguration'
const Settings = () => {
const [value, setValue] = useState(0)
+ const {configuration} = useConfiguration()
const [configurationData, setConfigurationData] = useState(() => {
const storedData = localStorage.getItem('configuration')
return storedData
@@ -106,12 +108,12 @@ const Settings = () => {
variant="scrollable"
>
-
+ {/*
-
-
-
-
+ */}
+
+
+
@@ -120,31 +122,31 @@ const Settings = () => {
-
+ {/*
Setup properties that are unique to the golden record
-
-
+ */}
+ {/*
Setup properties that are unique to the interaction
-
-
+ */}
+ {/*
Setup properties for Golden record lists
-
-
+ */}
+
-
+
-
+
diff --git a/JeMPI_Apps/JeMPI_UI/src/pages/settings/common/Common.tsx b/JeMPI_Apps/JeMPI_UI/src/pages/settings/common/Common.tsx
index 055ad8a30..5a4eb94eb 100644
--- a/JeMPI_Apps/JeMPI_UI/src/pages/settings/common/Common.tsx
+++ b/JeMPI_Apps/JeMPI_UI/src/pages/settings/common/Common.tsx
@@ -1,5 +1,5 @@
-import { useEffect, useState } from 'react'
-import Box from '@mui/material/Box'
+import { useEffect, useState } from 'react';
+import Box from '@mui/material/Box';
import {
DataGrid,
GridColDef,
@@ -17,49 +17,67 @@ import CancelIcon from '@mui/icons-material/Close'
import { EditToolbar } from 'components/shared/EditToolBar'
import { processIndex, toSnakeCase, transformFieldName } from 'utils/helpers'
import { useConfiguration } from 'hooks/useUIConfiguration'
-import { Configuration, LinkMetaData } from 'types/Configuration'
+import { Configuration, Field, LinkMetaData } from 'types/Configuration'
+import { IconButton, Tooltip, Switch } from '@mui/material'
import { RowData } from '../deterministic/SourceView'
+import { useSnackbar } from 'notistack'
+import FieldDialog from './FieldDialog'
+import AddIcon from '@mui/icons-material/Add'
const CommonSettings = () => {
const [rows, setRows] = useState([])
const { configuration, setConfiguration } = useConfiguration()
const [rowModesModel, setRowModesModel] = useState({})
+ const [openFieldModal, setOpenFieldModal] = useState(false)
+ const { enqueueSnackbar } = useSnackbar()
useEffect(() => {
- if (configuration && configuration.demographicFields) {
- const rowData = configuration?.demographicFields.map(
+ if (configuration?.demographicFields) {
+ const rowData = configuration.demographicFields.map(
(row: any, rowIndex: number) => ({
id: rowIndex + 1,
...row,
- rowIndex
+ rowIndex,
+ disable: row.isDisabled
})
- )
+ );
setRows(rowData)
}
}, [configuration])
const handleEditClick = (id: GridRowId) => () => {
setRowModesModel({ ...rowModesModel, [id]: { mode: GridRowModes.Edit } })
- }
+ };
const handleSaveClick = (id: GridRowId) => () => {
setRowModesModel({ ...rowModesModel, [id]: { mode: GridRowModes.View } })
- }
+ };
const handleUpdateConfiguration = (updatedRow: any, rowIndex: number) => {
- if (!configuration) return
- const updatedConfiguration = getUpdatedConfiguration(
- updatedRow,
- rowIndex,
- configuration
- )
- localStorage.setItem('configuration', JSON.stringify(updatedConfiguration))
- setConfiguration(updatedConfiguration)
- setRows((prevRows: any) =>
- prevRows.map((row: any) =>
- row.id === updatedRow.id ? { ...updatedRow } : row
+ if (!configuration) {
+ console.error("Cannot update configuration. Configuration is null.")
+ return;
+ }
+
+ const prevConfiguration = { ...configuration }
+ try {
+ const updatedConfiguration = getUpdatedConfiguration(
+ updatedRow,
+ rowIndex,
+ configuration
)
- )
+ localStorage.setItem('configuration', JSON.stringify(updatedConfiguration))
+ setConfiguration(updatedConfiguration)
+ setRows((prevRows: any) =>
+ prevRows.map((row: any) =>
+ row.id === updatedRow.id ? { ...updatedRow } : row
+ )
+ )
+ } catch (error) {
+ console.error("Error updating configuration:", error);
+ setConfiguration(prevConfiguration)
+ enqueueSnackbar("Failed to update configuration. Please try again.", { variant: 'error' })
+ }
}
const getUpdatedConfiguration = (
@@ -67,71 +85,162 @@ const CommonSettings = () => {
rowIndex: number,
currentConfiguration: Configuration
): Configuration => {
- const newConfiguration = { ...currentConfiguration }
+ const newConfiguration = { ...currentConfiguration }
const fieldName = toSnakeCase(updatedRow.fieldName)
+
if (!newConfiguration.demographicFields) {
- return currentConfiguration
+ return currentConfiguration;
}
- const fieldToUpdate = { ...newConfiguration.demographicFields[rowIndex] }
+ const fieldToUpdate = { ...newConfiguration.demographicFields[rowIndex] };
if (!fieldToUpdate) {
- return currentConfiguration
+ return currentConfiguration;
}
- fieldToUpdate.fieldName = fieldName
+ fieldToUpdate.fieldName = fieldName;
if (updatedRow?.indexGoldenRecord) {
- fieldToUpdate.indexGoldenRecord = `@index(${updatedRow.indexGoldenRecord.replace(
- ' ',
- ''
- )})`
+ if (!updatedRow.indexGoldenRecord.startsWith('@index(')) {
+ fieldToUpdate.indexGoldenRecord = `@index(${updatedRow.indexGoldenRecord.replace(
+ ' ',
+ ''
+ )})`
+ } else {
+ fieldToUpdate.indexGoldenRecord = updatedRow.indexGoldenRecord
+ }
}
if (updatedRow?.m) {
fieldToUpdate.linkMetaData = {
...fieldToUpdate.linkMetaData,
m: Number(updatedRow.m)
- } as LinkMetaData
+ } as LinkMetaData;
}
if (updatedRow?.u) {
fieldToUpdate.linkMetaData = {
...fieldToUpdate.linkMetaData,
u: Number(updatedRow.u)
- } as LinkMetaData
+ } as LinkMetaData;
}
- newConfiguration.demographicFields[rowIndex] = fieldToUpdate
+ newConfiguration.demographicFields[rowIndex] = fieldToUpdate;
- return newConfiguration
- }
+ return newConfiguration;
+ };
const handleCancelClick = (id: GridRowId) => () => {
setRowModesModel(prevRowModesModel => {
- const newRowModesModel = { ...prevRowModesModel }
- delete newRowModesModel[id]
- return newRowModesModel
- })
- }
+ const newRowModesModel = { ...prevRowModesModel };
+ delete newRowModesModel[id];
+ return newRowModesModel;
+ });
+ };
const handleRowEditStop: GridEventListener<'rowEditStop'> = ({ reason }) =>
- reason === GridRowEditStopReasons.rowFocusOut
+ reason === GridRowEditStopReasons.rowFocusOut;
const handleRowModesModelChange = (newRowModesModel: GridRowModesModel) => {
- setRowModesModel(newRowModesModel)
- }
+ setRowModesModel(newRowModesModel);
+ };
const processRowUpdate = (newRow: GridRowModel) => {
- const { id, ...updatedRow } = newRow
+ const isFieldNameValid = newRow?.fieldName && newRow.fieldName.toLowerCase() !== 'unknown_field';
+
+ if (!isFieldNameValid) {
+ enqueueSnackbar('Field name cannot be empty or unknown', { variant: 'error' });
+ }
+
+ const { id, ...updatedRow } = newRow;
const updatedRows = rows.map((row: { id: any }) =>
row.id === id ? ({ ...updatedRow, id } as RowData) : row
)
setRows(updatedRows)
+
+ if (updatedRow?.disable !== undefined) {
+ const rowIndex = updatedRow.rowIndex
+
+ const updatedConfiguration: Configuration = {
+ ...configuration,
+ auxInteractionFields: configuration?.auxInteractionFields || [],
+ auxGoldenRecordFields: configuration?.auxGoldenRecordFields || [],
+ additionalNodes: configuration?.additionalNodes || [],
+ demographicFields: configuration?.demographicFields || [],
+ rules: configuration?.rules || {
+ link: {
+ deterministic: [],
+ probabilistic: []
+ },
+ validate: {
+ deterministic: [],
+ probabilistic: []
+ },
+ matchNotification: {
+ deterministic: [],
+ probabilistic: []
+ }
+ }
+ }
+
+ if (
+ updatedConfiguration.demographicFields &&
+ updatedConfiguration.demographicFields[rowIndex]
+ ) {
+ updatedConfiguration.demographicFields[rowIndex].isDisabled =
+ updatedRow.disable
+ localStorage.setItem(
+ 'configuration',
+ JSON.stringify(updatedConfiguration)
+ )
+
+ setConfiguration(updatedConfiguration)
+ }
+ }
+
handleUpdateConfiguration(updatedRow, updatedRow.rowIndex)
return { ...updatedRow, id } as RowData
}
+ const handleSwitchChange = (
+ event: React.ChangeEvent,
+ params: any
+ ) => {
+ const updatedRow = { ...params.row, disable: event.target.checked }
+ processRowUpdate(updatedRow)
+ }
+
+ const handleAddNewRow = (fieldName: string) => {
+ const newRow: Field = {
+ id: (rows.length + 1).toString(),
+ fieldName,
+ fieldType: 'String',
+ linkMetaData: {
+ comparison: '',
+ comparisonLevels: [],
+ m: 0,
+ u: 0
+ },
+ };
+
+ if (configuration) {
+ const newConfiguration = {
+ ...configuration,
+ demographicFields: [...configuration.demographicFields, newRow]
+ }
+
+ localStorage.setItem('configuration', JSON.stringify(newConfiguration))
+ setConfiguration(newConfiguration)
+ setRows((prevRows: any) => [...prevRows, newRow])
+ setRowModesModel(prevRowModesModel => ({
+ ...prevRowModesModel,
+ [(newRow.id) as string]: { mode: GridRowModes.Edit, fieldToFocus: 'fieldName' }
+ }))
+ } else {
+ console.error("Configuration is null. Cannot add new row.")
+ }
+ }
+
const columns: GridColDef[] = [
{
field: 'fieldName',
@@ -149,7 +258,7 @@ const CommonSettings = () => {
width: 180,
align: 'center',
headerAlign: 'center',
- editable: false
+ editable: true,
},
{
field: 'indexGoldenRecord',
@@ -160,8 +269,8 @@ const CommonSettings = () => {
headerAlign: 'center',
editable: true,
valueGetter: params => {
- const indexGoldenRecord = params.row.indexGoldenRecord
- return processIndex(indexGoldenRecord)
+ const indexGoldenRecord = params.row.indexGoldenRecord;
+ return processIndex(indexGoldenRecord);
}
},
{
@@ -173,11 +282,11 @@ const CommonSettings = () => {
align: 'center',
headerAlign: 'center',
valueGetter: params => {
- const linkMetaData = params.row.linkMetaData
+ const linkMetaData = params.row.linkMetaData;
if (linkMetaData && typeof linkMetaData.m === 'number') {
- return linkMetaData.m.toFixed(7)
+ return linkMetaData.m.toFixed(7);
}
- return
+ return;
}
},
{
@@ -189,12 +298,13 @@ const CommonSettings = () => {
align: 'center',
headerAlign: 'center',
valueGetter: params => {
- const linkMetaData = params.row.linkMetaData
+ const linkMetaData = params.row.linkMetaData;
if (linkMetaData && typeof linkMetaData.u === 'number') {
- return linkMetaData.u.toFixed(7)
+ return linkMetaData.u.toFixed(7);
}
}
},
+
{
field: 'actions',
type: 'actions',
@@ -204,17 +314,19 @@ const CommonSettings = () => {
width: 300,
cellClassName: 'actions',
getActions: ({ id }) => {
- const isInEditMode = rowModesModel[id]?.mode === GridRowModes.Edit
+ const isInEditMode = rowModesModel[id]?.mode === GridRowModes.Edit;
+ const row = rows.find((row: any) => row.id === id);
+ const isFieldNameValid = row?.fieldName && row.fieldName.toLowerCase() !== 'unknown_field';
+
if (isInEditMode) {
return [
}
id="save-button"
label="Save"
- sx={{
- color: 'white'
- }}
+ sx={{ color: 'white' }}
onClick={handleSaveClick(id)}
+ disabled={!isFieldNameValid}
/>,
}
@@ -223,10 +335,11 @@ const CommonSettings = () => {
className="textPrimary"
onClick={handleCancelClick(id)}
color="inherit"
+ disabled={!isFieldNameValid}
/>
- ]
+ ];
}
-
+
return [
}
@@ -236,10 +349,25 @@ const CommonSettings = () => {
onClick={handleEditClick(id)}
color="inherit"
/>
- ]
+ ];
+ }
+ },
+ {
+ field: 'disable',
+ headerName: '',
+ width: 90,
+ align: 'center',
+ headerAlign: 'center',
+ renderCell: params => {
+ return (
+ handleSwitchChange(event, params)}
+ />
+ )
}
}
- ]
+ ];
return (
{
width: '100%'
}}
>
+
+
+ setOpenFieldModal(true)}>
+
+
+
+
+
{configuration && (
{
onRowModesModelChange={handleRowModesModelChange}
processRowUpdate={processRowUpdate}
onRowEditStop={handleRowEditStop}
- getRowId={row => row.id}
+ onProcessRowUpdateError={(error) => {
+ console.error(error);
+ }}
+ getRowId={(row) => row.id}
slots={{
toolbar: EditToolbar
}}
@@ -267,7 +410,7 @@ const CommonSettings = () => {
/>
)}
- )
-}
+ );
+};
-export default CommonSettings
+export default CommonSettings;
diff --git a/JeMPI_Apps/JeMPI_UI/src/pages/settings/common/FieldDialog.tsx b/JeMPI_Apps/JeMPI_UI/src/pages/settings/common/FieldDialog.tsx
new file mode 100644
index 000000000..20064cf9b
--- /dev/null
+++ b/JeMPI_Apps/JeMPI_UI/src/pages/settings/common/FieldDialog.tsx
@@ -0,0 +1,61 @@
+import Dialog from '@mui/material/Dialog';
+import DialogTitle from '@mui/material/DialogTitle';
+import DialogContent from '@mui/material/DialogContent';
+import DialogActions from '@mui/material/DialogActions';
+import Button from '@mui/material/Button';
+import TextField from '@mui/material/TextField';
+import { useState } from 'react';
+import { DialogContentText } from '@mui/material';
+
+interface FieldDialogProps {
+ openFieldModal: boolean;
+ setOpenFieldModal: React.Dispatch>;
+ onSave: (fieldName: string) => void;
+}
+
+export default function FieldDialog({ openFieldModal, setOpenFieldModal, onSave }: FieldDialogProps) {
+ const [fieldName, setFieldName] = useState('');
+
+ const handleClose = () => {
+ setOpenFieldModal(false);
+ };
+
+ const handleSave = () => {
+ onSave(fieldName);
+ handleClose();
+ };
+
+ return (
+
+ );
+}
diff --git a/JeMPI_Apps/JeMPI_UI/src/pages/settings/deterministic/DeterministicContent.tsx b/JeMPI_Apps/JeMPI_UI/src/pages/settings/deterministic/DeterministicContent.tsx
index c6a7306a3..38ca0a504 100644
--- a/JeMPI_Apps/JeMPI_UI/src/pages/settings/deterministic/DeterministicContent.tsx
+++ b/JeMPI_Apps/JeMPI_UI/src/pages/settings/deterministic/DeterministicContent.tsx
@@ -31,7 +31,8 @@ export const options = [
{ value: 0, label: 'Exact' },
{ value: 1, label: 'Low Fuzziness' },
{ value: 2, label: 'Medium Fuzziness' },
- { value: 3, label: 'High Fuzziness' }
+ { value: 3, label: 'High Fuzziness' },
+ { value: 4, label: 'Null' }
]
export enum Operator {
@@ -125,20 +126,29 @@ const DeterministicContent = ({
if (row.rowIndex !== undefined) {
setEditedRowIndex(row.rowIndex)
}
-
- const regex = /(eq|match)\(([^),]+)(?:, (\d+))?\)/g
+ const regex = /(eq|match|null)\(([^),]+)(?:, (\d+))?\)/g
const matchedFields: string[] = []
const matchedComparators: number[] = []
let match
while ((match = regex.exec(row.ruleText)) !== null) {
matchedFields.push(match[2])
- matchedComparators.push(match[1] === 'eq' ? 0 : parseInt(match[3], 10))
+
+ if (match[1] === 'eq') {
+ matchedComparators.push(0)
+ } else if (match[1] === 'match') {
+ matchedComparators.push(parseInt(match[3], 10))
+ } else if (match[1] === 'null') {
+ matchedComparators.push(4)
+ }
}
setComparators(matchedComparators)
setFields(matchedFields)
- setOperators(new Array(matchedFields.length - 1).fill(Operator.AND))
+
+ const operatorsLength = Math.max(matchedFields.length - 1, 0)
+ setOperators(new Array(operatorsLength).fill(Operator.AND))
+
setViewType(1)
}
@@ -163,12 +173,20 @@ const DeterministicContent = ({
const operator =
index > 0 ? ` ${operators[index - 1].toLowerCase()} ` : ''
const comparator = comparators[index]
- const comparatorFunction =
- comparator === 0 ? `eq(${field})` : `match(${field},${comparator})`
+ let comparatorFunction
+
+ if (comparator === 4) {
+ comparatorFunction = `null(${field})`
+ } else {
+ comparatorFunction =
+ comparator === 0 ? `eq(${field})` : `match(${field},${comparator})`
+ }
+
return `${operator}${comparatorFunction}`
})
.join('')
+ console.log('rule', vars, text)
const rule: Rule = { vars, text }
handleUpdateConfiguration(rule)
@@ -228,37 +246,40 @@ const DeterministicContent = ({
const handleDeleteRow = (index: number) => {
const updateArray = (arr: any[], idx: number) => {
- const newArr = [...arr];
- newArr.splice(idx, 1);
- return newArr;
- };
-
- setComparators(updateArray(comparators, index));
- setFields(updateArray(fields, index));
+ const newArr = [...arr]
+ newArr.splice(idx, 1)
+ return newArr
+ }
+
+ setComparators(updateArray(comparators, index))
+ setFields(updateArray(fields, index))
if (index > 0) {
- setOperators(updateArray(operators, index - 1));
+ setOperators(updateArray(operators, index - 1))
}
-
- const updatedConfiguration = { ...configuration };
+
+ const updatedConfiguration = { ...configuration }
const ruleType =
currentTab === 'link'
? 'link'
: currentTab === 'validate'
? 'validate'
- : 'matchNotification';
-
+ : 'matchNotification'
+
if (fields.length === 0) {
- const newRules = updateArray(rules, index);
- setRules(newRules);
-
+ const newRules = updateArray(rules, index)
+ setRules(newRules)
+
if (updatedConfiguration.rules?.[ruleType]) {
- updatedConfiguration.rules[ruleType].deterministic.splice(index, 1);
+ updatedConfiguration.rules[ruleType].deterministic.splice(index, 1)
}
-
- setConfiguration(updatedConfiguration as Configuration);
- localStorage.setItem('configuration', JSON.stringify(updatedConfiguration));
+
+ setConfiguration(updatedConfiguration as Configuration)
+ localStorage.setItem(
+ 'configuration',
+ JSON.stringify(updatedConfiguration)
+ )
}
- };
+ }
return (
(
diff --git a/JeMPI_Apps/JeMPI_UI/src/services/mockData.ts b/JeMPI_Apps/JeMPI_UI/src/services/mockData.ts
index 7db14d49f..63af64b11 100644
--- a/JeMPI_Apps/JeMPI_UI/src/services/mockData.ts
+++ b/JeMPI_Apps/JeMPI_UI/src/services/mockData.ts
@@ -399,6 +399,7 @@ const configuration = {
source: {
csvCol: 1
},
+ isDisabled: false,
indexGoldenRecord: '@index(exact,trigram)',
indexInteraction: '@index(exact,trigram)',
linkMetaData: {
@@ -414,6 +415,7 @@ const configuration = {
source: {
csvCol: 2
},
+ isDisabled: false,
indexGoldenRecord: '@index(exact,trigram)',
indexInteraction: '@index(exact,trigram)',
linkMetaData: {
@@ -429,6 +431,7 @@ const configuration = {
source: {
csvCol: 3
},
+ isDisabled: false,
indexGoldenRecord: '@index(exact,trigram)',
linkMetaData: {
comparison: 'JARO_WINKLER_SIMILARITY',
@@ -443,6 +446,7 @@ const configuration = {
source: {
csvCol: 4
},
+ isDisabled: false,
linkMetaData: {
comparison: 'JARO_WINKLER_SIMILARITY',
comparisonLevels: [0.92],
@@ -456,6 +460,7 @@ const configuration = {
source: {
csvCol: 5
},
+ isDisabled: false,
indexGoldenRecord: '@index(trigram)',
linkMetaData: {
comparison: 'JARO_WINKLER_SIMILARITY',
@@ -470,6 +475,7 @@ const configuration = {
source: {
csvCol: 6
},
+ isDisabled: false,
indexGoldenRecord: '@index(exact,trigram)',
linkMetaData: {
comparison: 'JARO_WINKLER_SIMILARITY',
@@ -484,6 +490,7 @@ const configuration = {
source: {
csvCol: 7
},
+ isDisabled: false,
indexGoldenRecord: '@index(exact,trigram)',
indexInteraction: '@index(exact,trigram)',
linkMetaData: {
diff --git a/JeMPI_Apps/JeMPI_UI/src/test/settings/BlockingContent.test.tsx b/JeMPI_Apps/JeMPI_UI/src/test/settings/BlockingContent.test.tsx
index 907424402..e80c8322d 100644
--- a/JeMPI_Apps/JeMPI_UI/src/test/settings/BlockingContent.test.tsx
+++ b/JeMPI_Apps/JeMPI_UI/src/test/settings/BlockingContent.test.tsx
@@ -1,5 +1,5 @@
import { fireEvent, render, screen } from '@testing-library/react'
-import '@testing-library/jest-dom/extend-expect'
+import '@testing-library/jest-dom'
import { BrowserRouter } from 'react-router-dom'
import BlockingContent from 'pages/settings/blocking/BlockingContent'
import mockData from 'services/mockData'
diff --git a/JeMPI_Apps/JeMPI_UI/src/test/settings/CommonSettings.test.tsx b/JeMPI_Apps/JeMPI_UI/src/test/settings/CommonSettings.test.tsx
index 5700c7a4d..da5d5f889 100644
--- a/JeMPI_Apps/JeMPI_UI/src/test/settings/CommonSettings.test.tsx
+++ b/JeMPI_Apps/JeMPI_UI/src/test/settings/CommonSettings.test.tsx
@@ -5,12 +5,21 @@ import CommonSettings from 'pages/settings/common/Common';
import mockData from 'services/mockData';
import '@testing-library/jest-dom';
import { useConfiguration } from 'hooks/useUIConfiguration';
+import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
+import { ConfigProvider } from 'hooks/useConfig';
+import { BrowserRouter } from 'react-router-dom';
jest.mock('hooks/useUIConfiguration', () => ({
useConfiguration: jest.fn(),
}));
+const queryClient = new QueryClient({
+ defaultOptions: {
+ queries: {}
+ }
+})
+
describe('CommonSettings Component', () => {
const configData = mockData.configuration.demographicFields.map((row, index) => ({
...row,
@@ -23,12 +32,27 @@ describe('CommonSettings Component', () => {
});
});
it('renders without crashing', () => {
- render();
+ render(
+
+
+
+
+
+ );
});
it('handles edit mode', async () => {
- render();
+ render(
+
+
+
+
+
+
+
+ )
+
const editIcon = document.getElementById('edit-button');
const saveButton = document.getElementById('save-button');
const cancelButton = document.getElementById('cancel-button');
diff --git a/JeMPI_Apps/JeMPI_UI/src/test/settings/Probabilistic.test.tsx b/JeMPI_Apps/JeMPI_UI/src/test/settings/Probabilistic.test.tsx
index 2902731fd..16d4bc7b0 100644
--- a/JeMPI_Apps/JeMPI_UI/src/test/settings/Probabilistic.test.tsx
+++ b/JeMPI_Apps/JeMPI_UI/src/test/settings/Probabilistic.test.tsx
@@ -1,5 +1,5 @@
import { fireEvent, render, screen } from '@testing-library/react'
-import '@testing-library/jest-dom/extend-expect'
+import '@testing-library/jest-dom'
import { BrowserRouter } from 'react-router-dom'
import mockData from 'services/mockData'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
diff --git a/JeMPI_Apps/JeMPI_UI/src/test/settings/SourceView.test.tsx b/JeMPI_Apps/JeMPI_UI/src/test/settings/SourceView.test.tsx
index 1fbdce823..45103c724 100644
--- a/JeMPI_Apps/JeMPI_UI/src/test/settings/SourceView.test.tsx
+++ b/JeMPI_Apps/JeMPI_UI/src/test/settings/SourceView.test.tsx
@@ -1,5 +1,5 @@
import { render, fireEvent } from '@testing-library/react'
-import '@testing-library/jest-dom/extend-expect'
+import '@testing-library/jest-dom'
import SourceView, { RowData } from 'pages/settings/deterministic/SourceView'
describe('SourceView Component', () => {
diff --git a/JeMPI_Apps/JeMPI_UI/src/types/Configuration.ts b/JeMPI_Apps/JeMPI_UI/src/types/Configuration.ts
index 49754b893..c11596016 100644
--- a/JeMPI_Apps/JeMPI_UI/src/types/Configuration.ts
+++ b/JeMPI_Apps/JeMPI_UI/src/types/Configuration.ts
@@ -21,6 +21,7 @@ export interface Field {
indexGoldenRecord?: string;
indexInteraction?: string;
linkMetaData?: LinkMetaData;
+ isDisabled?: boolean;
}