fix: update settings page for mobile viewport (#18991)

## Description

- This PR fixes
https://github.com/twentyhq/core-team-issues/issues/2313#issuecomment-4116380772
- Fixes Admin Panel Apps table, Data model table and Roles table
- made data model table scrollable for mobile viewport keeping name
column fixed.


## Visual Appearance

## Before

- Roles Table

<img width="636" height="1039" alt="Screenshot 2026-03-26 at 1 28 30 PM"
src="https://github.com/user-attachments/assets/fa7532bd-aeb0-4c8f-a40e-08cc976cd2c2"
/>



- Admin Apps table

<img width="610" height="998" alt="Screenshot 2026-03-26 at 1 28 12 PM"
src="https://github.com/user-attachments/assets/8712473c-350f-46f8-9e68-9cb0a5fa9d80"
/>





- Data Model table



https://github.com/user-attachments/assets/c48075c5-56dd-4b76-acd4-76330d6dab94






## After

- Roles Table

<img width="761" height="1045" alt="Screenshot 2026-03-26 at 1 23 19 PM"
src="https://github.com/user-attachments/assets/17099956-816a-4d41-b987-563f6931a995"
/>

- Admin Apps table

<img width="794" height="1044" alt="Screenshot 2026-03-26 at 1 23 34 PM"
src="https://github.com/user-attachments/assets/0463a087-2363-4192-9adb-7d27076f303a"
/>


- Data model Table


https://github.com/user-attachments/assets/fd44e353-cc7c-44cf-bda0-d2f3cd531f2e

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
Co-authored-by: Charles Bochet <charlesBochet@users.noreply.github.com>
This commit is contained in:
Harshit Singh
2026-03-26 21:17:40 +05:30
committed by GitHub
parent 7a341c6475
commit 34832815e6
13 changed files with 192 additions and 110 deletions
@@ -17,9 +17,8 @@ const StyledText = styled.div`
text-overflow: ellipsis;
`;
const StyledCloseButtonContainer = styled.div`
color: ${themeCssVariables.grayScale.gray1};
display: flex;
const StyledInvertedIconButton = styled(IconButton)`
color: ${themeCssVariables.font.color.inverted} !important;
`;
const StyledContent = styled.div<{ hasCloseButton: boolean }>`
@@ -78,15 +77,13 @@ export const InformationBanner = ({
)}
</StyledContent>
{onClose && (
<StyledCloseButtonContainer>
<IconButton
Icon={IconX}
size="small"
variant="tertiary"
onClick={onClose}
ariaLabel={t`Close banner`}
/>
</StyledCloseButtonContainer>
<StyledInvertedIconButton
Icon={IconX}
size="small"
variant="tertiary"
onClick={onClose}
ariaLabel={t`Close banner`}
/>
)}
</Banner>
)}
@@ -6,6 +6,7 @@ import { IconHelpCircle, IconSettings } from 'twenty-ui/display';
import { AnimatedExpandableContainer } from 'twenty-ui/layout';
import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState';
import { useOpenSettingsMenu } from '@/navigation/hooks/useOpenSettings';
import { getDocumentationUrl } from '@/support/utils/getDocumentationUrl';
import { isNavigationDrawerExpandedState } from '@/ui/navigation/states/isNavigationDrawerExpanded';
import { navigationDrawerExpandedMemorizedState } from '@/ui/navigation/states/navigationDrawerExpandedMemorizedState';
@@ -36,6 +37,8 @@ export const NavigationDrawerOtherSection = () => {
navigationMemorizedUrlState,
);
const { openSettingsMenu } = useOpenSettingsMenu();
const { toggleNavigationSection } = useNavigationSection('Other');
const isNavigationSectionOpen = useAtomFamilyStateValue(
isNavigationSectionOpenFamilyState,
@@ -46,6 +49,7 @@ export const NavigationDrawerOtherSection = () => {
setNavigationDrawerExpandedMemorized(isNavigationDrawerExpanded);
setIsNavigationDrawerExpanded(true);
setNavigationMemorizedUrl(location.pathname + location.search);
openSettingsMenu();
navigate(getSettingsPath(SettingsPath.ProfilePage));
};
@@ -41,9 +41,11 @@ const StyledMainContainerLayoutForMobile = styled.div`
const StyledPageBodyForMobileContainer = styled.div`
display: flex;
flex: 1;
flex: 1 1 0;
flex-direction: column;
min-height: 0;
min-width: 0;
width: 0;
> * {
padding-bottom: 0;
@@ -28,6 +28,7 @@ const StyledTableHeaderRowContainer = styled.div`
`;
const TABLE_GRID = '1fr 1fr 100px 80px';
const TABLE_GRID_MOBILE = '3fr 3fr 1fr 70px';
export const SettingsAdminApps = () => {
const [searchQuery, setSearchQuery] = useState('');
@@ -64,7 +65,10 @@ export const SettingsAdminApps = () => {
<StyledTableContainer>
<Table>
<StyledTableHeaderRowContainer>
<TableRow gridTemplateColumns={TABLE_GRID}>
<TableRow
gridAutoColumns={TABLE_GRID}
mobileGridAutoColumns={TABLE_GRID_MOBILE}
>
<TableHeader>{t`Name`}</TableHeader>
<TableHeader>{t`Source`}</TableHeader>
<TableHeader>{t`Listed`}</TableHeader>
@@ -81,9 +85,13 @@ export const SettingsAdminApps = () => {
)}
fullWidth
>
<TableRow gridTemplateColumns={TABLE_GRID} isClickable>
<TableRow
gridAutoColumns={TABLE_GRID}
mobileGridAutoColumns={TABLE_GRID_MOBILE}
isClickable
>
<TableCell>{registration.name}</TableCell>
<TableCell>
<TableCell overflow="hidden">
{registration.sourcePackage ?? registration.sourceType}
</TableCell>
<TableCell>
@@ -11,6 +11,7 @@ import {
SETTINGS_OBJECT_TABLE_ROW_GRID_TEMPLATE_COLUMNS,
StyledActionTableCell,
StyledNameTableCell,
StyledStickyFirstCell,
} from '@/settings/data-model/object-details/components/SettingsObjectItemTableRowStyledComponents';
import { TableCell } from '@/ui/layout/table/components/TableCell';
import { useIcons } from 'twenty-ui/display';
@@ -70,25 +71,27 @@ export const SettingsObjectMetadataItemTableRow = ({
key={objectMetadataItem.namePlural}
to={link}
>
<StyledNameTableCell>
{isDefined(Icon) && (
<Icon
style={{
minWidth: theme.icon.size.md,
}}
size={theme.icon.size.md}
stroke={theme.icon.stroke.sm}
/>
)}
<StyledNameContainer>
<StyledNameLabel title={objectMetadataItem.labelPlural}>
{objectMetadataItem.labelPlural}
</StyledNameLabel>
{!objectMetadataItem.isActive && (
<StyledInactiveLabel>{t`Deactivated`}</StyledInactiveLabel>
<StyledStickyFirstCell>
<StyledNameTableCell>
{isDefined(Icon) && (
<Icon
style={{
minWidth: theme.icon.size.md,
}}
size={theme.icon.size.md}
stroke={theme.icon.stroke.sm}
/>
)}
</StyledNameContainer>
</StyledNameTableCell>
<StyledNameContainer>
<StyledNameLabel title={objectMetadataItem.labelPlural}>
{objectMetadataItem.labelPlural}
</StyledNameLabel>
{!objectMetadataItem.isActive && (
<StyledInactiveLabel>{t`Deactivated`}</StyledInactiveLabel>
)}
</StyledNameContainer>
</StyledNameTableCell>
</StyledStickyFirstCell>
<TableCell>
<SettingsItemTypeTag item={objectMetadataItem} />
</TableCell>
@@ -1,11 +1,23 @@
import { TableCell } from '@/ui/layout/table/components/TableCell';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { styled } from '@linaria/react';
import { MOBILE_VIEWPORT, themeCssVariables } from 'twenty-ui/theme-constants';
import React from 'react';
export const SETTINGS_OBJECT_TABLE_COLUMN_WIDTH = '98.7px';
export const SETTINGS_OBJECT_TABLE_ROW_GRID_TEMPLATE_COLUMNS = `180px ${SETTINGS_OBJECT_TABLE_COLUMN_WIDTH} ${SETTINGS_OBJECT_TABLE_COLUMN_WIDTH} ${SETTINGS_OBJECT_TABLE_COLUMN_WIDTH} 36px`;
export const SETTINGS_OBJECT_TABLE_ROW_MOBILE_MIN_WIDTH = '520px';
export const StyledStickyFirstCell = styled.div`
@media (max-width: ${MOBILE_VIEWPORT}px) {
background: ${themeCssVariables.background.primary};
left: 0;
position: sticky;
z-index: 1;
}
`;
export const StyledNameTableCell = (
props: React.ComponentProps<typeof TableCell>,
) => (
@@ -6,7 +6,10 @@ import { Trans } from '@lingui/react/macro';
export const SettingsRolesTableHeader = () => {
return (
<Table>
<TableRow gridAutoColumns="332px 3fr 2fr 1fr">
<TableRow
mobileGridAutoColumns="5fr 1fr 1fr 35px"
gridAutoColumns="332px 3fr 2fr 1fr"
>
<TableHeader>
<Trans>Name</Trans>
</TableHeader>
@@ -14,6 +17,7 @@ export const SettingsRolesTableHeader = () => {
<Trans>Assigned to</Trans>
</TableHeader>
<TableHeader></TableHeader>
<TableHeader></TableHeader>
</TableRow>
</Table>
);
@@ -83,6 +83,7 @@ export const SettingsRolesTableRow = ({ role }: SettingsRolesTableRowProps) => {
<TableRow
key={role.id}
gridAutoColumns="332px 3fr 2fr 1fr"
mobileGridAutoColumns="5fr 1fr 1fr 35px"
to={getSettingsPath(SettingsPath.RoleDetail, { roleId: role.id })}
>
<TableCell>
@@ -36,6 +36,7 @@ const StyledLinkContainer = styled.div`
const StyledText = styled.span`
color: inherit;
cursor: pointer;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
@@ -129,7 +129,7 @@ export const NavigationDrawer = ({
isExpanded={isNavigationDrawerExpanded}
>
{isSettingsDrawer && title ? (
!isMobile && <NavigationDrawerBackButton title={title} />
<NavigationDrawerBackButton title={title} />
) : (
<NavigationDrawerHeader showCollapseButton />
)}
@@ -1,5 +1,6 @@
import { styled } from '@linaria/react';
import { currentMobileNavigationDrawerState } from '@/navigation/states/currentMobileNavigationDrawerState';
import { isNavigationDrawerExpandedState } from '@/ui/navigation/states/isNavigationDrawerExpanded';
import { navigationDrawerExpandedMemorizedState } from '@/ui/navigation/states/navigationDrawerExpandedMemorizedState';
import { navigationMemorizedUrlState } from '@/ui/navigation/states/navigationMemorizedUrlState';
@@ -53,6 +54,9 @@ export const NavigationDrawerBackButton = ({
const setIsNavigationDrawerExpanded = useSetAtomState(
isNavigationDrawerExpandedState,
);
const setCurrentMobileNavigationDrawer = useSetAtomState(
currentMobileNavigationDrawerState,
);
const navigationDrawerExpandedMemorized = useAtomStateValue(
navigationDrawerExpandedMemorizedState,
);
@@ -70,9 +74,10 @@ export const NavigationDrawerBackButton = ({
<UndecoratedLink
to={navigationMemorizedUrl}
replace
onClick={() =>
setIsNavigationDrawerExpanded(navigationDrawerExpandedMemorized)
}
onClick={() => {
setIsNavigationDrawerExpanded(navigationDrawerExpandedMemorized);
setCurrentMobileNavigationDrawer('main');
}}
>
<StyledIconAndButtonContainer>
<IconX