diff --git a/frontend/src/component/feature/FeatureView/FeatureMetrics/FeatureImpactMetrics.tsx b/frontend/src/component/feature/FeatureView/FeatureMetrics/FeatureImpactMetrics.tsx
index 76b58dc96d..41fa3f4282 100644
--- a/frontend/src/component/feature/FeatureView/FeatureMetrics/FeatureImpactMetrics.tsx
+++ b/frontend/src/component/feature/FeatureView/FeatureMetrics/FeatureImpactMetrics.tsx
@@ -1,6 +1,6 @@
import { PageContent } from 'component/common/PageContent/PageContent.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 { useImpactMetricsMetadata } from 'hooks/api/getters/useImpactMetricsMetadata/useImpactMetricsMetadata.ts';
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 { useFeatureImpactMetrics } from 'hooks/api/getters/useFeatureImpactMetrics/useFeatureImpactMetrics.ts';
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 }) => ({
fontSize: theme.fontSizes.mainHeader,
@@ -19,8 +23,9 @@ const StyledHeaderTitle = styled(Typography)(({ theme }) => ({
export const FeatureImpactMetrics: FC = () => {
const feature = useRequiredPathParam('featureId');
const [modalOpen, setModalOpen] = useState(false);
- const { createImpactMetric } = useImpactMetricsApi();
- const { impactMetrics } = useFeatureImpactMetrics(feature);
+ const { createImpactMetric, deleteImpactMetric } = useImpactMetricsApi();
+ const { impactMetrics, refetch } = useFeatureImpactMetrics(feature);
+ const { setToastApiError } = useToast();
const {
metadata,
@@ -49,14 +54,15 @@ export const FeatureImpactMetrics: FC = () => {
Impact Metrics
}
actions={
- }
onClick={handleAddChart}
disabled={metadataLoading || !!metadataError}
+ permission={ADMIN}
>
Add Chart
-
+
}
/>
@@ -65,7 +71,14 @@ export const FeatureImpactMetrics: FC = () => {
{}}
- onDelete={() => {}}
+ onDelete={async () => {
+ try {
+ await deleteImpactMetric(config.id);
+ refetch();
+ } catch (error: unknown) {
+ setToastApiError(formatUnknownError(error));
+ }
+ }}
/>
))}
>
@@ -73,7 +86,14 @@ export const FeatureImpactMetrics: FC = () => {
setModalOpen(false)}
- onSave={(data) => createImpactMetric({ ...data, feature })}
+ onSave={async (data) => {
+ try {
+ await createImpactMetric({ ...data, feature });
+ refetch();
+ } catch (error: unknown) {
+ setToastApiError(formatUnknownError(error));
+ }
+ }}
initialConfig={undefined}
metricSeries={metricSeries}
loading={metadataLoading}
diff --git a/frontend/src/component/impact-metrics/ChartItem.tsx b/frontend/src/component/impact-metrics/ChartItem.tsx
index 7d69d67d61..2fb3d458df 100644
--- a/frontend/src/component/impact-metrics/ChartItem.tsx
+++ b/frontend/src/component/impact-metrics/ChartItem.tsx
@@ -1,10 +1,12 @@
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 Delete from '@mui/icons-material/Delete';
import DragHandle from '@mui/icons-material/DragHandle';
import { ImpactMetricsChart } from './ImpactMetricsChart.tsx';
import type { ChartConfig, DisplayChartConfig } from './types.ts';
+import PermissionIconButton from '../common/PermissionIconButton/PermissionIconButton.tsx';
+import { ADMIN } from '../providers/AccessProvider/permissions.ts';
export interface ChartItemProps {
config: DisplayChartConfig;
@@ -117,12 +119,18 @@ export const ChartItem: FC = ({ config, onEdit, onDelete }) => (
- onEdit(config)}>
+ onEdit(config)}
+ permission={ADMIN}
+ >
-
- onDelete(config.id)}>
+
+ onDelete(config.id)}
+ permission={ADMIN}
+ >
-
+
diff --git a/frontend/src/component/impact-metrics/ImpactMetrics.tsx b/frontend/src/component/impact-metrics/ImpactMetrics.tsx
index b7c11bd815..1b636f0993 100644
--- a/frontend/src/component/impact-metrics/ImpactMetrics.tsx
+++ b/frontend/src/component/impact-metrics/ImpactMetrics.tsx
@@ -11,6 +11,8 @@ import { useImpactMetricsState } from './hooks/useImpactMetricsState.ts';
import type { ChartConfig, LayoutItem } from './types.ts';
import useToast from 'hooks/useToast';
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 }) => ({
textAlign: 'center',
@@ -138,14 +140,15 @@ export const ImpactMetrics: FC = () => {
}
actions={
- }
onClick={handleAddChart}
disabled={isLoading || !!hasError}
+ permission={ADMIN}
>
Add Chart
-
+
}
/>
diff --git a/frontend/src/hooks/api/actions/useImpactMetricsSettingsApi/useImpactMetricsApi.ts b/frontend/src/hooks/api/actions/useImpactMetricsSettingsApi/useImpactMetricsApi.ts
index 933f380f3b..101343eb5b 100644
--- a/frontend/src/hooks/api/actions/useImpactMetricsSettingsApi/useImpactMetricsApi.ts
+++ b/frontend/src/hooks/api/actions/useImpactMetricsSettingsApi/useImpactMetricsApi.ts
@@ -24,8 +24,25 @@ export const useImpactMetricsApi = () => {
[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 {
createImpactMetric,
+ deleteImpactMetric,
errors,
loading,
};