Skip to content

Commit

Permalink
feat: project feature limit UI (#4220)
Browse files Browse the repository at this point in the history
  • Loading branch information
sjaanus committed Jul 11, 2023
1 parent 81c0050 commit 469727b
Show file tree
Hide file tree
Showing 6 changed files with 112 additions and 6 deletions.
Expand Up @@ -32,6 +32,7 @@ const CreateProject = () => {
projectName,
projectMode,
projectDesc,
featureLimit,
setProjectId,
setProjectName,
setProjectDesc,
Expand All @@ -40,6 +41,7 @@ const CreateProject = () => {
validateProjectId,
validateName,
setProjectStickiness,
setFeatureLimit,
setProjectMode,
projectStickiness,
errors,
Expand Down Expand Up @@ -105,7 +107,9 @@ const CreateProject = () => {
projectName={projectName}
projectMode={projectMode}
projectStickiness={projectStickiness}
featureLimit={featureLimit}
setProjectStickiness={setProjectStickiness}
setFeatureLimit={setFeatureLimit}
setProjectMode={setProjectMode}
setProjectName={setProjectName}
projectDesc={projectDesc}
Expand Down
Expand Up @@ -126,6 +126,8 @@ const EditProject = () => {
projectStickiness={projectStickiness}
setProjectStickiness={setProjectStickiness}
setProjectMode={setProjectMode}
setFeatureLimit={() => {}}
featureLimit={''}
projectDesc={projectDesc}
setProjectDesc={setProjectDesc}
mode="Edit"
Expand Down
@@ -0,0 +1,16 @@
import { Box } from '@mui/material';
import { FC } from 'react';
import { HelpIcon } from 'component/common/HelpIcon/HelpIcon';

export const FeatureTogglesLimitTooltip: FC = () => (
<HelpIcon
htmlTooltip
tooltip={
<Box>
Enforce an upper limit of the number of feature toggles that may
be created for this project. You can create unlimited feature
toggle if there is no limit set.
</Box>
}
/>
);
78 changes: 74 additions & 4 deletions frontend/src/component/project/Project/ProjectForm/ProjectForm.tsx
Expand Up @@ -7,18 +7,23 @@ import { ProjectMode } from '../hooks/useProjectForm';
import { Box, styled, TextField } from '@mui/material';
import { CollaborationModeTooltip } from './CollaborationModeTooltip';
import Input from 'component/common/Input/Input';
import { FeatureTogglesLimitTooltip } from './FeatureTogglesLimitTooltip';
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';

interface IProjectForm {
projectId: string;
projectName: string;
projectDesc: string;
projectStickiness?: string;
projectMode?: string;
featureLimit: string;
featureCount?: number;
setProjectStickiness?: React.Dispatch<React.SetStateAction<string>>;
setProjectMode?: React.Dispatch<React.SetStateAction<ProjectMode>>;
setProjectId: React.Dispatch<React.SetStateAction<string>>;
setProjectName: React.Dispatch<React.SetStateAction<string>>;
setProjectDesc: React.Dispatch<React.SetStateAction<string>>;
setFeatureLimit: React.Dispatch<React.SetStateAction<string>>;
handleSubmit: (e: any) => void;
errors: { [key: string]: string };
mode: 'Create' | 'Edit';
Expand Down Expand Up @@ -47,22 +52,40 @@ const StyledDescription = styled('p')(({ theme }) => ({
marginRight: theme.spacing(1),
}));

const StyledSubtitle = styled('div')(({ theme }) => ({
color: theme.palette.text.secondary,
fontSize: theme.fontSizes.smallerBody,
lineHeight: 1.25,
paddingBottom: theme.spacing(1),
}));

const StyledInput = styled(Input)(({ theme }) => ({
width: '100%',
marginBottom: theme.spacing(2),
paddingRight: theme.spacing(1),
}));

const StyledTextField = styled(TextField)(({ theme }) => ({
width: '100%',
marginBottom: theme.spacing(2),
}));

const StyledSelect = styled(Select)(({ theme }) => ({
marginBottom: theme.spacing(2),
minWidth: '200px',
}));

const StyledButtonContainer = styled('div')(() => ({
marginTop: 'auto',
display: 'flex',
justifyContent: 'flex-end',
}));

const StyledInputContainer = styled('div')(() => ({
display: 'flex',
alignItems: 'center',
}));

const ProjectForm: React.FC<IProjectForm> = ({
children,
handleSubmit,
Expand All @@ -71,16 +94,20 @@ const ProjectForm: React.FC<IProjectForm> = ({
projectDesc,
projectStickiness,
projectMode,
featureLimit,
featureCount,
setProjectId,
setProjectName,
setProjectDesc,
setProjectStickiness,
setProjectMode,
setFeatureLimit,
errors,
mode,
validateProjectId,
clearErrors,
}) => {
const { uiConfig } = useUiConfig();
return (
<StyledForm onSubmit={handleSubmit}>
<StyledContainer>
Expand Down Expand Up @@ -158,7 +185,7 @@ const ProjectForm: React.FC<IProjectForm> = ({
<p>What is your project collaboration mode?</p>
<CollaborationModeTooltip />
</Box>
<Select
<StyledSelect
id="project-mode"
value={projectMode}
label="Project collaboration mode"
Expand All @@ -170,11 +197,54 @@ const ProjectForm: React.FC<IProjectForm> = ({
{ key: 'open', label: 'open' },
{ key: 'protected', label: 'protected' },
]}
style={{ minWidth: '200px' }}
></Select>
></StyledSelect>
</>
<ConditionallyRender
condition={Boolean(uiConfig.flags.newProjectLayout)}
show={
<>
<Box
sx={{
display: 'flex',
alignItems: 'center',
marginBottom: 1,
gap: 1,
}}
>
<p>Feature toggles limit?</p>
<FeatureTogglesLimitTooltip />
</Box>
<StyledSubtitle>
Leave it empty if you don’t want to add a limit
</StyledSubtitle>
<StyledInputContainer>
<StyledInput
label={'Limit'}
name="value"
type={'number'}
value={featureLimit}
onChange={e =>
setFeatureLimit(e.target.value)
}
/>
<ConditionallyRender
condition={
featureCount !== undefined &&
featureLimit !== undefined &&
featureLimit.length > 0
}
show={
<Box>
({featureCount} of {featureLimit}{' '}
used)
</Box>
}
/>
</StyledInputContainer>
</>
}
/>
</StyledContainer>

<StyledButtonContainer>{children}</StyledButtonContainer>
</StyledForm>
);
Expand Down
Expand Up @@ -29,7 +29,6 @@ const EditProject = () => {
const id = useRequiredPathParam('projectId');
const { project } = useProject(id);
const { defaultStickiness } = useDefaultProjectSettings(id);
const navigate = useNavigate();
const { trackEvent } = usePlausibleTracker();

const {
Expand All @@ -38,11 +37,13 @@ const EditProject = () => {
projectDesc,
projectStickiness,
projectMode,
featureLimit,
setProjectId,
setProjectName,
setProjectDesc,
setProjectStickiness,
setProjectMode,
setFeatureLimit,
getProjectPayload,
clearErrors,
validateProjectId,
Expand Down Expand Up @@ -113,13 +114,16 @@ const EditProject = () => {
setProjectId={setProjectId}
projectName={projectName}
projectMode={projectMode}
featureLimit={featureLimit}
featureCount={project.features.length}
setProjectName={setProjectName}
projectStickiness={projectStickiness}
setProjectStickiness={setProjectStickiness}
setProjectMode={setProjectMode}
projectDesc={projectDesc}
mode="Edit"
setProjectDesc={setProjectDesc}
setFeatureLimit={setFeatureLimit}
clearErrors={clearErrors}
validateProjectId={validateProjectId}
>
Expand Down
12 changes: 11 additions & 1 deletion frontend/src/component/project/Project/hooks/useProjectForm.ts
Expand Up @@ -9,7 +9,8 @@ const useProjectForm = (
initialProjectName = '',
initialProjectDesc = '',
initialProjectStickiness = DEFAULT_PROJECT_STICKINESS,
initialProjectMode: ProjectMode = 'open'
initialProjectMode: ProjectMode = 'open',
initialFeatureLimit = ''
) => {
const [projectId, setProjectId] = useState(initialProjectId);

Expand All @@ -20,6 +21,8 @@ const useProjectForm = (
);
const [projectMode, setProjectMode] =
useState<ProjectMode>(initialProjectMode);
const [featureLimit, setFeatureLimit] =
useState<string>(initialFeatureLimit);
const [errors, setErrors] = useState({});

const { validateId } = useProjectApi();
Expand All @@ -40,6 +43,10 @@ const useProjectForm = (
setProjectMode(initialProjectMode);
}, [initialProjectMode]);

useEffect(() => {
setFeatureLimit(initialFeatureLimit);
}, [initialFeatureLimit]);

useEffect(() => {
setProjectStickiness(initialProjectStickiness);
}, [initialProjectStickiness]);
Expand All @@ -50,6 +57,7 @@ const useProjectForm = (
name: projectName,
description: projectDesc,
defaultStickiness: projectStickiness,
featureLimit: featureLimit,
mode: projectMode,
};
};
Expand Down Expand Up @@ -87,11 +95,13 @@ const useProjectForm = (
projectDesc,
projectStickiness,
projectMode,
featureLimit,
setProjectId,
setProjectName,
setProjectDesc,
setProjectStickiness,
setProjectMode,
setFeatureLimit,
getProjectPayload,
validateName,
validateProjectId,
Expand Down

0 comments on commit 469727b

Please sign in to comment.