1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-06-18 01:18:23 +02:00
unleash.unleash/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewMetaData/DependencyRow.tsx
Thomas Heartman b2c58102dd
chore(unl-204): remove uses of toast text and confetti (#8941)
As of PR #8935, we no longer support both text and title, and confetti
has been removed.

This PR:
- removes `confetti` from the toast interface
- merges `text` and `title` into `text` and updates its uses across the
codebase.
- readjusts the text where necessary.
2024-12-10 13:38:04 +00:00

227 lines
9.1 KiB
TypeScript

import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
import { AddDependencyDialogue } from 'component/feature/Dependencies/AddDependencyDialogue';
import type { IFeatureToggle } from 'interfaces/featureToggle';
import { useState } from 'react';
import { StyledLink } from '../FeatureOverviewSidePanel/FeatureOverviewSidePanelDetails/StyledRow';
import { DependencyActions } from './DependencyActions';
import { useDependentFeaturesApi } from 'hooks/api/actions/useDependentFeaturesApi/useDependentFeaturesApi';
import { useFeature } from 'hooks/api/getters/useFeature/useFeature';
import { ChildrenTooltip } from './ChildrenTooltip';
import PermissionButton from 'component/common/PermissionButton/PermissionButton';
import { UPDATE_FEATURE_DEPENDENCY } from 'component/providers/AccessProvider/permissions';
import { useCheckProjectAccess } from 'hooks/useHasAccess';
import { useChangeRequestApi } from 'hooks/api/actions/useChangeRequestApi/useChangeRequestApi';
import { usePendingChangeRequests } from 'hooks/api/getters/usePendingChangeRequests/usePendingChangeRequests';
import useToast from 'hooks/useToast';
import { useHighestPermissionChangeRequestEnvironment } from 'hooks/useHighestPermissionChangeRequestEnvironment';
import { useChangeRequestsEnabled } from 'hooks/useChangeRequestsEnabled';
import { formatUnknownError } from 'utils/formatUnknownError';
import { usePlausibleTracker } from 'hooks/usePlausibleTracker';
import { VariantsTooltip } from './VariantsTooltip';
import { styled } from '@mui/material';
import {
StyledMetaDataItem,
StyledMetaDataItemLabel,
StyledMetaDataItemValue,
} from './FeatureOverviewMetaData';
const StyledPermissionButton = styled(PermissionButton)(({ theme }) => ({
'&&&': {
fontSize: theme.fontSizes.smallBody,
lineHeight: 1,
margin: 0,
},
}));
const useDeleteDependency = (project: string, featureId: string) => {
const { trackEvent } = usePlausibleTracker();
const { addChange } = useChangeRequestApi();
const { refetch: refetchChangeRequests } =
usePendingChangeRequests(project);
const { setToastData, setToastApiError } = useToast();
const { refetchFeature } = useFeature(project, featureId);
const environment = useHighestPermissionChangeRequestEnvironment(project)();
const { isChangeRequestConfiguredInAnyEnv } =
useChangeRequestsEnabled(project);
const { removeDependencies } = useDependentFeaturesApi(project);
const handleAddChange = async () => {
if (!environment) {
console.error('No change request environment');
return;
}
await addChange(project, environment, [
{
action: 'deleteDependency',
feature: featureId,
payload: undefined,
},
]);
};
const deleteDependency = async () => {
try {
if (isChangeRequestConfiguredInAnyEnv()) {
await handleAddChange();
trackEvent('dependent_features', {
props: {
eventType: 'delete dependency added to change request',
},
});
setToastData({
type: 'success',
text: 'Change added to draft',
});
await refetchChangeRequests();
} else {
await removeDependencies(featureId);
trackEvent('dependent_features', {
props: {
eventType: 'dependency removed',
},
});
setToastData({ text: 'Dependency removed', type: 'success' });
await refetchFeature();
}
} catch (error) {
setToastApiError(formatUnknownError(error));
}
};
return deleteDependency;
};
interface IDependencyRowProps {
feature: IFeatureToggle;
}
export const DependencyRow = ({ feature }: IDependencyRowProps) => {
const [showDependencyDialogue, setShowDependencyDialogue] = useState(false);
const canAddParentDependency =
Boolean(feature.project) &&
feature.dependencies.length === 0 &&
feature.children.length === 0;
const hasParentDependency =
Boolean(feature.project) && Boolean(feature.dependencies.length > 0);
const hasChildren = Boolean(feature.project) && feature.children.length > 0;
const environment = useHighestPermissionChangeRequestEnvironment(
feature.project,
)();
const checkAccess = useCheckProjectAccess(feature.project);
const deleteDependency = useDeleteDependency(feature.project, feature.name);
return (
<>
<ConditionallyRender
condition={canAddParentDependency}
show={
<StyledMetaDataItem>
<StyledMetaDataItemLabel>
Dependency:
</StyledMetaDataItemLabel>
<StyledPermissionButton
size='small'
permission={UPDATE_FEATURE_DEPENDENCY}
projectId={feature.project}
variant='text'
onClick={() => {
setShowDependencyDialogue(true);
}}
>
Add parent feature
</StyledPermissionButton>
</StyledMetaDataItem>
}
/>
<ConditionallyRender
condition={hasParentDependency}
show={
<StyledMetaDataItem>
<StyledMetaDataItemLabel>
Dependency:
</StyledMetaDataItemLabel>
<StyledMetaDataItemValue>
<StyledLink
to={`/projects/${feature.project}/features/${feature.dependencies[0]?.feature}`}
>
{feature.dependencies[0]?.feature}
</StyledLink>
<ConditionallyRender
condition={checkAccess(
UPDATE_FEATURE_DEPENDENCY,
environment,
)}
show={
<DependencyActions
feature={feature.name}
onEdit={() =>
setShowDependencyDialogue(true)
}
onDelete={deleteDependency}
/>
}
/>
</StyledMetaDataItemValue>
</StyledMetaDataItem>
}
/>
<ConditionallyRender
condition={
hasParentDependency && !feature.dependencies[0]?.enabled
}
show={
<StyledMetaDataItem>
<StyledMetaDataItemLabel>
Dependency value:
</StyledMetaDataItemLabel>
<span>disabled</span>
</StyledMetaDataItem>
}
/>
<ConditionallyRender
condition={
hasParentDependency &&
Boolean(feature.dependencies[0]?.variants?.length)
}
show={
<StyledMetaDataItem>
<StyledMetaDataItemLabel>
Dependency value:
</StyledMetaDataItemLabel>
<VariantsTooltip
variants={feature.dependencies[0]?.variants || []}
/>
</StyledMetaDataItem>
}
/>
<ConditionallyRender
condition={hasChildren}
show={
<StyledMetaDataItem>
<StyledMetaDataItemLabel>
Children:
</StyledMetaDataItemLabel>
<ChildrenTooltip
childFeatures={feature.children}
project={feature.project}
/>
</StyledMetaDataItem>
}
/>
<ConditionallyRender
condition={Boolean(feature.project)}
show={
<AddDependencyDialogue
project={feature.project}
featureId={feature.name}
parentDependency={feature.dependencies[0]}
onClose={() => setShowDependencyDialogue(false)}
showDependencyDialogue={showDependencyDialogue}
/>
}
/>
</>
);
};