Skip to content

Commit

Permalink
[frontend] Add required fields to Events
Browse files Browse the repository at this point in the history
Add required fields to Observed Data

Add required fields to Sightings
  • Loading branch information
VerboseCat committed Nov 8, 2024
1 parent c442783 commit 4cb8be2
Show file tree
Hide file tree
Showing 6 changed files with 106 additions and 46 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import { isEmptyField } from '../../../../utils/utils';
import ObjectAssigneeField from '../../common/form/ObjectAssigneeField';
import type { Theme } from '../../../../components/Theme';
import { Option } from '../../common/form/ReferenceField';
import { useSchemaCreationValidation } from '../../../../utils/hooks/useEntitySettings';
import { useDynamicSchemaCreationValidation, useIsMandatoryAttribute, yupShapeConditionalRequired } from '../../../../utils/hooks/useEntitySettings';
import useDefaultValues from '../../../../utils/hooks/useDefaultValues';
import ObjectParticipantField from '../../common/form/ObjectParticipantField';
import CustomFileUploader from '../../common/files/CustomFileUploader';
Expand Down Expand Up @@ -103,16 +103,17 @@ export const IncidentCreationForm: FunctionComponent<IncidentCreationProps> = ({
undefined,
{ successMessage: `${t_i18n('entity_Incident')} ${t_i18n('successfully created')}` },
);
const basicShape = {
name: Yup.string().trim().min(2).required(t_i18n('This field is required')),
const { mandatoryAttributes } = useIsMandatoryAttribute(INCIDENT_TYPE);
const basicShape = yupShapeConditionalRequired({
name: Yup.string().trim().min(2),
confidence: Yup.number().nullable(),
incident_type: Yup.string().nullable(),
severity: Yup.string().nullable(),
source: Yup.string().nullable(),
description: Yup.string().nullable(),
};
const incidentValidator = useSchemaCreationValidation(
INCIDENT_TYPE,
}, mandatoryAttributes);
const incidentValidator = useDynamicSchemaCreationValidation(
mandatoryAttributes,
basicShape,
);
const onSubmit: FormikConfig<IncidentAddInput>['onSubmit'] = (
Expand Down Expand Up @@ -178,6 +179,8 @@ export const IncidentCreationForm: FunctionComponent<IncidentCreationProps> = ({
<Formik<IncidentAddInput>
initialValues={initialValues}
validationSchema={incidentValidator}
validateOnChange={false}
validateOnBlur={false}
onSubmit={onSubmit}
onReset={onReset}
>
Expand All @@ -188,6 +191,7 @@ export const IncidentCreationForm: FunctionComponent<IncidentCreationProps> = ({
variant="standard"
name="name"
label={t_i18n('Name')}
required={(mandatoryAttributes.includes('name'))}
fullWidth={true}
detectDuplicate={['Incident']}
/>
Expand All @@ -199,6 +203,7 @@ export const IncidentCreationForm: FunctionComponent<IncidentCreationProps> = ({
label={t_i18n('Incident type')}
type="incident-type-ov"
name="incident_type"
required={(mandatoryAttributes.includes('incident_type'))}
containerStyle={fieldSpacingContainerStyle}
multiple={false}
onChange={setFieldValue}
Expand All @@ -207,6 +212,7 @@ export const IncidentCreationForm: FunctionComponent<IncidentCreationProps> = ({
label={t_i18n('Severity')}
type="incident-severity-ov"
name="severity"
required={(mandatoryAttributes.includes('severity'))}
containerStyle={fieldSpacingContainerStyle}
multiple={false}
onChange={setFieldValue}
Expand All @@ -215,6 +221,7 @@ export const IncidentCreationForm: FunctionComponent<IncidentCreationProps> = ({
component={MarkdownField}
name="description"
label={t_i18n('Description')}
required={(mandatoryAttributes.includes('description'))}
fullWidth={true}
multiline={true}
rows="4"
Expand All @@ -225,35 +232,42 @@ export const IncidentCreationForm: FunctionComponent<IncidentCreationProps> = ({
variant="standard"
name="source"
label={t_i18n('Source')}
required={(mandatoryAttributes.includes('source'))}
fullWidth={true}
style={{ marginTop: 20 }}
/>
<ObjectAssigneeField
name="objectAssignee"
required={(mandatoryAttributes.includes('objectAssignee'))}
style={fieldSpacingContainerStyle}
/>
<ObjectParticipantField
name="objectParticipant"
required={(mandatoryAttributes.includes('objectParticipant'))}
style={fieldSpacingContainerStyle}
/>
<CreatedByField
name="createdBy"
required={(mandatoryAttributes.includes('createdBy'))}
style={fieldSpacingContainerStyle}
setFieldValue={setFieldValue}
/>
<ObjectLabelField
name="objectLabel"
required={(mandatoryAttributes.includes('objectLabel'))}
style={fieldSpacingContainerStyle}
setFieldValue={setFieldValue}
values={values.objectLabel}
/>
<ObjectMarkingField
name="objectMarking"
required={(mandatoryAttributes.includes('objectMarking'))}
style={fieldSpacingContainerStyle}
setFieldValue={setFieldValue}
/>
<ExternalReferencesField
name="externalReferences"
required={(mandatoryAttributes.includes('externalReferences'))}
style={fieldSpacingContainerStyle}
setFieldValue={setFieldValue}
values={values.externalReferences}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { fieldSpacingContainerStyle } from '../../../../utils/field';
import ObjectAssigneeField from '../../common/form/ObjectAssigneeField';
import { Option } from '../../common/form/ReferenceField';
import { IncidentEditionOverview_incident$key } from './__generated__/IncidentEditionOverview_incident.graphql';
import { useSchemaEditionValidation } from '../../../../utils/hooks/useEntitySettings';
import { useDynamicSchemaCreationValidation, useIsMandatoryAttribute, yupShapeConditionalRequired } from '../../../../utils/hooks/useEntitySettings';
import useFormEditor, { GenericData } from '../../../../utils/hooks/useFormEditor';
import ObjectParticipantField from '../../common/form/ObjectParticipantField';
import { GenericContext } from '../../common/model/GenericContextModel';
Expand Down Expand Up @@ -134,6 +134,8 @@ const incidentEditionOverviewFragment = graphql`
}
`;

const INCIDENT_TYPE = 'Incident';

interface IncidentEditionOverviewProps {
incidentRef: IncidentEditionOverview_incident$key;
context?: readonly (GenericContext | null)[] | null;
Expand All @@ -157,16 +159,17 @@ IncidentEditionOverviewProps
> = ({ incidentRef, context, enableReferences = false, handleClose }) => {
const { t_i18n } = useFormatter();
const incident = useFragment(incidentEditionOverviewFragment, incidentRef);
const basicShape = {
name: Yup.string().trim().min(2).required(t_i18n('This field is required')),
const { mandatoryAttributes } = useIsMandatoryAttribute(INCIDENT_TYPE);
const basicShape = yupShapeConditionalRequired({
name: Yup.string().trim().min(2),
incident_type: Yup.string().nullable(),
severity: Yup.string().nullable(),
confidence: Yup.number().nullable(),
description: Yup.string().nullable(),
x_opencti_workflow_id: Yup.object(),
references: Yup.array(),
};
const incidentValidator = useSchemaEditionValidation('Incident', basicShape);
}, mandatoryAttributes);
const incidentValidator = useDynamicSchemaCreationValidation(mandatoryAttributes, basicShape);
const queries = {
fieldPatch: incidentMutationFieldPatch,
relationAdd: incidentMutationRelationAdd,
Expand Down Expand Up @@ -246,6 +249,8 @@ IncidentEditionOverviewProps
enableReinitialize={true}
initialValues={initialValues}
validationSchema={incidentValidator}
validateOnChange={true}
validateOnBlur={true}
onSubmit={onSubmit}
>
{({
Expand All @@ -263,6 +268,7 @@ IncidentEditionOverviewProps
variant="standard"
name="name"
label={t_i18n('Name')}
required={(mandatoryAttributes.includes('name'))}
fullWidth={true}
disabled={isInferred}
onFocus={editor.changeFocus}
Expand All @@ -284,6 +290,7 @@ IncidentEditionOverviewProps
label={t_i18n('Incident type')}
type="incident-type-ov"
name="incident_type"
required={(mandatoryAttributes.includes('incident_type'))}
onFocus={editor.changeFocus}
onSubmit={handleSubmitField}
onChange={setFieldValue}
Expand All @@ -296,6 +303,7 @@ IncidentEditionOverviewProps
label={t_i18n('Severity')}
type="incident-severity-ov"
name="severity"
required={(mandatoryAttributes.includes('severity'))}
onFocus={editor.changeFocus}
onSubmit={handleSubmitField}
onChange={setFieldValue}
Expand All @@ -308,6 +316,7 @@ IncidentEditionOverviewProps
component={MarkdownField}
name="description"
label={t_i18n('Description')}
required={(mandatoryAttributes.includes('description'))}
fullWidth={true}
multiline={true}
disabled={isInferred}
Expand All @@ -321,6 +330,7 @@ IncidentEditionOverviewProps
/>
<ObjectAssigneeField
name="objectAssignee"
required={(mandatoryAttributes.includes('objectAssignee'))}
style={fieldSpacingContainerStyle}
helpertext={
<SubscriptionFocus context={context} fieldname="objectAssignee" />
Expand All @@ -329,6 +339,7 @@ IncidentEditionOverviewProps
/>
<ObjectParticipantField
name="objectParticipant"
required={(mandatoryAttributes.includes('objectParticipant'))}
style={fieldSpacingContainerStyle}
onChange={editor.changeParticipant}
/>
Expand All @@ -350,6 +361,7 @@ IncidentEditionOverviewProps
)}
<CreatedByField
name="createdBy"
required={(mandatoryAttributes.includes('createdBy'))}
style={fieldSpacingContainerStyle}
setFieldValue={setFieldValue}
helpertext={
Expand All @@ -359,6 +371,7 @@ IncidentEditionOverviewProps
/>
<ObjectMarkingField
name="objectMarking"
required={(mandatoryAttributes.includes('objectMarking'))}
style={fieldSpacingContainerStyle}
disabled={isInferred}
helpertext={
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import { insertNode } from '../../../../utils/store';
import { ExternalReferencesField } from '../../common/form/ExternalReferencesField';
import DateTimePickerField from '../../../../components/DateTimePickerField';
import { fieldSpacingContainerStyle } from '../../../../utils/field';
import { useSchemaCreationValidation } from '../../../../utils/hooks/useEntitySettings';
import { useDynamicSchemaCreationValidation, useIsMandatoryAttribute, yupShapeConditionalRequired } from '../../../../utils/hooks/useEntitySettings';
import type { Theme } from '../../../../components/Theme';
import { Option } from '../../common/form/ReferenceField';
import { ObservedDataCreationMutation, ObservedDataCreationMutation$variables } from './__generated__/ObservedDataCreationMutation.graphql';
Expand Down Expand Up @@ -96,19 +96,18 @@ ObservedDataFormProps
}) => {
const classes = useStyles();
const { t_i18n } = useFormatter();
const basicShape = {
const { mandatoryAttributes } = useIsMandatoryAttribute(OBSERVED_DATA_TYPE);
const basicShape = yupShapeConditionalRequired({
objects: Yup.array(),
first_observed: Yup.date()
.typeError(t_i18n('The value must be a datetime (yyyy-MM-dd hh:mm (a|p)m)'))
.required(t_i18n('This field is required')),
.typeError(t_i18n('The value must be a datetime (yyyy-MM-dd hh:mm (a|p)m)')),
last_observed: Yup.date()
.typeError(t_i18n('The value must be a datetime (yyyy-MM-dd hh:mm (a|p)m)'))
.required(t_i18n('This field is required')),
number_observed: Yup.number().required(t_i18n('This field is required')),
.typeError(t_i18n('The value must be a datetime (yyyy-MM-dd hh:mm (a|p)m)')),
number_observed: Yup.number(),
confidence: Yup.number().nullable(),
};
const observedDataValidator = useSchemaCreationValidation(
OBSERVED_DATA_TYPE,
}, mandatoryAttributes);
const observedDataValidator = useDynamicSchemaCreationValidation(
mandatoryAttributes,
basicShape,
);
const [commit] = useApiMutation<ObservedDataCreationMutation>(
Expand Down Expand Up @@ -170,13 +169,16 @@ ObservedDataFormProps
<Formik
initialValues={initialValues}
validationSchema={observedDataValidator}
validateOnChange={false}
validateOnBlur={false}
onSubmit={onSubmit}
onReset={onReset}
>
{({ submitForm, handleReset, isSubmitting, setFieldValue, values }) => (
<Form style={{ margin: '20px 0 20px 0' }}>
<StixCoreObjectsField
name="objects"
required={(mandatoryAttributes.includes('objects'))}
style={{ width: '100%' }}
setFieldValue={setFieldValue}
values={values.objects}
Expand All @@ -186,6 +188,7 @@ ObservedDataFormProps
name="first_observed"
textFieldProps={{
label: t_i18n('First observed'),
required: (mandatoryAttributes.includes('first_observed')),
variant: 'standard',
fullWidth: true,
style: { marginTop: 20 },
Expand All @@ -196,6 +199,7 @@ ObservedDataFormProps
name="last_observed"
textFieldProps={{
label: t_i18n('Last observed'),
required: (mandatoryAttributes.includes('last_observed')),
variant: 'standard',
fullWidth: true,
style: { marginTop: 20 },
Expand All @@ -207,6 +211,7 @@ ObservedDataFormProps
name="number_observed"
type="number"
label={t_i18n('Number observed')}
required={(mandatoryAttributes.includes('number_observed'))}
fullWidth={true}
style={{ marginTop: 20 }}
/>
Expand All @@ -216,22 +221,26 @@ ObservedDataFormProps
/>
<CreatedByField
name="createdBy"
required={(mandatoryAttributes.includes('createdBy'))}
style={fieldSpacingContainerStyle}
setFieldValue={setFieldValue}
/>
<ObjectLabelField
name="objectLabel"
required={(mandatoryAttributes.includes('objectLabel'))}
style={fieldSpacingContainerStyle}
setFieldValue={setFieldValue}
values={values.objectLabel}
/>
<ObjectMarkingField
name="objectMarking"
required={(mandatoryAttributes.includes('objectMarking'))}
style={fieldSpacingContainerStyle}
setFieldValue={setFieldValue}
/>
<ExternalReferencesField
name="externalReferences"
required={(mandatoryAttributes.includes('externalReferences'))}
style={fieldSpacingContainerStyle}
setFieldValue={setFieldValue}
values={values.externalReferences}
Expand Down
Loading

0 comments on commit 4cb8be2

Please sign in to comment.