add a role column and filter for quick view in Users page

This commit is contained in:
Yinyin Liu 2026-06-16 14:54:45 +02:00
parent 4aa30acd0b
commit b0e3e47553
6 changed files with 83 additions and 4 deletions

View File

@ -14,9 +14,17 @@ import {
} from '@mui/material';
import { FormattedMessage } from 'react-intl';
import { useSearchParams } from 'react-router-dom';
import { InnovEnergyUser } from 'src/interfaces/UserTypes';
import { InnovEnergyUser, UserType } from 'src/interfaces/UserTypes';
import User from './User';
// Translation keys for each UserType, indexed by the enum value
// (client=0, partner=1, admin=2).
export const USER_ROLE_LABEL_IDS: Record<UserType, string> = {
[UserType.client]: 'roleClient',
[UserType.partner]: 'rolePartner',
[UserType.admin]: 'roleAdmin'
};
interface FlatUsersViewProps {
users: InnovEnergyUser[];
fetchDataAgain: () => void;
@ -79,6 +87,7 @@ const FlatUsersView = (props: FlatUsersViewProps) => {
<TableRow>
<TableCell padding="checkbox"></TableCell>
<TableCell><FormattedMessage id="username" defaultMessage="Username" /></TableCell>
<TableCell><FormattedMessage id="role" defaultMessage="Role" /></TableCell>
<TableCell><FormattedMessage id="email" defaultMessage="Email" /></TableCell>
</TableRow>
</TableHead>
@ -115,6 +124,21 @@ const FlatUsersView = (props: FlatUsersViewProps) => {
{user.name}
</Typography>
</TableCell>
<TableCell>
<Typography
variant="body1"
fontWeight="bold"
color="text.primary"
gutterBottom
noWrap
>
<FormattedMessage
id={
USER_ROLE_LABEL_IDS[user.userType] ?? 'roleClient'
}
/>
</Typography>
</TableCell>
<TableCell>
<Typography
variant="body1"

View File

@ -5,6 +5,7 @@ import {
Grid,
IconButton,
InputAdornment,
MenuItem,
TextField
} from '@mui/material';
import SearchTwoToneIcon from '@mui/icons-material/SearchTwoTone';
@ -20,6 +21,8 @@ import { UserType } from '../../../interfaces/UserTypes';
function UsersSearch() {
const intl = useIntl();
const [searchTerm, setSearchTerm] = useState('');
// 'all' = no role filter; otherwise the selected UserType enum value.
const [roleFilter, setRoleFilter] = useState<UserType | 'all'>('all');
const { allUsers, fetchAllUsers } = useContext(AccessContext);
const [filteredData, setFilteredData] = useState(allUsers);
const [openModal, setOpenModal] = useState(false);
@ -37,11 +40,13 @@ function UsersSearch() {
};
useEffect(() => {
const filtered = allUsers.filter((item) =>
item.name.toLowerCase().includes(searchTerm.toLowerCase())
const filtered = allUsers.filter(
(item) =>
item.name.toLowerCase().includes(searchTerm.toLowerCase()) &&
(roleFilter === 'all' || item.userType === roleFilter)
);
setFilteredData(filtered);
}, [searchTerm, allUsers]);
}, [searchTerm, roleFilter, allUsers]);
const handleSubmit = () => {
setOpenModal(true);
@ -162,6 +167,36 @@ function UsersSearch() {
/>
</FormControl>
</Grid>
<Grid item xs={12} md={isMobile ? 5 : 3}>
<FormControl variant="outlined" fullWidth>
<TextField
select
label={intl.formatMessage({ id: 'role' })}
value={roleFilter}
onChange={(e) =>
setRoleFilter(
e.target.value === 'all'
? 'all'
: (Number(e.target.value) as UserType)
)
}
fullWidth
>
<MenuItem value="all">
{intl.formatMessage({ id: 'allRoles' })}
</MenuItem>
<MenuItem value={UserType.client}>
{intl.formatMessage({ id: 'roleClient' })}
</MenuItem>
<MenuItem value={UserType.partner}>
{intl.formatMessage({ id: 'rolePartner' })}
</MenuItem>
<MenuItem value={UserType.admin}>
{intl.formatMessage({ id: 'roleAdmin' })}
</MenuItem>
</TextField>
</FormControl>
</Grid>
</Grid>
<FlatUsersView users={filteredData} fetchDataAgain={fetchDataAgain} />
</>

View File

@ -532,6 +532,11 @@
"stopTimeMustBeLater": "Die Stoppzeit muss nach der Startzeit liegen",
"signIn": "Anmelden",
"username": "Benutzername",
"role": "Rolle",
"allRoles": "Alle Rollen",
"roleClient": "Kunde",
"rolePartner": "Partner",
"roleAdmin": "Admin",
"password": "Passwort",
"rememberMe": "Angemeldet bleiben",
"login": "Anmelden",

View File

@ -280,6 +280,11 @@
"stopTimeMustBeLater": "Stop time must be later than start time",
"signIn": "Sign in",
"username": "Username",
"role": "Role",
"allRoles": "All roles",
"roleClient": "Client",
"rolePartner": "Partner",
"roleAdmin": "Admin",
"password": "Password",
"rememberMe": "Remember me",
"login": "Login",

View File

@ -532,6 +532,11 @@
"stopTimeMustBeLater": "L'heure d'arrêt doit être postérieure à l'heure de début",
"signIn": "Se connecter",
"username": "Nom d'utilisateur",
"role": "Rôle",
"allRoles": "Tous les rôles",
"roleClient": "Client",
"rolePartner": "Partenaire",
"roleAdmin": "Admin",
"password": "Mot de passe",
"rememberMe": "Se souvenir de moi",
"login": "Connexion",

View File

@ -532,6 +532,11 @@
"stopTimeMustBeLater": "L'ora di fine deve essere successiva all'ora di inizio",
"signIn": "Accedi",
"username": "Nome utente",
"role": "Ruolo",
"allRoles": "Tutti i ruoli",
"roleClient": "Cliente",
"rolePartner": "Partner",
"roleAdmin": "Admin",
"password": "Password",
"rememberMe": "Ricordami",
"login": "Accedi",