1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-07-26 13:48:33 +02:00

feat: delete link UI (#9923)

This commit is contained in:
Mateusz Kwasniewski 2025-05-07 15:58:51 +02:00 committed by GitHub
parent 471cef1f29
commit dac5a5e596
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 73 additions and 25 deletions

View File

@ -2,7 +2,7 @@ import { AddDependencyDialogue } from 'component/feature/Dependencies/AddDepende
import type { IFeatureToggle } from 'interfaces/featureToggle';
import { useState } from 'react';
import { StyledLink } from '../FeatureOverviewSidePanel/FeatureOverviewSidePanelDetails/StyledRow';
import { DependencyActions } from './DependencyActions';
import { ExtraActions } from './ExtraActions';
import { useDependentFeaturesApi } from 'hooks/api/actions/useDependentFeaturesApi/useDependentFeaturesApi';
import { useFeature } from 'hooks/api/getters/useFeature/useFeature';
import { ChildrenTooltip } from './ChildrenTooltip';
@ -143,7 +143,8 @@ export const DependencyRow = ({ feature }: IDependencyRowProps) => {
</Truncator>
</StyledLink>
{checkAccess(UPDATE_FEATURE_DEPENDENCY, environment) ? (
<DependencyActions
<ExtraActions
capabilityId='dependency'
feature={feature.name}
onEdit={() => setShowDependencyDialogue(true)}
onDelete={deleteDependency}

View File

@ -27,17 +27,19 @@ const StyledPopover = styled(Popover)(({ theme }) => ({
}));
interface IDependencyActionsProps {
capabilityId: string;
feature: string;
onEdit: () => void;
onDelete: () => void;
}
export const DependencyActions = ({
export const ExtraActions = ({
capabilityId,
feature,
onEdit,
onDelete,
}: IDependencyActionsProps) => {
const id = `dependency-${feature}-actions`;
const id = `${capabilityId}-${feature}-actions`;
const menuId = `${id}-menu`;
const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);

View File

@ -1,6 +1,7 @@
import { type FC, useState } from 'react';
import {
List,
ListItem,
ListItemButton,
ListItemIcon,
ListItemText,
@ -32,6 +33,11 @@ import LinkIcon from '@mui/icons-material/Link';
import { UPDATE_FEATURE } from '../../../../providers/AccessProvider/permissions';
import PermissionButton from 'component/common/PermissionButton/PermissionButton';
import { AddLinkDialogue } from './AddLinkDialogue';
import { useFeatureLinkApi } from 'hooks/api/actions/useFeatureLinkApi/useFeatureLinkApi';
import useToast from 'hooks/useToast';
import { useFeature } from 'hooks/api/getters/useFeature/useFeature';
import { formatUnknownError } from 'utils/formatUnknownError';
import { ExtraActions } from './ExtraActions';
const StyledMetaDataContainer = styled('div')(({ theme }) => ({
padding: theme.spacing(3),
@ -101,6 +107,9 @@ interface FeatureLinksProps {
const FeatureLinks: FC<FeatureLinksProps> = ({ links, project, feature }) => {
const [showAddLinkDialogue, setShowAddLinkDialogue] = useState(false);
const { deleteLink, loading } = useFeatureLinkApi(project, feature);
const { setToastData, setToastApiError } = useToast();
const { refetchFeature } = useFeature(project, feature);
const addLinkButton = (
<PermissionButton
@ -118,29 +127,54 @@ const FeatureLinks: FC<FeatureLinksProps> = ({ links, project, feature }) => {
const renderLinkItems = () => (
<List>
{links.map((link) => (
<ListItemButton
<ListItem
secondaryAction={
<ExtraActions
capabilityId='link'
feature={feature}
onEdit={() => {}}
onDelete={async () => {
try {
await deleteLink(link.id);
setToastData({
text: 'Link removed',
type: 'success',
});
refetchFeature();
} catch (error) {
setToastApiError(formatUnknownError(error));
}
}}
/>
}
key={link.id}
component='a'
href={link.url}
target='_blank'
rel='noopener noreferrer'
disablePadding
dense
>
<StyledListItemIcon>
<LinkIcon color='primary' />
</StyledListItemIcon>
<ListItemText
primary={link.title}
secondary={link.url}
secondaryTypographyProps={{
sx: {
overflow: 'hidden',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
display: 'block',
},
}}
/>
</ListItemButton>
<ListItemButton
component='a'
href={link.url}
target='_blank'
rel='noopener noreferrer'
disableGutters
>
<StyledListItemIcon>
<LinkIcon color='primary' />
</StyledListItemIcon>
<ListItemText
primary={link.title}
secondary={link.url}
secondaryTypographyProps={{
sx: {
overflow: 'hidden',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
display: 'block',
},
}}
/>
</ListItemButton>
</ListItem>
))}
</List>
);

View File

@ -19,6 +19,16 @@ export const useFeatureLinkApi = (project: string, feature: string) => {
await makeRequest(req.caller, req.id);
};
const deleteLink = async (linkId: string) => {
const req = createRequest(
`/api/admin/projects/${project}/features/${feature}/link/${linkId}`,
{
method: 'DELETE',
},
);
await makeRequest(req.caller, req.id);
};
const callbackDeps = [
createRequest,
makeRequest,
@ -27,6 +37,7 @@ export const useFeatureLinkApi = (project: string, feature: string) => {
];
return {
addLink: useCallback(addLink, callbackDeps),
deleteLink: useCallback(deleteLink, callbackDeps),
errors,
loading,
};