Untitled
unknown
plain_text
a year ago
56 kB
7
Indexable
import React, { useEffect, useMemo, useState } from 'react'; import { Form, Formik, Field, FieldProps, FastField } from 'formik'; import * as Yup from 'yup'; import { useTranslation } from 'react-i18next'; import { CKEditor } from 'ckeditor4-react'; import { useQueryClient } from 'react-query'; import { useToastify } from '@app/Hooks'; import useStylesForm from '@app/styles/form.styles'; import useFormServerErrors from '@app/Hooks/useFormServerErrors'; import { useSecurityExtension } from '@app/modules/Toetsing/hooks/useSecurity/useSecurityExtension'; import { useReviewDocumentGradeFromTargetStatusQuery, useStatusContractorDocumentFindingQuery, } from '@app/modules/Toetsing/hooks'; import { AcceptatieAppStatuses } from '@app/enums'; import useMandatoryFieldsQuery from '@app/modules/Toetsing/hooks/useMandatoryFields/useMandatoryFieldsQuery'; import useUpdateDocumentFindingCommentMutation from '@app/modules/Toetsing/hooks/useDocumentFindings/useUpdateDocumentFindingCommentMutation'; import useCreateDocumentFindingCommentMutation from '@app/modules/Toetsing/hooks/useDocumentFindings/useCreateDocumentFindingCommentMutation'; import trimValues from '@app/libs/form/trimValues'; import { revisieGridStore } from '@app/modules/Toetsing/pages/Toetsing'; import FieldControl from '../form/FieldControl'; import { useAppDispatch, useAppSelector } from '@app/modules/core/store'; import * as settings from '@app/modules/Toetsing/hooks/useSettings'; import { LantisDropDown } from '../LantisDropdown'; import { CommentDialogContainer, CommentDialogTitle, StyledGrid } from './DocumentComments.styles'; import { Button, Dialog, Grid, IconButton, Input } from '@mui/material'; import { DatePicker } from '@mui/x-date-pickers'; import { customSpecialCharacters } from './CustomSpecialCharacters'; import CloseIcon from '@mui/icons-material/Close'; import { t } from 'i18next'; import { Dot } from '@app/styles/globalStyles.styles'; export enum EMandatoryFieldsProperties { Contract = 'Ref Bestek', DocumentReference = 'Re. doc', Conditions = 'Voorwaarden', Commentaar = 'Commentaar', } const EditDocumentFindingsCommentsGrid = (props: any) => { const { t } = useTranslation(); const { showToastSuccess, showToastError } = useToastify(); const classesForm = useStylesForm(); const { closeCommentPopUpAction, reviewVersion, itemDocumentData, reviewByContractor, reviewId, isObsoleteComments, item, duplicateComment, isOpen, } = props; const dispatch = useAppDispatch(); const queryClient = useQueryClient(); const { currentProject } = useAppSelector(settings.selectors.getSettings); const { hasError, getFullErrorsFromServer, getErrorMsg } = useFormServerErrors(); const { hasAccessToComponent } = useSecurityExtension(); const { data: reviewDocumentGradeData, isLoading } = useReviewDocumentGradeFromTargetStatusQuery( itemDocumentData.purposeOfIssueId, itemDocumentData.status, itemDocumentData.documentType, ); const statusContractorDocumentFindingQuery = useStatusContractorDocumentFindingQuery(); const isInVrijgegevenTab = reviewVersion?.reviewRevisionWorkflowStatusId === AcceptatieAppStatuses.Vrijgegeven; const isEditableForContractor = reviewVersion?.reviewRevisionWorkflowStatusId === AcceptatieAppStatuses.Vrijgegeven; const defaultValueStatusContractor = statusContractorDocumentFindingQuery?.data ? (statusContractorDocumentFindingQuery as any)?.data.find((x: any) => x.default === true) : {}; const getReviewDocumentGrade = (item: any) => { if (item?.reviewDocumentGradeName) { return item?.reviewDocumentGradeName; } else { return reviewDocumentGradeData?.length == 1 ? reviewDocumentGradeData[0].name : ''; } }; const getInitialsValue = (item: any) => { const a = { id: item?.id, reviewVersionDocumentVersionId: itemDocumentData.reviewVersionDocumentVersionId, contract: item?.contract ?? '', comment: item?.comment ?? '', conditions: item?.conditions ?? '', commentContractor: item?.commentContractor ?? '', reviewDocumentGrade: { id: null, name: getReviewDocumentGrade(item), }, documentVersionId: item?.documentVersionId, dateContractor: item?.dateContractor != null ? new Date(item.dateContractor) : new Date(), referenceContractor: item?.referenceContractor ?? '', statusContractorDocumentFindingId: statusContractorDocumentFindingQuery.data && item?.statusContractorDocumentFindingId ? (statusContractorDocumentFindingQuery.data as any)?.find( (x: any) => x.id === item?.statusContractorDocumentFindingId, ) : defaultValueStatusContractor, documentReference: item?.documentReference ?? '', }; return a; }; const { data: typesFromMandatoryRoles, isLoading: isLoadingTypesFromMandatoryFields } = useMandatoryFieldsQuery(); useEffect(() => { queryClient.refetchQueries(['mandatory-fields-by-project-', currentProject]); queryClient.refetchQueries( [ 'target-status-review-document-grade', currentProject, itemDocumentData!.purposeOfIssueId!, itemDocumentData!.status!, itemDocumentData!.documentType, ], { exact: true, }, ); }, []); const validateMaxLength = (value: any, maxLength: number) => { if (value != null) { return byteLength(value) <= maxLength ? true : false; } return true; }; const byteLength = (str: string) => { // returns the byte length of an utf8 string let s = str.length; for (let i = str.length - 1; i >= 0; i--) { let code = str.charCodeAt(i); if (code > 0x7f && code <= 0x7ff) s++; else if (code > 0x7ff && code <= 0xffff) s += 2; if (code >= 0xdc00 && code <= 0xdfff) i--; } return s; }; const validationSchema = Yup.object().shape({ id: Yup.number(), comment: isInVrijgegevenTab ? Yup.string().nullable().default('') : Yup.string().when('reviewDocumentGrade', { is: (reviewDocumentGrade: any) => { return validateInput(reviewDocumentGrade, EMandatoryFieldsProperties.Commentaar); }, then: Yup.string() .test('Comment_required', 'Commentaar is vereist', (value) => { const regex = /<(?!\/?img)[^>]+>|<\/img>/gi; const processedValue = (value || '').replace(regex, '')?.trim(); return processedValue?.length > 0 ? true : false; }) .test('len', 'De grens is overschreden', (value) => { if (value?.trim() == '') { return false; } return validateMaxLength(value, 1024 * 1024); }), otherwise: Yup.string().test('len', 'De grens is overschreden', (value) => { if (value?.trim() == '') { return false; } else if ( validateInput(props?.parent?.reviewDocumentGrade, EMandatoryFieldsProperties.Commentaar) === false ) { return validateMaxLength(value, 1024 * 1024); } return true; }), }), contract: isInVrijgegevenTab ? Yup.string().nullable() : Yup.string().when('reviewDocumentGrade', { is: (reviewDocumentGrade: any) => { return validateInput(reviewDocumentGrade, EMandatoryFieldsProperties.Contract); }, then: Yup.string() .required(`${t('comments.contract_ref')} is vereist`) .trim() .test('len', 'Max lengte is 200', (value) => { if (value != null) { return value.length <= 200 ? true : false; } return true; }), otherwise: Yup.string() .trim() .test('len', 'Max lengte is 200', (value, props) => { if ( value != null && validateInput(props?.parent?.reviewDocumentGrade, EMandatoryFieldsProperties.Contract) === false ) { return value.length <= 200 ? true : false; } return true; }), }), conditions: isInVrijgegevenTab ? Yup.string().nullable() : Yup.string().when('reviewDocumentGrade', { is: (reviewDocumentGrade: any) => { return validateInput(reviewDocumentGrade, EMandatoryFieldsProperties.Conditions); }, then: Yup.string() .required('Voorwaarden is vereist') .trim() .test('len', 'Max lengte is 256', (value) => { if (value != null) { return value.length <= 256 ? true : false; } return true; }), otherwise: Yup.string() .trim() .test('len', 'Max lengte is 256', (value, props) => { if ( value != null && validateInput( props?.parent?.reviewDocumentGrade, EMandatoryFieldsProperties.Conditions, ) === false ) { return value.length <= 256 ? true : false; } return true; }), }), commentContractor: isEditableForContractor ? Yup.string().test('len', 'De grens is overschreden', (value) => { if (value != null) { return value.length <= 1024 * 1024 ? true : false; } return true; }) : Yup.string().nullable(), reviewDocumentGrade: Yup.object().test('reviewDocumentGrade_required', 'Type is vereist', (value) => { return validateType(value); }), dateContractor: isEditableForContractor ? Yup.date().nullable().required('Datum is vereist').default(new Date()) : Yup.date().nullable(), referenceContractor: isEditableForContractor ? Yup.string().test('len', 'Max lengte is 200', (value) => { if (value != null) { return value.length <= 200 ? true : false; } return true; }) : Yup.string().nullable(), documentReference: isInVrijgegevenTab ? Yup.string().nullable() : Yup.string().when('reviewDocumentGrade', { is: (reviewDocumentGrade: any) => { return validateInput(reviewDocumentGrade, EMandatoryFieldsProperties.DocumentReference); }, then: Yup.string() .required(`${t('comments.document_ref')} is vereist`) .trim() .test('len', 'Max lengte is 256', (value) => { if (value != null) { return value.length <= 256 ? true : false; } return true; }), otherwise: Yup.string() .trim() .test('len', 'Max lengte is 256', (value, props) => { if ( value != null && validateInput( props?.parent?.reviewDocumentGrade, EMandatoryFieldsProperties.DocumentReference, ) === false ) { return value.length <= 256 ? true : false; } return true; }), }), }); const getMandatoryFieldsByReviewGradeName = (reviewDocumentGradeName: string | null | undefined) => { const mandatoryFields = typesFromMandatoryRoles?.find( (x: any) => x?.poiId == itemDocumentData.purposeOfIssueId && x.reviewDocumentGrade?.name === reviewDocumentGradeName, ) as any; return mandatoryFields; }; const validateType = (reviewDocumentGrade: any | null) => { return Boolean(reviewDocumentGrade?.name); }; const validateInput = (reviewDocumentGrade: any | null, property: EMandatoryFieldsProperties) => { if (Boolean(reviewDocumentGrade?.name)) { const mandatoryFields = getMandatoryFieldsByReviewGradeName(reviewDocumentGrade.name); // configuration does not exist for the current POI if (!mandatoryFields) { return false; } switch (property) { case EMandatoryFieldsProperties.Contract: return mandatoryFields.refBestek; case EMandatoryFieldsProperties.DocumentReference: return mandatoryFields.reDoc; case EMandatoryFieldsProperties.Conditions: return mandatoryFields.voorwaarden; case EMandatoryFieldsProperties.Commentaar: return mandatoryFields.commentaar; default: return false; } } return false; }; const { mutate: updateFinding, isLoading: isLoadingUpdateFinding } = useUpdateDocumentFindingCommentMutation(); const { mutate: createFinding, isLoading: isLoadingCreateFinding } = useCreateDocumentFindingCommentMutation(); const mapDataSend = (valueForm: any) => { const mandatoryFields = getMandatoryFieldsByReviewGradeName(valueForm.reviewDocumentGrade?.name); return { id: valueForm.id, reviewVersionDocumentVersionId: itemDocumentData.reviewVersionDocumentVersionId, reviewDocumentGradeName: valueForm.reviewDocumentGrade?.name, contract: mandatoryFields?.refBestek === null ? '' : valueForm.contract ?? '', comment: mandatoryFields?.commentaar === null ? '' : valueForm.comment ?? '', conditions: mandatoryFields?.voorwaarden === null ? '' : valueForm.conditions ?? '', documentReference: mandatoryFields?.reDoc === null ? '' : valueForm.documentReference ?? '', commentContractor: valueForm.commentContractor ?? '', documentVersionId: itemDocumentData.documentVersionId, isEditedByContractor: isEditableForContractor, dateContractor: valueForm.dateContractor, referenceContractor: valueForm.referenceContractor, statusContractorDocumentFindingId: valueForm.statusContractorDocumentFindingId?.id, poiId: itemDocumentData.purposeOfIssueId, projectId: currentProject, }; }; const makeUpdateStatusContractor = (initalsValues: any, newValue: any) => { if (initalsValues.statusContractorDocumentFindingId?.id != newValue.statusContractorDocumentFindingId) { if (newValue.statusContractorDocumentFindingId == 2) { return 1; } else { return -1; } } return false; }; const handleSubmit = (values: any, formikProps: any) => { const trimedValues = trimValues({ ...values }); const dataSend = mapDataSend(trimedValues); dataSend.dateContractor = new Date(dataSend.dateContractor.setHours(0, 0, 0, 0)); if (item.id && item.id !== 0 && !duplicateComment) { updateFinding(dataSend, { onSuccess: (result: any) => { if (hasError(result)) { const errorsFromServer = getFullErrorsFromServer(result, dataSend); formikProps.setErrors(errorsFromServer.fieldsErrors); showToastError(getErrorMsg(result)); } else { if (result === true) { closeCommentPopUpAction(); queryClient.invalidateQueries([ 'document-findings', props.itemDocumentData.documentId, reviewId, ]); queryClient.refetchQueries(['review-version-', reviewVersion?.id?.toString()]); showToastSuccess('Wijzigingen succesvol geladen'); if (dataSend.isEditedByContractor) { const type = makeUpdateStatusContractor(getInitialsValue(props.item), dataSend); if (type !== false) { dispatch( revisieGridStore.actions.updateStatusContractor({ id: props.reviewVersionId, type: type, }), ); } } } else { showToastError('Fault'); } } formikProps.setSubmitting(false); }, onError(error: any) { showToastError(error?.message); formikProps.setSubmitting(false); }, }); } else { createFinding(dataSend, { onSuccess: (result: any) => { if (hasError(result)) { const errorsFromServer = getFullErrorsFromServer(result, dataSend); formikProps.setErrors(errorsFromServer.fieldsErrors); showToastError(getErrorMsg(result)); } else { if (!isNaN(Number(result)) && Number(result) > 0) { closeCommentPopUpAction(); queryClient.invalidateQueries([ 'document-findings', props.itemDocumentData.documentId, reviewId, ]); queryClient.refetchQueries('review-version-main-grid-'); queryClient.refetchQueries(['review-version-', reviewVersion?.id?.toString()]); showToastSuccess('Wijzigingen succesvol geladen'); } else { showToastError('Fault'); } } formikProps.setSubmitting(false); }, onError(error: any) { formikProps.setSubmitting(false); }, }); } }; const getMandatoryFieldsValue = (formikValues: any, property: EMandatoryFieldsProperties) => { const reviewDocumentGradeName = (formikValues as any).reviewDocumentGrade.name; const mandatoryFields = getMandatoryFieldsByReviewGradeName(reviewDocumentGradeName); // configuration does not exist for the current POI if (mandatoryFields === null) { return false; } switch (property) { case EMandatoryFieldsProperties.Contract: if (isInVrijgegevenTab && formikValues.contract.length > 0) return true; return mandatoryFields?.refBestek; case EMandatoryFieldsProperties.DocumentReference: if (isInVrijgegevenTab && formikValues.documentReference.length > 0) return true; return mandatoryFields?.reDoc; case EMandatoryFieldsProperties.Conditions: if (isInVrijgegevenTab && formikValues.conditions.length > 0) return true; return mandatoryFields?.voorwaarden; case EMandatoryFieldsProperties.Commentaar: if (isInVrijgegevenTab && formikValues.comment.length > 0) return true; return mandatoryFields?.commentaar; default: return null; } }; const onKeyDownEventHandler = (e: any) => { // ESC button if (e.keyDown == 27) { props.cancelEdit(); } e.stopPropagation(); }; const hasReplyCommentSecurityAccess = useMemo(() => { if (reviewVersion?.reviewRevisionWorkflowStatusId === AcceptatieAppStatuses.Vrijgegeven) { return ( hasAccessToComponent('Completed_CommentsReply') && (props.item.statusContractorDocumentFindingId === 1 ? true : false) ); } }, []); return ( <> { <Dialog maxWidth={'xl'} open={isOpen} fullWidth autoFocus={true} onClose={props.cancelEdit} onKeyDown={(e) => { onKeyDownEventHandler(e); }} > <CommentDialogContainer> {<CommentDialogTitle>{props.item?.id ? 'Bewerk' : 'Toevoegen'}</CommentDialogTitle>} <IconButton aria-label="close" onClick={props.cancelEdit} sx={{ position: 'absolute', right: 8, top: 8, color: (theme) => theme.palette.grey[500], }} > <CloseIcon style={{ width: '16px', height: '16px' }} /> </IconButton> <Formik initialValues={getInitialsValue(props.item)} validationSchema={validationSchema} validateOnBlur={true} validateOnChange={true} onSubmit={(values, formikProps) => handleSubmit(values, formikProps)} > {({ values, setFieldValue, dirty, isSubmitting, resetForm }) => ( <Form style={{ height: '100%', display: 'flex', flexDirection: 'column', alignItems: 'flex-start', background: '#FFF', }} > <div style={{ width: '100%' }}> <Grid container style={{ height: '128px', display: 'flex', flexDirection: 'row', justifyContent: 'space-between', gap: '16px', flex: '1', }} > <Field name="reviewDocumentGrade"> {(fieldProps: FieldProps) => ( <FieldControl {...fieldProps} name="reviewDocumentGrade"> {(inputProps) => ( <div style={{ display: 'flex', flexDirection: 'column', gap: '8px', }} > <div style={{ display: 'flex' }}> <div style={{ color: '#334155', fontFamily: 'Open Sans', fontSize: '0.875rem', fontWeight: 600, lineHeight: '150%', }} > Type </div> <Dot>*</Dot> </div> <LantisDropDown options={reviewDocumentGradeData || []} value={values.reviewDocumentGrade} labelKey="name" valueKey="name" w={220} menuItemWidth={220} onChange={(selectedType) => setFieldValue( 'reviewDocumentGrade', selectedType, ) } isDisabled={ hasReplyCommentSecurityAccess || isInVrijgegevenTab || isObsoleteComments } /> </div> )} </FieldControl> )} </Field> <CustomMandatoryField fieldName={'contract'} fieldLabel={ t('comments.contract_ref') ?? EMandatoryFieldsProperties.Contract } mandatoryFieldsValue={getMandatoryFieldsValue( values, EMandatoryFieldsProperties.Contract, )} isReadonlyForContractor={hasReplyCommentSecurityAccess} className={classesForm.input} disabled={ hasReplyCommentSecurityAccess || isInVrijgegevenTab || isObsoleteComments } maxlength={200} /> <CustomMandatoryField fieldName={'documentReference'} fieldLabel={ t('comments.document_ref') ?? EMandatoryFieldsProperties.DocumentReference } mandatoryFieldsValue={getMandatoryFieldsValue( values, EMandatoryFieldsProperties.DocumentReference, )} isReadonlyForContractor={hasReplyCommentSecurityAccess} disabled={ hasReplyCommentSecurityAccess || isInVrijgegevenTab || isObsoleteComments } maxlength={256} /> <CustomMandatoryField fieldName={'conditions'} fieldLabel={EMandatoryFieldsProperties.Conditions} mandatoryFieldsValue={getMandatoryFieldsValue( values, EMandatoryFieldsProperties.Conditions, )} isReadonlyForContractor={hasReplyCommentSecurityAccess} disabled={ hasReplyCommentSecurityAccess || isInVrijgegevenTab || isObsoleteComments } showField={values.conditions} /> </Grid> <Grid style={{ flex: '1', marginTop: '32px' }}> {getMandatoryFieldsValue(values, EMandatoryFieldsProperties.Commentaar) === null ? null : ( <StyledGrid> <FastField name="comment"> {(fieldProps: FieldProps) => !hasReplyCommentSecurityAccess && !isInVrijgegevenTab ? ( <FieldControl {...fieldProps} name="comment"> {(inputProps) => ( <> <div style={{ color: '#334155', fontFamily: 'Open Sans', fontSize: '0.875rem', fontWeight: 600, lineHeight: '150%', }} > {getMandatoryFieldsValue( values, EMandatoryFieldsProperties.Commentaar, ) === true ? ( <> Commentaar<Dot>*</Dot> </> ) : ( 'Commentaar' )} </div> <CKEditorFormComponent {...fieldProps} isObsoleteComments={isObsoleteComments} /> </> )} </FieldControl> ) : ( <FieldControl {...fieldProps} name="comment" label={EMandatoryFieldsProperties.Commentaar} > {(inputProps) => ( <div className={classesForm.disableContentInDiv} dangerouslySetInnerHTML={{ __html: fieldProps.field.value, }} ></div> )} </FieldControl> ) } </FastField> </StyledGrid> )} </Grid> {hasReplyCommentSecurityAccess || isInVrijgegevenTab ? ( <Grid container spacing={3}> <Grid item className={classesForm.itemFieldIntput} md={8}> <Field name="referenceContractor"> {(fieldProps: FieldProps) => ( <FieldControl {...fieldProps} name="referenceContractor" label="Ref" > {(inputProps) => ( <Input {...inputProps} {...fieldProps.field} className={classesForm.input} disabled={ isInVrijgegevenTab && !hasReplyCommentSecurityAccess } /> )} </FieldControl> )} </Field> </Grid> <Grid item className={classesForm.itemFieldIntput} md={2}> <Field name="dateContractor"> {(fieldProps: FieldProps) => ( <FieldControl {...fieldProps} name="dateContractor" label="Datum *" > {(inputProps) => ( <DatePicker format="dd/MM/yyyy" {...inputProps} {...fieldProps.field} className={classesForm.input} disabled={ isInVrijgegevenTab && !hasReplyCommentSecurityAccess } /> )} </FieldControl> )} </Field> </Grid> <Grid item className={classesForm.itemFieldIntput} md={2}> <Field name="statusContractorDocumentFindingId"> {(fieldProps: FieldProps) => ( <FieldControl {...fieldProps} name="statusContractorDocumentFindingId" label="Status *" > {(inputProps) => ( <LantisDropDown {...inputProps} {...fieldProps.field} data={ statusContractorDocumentFindingQuery.data || [] } textField="name" dataItemKey="id" filterable={true} defaultValue={defaultValueStatusContractor} className={classesForm.input} disabled={true} /> )} </FieldControl> )} </Field> </Grid> {!reviewByContractor && ( <Grid item className={classesForm.itemFieldIntput} md={12}> <Field name="commentContractor"> {(fieldProps: FieldProps) => !isInVrijgegevenTab || hasReplyCommentSecurityAccess ? ( <FieldControl {...fieldProps} name="commentContractor" label="Antwoord" > {(inputProps) => ( <CKEditorFormComponent {...fieldProps} isObsoleteComments={isObsoleteComments} /> )} </FieldControl> ) : ( <FieldControl {...fieldProps} name="commentContractor" label="Antwoord" > {(inputProps) => ( <div style={{ minHeight: '2rem', }} className={ classesForm.disableContentInDiv } dangerouslySetInnerHTML={{ __html: fieldProps.field.value, }} ></div> )} </FieldControl> ) } </Field> </Grid> )} </Grid> ) : ( '' )} </div> <div style={{ display: 'flex', gap: '32px', marginTop: '15px' }}> <SubmitButton isLoading={isLoadingUpdateFinding || isLoadingCreateFinding} disabled={ (!dirty || isSubmitting) && (reviewDocumentGradeData?.length !== 1 || props.item?.id) && !duplicateComment } /> <Button type="button" variant="text" color="inherit" sx={{ width: '160px !important' }} onClick={() => { const initalValue = getInitialsValue(props.item); resetForm({ values: { ...initalValue } }); }} disabled={(!dirty || isSubmitting) && !duplicateComment} > {t('general.cancel')} </Button> </div> </Form> )} </Formik> </CommentDialogContainer> </Dialog> } </> ); }; const CustomMandatoryField: React.FC<any> = ({ fieldLabel, fieldName, mandatoryFieldsValue, maxLength, ...props }) => { return ( <> {mandatoryFieldsValue !== null ? ( <StyledGrid style={{ flex: '1', height: '100%' }}> <Field name={fieldName}> {(fieldProps: FieldProps) => ( <FieldControl {...fieldProps} name={fieldName}> {() => ( <div style={{ display: 'flex', flexDirection: 'column', gap: '8px', height: '100%', }} > <div style={{ display: 'flex' }}> <div style={{ color: '#334155', fontFamily: 'Open Sans', fontSize: '0.875rem', fontWeight: 600, lineHeight: '150%', }} > {fieldLabel} {mandatoryFieldsValue && <Dot>*</Dot>} </div> </div> <textarea {...fieldProps.field} disabled={props.disabled} maxLength={maxLength} style={{ resize: 'none', width: '100%', height: '98px', display: 'flex', padding: '10px 12px', alignSelf: 'stretch', borderRadius: '6px', border: '2px solid #CBD5E1', background: '#FFF', }} /> </div> )} </FieldControl> )} </Field> </StyledGrid> ) : null} </> ); }; const SubmitButton: React.FC<any> = ({ isLoading, ...props }) => { return ( <Button isLoading={isLoading} type="submit" variant="contained" color="secondary" sx={{ width: '160px !important' }} {...props} > {t('general.save')} </Button> ); }; const CKEditorFormComponent: React.FC<any> = ({ isObsoleteComments, ...props }) => { const field = props.field; const form = props.form; const [ready, setReady] = useState<boolean>(false); const [editor, setEditor] = useState<any>(null); const [isLoading, setIsLoading] = useState<boolean>(true); const initData = (form?.initialValues as any)![field?.name] ?? ''; useEffect(() => { if (ready && !form.dirty && editor && editor.checkDirty() && initData.trim() !== editor.getData().trim()) { editor.setData(initData, { noSnapshot: true }); } if (ready) { setIsLoading(false); } }, [form.dirty, ready, editor, field]); const handleInstanceReady = ({ editor }: any) => { setEditor(editor); setReady(true); }; if (!field) { return <></>; } return ( <> <CKEditor name={field.name} initData={field.value ? field.value : initData} data={field.value} onChange={(event: any) => { form.setFieldValue(field.name, event.editor.getData().trim()); }} onInstanceReady={handleInstanceReady} style={{ height: 'auto' }} config={{ removePlugins: 'about, maximize, resize', specialChars: customSpecialCharacters }} readOnly={isObsoleteComments} /> </> ); }; export default EditDocumentFindingsCommentsGrid;
Editor is loading...
Leave a Comment