Fix: Added description below application variable (#20781)

Fixes #20757 

Before: 
<img width="655" height="777" alt="Screenshot 2026-05-21 at 12 51 25 AM"
src="https://github.com/user-attachments/assets/d164d2b8-22e6-43b4-9079-a4c33324d7dc"
/>

After:
<img width="655" height="777" alt="Screenshot 2026-05-21 at 12 50 52 AM"
src="https://github.com/user-attachments/assets/0f83062f-7703-43b9-a049-0164f5e7d9cd"
/>

---------

Co-authored-by: Etienne <45695613+etiennejouan@users.noreply.github.com>
This commit is contained in:
Priyanshu Bartwal
2026-05-22 02:44:42 +05:30
committed by GitHub
parent 9a7f50fcb7
commit e2ee4ffdff
@@ -1,12 +1,18 @@
import { type ApplicationVariable } from '~/generated-metadata/graphql';
import { t } from '@lingui/core/macro';
import { H2Title } from 'twenty-ui/display';
import { Section } from 'twenty-ui/layout';
import { TextInput } from '@/ui/input/components/TextInput';
import { useDebouncedCallback } from 'use-debounce';
import { useState } from 'react';
import { styled } from '@linaria/react';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { t } from '@lingui/core/macro';
import { isNonEmptyString } from '@sniptt/guards';
import { useContext, useState } from 'react';
import {
AppTooltip,
H2Title,
IconInfoCircle,
TooltipDelay,
} from 'twenty-ui/display';
import { Section } from 'twenty-ui/layout';
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
import { useDebouncedCallback } from 'use-debounce';
import { type ApplicationVariable } from '~/generated-metadata/graphql';
const StyledContainer = styled.div`
display: flex;
@@ -14,6 +20,19 @@ const StyledContainer = styled.div`
gap: ${themeCssVariables.spacing[4]};
`;
const StyledLabelRow = styled.div`
align-items: center;
display: flex;
gap: ${themeCssVariables.spacing[1]};
margin-bottom: ${themeCssVariables.spacing[1]};
`;
const StyledLabel = styled.span`
color: ${themeCssVariables.font.color.light};
font-size: 11px;
font-weight: ${themeCssVariables.font.weight.semiBold};
`;
export const SettingsApplicationDetailEnvironmentVariablesTable = ({
envVariables,
onUpdate,
@@ -22,6 +41,7 @@ export const SettingsApplicationDetailEnvironmentVariablesTable = ({
onUpdate: (newEnv: Pick<ApplicationVariable, 'key' | 'value'>) => void;
readonly?: boolean;
}) => {
const { theme } = useContext(ThemeContext);
const [editedEnvVariables, setEditedEnvVariables] = useState(envVariables);
const onUpdateDebounced = useDebouncedCallback(
(value: Pick<ApplicationVariable, 'key' | 'value'>) => {
@@ -29,34 +49,59 @@ export const SettingsApplicationDetailEnvironmentVariablesTable = ({
},
250,
);
const description =
const sectionDescription =
editedEnvVariables.length > 0
? t`Set your application configuration variables`
: t`No variables to set for this application`;
return (
<Section>
<H2Title title={t`Configuration`} description={description} />
<H2Title title={t`Configuration`} description={sectionDescription} />
<StyledContainer>
{editedEnvVariables.map((editedEnvVariable) => (
<TextInput
key={editedEnvVariable.key}
label={editedEnvVariable.key}
value={editedEnvVariable.value}
onChange={(newValue) => {
setEditedEnvVariables((prevState) =>
prevState.map((val) => {
if (val.key === editedEnvVariable.key) {
return { ...val, value: newValue };
}
return val;
}),
);
onUpdateDebounced({ ...editedEnvVariable, value: newValue });
}}
placeholder={t`Value`}
fullWidth
/>
))}
{editedEnvVariables.map((editedEnvVariable) => {
const tooltipId = `env-var-desc-${editedEnvVariable.key}`;
return (
<div key={editedEnvVariable.key}>
<StyledLabelRow>
<StyledLabel>{editedEnvVariable.key}</StyledLabel>
{isNonEmptyString(editedEnvVariable.description) && (
<>
<IconInfoCircle
id={`env-var-desc-${editedEnvVariable.key}`}
size={theme.icon.size.sm}
color={theme.font.color.tertiary}
style={{ outline: 'none', cursor: 'pointer' }}
/>
<AppTooltip
anchorSelect={`#${tooltipId}`}
content={editedEnvVariable.description}
offset={5}
noArrow
place="bottom"
positionStrategy="fixed"
delay={TooltipDelay.shortDelay}
/>
</>
)}
</StyledLabelRow>
<TextInput
value={editedEnvVariable.value}
onChange={(newValue) => {
setEditedEnvVariables((prevState) =>
prevState.map((val) => {
if (val.key === editedEnvVariable.key) {
return { ...val, value: newValue };
}
return val;
}),
);
onUpdateDebounced({ ...editedEnvVariable, value: newValue });
}}
placeholder={t`Value`}
fullWidth
/>
</div>
);
})}
</StyledContainer>
</Section>
);