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:
committed by
GitHub
parent
9a7f50fcb7
commit
e2ee4ffdff
+74
-29
@@ -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>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user