Fix dark mode text color on permissions tab empty stat (#19336) (#19340)

Before: black text in dark mode
<img width="1224" height="860" alt="image"
src="https://github.com/user-attachments/assets/a419ef77-9358-4588-ad19-a15b57448682"
/>


After updated styling: the correct grey text in dark mode
<img width="638" height="249" alt="Screenshot 2026-04-05 at 2 47 24 PM"
src="https://github.com/user-attachments/assets/bf736464-d33c-40f1-8244-2cf5d93b7e9c"
/>

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
Neil Kanakia
2026-04-06 03:46:10 +08:00
committed by GitHub
parent f25e040712
commit bad488494f
10 changed files with 70 additions and 50 deletions
@@ -1,3 +1,4 @@
import { SettingsEmptyPlaceholder } from '@/settings/components/SettingsEmptyPlaceholder';
import { SettingsAdminDeleteJobsConfirmationModal } from '@/settings/admin-panel/health-status/components/SettingsAdminDeleteJobsConfirmationModal';
import { SettingsAdminJobDetailsExpandable } from '@/settings/admin-panel/health-status/components/SettingsAdminJobDetailsExpandable';
import { SettingsAdminJobStateBadge } from '@/settings/admin-panel/health-status/components/SettingsAdminJobStateBadge';
@@ -49,12 +50,6 @@ const StyledControlsContainer = styled.div`
justify-content: space-between;
`;
const StyledEmptyState = styled.div`
color: ${themeCssVariables.font.color.tertiary};
padding: ${themeCssVariables.spacing[8]};
text-align: center;
`;
const StyledPaginationContainer = styled.div`
align-items: center;
display: flex;
@@ -261,9 +256,9 @@ export const SettingsAdminQueueJobsTable = ({
</StyledControlsContainer>
{loading && jobs.length === 0 ? (
<StyledEmptyState>{t`Loading jobs...`}</StyledEmptyState>
<SettingsEmptyPlaceholder>{t`Loading jobs...`}</SettingsEmptyPlaceholder>
) : jobs.length === 0 ? (
<StyledEmptyState>{t`No jobs found`}</StyledEmptyState>
<SettingsEmptyPlaceholder>{t`No jobs found`}</SettingsEmptyPlaceholder>
) : (
<>
<Table>
@@ -0,0 +1,35 @@
import { styled } from '@linaria/react';
import { type ReactNode } from 'react';
import { themeCssVariables } from 'twenty-ui/theme-constants';
type ThemeSpacingKey = keyof typeof themeCssVariables.spacing;
type SettingsEmptyPlaceholderProps = {
children: ReactNode;
padding?: ThemeSpacingKey;
textAlign?: 'left' | 'center' | 'right';
};
const StyledPlaceholder = styled.div<{
placeholderPadding: string;
placeholderTextAlign: string;
}>`
color: ${themeCssVariables.font.color.tertiary};
padding: ${({ placeholderPadding }) => placeholderPadding};
text-align: ${({ placeholderTextAlign }) => placeholderTextAlign};
`;
export const SettingsEmptyPlaceholder = ({
children,
padding = '8',
textAlign = 'center',
}: SettingsEmptyPlaceholderProps) => {
return (
<StyledPlaceholder
placeholderPadding={themeCssVariables.spacing[padding]}
placeholderTextAlign={textAlign}
>
{children}
</StyledPlaceholder>
);
};
@@ -1,3 +1,4 @@
import { SettingsEmptyPlaceholder } from '@/settings/components/SettingsEmptyPlaceholder';
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
import { DropdownMenuSearchInput } from '@/ui/layout/dropdown/components/DropdownMenuSearchInput';
@@ -35,12 +36,6 @@ const StyledItemName = styled.div`
font-weight: ${themeCssVariables.font.weight.medium};
`;
const StyledEmptyState = styled.div`
color: ${themeCssVariables.font.color.tertiary};
padding: ${themeCssVariables.spacing[2]};
text-align: center;
`;
type EntityData = Agent | ApiKeyForRole;
type SettingsRoleAssignmentEntityPickerDropdownProps = {
@@ -138,7 +133,9 @@ export const SettingsRoleAssignmentEntityPickerDropdown = ({
</StyledDropdownItem>
))
) : (
<StyledEmptyState>{getEmptyStateMessage()}</StyledEmptyState>
<SettingsEmptyPlaceholder padding="2">
{getEmptyStateMessage()}
</SettingsEmptyPlaceholder>
)}
</DropdownMenuItemsContainer>
</DropdownContent>
@@ -1,3 +1,4 @@
import { SettingsEmptyPlaceholder } from '@/settings/components/SettingsEmptyPlaceholder';
import { styled } from '@linaria/react';
import { t } from '@lingui/core/macro';
import { type ComponentType, useContext } from 'react';
@@ -89,7 +90,9 @@ export const SettingsToolParameterTable = ({
const entries = Object.entries(schemaProperties);
if (entries.length === 0 && !functionLink) {
return <div>{t`No parameters`}</div>;
return (
<SettingsEmptyPlaceholder>{t`No parameters`}</SettingsEmptyPlaceholder>
);
}
return (
@@ -1,3 +1,4 @@
import { SettingsEmptyPlaceholder } from '@/settings/components/SettingsEmptyPlaceholder';
import { SETTINGS_OBJECT_TABLE_COLUMN_WIDTH } from '@/settings/data-model/object-details/components/SettingsObjectItemTableRowStyledComponents';
import { Table } from '@/ui/layout/table/components/Table';
import { TableHeader } from '@/ui/layout/table/components/TableHeader';
@@ -39,12 +40,6 @@ const StyledSearchInputContainer = styled.div`
padding-bottom: ${themeCssVariables.spacing[2]};
`;
const StyledEmptyState = styled.div`
color: ${themeCssVariables.font.color.tertiary};
padding: ${themeCssVariables.spacing[8]};
text-align: center;
`;
export const SettingsApplicationDataTable = ({
objectRows,
fieldGroupRows,
@@ -102,7 +97,7 @@ export const SettingsApplicationDataTable = ({
/>
</StyledSearchInputContainer>
{hasNoResults ? (
<StyledEmptyState>{t`No object found`}</StyledEmptyState>
<SettingsEmptyPlaceholder>{t`No object found`}</SettingsEmptyPlaceholder>
) : (
<Table>
<TableRow gridAutoColumns={MAIN_ROW_GRID_COLUMNS}>
@@ -5,6 +5,7 @@ import { SettingsRolesQueryEffect } from '@/settings/roles/components/SettingsRo
import { SettingsRolePermissions } from '@/settings/roles/role-permissions/components/SettingsRolePermissions';
import { settingsDraftRoleFamilyState } from '@/settings/roles/states/settingsDraftRoleFamilyState';
import { type RoleWithPartialMembers } from '@/settings/roles/types/RoleWithPartialMembers';
import { SettingsEmptyPlaceholder } from '@/settings/components/SettingsEmptyPlaceholder';
import { useSetAtomFamilyState } from '@/ui/utilities/state/jotai/hooks/useSetAtomFamilyState';
import { t } from '@lingui/core/macro';
import { useCallback, useEffect, useMemo, useState } from 'react';
@@ -393,5 +394,9 @@ export const SettingsApplicationPermissionsTab = ({
);
}
return <div>{t`No permissions configured for this application.`}</div>;
return (
<SettingsEmptyPlaceholder padding="0">
{t`No permissions configured for this application.`}
</SettingsEmptyPlaceholder>
);
};
@@ -1,3 +1,4 @@
import { SettingsEmptyPlaceholder } from '@/settings/components/SettingsEmptyPlaceholder';
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
@@ -26,12 +27,6 @@ const StyledCardsGrid = styled.div`
}
`;
const StyledEmptyState = styled.div`
color: ${themeCssVariables.font.color.tertiary};
padding: ${themeCssVariables.spacing[4]};
text-align: center;
`;
const StyledHintLink = styled.button`
background: none;
border: none;
@@ -73,7 +68,7 @@ export const SettingsApplicationsAvailableTab = () => {
if (isLoading) {
return (
<Section>
<StyledEmptyState>{t`Loading applications...`}</StyledEmptyState>
<SettingsEmptyPlaceholder padding="4">{t`Loading applications...`}</SettingsEmptyPlaceholder>
</Section>
);
}
@@ -115,7 +110,7 @@ export const SettingsApplicationsAvailableTab = () => {
</StyledSearchInputContainer>
{filteredApplications.length === 0 ? (
<StyledEmptyState>
<SettingsEmptyPlaceholder padding="4">
{showNonFeaturedHint
? t`No featured applications found. ${nonFeaturedCount} non-featured result(s) available — `
: t`No applications available`}
@@ -124,7 +119,7 @@ export const SettingsApplicationsAvailableTab = () => {
{t`show all`}
</StyledHintLink>
)}
</StyledEmptyState>
</SettingsEmptyPlaceholder>
) : (
<StyledCardsGrid>
{filteredApplications.map((application) => (
@@ -1,4 +1,5 @@
import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState';
import { SettingsEmptyPlaceholder } from '@/settings/components/SettingsEmptyPlaceholder';
import { SettingsListCard } from '@/settings/components/SettingsListCard';
import {
StyledActionTableCell,
@@ -50,12 +51,6 @@ const StyledSearchInputContainer = styled.div`
padding-bottom: ${themeCssVariables.spacing[2]};
`;
const StyledEmptyState = styled.div`
color: ${themeCssVariables.font.color.tertiary};
padding: ${themeCssVariables.spacing[8]};
text-align: center;
`;
const StyledTableRowsContainer = styled.div`
border-bottom: 1px solid ${themeCssVariables.border.color.light};
padding: ${themeCssVariables.spacing[2]} 0;
@@ -235,7 +230,7 @@ export const SettingsApplicationsDeveloperTab = () => {
/>
</StyledSearchInputContainer>
{filteredMarketplaceApps.length === 0 ? (
<StyledEmptyState>{t`No application found`}</StyledEmptyState>
<SettingsEmptyPlaceholder>{t`No application found`}</SettingsEmptyPlaceholder>
) : (
<Table>
<TableRow gridAutoColumns={NPM_PACKAGES_GRID_COLUMNS}>
@@ -1,3 +1,4 @@
import { SettingsEmptyPlaceholder } from '@/settings/components/SettingsEmptyPlaceholder';
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
import { SettingsEmailingDomainVerificationRecords } from '@/settings/emailing-domains/components/SettingsEmailingDomainVerificationRecords';
@@ -26,11 +27,15 @@ export const SettingsEmailingDomainDetail = () => {
);
if (loading) {
return <div>{t`Loading...`}</div>;
return <SettingsEmptyPlaceholder>{t`Loading...`}</SettingsEmptyPlaceholder>;
}
if (isDefined(error) || !isDefined(emailingDomain)) {
return <Trans>Domain not found</Trans>;
return (
<SettingsEmptyPlaceholder>
<Trans>Domain not found</Trans>
</SettingsEmptyPlaceholder>
);
}
return (
@@ -1,3 +1,4 @@
import { SettingsEmptyPlaceholder } from '@/settings/components/SettingsEmptyPlaceholder';
import { styled } from '@linaria/react';
import { msg } from '@lingui/core/macro';
import { Trans, useLingui } from '@lingui/react/macro';
@@ -132,12 +133,6 @@ const StyledResizeHandle = styled.div<{ isResizing: boolean }>`
}
`;
const StyledEmptyState = styled.div`
color: ${themeCssVariables.font.color.tertiary};
padding: ${themeCssVariables.spacing[8]};
text-align: center;
`;
const StyledLoadingMore = styled.div`
color: ${themeCssVariables.font.color.tertiary};
padding: ${themeCssVariables.spacing[4]};
@@ -292,9 +287,9 @@ export const EventLogResultsTable = ({
if (!loading && records.length === 0) {
return (
<StyledEmptyState>
<SettingsEmptyPlaceholder>
<Trans>No event logs found</Trans>
</StyledEmptyState>
</SettingsEmptyPlaceholder>
);
}