mirror of
				https://github.com/Unleash/unleash.git
				synced 2025-10-27 11:02:16 +01:00 
			
		
		
		
	feat: disabled feature dependency (#6731)
This commit is contained in:
		
							parent
							
								
									81aff26394
								
							
						
					
					
						commit
						664ceaea09
					
				@ -42,6 +42,9 @@ export const DependencyChange: VFC<{
 | 
				
			|||||||
                            >
 | 
					                            >
 | 
				
			||||||
                                {change.payload.feature}
 | 
					                                {change.payload.feature}
 | 
				
			||||||
                            </StyledLink>
 | 
					                            </StyledLink>
 | 
				
			||||||
 | 
					                            {change.payload.enabled === false
 | 
				
			||||||
 | 
					                                ? ' (disabled)'
 | 
				
			||||||
 | 
					                                : null}
 | 
				
			||||||
                        </AddDependencyWrapper>
 | 
					                        </AddDependencyWrapper>
 | 
				
			||||||
                        {actions}
 | 
					                        {actions}
 | 
				
			||||||
                    </ChangeItemWrapper>
 | 
					                    </ChangeItemWrapper>
 | 
				
			||||||
 | 
				
			|||||||
@ -223,7 +223,7 @@ type ChangeRequestVariantPatch = {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
type ChangeRequestEnabled = { enabled: boolean };
 | 
					type ChangeRequestEnabled = { enabled: boolean };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type ChangeRequestAddDependency = { feature: string };
 | 
					type ChangeRequestAddDependency = { feature: string; enabled: boolean };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export type ChangeRequestAddStrategy = Pick<
 | 
					export type ChangeRequestAddStrategy = Pick<
 | 
				
			||||||
    IFeatureStrategy,
 | 
					    IFeatureStrategy,
 | 
				
			||||||
 | 
				
			|||||||
@ -11,6 +11,9 @@ const setupApi = () => {
 | 
				
			|||||||
        versionInfo: {
 | 
					        versionInfo: {
 | 
				
			||||||
            current: { oss: 'irrelevant', enterprise: 'some value' },
 | 
					            current: { oss: 'irrelevant', enterprise: 'some value' },
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
 | 
					        flags: {
 | 
				
			||||||
 | 
					            variantDependencies: true,
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    testServerRoute(
 | 
					    testServerRoute(
 | 
				
			||||||
@ -103,13 +106,17 @@ test('Edit dependency', async () => {
 | 
				
			|||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Open the dropdown by selecting the role.
 | 
					    // Open the dropdown by selecting the role.
 | 
				
			||||||
    const dropdown = screen.queryAllByRole('combobox')[0];
 | 
					    const [featureDropdown, featureStatusDropdown] =
 | 
				
			||||||
    expect(dropdown.innerHTML).toBe('parentB');
 | 
					        screen.queryAllByRole('combobox');
 | 
				
			||||||
    userEvent.click(dropdown);
 | 
					    expect(featureDropdown.innerHTML).toBe('parentB');
 | 
				
			||||||
 | 
					    userEvent.click(featureDropdown);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const parentAOption = await screen.findByText('parentA');
 | 
					    const parentAOption = await screen.findByText('parentA');
 | 
				
			||||||
    userEvent.click(parentAOption);
 | 
					    userEvent.click(parentAOption);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    await screen.findByText('feature status');
 | 
				
			||||||
 | 
					    expect(featureStatusDropdown.innerHTML).toBe('enabled');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const addButton = await screen.findByText('Add');
 | 
					    const addButton = await screen.findByText('Add');
 | 
				
			||||||
    userEvent.click(addButton);
 | 
					    userEvent.click(addButton);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -14,11 +14,13 @@ import useToast from 'hooks/useToast';
 | 
				
			|||||||
import { formatUnknownError } from 'utils/formatUnknownError';
 | 
					import { formatUnknownError } from 'utils/formatUnknownError';
 | 
				
			||||||
import { usePlausibleTracker } from 'hooks/usePlausibleTracker';
 | 
					import { usePlausibleTracker } from 'hooks/usePlausibleTracker';
 | 
				
			||||||
import { DependenciesUpgradeAlert } from './DependenciesUpgradeAlert';
 | 
					import { DependenciesUpgradeAlert } from './DependenciesUpgradeAlert';
 | 
				
			||||||
 | 
					import { useUiFlag } from 'hooks/useUiFlag';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
interface IAddDependencyDialogueProps {
 | 
					interface IAddDependencyDialogueProps {
 | 
				
			||||||
    project: string;
 | 
					    project: string;
 | 
				
			||||||
    featureId: string;
 | 
					    featureId: string;
 | 
				
			||||||
    parentFeatureId?: string;
 | 
					    parentFeatureId?: string;
 | 
				
			||||||
 | 
					    parentFeatureValue?: ParentValue;
 | 
				
			||||||
    showDependencyDialogue: boolean;
 | 
					    showDependencyDialogue: boolean;
 | 
				
			||||||
    onClose: () => void;
 | 
					    onClose: () => void;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -40,7 +42,7 @@ const LazyOptions: FC<{
 | 
				
			|||||||
    parent: string;
 | 
					    parent: string;
 | 
				
			||||||
    onSelect: (parent: string) => void;
 | 
					    onSelect: (parent: string) => void;
 | 
				
			||||||
}> = ({ project, featureId, parent, onSelect }) => {
 | 
					}> = ({ project, featureId, parent, onSelect }) => {
 | 
				
			||||||
    const { parentOptions, loading } = useParentOptions(project, featureId);
 | 
					    const { parentOptions } = useParentOptions(project, featureId);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const options = parentOptions
 | 
					    const options = parentOptions
 | 
				
			||||||
        ? [
 | 
					        ? [
 | 
				
			||||||
@ -61,10 +63,30 @@ const LazyOptions: FC<{
 | 
				
			|||||||
    );
 | 
					    );
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const FeatureValueOptions: FC<{
 | 
				
			||||||
 | 
					    parentValue: ParentValue;
 | 
				
			||||||
 | 
					    onSelect: (parent: string) => void;
 | 
				
			||||||
 | 
					}> = ({ onSelect, parentValue }) => {
 | 
				
			||||||
 | 
					    return (
 | 
				
			||||||
 | 
					        <StyledSelect
 | 
				
			||||||
 | 
					            fullWidth
 | 
				
			||||||
 | 
					            options={[
 | 
				
			||||||
 | 
					                { key: 'enabled', label: 'enabled' },
 | 
				
			||||||
 | 
					                { key: 'disabled', label: 'disabled' },
 | 
				
			||||||
 | 
					            ]}
 | 
				
			||||||
 | 
					            value={parentValue.status}
 | 
				
			||||||
 | 
					            onChange={onSelect}
 | 
				
			||||||
 | 
					        />
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type ParentValue = { status: 'enabled' } | { status: 'disabled' };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const useManageDependency = (
 | 
					const useManageDependency = (
 | 
				
			||||||
    project: string,
 | 
					    project: string,
 | 
				
			||||||
    featureId: string,
 | 
					    featureId: string,
 | 
				
			||||||
    parent: string,
 | 
					    parent: string,
 | 
				
			||||||
 | 
					    parentValue: ParentValue,
 | 
				
			||||||
    onClose: () => void,
 | 
					    onClose: () => void,
 | 
				
			||||||
) => {
 | 
					) => {
 | 
				
			||||||
    const { trackEvent } = usePlausibleTracker();
 | 
					    const { trackEvent } = usePlausibleTracker();
 | 
				
			||||||
@ -91,7 +113,10 @@ const useManageDependency = (
 | 
				
			|||||||
                {
 | 
					                {
 | 
				
			||||||
                    action: actionType,
 | 
					                    action: actionType,
 | 
				
			||||||
                    feature: featureId,
 | 
					                    feature: featureId,
 | 
				
			||||||
                    payload: { feature: parent },
 | 
					                    payload: {
 | 
				
			||||||
 | 
					                        feature: parent,
 | 
				
			||||||
 | 
					                        enabled: parentValue.status !== 'disabled',
 | 
				
			||||||
 | 
					                    },
 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
            ]);
 | 
					            ]);
 | 
				
			||||||
            trackEvent('dependent_features', {
 | 
					            trackEvent('dependent_features', {
 | 
				
			||||||
@ -105,7 +130,7 @@ const useManageDependency = (
 | 
				
			|||||||
                { action: actionType, feature: featureId, payload: undefined },
 | 
					                { action: actionType, feature: featureId, payload: undefined },
 | 
				
			||||||
            ]);
 | 
					            ]);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        refetchChangeRequests();
 | 
					        void refetchChangeRequests();
 | 
				
			||||||
        setToastData({
 | 
					        setToastData({
 | 
				
			||||||
            text:
 | 
					            text:
 | 
				
			||||||
                actionType === 'addDependency'
 | 
					                actionType === 'addDependency'
 | 
				
			||||||
@ -116,7 +141,7 @@ const useManageDependency = (
 | 
				
			|||||||
        });
 | 
					        });
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const manageDependency = async () => {
 | 
					    return async () => {
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
            if (isChangeRequestConfiguredInAnyEnv()) {
 | 
					            if (isChangeRequestConfiguredInAnyEnv()) {
 | 
				
			||||||
                const actionType =
 | 
					                const actionType =
 | 
				
			||||||
@ -141,7 +166,10 @@ const useManageDependency = (
 | 
				
			|||||||
                });
 | 
					                });
 | 
				
			||||||
                setToastData({ title: 'Dependency removed', type: 'success' });
 | 
					                setToastData({ title: 'Dependency removed', type: 'success' });
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                await addDependency(featureId, { feature: parent });
 | 
					                await addDependency(featureId, {
 | 
				
			||||||
 | 
					                    feature: parent,
 | 
				
			||||||
 | 
					                    enabled: parentValue.status !== 'disabled',
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
                trackEvent('dependent_features', {
 | 
					                trackEvent('dependent_features', {
 | 
				
			||||||
                    props: {
 | 
					                    props: {
 | 
				
			||||||
                        eventType: 'dependency added',
 | 
					                        eventType: 'dependency added',
 | 
				
			||||||
@ -152,32 +180,37 @@ const useManageDependency = (
 | 
				
			|||||||
        } catch (error) {
 | 
					        } catch (error) {
 | 
				
			||||||
            setToastApiError(formatUnknownError(error));
 | 
					            setToastApiError(formatUnknownError(error));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        await refetchFeature();
 | 
					        void refetchFeature();
 | 
				
			||||||
        onClose();
 | 
					        onClose();
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					 | 
				
			||||||
    return manageDependency;
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const AddDependencyDialogue = ({
 | 
					export const AddDependencyDialogue = ({
 | 
				
			||||||
    project,
 | 
					    project,
 | 
				
			||||||
    featureId,
 | 
					    featureId,
 | 
				
			||||||
    parentFeatureId,
 | 
					    parentFeatureId,
 | 
				
			||||||
 | 
					    parentFeatureValue,
 | 
				
			||||||
    showDependencyDialogue,
 | 
					    showDependencyDialogue,
 | 
				
			||||||
    onClose,
 | 
					    onClose,
 | 
				
			||||||
}: IAddDependencyDialogueProps) => {
 | 
					}: IAddDependencyDialogueProps) => {
 | 
				
			||||||
    const [parent, setParent] = useState(
 | 
					    const [parent, setParent] = useState(
 | 
				
			||||||
        parentFeatureId || REMOVE_DEPENDENCY_OPTION.key,
 | 
					        parentFeatureId || REMOVE_DEPENDENCY_OPTION.key,
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
 | 
					    const [parentValue, setParentValue] = useState<ParentValue>(
 | 
				
			||||||
 | 
					        parentFeatureValue || { status: 'enabled' },
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
    const handleClick = useManageDependency(
 | 
					    const handleClick = useManageDependency(
 | 
				
			||||||
        project,
 | 
					        project,
 | 
				
			||||||
        featureId,
 | 
					        featureId,
 | 
				
			||||||
        parent,
 | 
					        parent,
 | 
				
			||||||
 | 
					        parentValue,
 | 
				
			||||||
        onClose,
 | 
					        onClose,
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
    const { isChangeRequestConfiguredInAnyEnv } =
 | 
					    const { isChangeRequestConfiguredInAnyEnv } =
 | 
				
			||||||
        useChangeRequestsEnabled(project);
 | 
					        useChangeRequestsEnabled(project);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const variantDependenciesEnabled = useUiFlag('variantDependencies');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return (
 | 
					    return (
 | 
				
			||||||
        <Dialogue
 | 
					        <Dialogue
 | 
				
			||||||
            open={showDependencyDialogue}
 | 
					            open={showDependencyDialogue}
 | 
				
			||||||
@ -197,10 +230,18 @@ export const AddDependencyDialogue = ({
 | 
				
			|||||||
                <DependenciesUpgradeAlert />
 | 
					                <DependenciesUpgradeAlert />
 | 
				
			||||||
                <Box sx={{ mt: 2, mb: 4 }}>
 | 
					                <Box sx={{ mt: 2, mb: 4 }}>
 | 
				
			||||||
                    Your feature will be evaluated only when the selected parent
 | 
					                    Your feature will be evaluated only when the selected parent
 | 
				
			||||||
                    feature is enabled in the same environment.
 | 
					                    feature is{' '}
 | 
				
			||||||
 | 
					                    <b>
 | 
				
			||||||
 | 
					                        {parentValue.status === 'disabled'
 | 
				
			||||||
 | 
					                            ? 'disabled'
 | 
				
			||||||
 | 
					                            : 'enabled'}
 | 
				
			||||||
 | 
					                    </b>{' '}
 | 
				
			||||||
 | 
					                    in the same environment.
 | 
				
			||||||
                </Box>
 | 
					                </Box>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                <Typography>What feature do you want to depend on?</Typography>
 | 
					                <Typography>
 | 
				
			||||||
 | 
					                    What <b>feature</b> do you want to depend on?
 | 
				
			||||||
 | 
					                </Typography>
 | 
				
			||||||
                <ConditionallyRender
 | 
					                <ConditionallyRender
 | 
				
			||||||
                    condition={showDependencyDialogue}
 | 
					                    condition={showDependencyDialogue}
 | 
				
			||||||
                    show={
 | 
					                    show={
 | 
				
			||||||
@ -208,10 +249,39 @@ export const AddDependencyDialogue = ({
 | 
				
			|||||||
                            project={project}
 | 
					                            project={project}
 | 
				
			||||||
                            featureId={featureId}
 | 
					                            featureId={featureId}
 | 
				
			||||||
                            parent={parent}
 | 
					                            parent={parent}
 | 
				
			||||||
                            onSelect={setParent}
 | 
					                            onSelect={(status) => {
 | 
				
			||||||
 | 
					                                setParentValue({ status: 'enabled' });
 | 
				
			||||||
 | 
					                                setParent(status);
 | 
				
			||||||
 | 
					                            }}
 | 
				
			||||||
                        />
 | 
					                        />
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                />
 | 
					                />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                <ConditionallyRender
 | 
				
			||||||
 | 
					                    condition={
 | 
				
			||||||
 | 
					                        parent !== REMOVE_DEPENDENCY_OPTION.key &&
 | 
				
			||||||
 | 
					                        variantDependenciesEnabled
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    show={
 | 
				
			||||||
 | 
					                        <Box sx={{ mt: 2 }}>
 | 
				
			||||||
 | 
					                            <Typography>
 | 
				
			||||||
 | 
					                                What <b>feature status</b> do you want to depend
 | 
				
			||||||
 | 
					                                on?
 | 
				
			||||||
 | 
					                            </Typography>
 | 
				
			||||||
 | 
					                            <FeatureValueOptions
 | 
				
			||||||
 | 
					                                parentValue={parentValue}
 | 
				
			||||||
 | 
					                                onSelect={(value) =>
 | 
				
			||||||
 | 
					                                    setParentValue({
 | 
				
			||||||
 | 
					                                        status:
 | 
				
			||||||
 | 
					                                            value === 'disabled'
 | 
				
			||||||
 | 
					                                                ? 'disabled'
 | 
				
			||||||
 | 
					                                                : 'enabled',
 | 
				
			||||||
 | 
					                                    })
 | 
				
			||||||
 | 
					                                }
 | 
				
			||||||
 | 
					                            />
 | 
				
			||||||
 | 
					                        </Box>
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                />
 | 
				
			||||||
            </Box>
 | 
					            </Box>
 | 
				
			||||||
        </Dialogue>
 | 
					        </Dialogue>
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
 | 
				
			|||||||
@ -144,6 +144,23 @@ export const DependencyRow: FC<{ feature: IFeatureToggle }> = ({ feature }) => {
 | 
				
			|||||||
                    </FlexRow>
 | 
					                    </FlexRow>
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            />
 | 
					            />
 | 
				
			||||||
 | 
					            <ConditionallyRender
 | 
				
			||||||
 | 
					                condition={
 | 
				
			||||||
 | 
					                    hasParentDependency && !feature.dependencies[0]?.enabled
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                show={
 | 
				
			||||||
 | 
					                    <FlexRow>
 | 
				
			||||||
 | 
					                        <StyledDetail>
 | 
				
			||||||
 | 
					                            <StyledLabel>Dependency value:</StyledLabel>
 | 
				
			||||||
 | 
					                            <span>
 | 
				
			||||||
 | 
					                                {feature.dependencies[0]?.enabled
 | 
				
			||||||
 | 
					                                    ? 'enabled'
 | 
				
			||||||
 | 
					                                    : 'disabled'}
 | 
				
			||||||
 | 
					                            </span>
 | 
				
			||||||
 | 
					                        </StyledDetail>
 | 
				
			||||||
 | 
					                    </FlexRow>
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            />
 | 
				
			||||||
            <ConditionallyRender
 | 
					            <ConditionallyRender
 | 
				
			||||||
                condition={hasChildren}
 | 
					                condition={hasChildren}
 | 
				
			||||||
                show={
 | 
					                show={
 | 
				
			||||||
@ -158,6 +175,7 @@ export const DependencyRow: FC<{ feature: IFeatureToggle }> = ({ feature }) => {
 | 
				
			|||||||
                    </FlexRow>
 | 
					                    </FlexRow>
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            />
 | 
					            />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            <ConditionallyRender
 | 
					            <ConditionallyRender
 | 
				
			||||||
                condition={Boolean(feature.project)}
 | 
					                condition={Boolean(feature.project)}
 | 
				
			||||||
                show={
 | 
					                show={
 | 
				
			||||||
@ -165,6 +183,12 @@ export const DependencyRow: FC<{ feature: IFeatureToggle }> = ({ feature }) => {
 | 
				
			|||||||
                        project={feature.project}
 | 
					                        project={feature.project}
 | 
				
			||||||
                        featureId={feature.name}
 | 
					                        featureId={feature.name}
 | 
				
			||||||
                        parentFeatureId={feature.dependencies[0]?.feature}
 | 
					                        parentFeatureId={feature.dependencies[0]?.feature}
 | 
				
			||||||
 | 
					                        parentFeatureValue={{
 | 
				
			||||||
 | 
					                            status:
 | 
				
			||||||
 | 
					                                feature.dependencies[0]?.enabled === false
 | 
				
			||||||
 | 
					                                    ? 'disabled'
 | 
				
			||||||
 | 
					                                    : 'enabled',
 | 
				
			||||||
 | 
					                        }}
 | 
				
			||||||
                        onClose={() => setShowDependencyDialogue(false)}
 | 
					                        onClose={() => setShowDependencyDialogue(false)}
 | 
				
			||||||
                        showDependencyDialogue={showDependencyDialogue}
 | 
					                        showDependencyDialogue={showDependencyDialogue}
 | 
				
			||||||
                    />
 | 
					                    />
 | 
				
			||||||
 | 
				
			|||||||
@ -13,6 +13,9 @@ const setupApi = () => {
 | 
				
			|||||||
        versionInfo: {
 | 
					        versionInfo: {
 | 
				
			||||||
            current: { oss: 'irrelevant', enterprise: 'some value' },
 | 
					            current: { oss: 'irrelevant', enterprise: 'some value' },
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
 | 
					        flags: {
 | 
				
			||||||
 | 
					            variantDependencies: true,
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    testServerRoute(server, '/api/admin/projects/default/features/feature', {});
 | 
					    testServerRoute(server, '/api/admin/projects/default/features/feature', {});
 | 
				
			||||||
    testServerRoute(
 | 
					    testServerRoute(
 | 
				
			||||||
@ -250,7 +253,7 @@ test('edit dependency', async () => {
 | 
				
			|||||||
                {
 | 
					                {
 | 
				
			||||||
                    name: 'feature',
 | 
					                    name: 'feature',
 | 
				
			||||||
                    project: 'default',
 | 
					                    project: 'default',
 | 
				
			||||||
                    dependencies: [{ feature: 'some_parent' }],
 | 
					                    dependencies: [{ feature: 'some_parent', enabled: false }],
 | 
				
			||||||
                    children: [] as string[],
 | 
					                    children: [] as string[],
 | 
				
			||||||
                } as IFeatureToggle
 | 
					                } as IFeatureToggle
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@ -265,6 +268,8 @@ test('edit dependency', async () => {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    await screen.findByText('Dependency:');
 | 
					    await screen.findByText('Dependency:');
 | 
				
			||||||
    await screen.findByText('some_parent');
 | 
					    await screen.findByText('some_parent');
 | 
				
			||||||
 | 
					    await screen.findByText('Dependency value:');
 | 
				
			||||||
 | 
					    await screen.findByText('disabled');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const actionsButton = await screen.findByRole('button', {
 | 
					    const actionsButton = await screen.findByRole('button', {
 | 
				
			||||||
        name: /Dependency actions/i,
 | 
					        name: /Dependency actions/i,
 | 
				
			||||||
 | 
				
			|||||||
@ -7,7 +7,6 @@ import { useLocationSettings } from 'hooks/useLocationSettings';
 | 
				
			|||||||
import { formatDateYMD } from 'utils/formatDate';
 | 
					import { formatDateYMD } from 'utils/formatDate';
 | 
				
			||||||
import { parseISO } from 'date-fns';
 | 
					import { parseISO } from 'date-fns';
 | 
				
			||||||
import { FeatureEnvironmentSeen } from '../../../FeatureEnvironmentSeen/FeatureEnvironmentSeen';
 | 
					import { FeatureEnvironmentSeen } from '../../../FeatureEnvironmentSeen/FeatureEnvironmentSeen';
 | 
				
			||||||
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
 | 
					 | 
				
			||||||
import { DependencyRow } from './DependencyRow';
 | 
					import { DependencyRow } from './DependencyRow';
 | 
				
			||||||
import { FlexRow, StyledDetail, StyledLabel } from './StyledRow';
 | 
					import { FlexRow, StyledDetail, StyledLabel } from './StyledRow';
 | 
				
			||||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
 | 
					import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
 | 
				
			||||||
@ -30,7 +29,6 @@ export const FeatureOverviewSidePanelDetails = ({
 | 
				
			|||||||
    header,
 | 
					    header,
 | 
				
			||||||
}: IFeatureOverviewSidePanelDetailsProps) => {
 | 
					}: IFeatureOverviewSidePanelDetailsProps) => {
 | 
				
			||||||
    const { locationSettings } = useLocationSettings();
 | 
					    const { locationSettings } = useLocationSettings();
 | 
				
			||||||
    const { uiConfig } = useUiConfig();
 | 
					 | 
				
			||||||
    const showDependentFeatures = useShowDependentFeatures(feature.project);
 | 
					    const showDependentFeatures = useShowDependentFeatures(feature.project);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const lastSeenEnvironments: ILastSeenEnvironments[] =
 | 
					    const lastSeenEnvironments: ILastSeenEnvironments[] =
 | 
				
			||||||
 | 
				
			|||||||
@ -54,6 +54,7 @@ export interface IFeatureToggle {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
export interface IDependency {
 | 
					export interface IDependency {
 | 
				
			||||||
    feature: string;
 | 
					    feature: string;
 | 
				
			||||||
 | 
					    enabled: boolean;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export interface IFeatureEnvironment {
 | 
					export interface IFeatureEnvironment {
 | 
				
			||||||
 | 
				
			|||||||
@ -78,6 +78,7 @@ export type UiFlags = {
 | 
				
			|||||||
    outdatedSdksBanner?: boolean;
 | 
					    outdatedSdksBanner?: boolean;
 | 
				
			||||||
    projectOverviewRefactor?: string;
 | 
					    projectOverviewRefactor?: string;
 | 
				
			||||||
    collectTrafficDataUsage?: boolean;
 | 
					    collectTrafficDataUsage?: boolean;
 | 
				
			||||||
 | 
					    variantDependencies?: boolean;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export interface IVersionInfo {
 | 
					export interface IVersionInfo {
 | 
				
			||||||
 | 
				
			|||||||
@ -143,6 +143,7 @@ exports[`should create default config 1`] = `
 | 
				
			|||||||
      "stripClientHeadersOn304": false,
 | 
					      "stripClientHeadersOn304": false,
 | 
				
			||||||
      "useMemoizedActiveTokens": false,
 | 
					      "useMemoizedActiveTokens": false,
 | 
				
			||||||
      "userAccessUIEnabled": false,
 | 
					      "userAccessUIEnabled": false,
 | 
				
			||||||
 | 
					      "variantDependencies": false,
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "externalResolver": {
 | 
					    "externalResolver": {
 | 
				
			||||||
      "getVariant": [Function],
 | 
					      "getVariant": [Function],
 | 
				
			||||||
 | 
				
			|||||||
@ -54,7 +54,8 @@ export type IFlagKey =
 | 
				
			|||||||
    | 'displayEdgeBanner'
 | 
					    | 'displayEdgeBanner'
 | 
				
			||||||
    | 'globalFrontendApiCache'
 | 
					    | 'globalFrontendApiCache'
 | 
				
			||||||
    | 'returnGlobalFrontendApiCache'
 | 
					    | 'returnGlobalFrontendApiCache'
 | 
				
			||||||
    | 'projectOverviewRefactor';
 | 
					    | 'projectOverviewRefactor'
 | 
				
			||||||
 | 
					    | 'variantDependencies';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export type IFlags = Partial<{ [key in IFlagKey]: boolean | Variant }>;
 | 
					export type IFlags = Partial<{ [key in IFlagKey]: boolean | Variant }>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -267,6 +268,10 @@ const flags: IFlags = {
 | 
				
			|||||||
        process.env.UNLEASH_EXPERIMENTAL_PROJECT_OVERVIEW_REFACTOR,
 | 
					        process.env.UNLEASH_EXPERIMENTAL_PROJECT_OVERVIEW_REFACTOR,
 | 
				
			||||||
        false,
 | 
					        false,
 | 
				
			||||||
    ),
 | 
					    ),
 | 
				
			||||||
 | 
					    variantDependencies: parseEnvVarBoolean(
 | 
				
			||||||
 | 
					        process.env.UNLEASH_EXPERIMENTAL_VARIANT_DEPENDENCIES,
 | 
				
			||||||
 | 
					        false,
 | 
				
			||||||
 | 
					    ),
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const defaultExperimentalOptions: IExperimentalOptions = {
 | 
					export const defaultExperimentalOptions: IExperimentalOptions = {
 | 
				
			||||||
 | 
				
			|||||||
@ -52,6 +52,7 @@ process.nextTick(async () => {
 | 
				
			|||||||
                        globalFrontendApiCache: true,
 | 
					                        globalFrontendApiCache: true,
 | 
				
			||||||
                        returnGlobalFrontendApiCache: false,
 | 
					                        returnGlobalFrontendApiCache: false,
 | 
				
			||||||
                        projectOverviewRefactor: true,
 | 
					                        projectOverviewRefactor: true,
 | 
				
			||||||
 | 
					                        variantDependencies: true,
 | 
				
			||||||
                    },
 | 
					                    },
 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
                authentication: {
 | 
					                authentication: {
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user