handle empty collaborators error
This commit is contained in:
parent
ecaa7f2801
commit
f92946b668
@ -24,7 +24,7 @@
|
||||
"eslint-config-next": "13.2.4",
|
||||
"form-data": "^4.0.0",
|
||||
"jwt-decode": "^3.1.2",
|
||||
"le-coffre-resources": "git@github.com:smart-chain-fr/leCoffre-resources.git#v2.93",
|
||||
"le-coffre-resources": "git@github.com:smart-chain-fr/leCoffre-resources.git#v2.94",
|
||||
"next": "13.2.4",
|
||||
"prettier": "^2.8.7",
|
||||
"react": "18.2.0",
|
||||
|
@ -66,5 +66,14 @@
|
||||
z-index: 1;
|
||||
padding: 0 16px;
|
||||
}
|
||||
|
||||
&[data-is-errored="true"] {
|
||||
.input {
|
||||
border: 1px solid var(--red-flash);
|
||||
~ .fake-placeholder {
|
||||
color: var(--red-flash);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,9 +3,10 @@ import React from "react";
|
||||
import ReactSelect, { ActionMeta, MultiValue, Options, PropsValue } from "react-select";
|
||||
|
||||
import { IOption } from "../Form/SelectField";
|
||||
import Typography, { ITypo } from "../Typography";
|
||||
import Typography, { ITypo, ITypoColor } from "../Typography";
|
||||
import classes from "./classes.module.scss";
|
||||
import { styles } from "./styles";
|
||||
import { ValidationError } from "class-validator";
|
||||
|
||||
type IProps = {
|
||||
options: IOption[];
|
||||
@ -17,10 +18,12 @@ type IProps = {
|
||||
isMulti?: boolean;
|
||||
shouldCloseMenuOnSelect: boolean;
|
||||
isOptionDisabled?: (option: IOption, selectValue: Options<IOption>) => boolean;
|
||||
validationError?: ValidationError;
|
||||
};
|
||||
type IState = {
|
||||
isFocused: boolean;
|
||||
selectedOptions: MultiValue<IOption>;
|
||||
validationError: ValidationError | null;
|
||||
};
|
||||
|
||||
export default class MultiSelect extends React.Component<IProps, IState> {
|
||||
@ -34,11 +37,15 @@ export default class MultiSelect extends React.Component<IProps, IState> {
|
||||
this.state = {
|
||||
isFocused: false,
|
||||
selectedOptions: [],
|
||||
validationError: this.props.validationError ?? null
|
||||
|
||||
};
|
||||
this.hasError = this.hasError.bind(this);
|
||||
this.onChange = this.onChange.bind(this);
|
||||
this.onEmptyResearch = this.onEmptyResearch.bind(this);
|
||||
this.onFocus = this.onFocus.bind(this);
|
||||
this.onBlur = this.onBlur.bind(this);
|
||||
this.renderErrors = this.renderErrors.bind(this);
|
||||
}
|
||||
public override render(): JSX.Element {
|
||||
return (
|
||||
@ -70,6 +77,7 @@ export default class MultiSelect extends React.Component<IProps, IState> {
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
{this.hasError() && <div className={classes["errors-container"]}>{this.renderErrors()}</div>}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@ -89,8 +97,12 @@ export default class MultiSelect extends React.Component<IProps, IState> {
|
||||
}
|
||||
|
||||
public override componentDidUpdate(prevProps: IProps): void {
|
||||
if (this.props.defaultValue === prevProps.defaultValue) return;
|
||||
if (this.props.defaultValue) {
|
||||
if (this.props.validationError !== prevProps.validationError) {
|
||||
this.setState({
|
||||
validationError: this.props.validationError ?? null,
|
||||
});
|
||||
}
|
||||
if (this.props.defaultValue && this.props.defaultValue !== prevProps.defaultValue) {
|
||||
// If default value contains multiple IOptions
|
||||
if (Array.isArray(this.props.defaultValue)) {
|
||||
this.setState({ selectedOptions: this.props.defaultValue });
|
||||
@ -115,6 +127,7 @@ export default class MultiSelect extends React.Component<IProps, IState> {
|
||||
this.props.onChange && this.props.onChange(newValue, actionMeta);
|
||||
this.setState({
|
||||
selectedOptions: newValue,
|
||||
validationError: null,
|
||||
});
|
||||
}
|
||||
|
||||
@ -124,4 +137,21 @@ export default class MultiSelect extends React.Component<IProps, IState> {
|
||||
}
|
||||
return "Aucune option trouvée";
|
||||
}
|
||||
|
||||
protected hasError(): boolean {
|
||||
return this.state.validationError !== null;
|
||||
}
|
||||
|
||||
protected renderErrors(): JSX.Element[] | null {
|
||||
if (!this.state.validationError || !this.state.validationError.constraints) return null;
|
||||
let errors: JSX.Element[] = [];
|
||||
Object.entries(this.state.validationError.constraints).forEach(([key, value]) => {
|
||||
errors.push(
|
||||
<Typography key={key} typo={ITypo.CAPTION_14} color={ITypoColor.RED_FLASH}>
|
||||
{value}
|
||||
</Typography>,
|
||||
);
|
||||
});
|
||||
return errors;
|
||||
}
|
||||
}
|
||||
|
@ -74,6 +74,7 @@ class CreateFolderClass extends BasePage<IPropsClass, IState> {
|
||||
this.onCollaboratorsChange = this.onCollaboratorsChange.bind(this);
|
||||
this.isFormSubmittable = this.isFormSubmittable.bind(this);
|
||||
this.onFormSubmit = this.onFormSubmit.bind(this);
|
||||
this.renderSelectCollaborators = this.renderSelectCollaborators.bind(this);
|
||||
}
|
||||
|
||||
public override render(): JSX.Element {
|
||||
@ -115,7 +116,7 @@ class CreateFolderClass extends BasePage<IPropsClass, IState> {
|
||||
validationError={this.state.validationError.find((error) => error.property === "description")}
|
||||
required={false}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className={classes["access-container"]}>
|
||||
<Typography typo={ITypo.H3} color={ITypoColor.PURPLE_FLASH}>
|
||||
Accès au dossier
|
||||
@ -128,22 +129,14 @@ class CreateFolderClass extends BasePage<IPropsClass, IState> {
|
||||
Sélectionner certains collaborateurs
|
||||
</RadioBox>
|
||||
</div>
|
||||
{this.state.folder_access === "select_collaborators" && (
|
||||
<div className={classes["collaborators-container"]}>
|
||||
<MultiSelect
|
||||
options={this.state.collaboratorsOptions}
|
||||
placeholder="Sélectionner les collaborateurs"
|
||||
onChange={this.onCollaboratorsChange}
|
||||
defaultValue={this.state.formValues.collaborators ?? []}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
{this.renderSelectCollaborators()}
|
||||
<div className={classes["buttons-container"]}>
|
||||
<Button fullwidth type="submit">
|
||||
Créer un dossier
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Form>
|
||||
</div>
|
||||
</DefaultDoubleSidePage>
|
||||
@ -259,9 +252,8 @@ class CreateFolderClass extends BasePage<IPropsClass, IState> {
|
||||
});
|
||||
|
||||
try {
|
||||
await officeFolderForm.validateOrReject?.({ groups: ["createFolder"], forbidUnknownValues: false });
|
||||
await officeFolderForm.validateOrReject?.({ groups: ["createFolder"], forbidUnknownValues: true });
|
||||
} catch (validationErrors) {
|
||||
console.log(validationErrors);
|
||||
this.setState({
|
||||
validationError: validationErrors as ValidationError[],
|
||||
});
|
||||
@ -277,9 +269,24 @@ class CreateFolderClass extends BasePage<IPropsClass, IState> {
|
||||
this.setState({
|
||||
validationError: backError as ValidationError[],
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private renderSelectCollaborators() {
|
||||
if (this.state.folder_access !== "select_collaborators") return null;
|
||||
return (
|
||||
<div className={classes["collaborators-container"]}>
|
||||
<MultiSelect
|
||||
options={this.state.collaboratorsOptions}
|
||||
placeholder="Sélectionner les collaborateurs"
|
||||
onChange={this.onCollaboratorsChange}
|
||||
defaultValue={this.state.formValues.collaborators ?? []}
|
||||
validationError={this.state.validationError.find((error) => error.property === "stakeholders")}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
private isFormSubmittable(): boolean {
|
||||
if (
|
||||
this.state.formValues.entitled === "" ||
|
||||
|
@ -16,6 +16,7 @@ import { NextRouter, useRouter } from "next/router";
|
||||
|
||||
import BasePage from "../../Base";
|
||||
import classes from "./classes.module.scss";
|
||||
import { ValidationError } from "class-validator";
|
||||
|
||||
type IPropsClass = {
|
||||
selectedFolderUid: string;
|
||||
@ -28,6 +29,7 @@ type IState = {
|
||||
defaultCheckedAllOffice: boolean;
|
||||
selectedCollaborators: readonly IOption[];
|
||||
loading: boolean;
|
||||
validationError?: ValidationError[];
|
||||
};
|
||||
|
||||
enum ERadioBoxValue {
|
||||
@ -96,6 +98,7 @@ class UpdateFolderCollaboratorsClass extends BasePage<IPropsClass, IState> {
|
||||
options={selectOptions}
|
||||
placeholder="Collaborateurs"
|
||||
defaultValue={this.state.selectedCollaborators}
|
||||
validationError={this.state.validationError?.find((error) => error.property === "stakeholders")}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
@ -204,7 +207,8 @@ class UpdateFolderCollaboratorsClass extends BasePage<IPropsClass, IState> {
|
||||
.modules.pages.Folder.pages.FolderInformation.props.path.replace("[folderUid]", this.props.selectedFolderUid),
|
||||
);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
if(!Array.isArray(error)) return;
|
||||
this.setState({ validationError: error });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user