1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-09-05 17:53:12 +02:00

feat: delete flag impact metrics (#10613)

This commit is contained in:
Mateusz Kwasniewski 2025-09-03 15:58:39 +02:00 committed by GitHub
parent a874a9ce6c
commit cc8a950348
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 62 additions and 14 deletions

View File

@ -1,6 +1,6 @@
import { PageContent } from 'component/common/PageContent/PageContent.tsx'; import { PageContent } from 'component/common/PageContent/PageContent.tsx';
import { PageHeader } from '../../../common/PageHeader/PageHeader.tsx'; import { PageHeader } from '../../../common/PageHeader/PageHeader.tsx';
import { Button, styled, Typography } from '@mui/material'; import { styled, Typography } from '@mui/material';
import Add from '@mui/icons-material/Add'; import Add from '@mui/icons-material/Add';
import { useImpactMetricsMetadata } from 'hooks/api/getters/useImpactMetricsMetadata/useImpactMetricsMetadata.ts'; import { useImpactMetricsMetadata } from 'hooks/api/getters/useImpactMetricsMetadata/useImpactMetricsMetadata.ts';
import { type FC, useMemo, useState } from 'react'; import { type FC, useMemo, useState } from 'react';
@ -9,6 +9,10 @@ import { useImpactMetricsApi } from 'hooks/api/actions/useImpactMetricsSettingsA
import { useRequiredPathParam } from 'hooks/useRequiredPathParam.ts'; import { useRequiredPathParam } from 'hooks/useRequiredPathParam.ts';
import { useFeatureImpactMetrics } from 'hooks/api/getters/useFeatureImpactMetrics/useFeatureImpactMetrics.ts'; import { useFeatureImpactMetrics } from 'hooks/api/getters/useFeatureImpactMetrics/useFeatureImpactMetrics.ts';
import { ChartItem } from '../../../impact-metrics/ChartItem.tsx'; import { ChartItem } from '../../../impact-metrics/ChartItem.tsx';
import PermissionButton from 'component/common/PermissionButton/PermissionButton.tsx';
import { ADMIN } from 'component/providers/AccessProvider/permissions.ts';
import useToast from 'hooks/useToast.tsx';
import { formatUnknownError } from 'utils/formatUnknownError.ts';
const StyledHeaderTitle = styled(Typography)(({ theme }) => ({ const StyledHeaderTitle = styled(Typography)(({ theme }) => ({
fontSize: theme.fontSizes.mainHeader, fontSize: theme.fontSizes.mainHeader,
@ -19,8 +23,9 @@ const StyledHeaderTitle = styled(Typography)(({ theme }) => ({
export const FeatureImpactMetrics: FC = () => { export const FeatureImpactMetrics: FC = () => {
const feature = useRequiredPathParam('featureId'); const feature = useRequiredPathParam('featureId');
const [modalOpen, setModalOpen] = useState(false); const [modalOpen, setModalOpen] = useState(false);
const { createImpactMetric } = useImpactMetricsApi(); const { createImpactMetric, deleteImpactMetric } = useImpactMetricsApi();
const { impactMetrics } = useFeatureImpactMetrics(feature); const { impactMetrics, refetch } = useFeatureImpactMetrics(feature);
const { setToastApiError } = useToast();
const { const {
metadata, metadata,
@ -49,14 +54,15 @@ export const FeatureImpactMetrics: FC = () => {
<StyledHeaderTitle>Impact Metrics</StyledHeaderTitle> <StyledHeaderTitle>Impact Metrics</StyledHeaderTitle>
} }
actions={ actions={
<Button <PermissionButton
variant='contained' variant='contained'
startIcon={<Add />} startIcon={<Add />}
onClick={handleAddChart} onClick={handleAddChart}
disabled={metadataLoading || !!metadataError} disabled={metadataLoading || !!metadataError}
permission={ADMIN}
> >
Add Chart Add Chart
</Button> </PermissionButton>
} }
/> />
@ -65,7 +71,14 @@ export const FeatureImpactMetrics: FC = () => {
<ChartItem <ChartItem
config={config} config={config}
onEdit={() => {}} onEdit={() => {}}
onDelete={() => {}} onDelete={async () => {
try {
await deleteImpactMetric(config.id);
refetch();
} catch (error: unknown) {
setToastApiError(formatUnknownError(error));
}
}}
/> />
))} ))}
</> </>
@ -73,7 +86,14 @@ export const FeatureImpactMetrics: FC = () => {
<ChartConfigModal <ChartConfigModal
open={modalOpen} open={modalOpen}
onClose={() => setModalOpen(false)} onClose={() => setModalOpen(false)}
onSave={(data) => createImpactMetric({ ...data, feature })} onSave={async (data) => {
try {
await createImpactMetric({ ...data, feature });
refetch();
} catch (error: unknown) {
setToastApiError(formatUnknownError(error));
}
}}
initialConfig={undefined} initialConfig={undefined}
metricSeries={metricSeries} metricSeries={metricSeries}
loading={metadataLoading} loading={metadataLoading}

View File

@ -1,10 +1,12 @@
import type { FC } from 'react'; import type { FC } from 'react';
import { Box, Typography, IconButton, styled, Paper } from '@mui/material'; import { Box, Typography, styled, Paper } from '@mui/material';
import Edit from '@mui/icons-material/Edit'; import Edit from '@mui/icons-material/Edit';
import Delete from '@mui/icons-material/Delete'; import Delete from '@mui/icons-material/Delete';
import DragHandle from '@mui/icons-material/DragHandle'; import DragHandle from '@mui/icons-material/DragHandle';
import { ImpactMetricsChart } from './ImpactMetricsChart.tsx'; import { ImpactMetricsChart } from './ImpactMetricsChart.tsx';
import type { ChartConfig, DisplayChartConfig } from './types.ts'; import type { ChartConfig, DisplayChartConfig } from './types.ts';
import PermissionIconButton from '../common/PermissionIconButton/PermissionIconButton.tsx';
import { ADMIN } from '../providers/AccessProvider/permissions.ts';
export interface ChartItemProps { export interface ChartItemProps {
config: DisplayChartConfig; config: DisplayChartConfig;
@ -117,12 +119,18 @@ export const ChartItem: FC<ChartItemProps> = ({ config, onEdit, onDelete }) => (
</Typography> </Typography>
</StyledChartTitle> </StyledChartTitle>
<StyledChartActions> <StyledChartActions>
<IconButton onClick={() => onEdit(config)}> <PermissionIconButton
onClick={() => onEdit(config)}
permission={ADMIN}
>
<Edit /> <Edit />
</IconButton> </PermissionIconButton>
<IconButton onClick={() => onDelete(config.id)}> <PermissionIconButton
onClick={() => onDelete(config.id)}
permission={ADMIN}
>
<Delete /> <Delete />
</IconButton> </PermissionIconButton>
</StyledChartActions> </StyledChartActions>
</StyledHeader> </StyledHeader>

View File

@ -11,6 +11,8 @@ import { useImpactMetricsState } from './hooks/useImpactMetricsState.ts';
import type { ChartConfig, LayoutItem } from './types.ts'; import type { ChartConfig, LayoutItem } from './types.ts';
import useToast from 'hooks/useToast'; import useToast from 'hooks/useToast';
import { formatUnknownError } from 'utils/formatUnknownError'; import { formatUnknownError } from 'utils/formatUnknownError';
import PermissionButton from 'component/common/PermissionButton/PermissionButton.tsx';
import { ADMIN } from '../providers/AccessProvider/permissions.ts';
const StyledEmptyState = styled(Paper)(({ theme }) => ({ const StyledEmptyState = styled(Paper)(({ theme }) => ({
textAlign: 'center', textAlign: 'center',
@ -138,14 +140,15 @@ export const ImpactMetrics: FC = () => {
</Typography> </Typography>
} }
actions={ actions={
<Button <PermissionButton
variant='contained' variant='contained'
startIcon={<Add />} startIcon={<Add />}
onClick={handleAddChart} onClick={handleAddChart}
disabled={isLoading || !!hasError} disabled={isLoading || !!hasError}
permission={ADMIN}
> >
Add Chart Add Chart
</Button> </PermissionButton>
} }
/> />

View File

@ -24,8 +24,25 @@ export const useImpactMetricsApi = () => {
[makeRequest, createRequest], [makeRequest, createRequest],
); );
const deleteImpactMetric = useCallback(
async (metricId: string) => {
const path = `api/admin/impact-metrics/config/${metricId}`;
const req = createRequest(
path,
{
method: 'DELETE',
},
'deleteImpactMetric',
);
return makeRequest(req.caller, req.id);
},
[makeRequest, createRequest],
);
return { return {
createImpactMetric, createImpactMetric,
deleteImpactMetric,
errors, errors,
loading, loading,
}; };