1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-07-17 13:46:47 +02:00

chore: fix small UI issues in release templates/plans (#9341)

This commit is contained in:
David Leek 2025-02-24 15:25:44 +01:00 committed by GitHub
parent 26e01177be
commit f19ffd0e7e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 43 additions and 16 deletions

View File

@ -22,6 +22,7 @@ import { usePendingChangeRequests } from 'hooks/api/getters/usePendingChangeRequ
import { RemoveReleasePlanChangeRequestDialog } from './ChangeRequest/RemoveReleasePlanChangeRequestDialog'; import { RemoveReleasePlanChangeRequestDialog } from './ChangeRequest/RemoveReleasePlanChangeRequestDialog';
import { StartMilestoneChangeRequestDialog } from './ChangeRequest/StartMilestoneChangeRequestDialog'; import { StartMilestoneChangeRequestDialog } from './ChangeRequest/StartMilestoneChangeRequestDialog';
import { usePlausibleTracker } from 'hooks/usePlausibleTracker'; import { usePlausibleTracker } from 'hooks/usePlausibleTracker';
import { Truncator } from 'component/common/Truncator/Truncator';
const StyledContainer = styled('div', { const StyledContainer = styled('div', {
shouldForwardProp: (prop) => prop !== 'readonly', shouldForwardProp: (prop) => prop !== 'readonly',
@ -58,7 +59,6 @@ const StyledHeaderTitleLabel = styled('span')(({ theme }) => ({
const StyledHeaderDescription = styled('span')(({ theme }) => ({ const StyledHeaderDescription = styled('span')(({ theme }) => ({
fontSize: theme.fontSizes.smallBody, fontSize: theme.fontSizes.smallBody,
lineHeight: 0.5,
color: theme.palette.text.secondary, color: theme.palette.text.secondary,
})); }));
@ -248,7 +248,9 @@ export const ReleasePlan = ({
</StyledHeaderTitleLabel> </StyledHeaderTitleLabel>
<span>{name}</span> <span>{name}</span>
<StyledHeaderDescription> <StyledHeaderDescription>
<Truncator lines={2} title={description}>
{description} {description}
</Truncator>
</StyledHeaderDescription> </StyledHeaderDescription>
</StyledHeaderTitleContainer> </StyledHeaderTitleContainer>
{!readonly && ( {!readonly && (

View File

@ -12,10 +12,7 @@ import {
FormHelperText, FormHelperText,
} from '@mui/material'; } from '@mui/material';
import Delete from '@mui/icons-material/DeleteOutlined'; import Delete from '@mui/icons-material/DeleteOutlined';
import type { import type { IReleasePlanMilestoneStrategy } from 'interfaces/releasePlans';
IReleasePlanMilestonePayload,
IReleasePlanMilestoneStrategy,
} from 'interfaces/releasePlans';
import { type DragEventHandler, type RefObject, useRef, useState } from 'react'; import { type DragEventHandler, type RefObject, useRef, useState } from 'react';
import ExpandMore from '@mui/icons-material/ExpandMore'; import ExpandMore from '@mui/icons-material/ExpandMore';
import { MilestoneCardName } from './MilestoneCardName'; import { MilestoneCardName } from './MilestoneCardName';
@ -25,6 +22,7 @@ import { SidebarModal } from 'component/common/SidebarModal/SidebarModal';
import { ReleasePlanTemplateAddStrategyForm } from '../../MilestoneStrategy/ReleasePlanTemplateAddStrategyForm'; import { ReleasePlanTemplateAddStrategyForm } from '../../MilestoneStrategy/ReleasePlanTemplateAddStrategyForm';
import DragIndicator from '@mui/icons-material/DragIndicator'; import DragIndicator from '@mui/icons-material/DragIndicator';
import { type OnMoveItem, useDragItem } from 'hooks/useDragItem'; import { type OnMoveItem, useDragItem } from 'hooks/useDragItem';
import type { IExtendedMilestonePayload } from 'component/releases/hooks/useTemplateForm';
const StyledMilestoneCard = styled(Card, { const StyledMilestoneCard = styled(Card, {
shouldForwardProp: (prop) => prop !== 'hasError', shouldForwardProp: (prop) => prop !== 'hasError',
@ -124,8 +122,8 @@ const StyledDragIcon = styled(IconButton)(({ theme }) => ({
})); }));
export interface IMilestoneCardProps { export interface IMilestoneCardProps {
milestone: IReleasePlanMilestonePayload; milestone: IExtendedMilestonePayload;
milestoneChanged: (milestone: IReleasePlanMilestonePayload) => void; milestoneChanged: (milestone: IExtendedMilestonePayload) => void;
errors: { [key: string]: string }; errors: { [key: string]: string };
clearErrors: () => void; clearErrors: () => void;
removable: boolean; removable: boolean;
@ -152,7 +150,7 @@ export const MilestoneCard = ({
} | null>(null); } | null>(null);
const [addUpdateStrategyOpen, setAddUpdateStrategyOpen] = useState(false); const [addUpdateStrategyOpen, setAddUpdateStrategyOpen] = useState(false);
const [strategyModeEdit, setStrategyModeEdit] = useState(false); const [strategyModeEdit, setStrategyModeEdit] = useState(false);
const [expanded, setExpanded] = useState(false); const [expanded, setExpanded] = useState(Boolean(milestone.startExpanded));
const isPopoverOpen = Boolean(anchor); const isPopoverOpen = Boolean(anchor);
const popoverId = isPopoverOpen const popoverId = isPopoverOpen
? 'MilestoneStrategyMenuPopover' ? 'MilestoneStrategyMenuPopover'

View File

@ -80,6 +80,15 @@ export const MilestoneList = ({
id: uuidv4(), id: uuidv4(),
name: `Milestone ${prev.length + 1}`, name: `Milestone ${prev.length + 1}`,
sortOrder: prev.length, sortOrder: prev.length,
strategies: prev[prev.length - 1].strategies?.map(
(strat) => {
return {
...strat,
id: uuidv4(),
};
},
),
startExpanded: true,
}, },
]) ])
} }

View File

@ -4,9 +4,9 @@ import type { IReleasePlanMilestonePayload } from 'interfaces/releasePlans';
import FormTemplate from 'component/common/FormTemplate/FormTemplate'; import FormTemplate from 'component/common/FormTemplate/FormTemplate';
import { TemplateFormDescription } from './TemplateFormDescription'; import { TemplateFormDescription } from './TemplateFormDescription';
import { MilestoneList } from './MilestoneList/MilestoneList'; import { MilestoneList } from './MilestoneList/MilestoneList';
import type { IExtendedMilestonePayload } from 'component/releases/hooks/useTemplateForm';
const StyledInput = styled(Input)(({ theme }) => ({ const StyledInput = styled(Input)(({ theme }) => ({
width: '100%',
maxWidth: theme.spacing(50), maxWidth: theme.spacing(50),
fieldset: { border: 'none' }, fieldset: { border: 'none' },
'label::first-letter': { 'label::first-letter': {
@ -16,6 +16,16 @@ const StyledInput = styled(Input)(({ theme }) => ({
padding: theme.spacing(0), padding: theme.spacing(0),
})); }));
const StyledDescriptionInput = styled(Input)(({ theme }) => ({
width: '100%',
fieldset: { border: 'none' },
'label::first-letter': {
textTransform: 'uppercase',
},
marginBottom: theme.spacing(2),
padding: theme.spacing(2, 5, 1, 1.75),
}));
const StyledForm = styled('form')(({ theme }) => ({ const StyledForm = styled('form')(({ theme }) => ({
display: 'flex', display: 'flex',
flexDirection: 'column', flexDirection: 'column',
@ -28,9 +38,9 @@ interface ITemplateFormProps {
setName: React.Dispatch<React.SetStateAction<string>>; setName: React.Dispatch<React.SetStateAction<string>>;
description: string; description: string;
setDescription: React.Dispatch<React.SetStateAction<string>>; setDescription: React.Dispatch<React.SetStateAction<string>>;
milestones: IReleasePlanMilestonePayload[]; milestones: IExtendedMilestonePayload[];
setMilestones: React.Dispatch< setMilestones: React.Dispatch<
React.SetStateAction<IReleasePlanMilestonePayload[]> React.SetStateAction<IExtendedMilestonePayload[]>
>; >;
errors: { [key: string]: string }; errors: { [key: string]: string };
clearErrors: () => void; clearErrors: () => void;
@ -91,8 +101,9 @@ export const TemplateForm: React.FC<ITemplateFormProps> = ({
}} }}
size='medium' size='medium'
/> />
<StyledInput <StyledDescriptionInput
label='Template description (optional)' label='Template description (optional)'
multiline
value={description} value={description}
onChange={(e) => setDescription(e.target.value)} onChange={(e) => setDescription(e.target.value)}
InputProps={{ InputProps={{
@ -107,7 +118,7 @@ export const TemplateForm: React.FC<ITemplateFormProps> = ({
padding: 0, padding: 0,
}, },
}} }}
size='medium' size='small'
/> />
<MilestoneList <MilestoneList
milestones={milestones} milestones={milestones}

View File

@ -2,10 +2,15 @@ import type { IReleasePlanMilestonePayload } from 'interfaces/releasePlans';
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
import { v4 as uuidv4 } from 'uuid'; import { v4 as uuidv4 } from 'uuid';
export interface IExtendedMilestonePayload
extends IReleasePlanMilestonePayload {
startExpanded?: boolean;
}
export const useTemplateForm = ( export const useTemplateForm = (
initialName = '', initialName = '',
initialDescription = '', initialDescription = '',
initialMilestones: IReleasePlanMilestonePayload[] = [ initialMilestones: IExtendedMilestonePayload[] = [
{ id: uuidv4(), name: 'Milestone 1', sortOrder: 0 }, { id: uuidv4(), name: 'Milestone 1', sortOrder: 0 },
], ],
) => { ) => {
@ -93,7 +98,9 @@ export const useTemplateForm = (
return { return {
name, name,
description, description,
milestones, milestones: milestones.map(
({ startExpanded, ...milestone }) => milestone,
),
}; };
}; };