Enhance handling of associated pgroups in Contacts and Address views.
Ensure `associatedPgroups` defaults to an empty array to avoid undefined behavior. Add non-editable pgroups input fields for new items and improve conditional rendering of pgroup chips in both views. Minor structural updates for consistency and clarity.
This commit is contained in:
parent
382b1eaba8
commit
4a1852882a
@ -49,6 +49,7 @@ const AddressManager: React.FC<AddressManagerProps> = ({ pgroups, activePgroup }
|
||||
const [countrySuggestions, setCountrySuggestions] = React.useState<string[]>([]);
|
||||
const [addresses, setAddresses] = React.useState<Address[]>([]);
|
||||
const [newAddress, setNewAddress] = React.useState<Partial<Address>>({
|
||||
pgroups: activePgroup,
|
||||
house_number: '',
|
||||
street: '',
|
||||
city: '',
|
||||
@ -80,13 +81,13 @@ const AddressManager: React.FC<AddressManagerProps> = ({ pgroups, activePgroup }
|
||||
try {
|
||||
const response = await AddressesService.getAllAddressesProtectedAddressesAllGet();
|
||||
|
||||
// Preprocess: Add associated and unassociated pgroups
|
||||
// Preprocess: Add associated pgroups with a default value if not available
|
||||
const transformedAddresses = response.map((address) => {
|
||||
const addressPgroups = address.pgroups?.split(',').map((p) => p.trim()) || [];
|
||||
const associatedPgroups = pgroups.filter((pgroup) => addressPgroups.includes(pgroup));
|
||||
return {
|
||||
...address,
|
||||
associatedPgroups, // pgroups linked to the address
|
||||
associatedPgroups: associatedPgroups || [], // Ensure it's always an array
|
||||
};
|
||||
});
|
||||
|
||||
@ -240,7 +241,7 @@ const AddressManager: React.FC<AddressManagerProps> = ({ pgroups, activePgroup }
|
||||
<TextField
|
||||
label="pgroup"
|
||||
name="pgroup"
|
||||
value={newAddress.activePgroup || ''}
|
||||
value={newAddress.pgroups || ''}
|
||||
disabled
|
||||
sx={{ width: '120px' }} // Small fixed-size for non-editable field
|
||||
/>
|
||||
@ -343,7 +344,9 @@ const AddressManager: React.FC<AddressManagerProps> = ({ pgroups, activePgroup }
|
||||
primary={`${address.house_number}, ${address.street}, ${address.city}`}
|
||||
secondary={
|
||||
<Box display="flex" flexWrap="wrap">
|
||||
{renderPgroupChips(address)}
|
||||
{address.associatedPgroups
|
||||
? renderPgroupChips(address) // Render chips if associatedPgroups is available
|
||||
: null}
|
||||
</Box>
|
||||
}
|
||||
/>
|
||||
|
@ -37,6 +37,7 @@ interface ContactWithPgroups extends Contact {
|
||||
const ContactsManager: React.FC<ContactsManagerProps> = ({ pgroups, activePgroup }) => {
|
||||
const [contacts, setContacts] = React.useState<ContactWithPgroups[]>([]);
|
||||
const [newContact, setNewContact] = React.useState<Partial<Contact>>({
|
||||
pgroups: activePgroup,
|
||||
firstname: '',
|
||||
lastname: '',
|
||||
phone_number: '',
|
||||
@ -58,7 +59,7 @@ const ContactsManager: React.FC<ContactsManagerProps> = ({ pgroups, activePgroup
|
||||
const associatedPgroups = pgroups.filter((pgroup) => contactPgroups.includes(pgroup));
|
||||
return {
|
||||
...contact,
|
||||
associatedPgroups, // pgroups linked to the contact
|
||||
associatedPgroups: associatedPgroups || [], // Ensure associatedPgroups is always an array
|
||||
};
|
||||
});
|
||||
|
||||
@ -168,30 +169,30 @@ const ContactsManager: React.FC<ContactsManagerProps> = ({ pgroups, activePgroup
|
||||
|
||||
const renderPgroupChips = (contact: ContactWithPgroups) => {
|
||||
return pgroups.map((pgroup) => {
|
||||
const isAssociated = contact.associatedPgroups.includes(pgroup);
|
||||
const isAssociated = (contact.associatedPgroups ?? []).includes(pgroup); // Ensure default empty array
|
||||
return (
|
||||
<Chip
|
||||
key={pgroup}
|
||||
label={pgroup}
|
||||
onClick={
|
||||
!isAssociated
|
||||
? () => togglePgroupAssociation(contact.id, pgroup)
|
||||
: undefined
|
||||
}
|
||||
sx={{
|
||||
backgroundColor: isAssociated ? '#19d238' : '#b0b0b0',
|
||||
color: 'white',
|
||||
borderRadius: '8px',
|
||||
fontWeight: 'bold',
|
||||
height: '20px',
|
||||
fontSize: '12px',
|
||||
boxShadow: '0px 1px 3px rgba(0, 0, 0, 0.2)',
|
||||
cursor: isAssociated ? 'default' : 'pointer', // Disable pointer for associated chips
|
||||
'&:hover': { opacity: isAssociated ? 1 : 0.8 }, // Disable hover effect for associated chips
|
||||
mr: 1,
|
||||
mb: 1,
|
||||
}}
|
||||
/>
|
||||
<Chip
|
||||
key={pgroup}
|
||||
label={pgroup}
|
||||
onClick={
|
||||
!isAssociated
|
||||
? () => togglePgroupAssociation(contact.id, pgroup)
|
||||
: undefined
|
||||
}
|
||||
sx={{
|
||||
backgroundColor: isAssociated ? '#19d238' : '#b0b0b0',
|
||||
color: 'white',
|
||||
borderRadius: '8px',
|
||||
fontWeight: 'bold',
|
||||
height: '20px',
|
||||
fontSize: '12px',
|
||||
boxShadow: '0px 1px 3px rgba(0, 0, 0, 0.2)',
|
||||
cursor: isAssociated ? 'default' : 'pointer', // Disable pointer for associated chips
|
||||
'&:hover': { opacity: isAssociated ? 1 : 0.8 }, // Disable hover effect for associated chips
|
||||
mr: 1,
|
||||
mb: 1,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
});
|
||||
};
|
||||
@ -202,6 +203,13 @@ const ContactsManager: React.FC<ContactsManagerProps> = ({ pgroups, activePgroup
|
||||
Contacts Management
|
||||
</Typography>
|
||||
<Box mb={3} display="flex" justifyContent="center" alignItems="center">
|
||||
<TextField
|
||||
label="pgroup"
|
||||
name="pgroup"
|
||||
value={newContact.pgroups || ''}
|
||||
disabled
|
||||
sx={{ width: '120px' }} // Small fixed-size for non-editable field
|
||||
/>
|
||||
<TextField
|
||||
label="First Name"
|
||||
name="firstname"
|
||||
@ -233,28 +241,30 @@ const ContactsManager: React.FC<ContactsManagerProps> = ({ pgroups, activePgroup
|
||||
{errorMessage && <Typography color="error">{errorMessage}</Typography>}
|
||||
<List>
|
||||
{contacts.length > 0 ? (
|
||||
contacts.map((contact) => (
|
||||
<ListItem key={contact.id} button>
|
||||
<ListItemText
|
||||
primary={`${contact.firstname} ${contact.lastname}`}
|
||||
secondary={
|
||||
<Box display="flex" flexWrap="wrap">
|
||||
{renderPgroupChips(contact)}
|
||||
</Box>
|
||||
}
|
||||
/>
|
||||
<ListItemSecondaryAction>
|
||||
<IconButton edge="end" color="primary" onClick={() => handleEditContact(contact)}>
|
||||
<EditIcon />
|
||||
</IconButton>
|
||||
<IconButton edge="end" color="secondary" onClick={() => openDialog(contact)}>
|
||||
<DeleteIcon />
|
||||
</IconButton>
|
||||
</ListItemSecondaryAction>
|
||||
</ListItem>
|
||||
))
|
||||
contacts.map((contact) => (
|
||||
<ListItem key={contact.id} button>
|
||||
<ListItemText
|
||||
primary={`${contact.firstname} ${contact.lastname}`}
|
||||
secondary={
|
||||
<Box display="flex" flexWrap="wrap">
|
||||
{contact.associatedPgroups
|
||||
? renderPgroupChips(contact) // Render chips only if associatedPgroups exists
|
||||
: null}
|
||||
</Box>
|
||||
}
|
||||
/>
|
||||
<ListItemSecondaryAction>
|
||||
<IconButton edge="end" color="primary" onClick={() => handleEditContact(contact)}>
|
||||
<EditIcon />
|
||||
</IconButton>
|
||||
<IconButton edge="end" color="secondary" onClick={() => openDialog(contact)}>
|
||||
<DeleteIcon />
|
||||
</IconButton>
|
||||
</ListItemSecondaryAction>
|
||||
</ListItem>
|
||||
))
|
||||
) : (
|
||||
<Typography>No contacts found</Typography>
|
||||
<Typography>No contacts found</Typography>
|
||||
)}
|
||||
</List>
|
||||
<Dialog
|
||||
|
Loading…
x
Reference in New Issue
Block a user