mirror of
https://github.com/Unleash/unleash.git
synced 2025-09-05 17:53:12 +02:00
feat: grid layout for flag impact metrics (#10619)
This commit is contained in:
parent
9388ef66d0
commit
4e4950adb7
@ -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 {
|
||||||
|
GridLayoutWrapper,
|
||||||
|
type GridItem,
|
||||||
|
} from '../../../impact-metrics/GridLayoutWrapper.tsx';
|
||||||
import PermissionButton from 'component/common/PermissionButton/PermissionButton.tsx';
|
import PermissionButton from 'component/common/PermissionButton/PermissionButton.tsx';
|
||||||
import { UPDATE_FEATURE } from 'component/providers/AccessProvider/permissions.ts';
|
import { UPDATE_FEATURE } from 'component/providers/AccessProvider/permissions.ts';
|
||||||
import useToast from 'hooks/useToast.tsx';
|
import useToast from 'hooks/useToast.tsx';
|
||||||
@ -98,6 +102,28 @@ export const FeatureImpactMetrics: FC = () => {
|
|||||||
const editingChart =
|
const editingChart =
|
||||||
modalState.type === 'editing' ? modalState.config : undefined;
|
modalState.type === 'editing' ? modalState.config : undefined;
|
||||||
|
|
||||||
|
const gridItems: GridItem[] = useMemo(
|
||||||
|
() =>
|
||||||
|
impactMetrics.configs.map((config, index) => ({
|
||||||
|
id: config.id,
|
||||||
|
component: (
|
||||||
|
<ChartItem
|
||||||
|
config={config}
|
||||||
|
onEdit={() => handleEditChart(config)}
|
||||||
|
onDelete={() => handleDeleteChart(config.id)}
|
||||||
|
permission={UPDATE_FEATURE}
|
||||||
|
projectId={project}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
w: 6,
|
||||||
|
h: 2,
|
||||||
|
x: (index % 2) * 6,
|
||||||
|
y: Math.floor(index / 2) * 2,
|
||||||
|
static: true,
|
||||||
|
})),
|
||||||
|
[impactMetrics.configs, project],
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PageContent>
|
<PageContent>
|
||||||
<PageHeader
|
<PageHeader
|
||||||
@ -118,18 +144,9 @@ export const FeatureImpactMetrics: FC = () => {
|
|||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<>
|
{impactMetrics.configs.length > 0 && (
|
||||||
{impactMetrics.configs.map((config) => (
|
<GridLayoutWrapper items={gridItems} />
|
||||||
<ChartItem
|
)}
|
||||||
key={config.id}
|
|
||||||
config={config}
|
|
||||||
onEdit={() => handleEditChart(config)}
|
|
||||||
onDelete={() => handleDeleteChart(config.id)}
|
|
||||||
permission={UPDATE_FEATURE}
|
|
||||||
projectId={project}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</>
|
|
||||||
|
|
||||||
<ChartConfigModal
|
<ChartConfigModal
|
||||||
open={isModalOpen}
|
open={isModalOpen}
|
||||||
|
@ -2,7 +2,6 @@ import type { FC } from 'react';
|
|||||||
import { Box, Typography, 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 { 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 PermissionIconButton from '../common/PermissionIconButton/PermissionIconButton.tsx';
|
||||||
@ -14,6 +13,7 @@ export interface ChartItemProps {
|
|||||||
onDelete: (id: string) => void;
|
onDelete: (id: string) => void;
|
||||||
permission?: string;
|
permission?: string;
|
||||||
projectId?: string;
|
projectId?: string;
|
||||||
|
dragHandle?: React.ReactNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
const getConfigDescription = (config: DisplayChartConfig): string => {
|
const getConfigDescription = (config: DisplayChartConfig): string => {
|
||||||
@ -77,19 +77,6 @@ const StyledHeader = styled(Box)(({ theme }) => ({
|
|||||||
borderBottom: `1px solid ${theme.palette.divider}`,
|
borderBottom: `1px solid ${theme.palette.divider}`,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const StyledDragHandle = styled(Box)(({ theme }) => ({
|
|
||||||
display: 'flex',
|
|
||||||
alignItems: 'center',
|
|
||||||
cursor: 'move',
|
|
||||||
padding: theme.spacing(0.5),
|
|
||||||
borderRadius: theme.shape.borderRadius,
|
|
||||||
color: theme.palette.text.secondary,
|
|
||||||
'&:hover': {
|
|
||||||
backgroundColor: theme.palette.action.hover,
|
|
||||||
color: theme.palette.text.primary,
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
|
|
||||||
const StyledChartTitle = styled(Box)(({ theme }) => ({
|
const StyledChartTitle = styled(Box)(({ theme }) => ({
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
flexDirection: 'column',
|
flexDirection: 'column',
|
||||||
@ -112,12 +99,11 @@ export const ChartItem: FC<ChartItemProps> = ({
|
|||||||
onDelete,
|
onDelete,
|
||||||
permission = ADMIN,
|
permission = ADMIN,
|
||||||
projectId,
|
projectId,
|
||||||
|
dragHandle,
|
||||||
}) => (
|
}) => (
|
||||||
<StyledWidget>
|
<StyledWidget>
|
||||||
<StyledHeader>
|
<StyledHeader>
|
||||||
<StyledDragHandle className='grid-item-drag-handle'>
|
{dragHandle}
|
||||||
<DragHandle fontSize='small' />
|
|
||||||
</StyledDragHandle>
|
|
||||||
<StyledChartTitle>
|
<StyledChartTitle>
|
||||||
{config.title && (
|
{config.title && (
|
||||||
<Typography variant='h6'>{config.title}</Typography>
|
<Typography variant='h6'>{config.title}</Typography>
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
import type { FC } from 'react';
|
import type { FC } from 'react';
|
||||||
import { useMemo, useState, useCallback } from 'react';
|
import { useMemo, useState, useCallback } from 'react';
|
||||||
import { Typography, Button, Paper, styled } from '@mui/material';
|
import { Typography, Button, Paper, styled, Box } from '@mui/material';
|
||||||
import Add from '@mui/icons-material/Add';
|
import Add from '@mui/icons-material/Add';
|
||||||
|
import DragHandle from '@mui/icons-material/DragHandle';
|
||||||
import { PageHeader } from 'component/common/PageHeader/PageHeader.tsx';
|
import { PageHeader } from 'component/common/PageHeader/PageHeader.tsx';
|
||||||
import { useImpactMetricsMetadata } from 'hooks/api/getters/useImpactMetricsMetadata/useImpactMetricsMetadata';
|
import { useImpactMetricsMetadata } from 'hooks/api/getters/useImpactMetricsMetadata/useImpactMetricsMetadata';
|
||||||
import { ChartConfigModal } from './ChartConfigModal/ChartConfigModal.tsx';
|
import { ChartConfigModal } from './ChartConfigModal/ChartConfigModal.tsx';
|
||||||
@ -22,6 +23,19 @@ const StyledEmptyState = styled(Paper)(({ theme }) => ({
|
|||||||
boxShadow: 'none',
|
boxShadow: 'none',
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
const StyledDragHandle = styled(Box)(({ theme }) => ({
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
cursor: 'move',
|
||||||
|
padding: theme.spacing(0.5),
|
||||||
|
borderRadius: theme.shape.borderRadius,
|
||||||
|
color: theme.palette.text.secondary,
|
||||||
|
'&:hover': {
|
||||||
|
backgroundColor: theme.palette.action.hover,
|
||||||
|
color: theme.palette.text.primary,
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
export const ImpactMetrics: FC = () => {
|
export const ImpactMetrics: FC = () => {
|
||||||
const [modalOpen, setModalOpen] = useState(false);
|
const [modalOpen, setModalOpen] = useState(false);
|
||||||
const [editingChart, setEditingChart] = useState<ChartConfig | undefined>();
|
const [editingChart, setEditingChart] = useState<ChartConfig | undefined>();
|
||||||
@ -112,6 +126,11 @@ export const ImpactMetrics: FC = () => {
|
|||||||
config={config}
|
config={config}
|
||||||
onEdit={handleEditChart}
|
onEdit={handleEditChart}
|
||||||
onDelete={handleDeleteChart}
|
onDelete={handleDeleteChart}
|
||||||
|
dragHandle={
|
||||||
|
<StyledDragHandle className='grid-item-drag-handle'>
|
||||||
|
<DragHandle fontSize='small' />
|
||||||
|
</StyledDragHandle>
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
w: existingLayout?.w ?? 6,
|
w: existingLayout?.w ?? 6,
|
||||||
|
Loading…
Reference in New Issue
Block a user