diff --git a/frontend/src/component/feature/CreateFeature/CreateFeature/CreateFeature.tsx b/frontend/src/component/feature/CreateFeature/CreateFeature/CreateFeature.tsx index f5649d66b8..d3b7ba4dd3 100644 --- a/frontend/src/component/feature/CreateFeature/CreateFeature/CreateFeature.tsx +++ b/frontend/src/component/feature/CreateFeature/CreateFeature/CreateFeature.tsx @@ -28,6 +28,8 @@ const CreateFeature = () => { description, setDescription, validateToggleName, + impressionData, + setImpressionData, getTogglePayload, clearErrors, errors, @@ -90,6 +92,8 @@ const CreateFeature = () => { setProject={setProject} setDescription={setDescription} validateToggleName={validateToggleName} + setImpressionData={setImpressionData} + impressionData={impressionData} errors={errors} handleSubmit={handleSubmit} handleCancel={handleCancel} diff --git a/frontend/src/component/feature/CreateFeature/EditFeature/EditFeature.tsx b/frontend/src/component/feature/CreateFeature/EditFeature/EditFeature.tsx index 780af6765b..668ab42d30 100644 --- a/frontend/src/component/feature/CreateFeature/EditFeature/EditFeature.tsx +++ b/frontend/src/component/feature/CreateFeature/EditFeature/EditFeature.tsx @@ -29,17 +29,20 @@ const EditFeature = () => { setProject, description, setDescription, + impressionData, + setImpressionData, clearErrors, errors, } = useFeatureForm( feature?.name, feature?.type, feature?.project, - feature?.description + feature?.description, + feature?.impressionData ); const createPatch = () => { - const comparison = { ...feature, type, description }; + const comparison = { ...feature, type, description, impressionData }; const patch = jsonpatch.compare(feature, comparison); return patch; }; @@ -95,11 +98,12 @@ const EditFeature = () => { errors={errors} handleSubmit={handleSubmit} handleCancel={handleCancel} + impressionData={impressionData} + setImpressionData={setImpressionData} mode="Edit" clearErrors={clearErrors} > ({ minWidth: '379px', }, }, + link: { + color: theme.palette.primary.light, + }, label: { minWidth: '300px', [theme.breakpoints.down(600)]: { @@ -58,4 +61,12 @@ export const useStyles = makeStyles(theme => ({ position: 'absolute', top: '-8px', }, + roleSubtitle: { + margin: '0.5rem 0', + }, + flexRow: { + display: 'flex', + alignItems: 'center', + marginTop: '0.5rem', + }, })); diff --git a/frontend/src/component/feature/CreateFeature/FeatureForm/FeatureForm.tsx b/frontend/src/component/feature/CreateFeature/FeatureForm/FeatureForm.tsx index 6bcebe895e..8b43ac3c0b 100644 --- a/frontend/src/component/feature/CreateFeature/FeatureForm/FeatureForm.tsx +++ b/frontend/src/component/feature/CreateFeature/FeatureForm/FeatureForm.tsx @@ -1,6 +1,6 @@ import { CREATE_FEATURE } from '../../../providers/AccessProvider/permissions'; import Input from '../../../common/Input/Input'; -import { Button } from '@material-ui/core'; +import { Button, FormControl, Switch, Typography } from '@material-ui/core'; import { useStyles } from './FeatureForm.styles'; import FeatureTypeSelect from '../../FeatureView2/FeatureSettings/FeatureSettingsMetadata/FeatureTypeSelect/FeatureTypeSelect'; import { CF_DESC_ID, CF_NAME_ID, CF_TYPE_ID } from '../../../../testIds'; @@ -17,11 +17,13 @@ interface IFeatureToggleForm { name: string; description: string; project: string; + impressionData: boolean; setType: React.Dispatch>; setName: React.Dispatch>; setDescription: React.Dispatch>; setProject: React.Dispatch>; validateToggleName: () => void; + setImpressionData: React.Dispatch>; handleSubmit: (e: any) => void; handleCancel: () => void; errors: { [key: string]: string }; @@ -40,6 +42,8 @@ const FeatureForm: React.FC = ({ setDescription, setProject, validateToggleName, + setImpressionData, + impressionData, handleSubmit, handleCancel, errors, @@ -81,9 +85,7 @@ const FeatureForm: React.FC = ({

- setType(e.target.value) - } + onChange={(e: React.ChangeEvent) => setType(e.target.value)} label={'Toggle type'} id="feature-type-select" editable @@ -108,7 +110,6 @@ const FeatureForm: React.FC = ({ value={project} onChange={e => setProject(e.target.value)} enabled={editable} - label="Project" filter={projectFilterGenerator( { permissions }, CREATE_FEATURE @@ -127,11 +128,39 @@ const FeatureForm: React.FC = ({ label="Description" placeholder="A short description of the feature toggle" value={description} - inputProps={{ - 'data-test': CF_DESC_ID, - }} + data-test={CF_DESC_ID} onChange={e => setDescription(e.target.value)} /> + + + Impression Data + +

+ When you enable impression data for a feature toggle, + your client SDKs will emit events you can listen for + every time this toggle gets triggered. Learn more in{' '} + + the impression data documentation + +

+
+ setImpressionData(!impressionData)} + checked={impressionData} + /> + {impressionData ? 'Yes' : 'No'} +
+
diff --git a/frontend/src/component/feature/CreateFeature/hooks/useFeatureForm.ts b/frontend/src/component/feature/CreateFeature/hooks/useFeatureForm.ts index cea7759b95..b9eaed7adf 100644 --- a/frontend/src/component/feature/CreateFeature/hooks/useFeatureForm.ts +++ b/frontend/src/component/feature/CreateFeature/hooks/useFeatureForm.ts @@ -8,7 +8,8 @@ const useFeatureForm = ( initialName = '', initialType = 'release', initialProject = 'default', - initialDescription = '' + initialDescription = '', + initialImpressionData = false ) => { const { projectId } = useParams(); const params = useQueryParams(); @@ -18,6 +19,9 @@ const useFeatureForm = ( const [name, setName] = useState(toggleQueryName || initialName); const [project, setProject] = useState(projectId || initialProject); const [description, setDescription] = useState(initialDescription); + const [impressionData, setImpressionData] = useState( + initialImpressionData + ); const [errors, setErrors] = useState({}); useEffect(() => { @@ -38,12 +42,17 @@ const useFeatureForm = ( setDescription(initialDescription); }, [initialDescription]); + useEffect(() => { + setImpressionData(initialImpressionData); + }, [initialImpressionData]); + const getTogglePayload = () => { return { - type: type, - name: name, + type, + name, projectId: project, description: description, + impressionData }; }; @@ -81,6 +90,8 @@ const useFeatureForm = ( setProject, description, setDescription, + impressionData, + setImpressionData, getTogglePayload, validateToggleName, clearErrors, diff --git a/frontend/src/hooks/api/actions/useFeatureApi/useFeatureApi.ts b/frontend/src/hooks/api/actions/useFeatureApi/useFeatureApi.ts index 030d7b5317..b7df01e574 100644 --- a/frontend/src/hooks/api/actions/useFeatureApi/useFeatureApi.ts +++ b/frontend/src/hooks/api/actions/useFeatureApi/useFeatureApi.ts @@ -1,4 +1,4 @@ -import { IFeatureToggleDTO } from '../../../../interfaces/featureToggle'; +import { IFeatureTogglePayload } from '../../../../interfaces/featureToggle'; import { ITag } from '../../../../interfaces/tags'; import useAPI from '../useApi/useApi'; import { Operation } from 'fast-json-patch'; @@ -26,7 +26,7 @@ const useFeatureApi = () => { const createFeatureToggle = async ( projectId: string, - featureToggle: IFeatureToggleDTO + featureToggle: IFeatureTogglePayload ) => { const path = `api/admin/projects/${projectId}/features`; const req = createRequest(path, { diff --git a/frontend/src/interfaces/featureToggle.ts b/frontend/src/interfaces/featureToggle.ts index f810792e1b..b8d62137d9 100644 --- a/frontend/src/interfaces/featureToggle.ts +++ b/frontend/src/interfaces/featureToggle.ts @@ -21,6 +21,14 @@ export interface IFeatureToggleDTO { variants: IFeatureVariant[]; } +export interface IFeatureTogglePayload { + description: string; + name: string; + projectId: string; + type: string; + impressionData: boolean; +} + export interface IFeatureToggle { stale: boolean; archived: boolean; @@ -32,6 +40,7 @@ export interface IFeatureToggle { project: string; type: string; variants: IFeatureVariant[]; + impressionData: boolean; } export interface IFeatureEnvironment {