1
0
mirror of https://github.com/Unleash/unleash.git synced 2026-02-04 20:10:52 +01:00

Group playground context fields into global / project (#11244)

Groups project fields in the playground context selector the same way as
in the constraint editor. Uses a similar grouping mechanism as in the
editable constraint, but simplifies it because there is no need to
handle the "current context field", as this is not an editing operation.
Also sorts the data by sortOrder.

Updates the playground component by using the shared general select
component instead of a custom impl.

<img width="887" height="875" alt="image"
src="https://github.com/user-attachments/assets/b9d30980-91ab-4eeb-a53c-2cfb9b502f83"
/>
This commit is contained in:
Thomas Heartman 2026-01-22 12:33:36 +01:00 committed by GitHub
parent 7adc551d41
commit 36aad2556e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -1,24 +1,19 @@
import {
type Dispatch,
type FC,
type FormEvent,
type SetStateAction,
useEffect,
useMemo,
useState,
type VFC,
} from 'react';
import {
Box,
Button,
FormControl,
InputLabel,
MenuItem,
Select,
TextField,
Typography,
useTheme,
Autocomplete,
type SelectChangeEvent,
Checkbox,
} from '@mui/material';
@ -34,23 +29,81 @@ import {
import CheckBoxOutlineBlank from '@mui/icons-material/CheckBoxOutlineBlank';
import CheckBoxIcon from '@mui/icons-material/CheckBox';
import { useFullUnleashContext } from 'hooks/api/getters/useUnleashContext/useFullUnleashContext.ts';
import { useUiFlag } from 'hooks/useUiFlag.ts';
import type { IUnleashContextDefinition } from 'interfaces/context.ts';
import type {
ISelectOption,
SelectOptionGroup,
} from 'component/common/GeneralSelect/GeneralSelect.tsx';
import GeneralSelect from 'component/common/GeneralSelect/GeneralSelect.tsx';
interface IPlaygroundCodeFieldsetProps {
context: string | undefined;
setContext: Dispatch<SetStateAction<string | undefined>>;
}
export const PlaygroundCodeFieldset: VFC<IPlaygroundCodeFieldsetProps> = ({
const createContextFieldOptions = (
context: IUnleashContextDefinition[],
{ groupOptions }: { groupOptions: boolean },
): ISelectOption[] | SelectOptionGroup[] => {
const optList = (opts: { name: string; sortOrder: number }[]) =>
opts
.toSorted((a, b) => a.sortOrder - b.sortOrder)
.map((option) => ({
key: option.name,
label: option.name,
}));
if (!groupOptions) {
return optList(context);
}
const fields = context.reduce(
({ project, global }, next) => {
if (next.project) {
project.push(next);
} else {
global.push(next);
}
return { project: project, global: global };
},
{
project: [] as IUnleashContextDefinition[],
global: [] as IUnleashContextDefinition[],
},
);
const groups: SelectOptionGroup[] = [];
if (fields.project.length) {
groups.push({
groupHeader: 'Project context fields',
options: optList(fields.project),
});
}
if (fields.global.length) {
groups.push({
groupHeader: 'Global context fields',
options: optList(fields.global),
});
}
return groups;
};
export const PlaygroundCodeFieldset: FC<IPlaygroundCodeFieldsetProps> = ({
context,
setContext,
}) => {
const theme = useTheme();
const { setToastData } = useToast();
const { context: contextData } = useFullUnleashContext();
const contextOptions = contextData
.sort((a, b) => a.sortOrder - b.sortOrder)
.map(({ name }) => name);
const groupOptions = useUiFlag('projectContextFields');
const contextOptions = createContextFieldOptions(contextData, {
groupOptions,
});
const [error, setError] = useState<string>();
const [fieldExist, setFieldExist] = useState<boolean>(false);
const [contextField, setContextField] = useState<string>('');
@ -237,10 +290,10 @@ export const PlaygroundCodeFieldset: VFC<IPlaygroundCodeFieldsetProps> = ({
);
};
const changeContextField = (event: SelectChangeEvent) => {
setContextField(event.target.value || '');
const changeContextField = (value: string) => {
setContextField(value || '');
if (event.target.value === 'currentTime') {
if (value === 'currentTime') {
return setContextValue(new Date().toISOString());
}
@ -260,27 +313,18 @@ export const PlaygroundCodeFieldset: VFC<IPlaygroundCodeFieldsetProps> = ({
</Box>
<Box sx={{ display: 'flex', gap: 2, flexWrap: 'wrap', mb: 2 }}>
<FormControl>
<InputLabel id='context-field-label' size='small'>
Context field
</InputLabel>
<Select
label='Context field'
labelId='context-field-label'
id='context-field'
value={contextField}
onChange={changeContextField}
variant='outlined'
size='small'
sx={{ width: 200, maxWidth: '100%' }}
>
{contextOptions.map((option) => (
<MenuItem key={option} value={option}>
{option}
</MenuItem>
))}
</Select>
</FormControl>
<GeneralSelect
label='Context field'
labelId='context-field-label'
id='context-field'
value={contextField}
onChange={changeContextField}
variant='outlined'
size='small'
sx={{ width: 200, maxWidth: '100%' }}
options={contextOptions}
/>
{resolveInput()}
<Button
variant='outlined'