From 3746b614a28e2020d058c03058ac9f5bfc249654 Mon Sep 17 00:00:00 2001 From: Damien Date: Wed, 7 Jan 2026 19:56:09 +0000 Subject: [PATCH 1/3] Updated UsersTable Component to add Channel Profiles Column --- frontend/src/components/tables/UsersTable.jsx | 37 ++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/frontend/src/components/tables/UsersTable.jsx b/frontend/src/components/tables/UsersTable.jsx index 3e9e4971..a5ba02b2 100644 --- a/frontend/src/components/tables/UsersTable.jsx +++ b/frontend/src/components/tables/UsersTable.jsx @@ -2,6 +2,7 @@ import React, { useMemo, useCallback, useState } from 'react'; import API from '../../api'; import UserForm from '../forms/User'; import useUsersStore from '../../store/users'; +import useChannelsStore from '../../store/channels'; import useAuthStore from '../../store/auth'; import { USER_LEVELS, USER_LEVEL_LABELS } from '../../constants'; import useWarningsStore from '../../store/warnings'; @@ -26,6 +27,7 @@ import { UnstyledButton, LoadingOverlay, Stack, + Badge, } from '@mantine/core'; import { CustomTable, useTable } from './CustomTable'; import ConfirmationDialog from '../ConfirmationDialog'; @@ -83,6 +85,7 @@ const UsersTable = () => { * STORES */ const users = useUsersStore((s) => s.users); + const profiles = useChannelsStore((s) => s.profiles); const authUser = useAuthStore((s) => s.user); const isWarningSuppressed = useWarningsStore((s) => s.isWarningSuppressed); const suppressWarning = useWarningsStore((s) => s.suppressWarning); @@ -259,6 +262,37 @@ const UsersTable = () => { ); }, }, + { + header: 'Channel Profiles', + accessorKey: 'channel_profiles', + grow: true, + cell: ({ getValue }) => { + const userProfiles = getValue() || []; + const profileNames = Object.values(profiles) + .filter((profile) => userProfiles.includes(profile.id)) + .map((profile) => profile.name); + return ( + + {profileNames.length > 0 ? ( + profileNames.map((name, index) => ( + + {name} + + )) + ) : ( + + All + + )} + + ); + }, + }, { id: 'actions', size: 80, @@ -313,6 +347,7 @@ const UsersTable = () => { user_level: renderHeaderCell, last_login: renderHeaderCell, date_joined: renderHeaderCell, + channel_profiles: renderHeaderCell, custom_properties: renderHeaderCell, }, }); @@ -327,7 +362,7 @@ const UsersTable = () => { minHeight: '100vh', }} > - + Date: Wed, 7 Jan 2026 20:10:10 +0000 Subject: [PATCH 2/3] Added Vertical Spacing to ensure badges look like they're within the table row. --- frontend/src/components/tables/UsersTable.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/components/tables/UsersTable.jsx b/frontend/src/components/tables/UsersTable.jsx index a5ba02b2..bd4f17f6 100644 --- a/frontend/src/components/tables/UsersTable.jsx +++ b/frontend/src/components/tables/UsersTable.jsx @@ -272,7 +272,7 @@ const UsersTable = () => { .filter((profile) => userProfiles.includes(profile.id)) .map((profile) => profile.name); return ( - + {profileNames.length > 0 ? ( profileNames.map((name, index) => ( Date: Wed, 7 Jan 2026 20:24:51 +0000 Subject: [PATCH 3/3] Second Thought.. We should useMemo same as we do for the other data to prevent unnecessary compute. --- frontend/src/components/tables/UsersTable.jsx | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/frontend/src/components/tables/UsersTable.jsx b/frontend/src/components/tables/UsersTable.jsx index bd4f17f6..eecb8fc5 100644 --- a/frontend/src/components/tables/UsersTable.jsx +++ b/frontend/src/components/tables/UsersTable.jsx @@ -141,6 +141,15 @@ const UsersTable = () => { /** * useMemo */ + // Create a profile ID to name lookup map for efficient rendering + const profileIdToName = useMemo(() => { + const map = {}; + Object.values(profiles).forEach((profile) => { + map[profile.id] = profile.name; + }); + return map; + }, [profiles]); + const columns = useMemo( () => [ { @@ -268,9 +277,9 @@ const UsersTable = () => { grow: true, cell: ({ getValue }) => { const userProfiles = getValue() || []; - const profileNames = Object.values(profiles) - .filter((profile) => userProfiles.includes(profile.id)) - .map((profile) => profile.name); + const profileNames = userProfiles + .map((id) => profileIdToName[id]) + .filter(Boolean); // Filter out any undefined values return ( {profileNames.length > 0 ? ( @@ -308,7 +317,7 @@ const UsersTable = () => { ), }, ], - [theme, editUser, deleteUser, visiblePasswords, togglePasswordVisibility] + [theme, editUser, deleteUser, visiblePasswords, togglePasswordVisibility, profileIdToName] ); const closeUserForm = () => {