- saving progress;
This commit is contained in:
@@ -34,7 +34,7 @@ const DatepickerRange = ({
|
||||
<Calendar id={field.name}
|
||||
value={field.value}
|
||||
onChange={field.onChange}
|
||||
|
||||
dateFormat="dd/mm/yy"
|
||||
mask="99/99/9999"
|
||||
showIcon
|
||||
minDate={minDate}
|
||||
|
||||
@@ -21,9 +21,11 @@ const Fileupload = ({
|
||||
doctype = 'images',
|
||||
emptyText = __('Trascina qui il tuo file', 'gepafin'),
|
||||
chooseLabel = __('Aggiungi immagine', 'gepafin'),
|
||||
multiple = false
|
||||
multiple = false,
|
||||
callId = 0
|
||||
}) => {
|
||||
const [stateFieldData, setStateFieldData] = useState([]);
|
||||
const [acceptFormats, setAcceptFormats] = useState('');
|
||||
const inputRef = useRef();
|
||||
|
||||
const customBase64Uploader = (event) => {
|
||||
@@ -31,14 +33,10 @@ const Fileupload = ({
|
||||
for (const file of event.files) {
|
||||
formData.append('file', file)
|
||||
}
|
||||
/*for (const pair of formData.entries()) {
|
||||
console.log(pair[0], pair[1]);
|
||||
}*/
|
||||
FileUploadService.uploadFile(formData, callback, errorCallback, [['documentType', doctype.toUpperCase()]]);
|
||||
FileUploadService.uploadFile(callId, formData, callback, errorCallback, [['documentType', doctype.toUpperCase()]]);
|
||||
};
|
||||
|
||||
const callback = (data) => {
|
||||
console.log('data', data);
|
||||
if (data.status === 'SUCCESS') {
|
||||
setStateFieldData(data.data);
|
||||
const files = inputRef.current.getFiles();
|
||||
@@ -86,7 +84,6 @@ const Fileupload = ({
|
||||
setStateFieldData(prevState => {
|
||||
const newFiles = prevState.filter(o => o.id !== id);
|
||||
inputRef.current.setUploadedFiles(newFiles);
|
||||
console.log('newFiles', newFiles);
|
||||
return newFiles;
|
||||
});
|
||||
}
|
||||
@@ -96,39 +93,61 @@ const Fileupload = ({
|
||||
console.log('err', err);
|
||||
}
|
||||
|
||||
const onBeforeDrop = (e) => {
|
||||
return validateFileInputType(e.dataTransfer.files);
|
||||
}
|
||||
|
||||
const validateFileInputType = ( files ) => {
|
||||
const MIMEtype = new RegExp( acceptFormats );
|
||||
|
||||
return Array.prototype.every.call( files, function passesAcceptedFormat( file ){
|
||||
return MIMEtype.test( file.type );
|
||||
} );
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
setStateFieldData(defaultValue);
|
||||
register(fieldName, config)
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
// eslint-disable-next-line no-useless-escape
|
||||
setAcceptFormats(accept.replace( /\*/g, '.\*' ).replace( /,/g, '|' ));
|
||||
}, [accept]);
|
||||
|
||||
useEffect(() => {
|
||||
inputRef.current.setUploadedFiles(stateFieldData);
|
||||
setDataFn(fieldName, [...stateFieldData], { shouldValidate: true });
|
||||
}, [stateFieldData])
|
||||
|
||||
return (
|
||||
<>
|
||||
<label htmlFor={fieldName} className={classNames({ 'p-error': errors[fieldName] })}>
|
||||
{label}{config.required ? '*' : null}
|
||||
</label>
|
||||
<FileUpload
|
||||
ref={inputRef}
|
||||
id={fieldName}
|
||||
name={fieldName}
|
||||
url={'/document/uploadFile'}
|
||||
multiple={multiple}
|
||||
accept={accept}
|
||||
maxFileSize={1000000}
|
||||
emptyTemplate={<p>{emptyText}</p>}
|
||||
chooseLabel={chooseLabel}
|
||||
cancelLabel={__('Cancella', 'gepafin')}
|
||||
uploadLabel={__('Carica', 'gepafin')}
|
||||
className={classNames({ 'p-invalid': errors[fieldName] })}
|
||||
itemTemplate={itemTemplate}
|
||||
customUpload
|
||||
uploadHandler={customBase64Uploader}/>
|
||||
{infoText ? <small>{infoText}</small> : null}
|
||||
</>)
|
||||
callId && callId !== 0
|
||||
? <>
|
||||
<label htmlFor={fieldName} className={classNames({ 'p-error': errors[fieldName] })}>
|
||||
{label}{config.required ? '*' : null}
|
||||
{acceptFormats ? ' (' + acceptFormats.split('|').join(', ') + ')' : null}
|
||||
</label>
|
||||
<FileUpload
|
||||
ref={inputRef}
|
||||
id={fieldName}
|
||||
name={fieldName}
|
||||
url={'/document/uploadFile'}
|
||||
multiple={multiple}
|
||||
accept={accept}
|
||||
maxFileSize={1000000}
|
||||
emptyTemplate={<p>{emptyText}</p>}
|
||||
chooseLabel={chooseLabel}
|
||||
cancelLabel={__('Cancella', 'gepafin')}
|
||||
uploadLabel={__('Carica', 'gepafin')}
|
||||
className={classNames({ 'p-invalid': errors[fieldName] })}
|
||||
itemTemplate={itemTemplate}
|
||||
customUpload
|
||||
onBeforeDrop={onBeforeDrop}
|
||||
uploadHandler={customBase64Uploader}/>
|
||||
{infoText ? <small>{infoText}</small> : null}
|
||||
</>
|
||||
: null
|
||||
)
|
||||
}
|
||||
|
||||
export default Fileupload;
|
||||
@@ -1,7 +1,7 @@
|
||||
import React, { useRef, useEffect, useState } from 'react';
|
||||
import React, { useRef, useEffect, useState, useCallback } from 'react';
|
||||
import { classNames } from 'primereact/utils';
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import { isEmpty } from 'ramda';
|
||||
import { head, isNil, pluck } from 'ramda';
|
||||
|
||||
// components
|
||||
import { InputText } from 'primereact/inputtext';
|
||||
@@ -22,19 +22,20 @@ const FormFieldRepeater = ({
|
||||
}) => {
|
||||
const forMenu = useRef(null);
|
||||
const [stateFieldData, setStateFieldData] = useState([]);
|
||||
const [stateOptionsData, setStateOptionsData] = useState([]);
|
||||
const menuItems = [
|
||||
{
|
||||
type: 'existing',
|
||||
label: __('Esistente', 'gepafin'),
|
||||
command: (data) => {
|
||||
setStateFieldData([...stateFieldData, { id: null, value: '', status: data.item.type }]);
|
||||
setStateFieldData([...stateFieldData, { id: null, value: '', lookUpDataId: 0 }]);
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'new',
|
||||
label: __('Nuovo', 'gepafin'),
|
||||
command: (data) => {
|
||||
setStateFieldData([...stateFieldData, { id: null, value: '', status: data.item.type }]);
|
||||
setStateFieldData([...stateFieldData, { id: null, value: '', lookUpDataId: null }]);
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -45,14 +46,14 @@ const FormFieldRepeater = ({
|
||||
}
|
||||
|
||||
const selectItem = (e, index) => {
|
||||
const newData = stateFieldData.map((o, i) => {
|
||||
if (i === index) {
|
||||
o.value = e.value;
|
||||
o.id = e.id;
|
||||
}
|
||||
return o;
|
||||
})
|
||||
setStateFieldData(newData);
|
||||
const targetedOption = head(stateOptionsData.filter(o => o.value === e.value));
|
||||
|
||||
if (targetedOption) {
|
||||
const newData = stateFieldData.map((o, i) => {
|
||||
return i === index ? targetedOption : o;
|
||||
})
|
||||
setStateFieldData(newData);
|
||||
}
|
||||
}
|
||||
|
||||
const onInputChange = (e, index) => {
|
||||
@@ -67,24 +68,30 @@ const FormFieldRepeater = ({
|
||||
}
|
||||
|
||||
const properField = (item, i) => {
|
||||
return item.status === 'new'
|
||||
? <InputText value={item.value} onInput={(e) => onInputChange(e, i)}/>
|
||||
: <Dropdown value={item.value}
|
||||
return !isNil(item.lookUpDataId)
|
||||
? <Dropdown value={item.value}
|
||||
onChange={(e) => selectItem(e, i)}
|
||||
optionDisabled={(opt) => usedExistingValues.includes(opt.value)}
|
||||
options={options} optionLabel="value"/>
|
||||
optionDisabled={(opt) => usedExistingValues().includes(opt.value)}
|
||||
options={stateOptionsData}
|
||||
optionLabel="value"/>
|
||||
: <InputText value={item.value} onInput={(e) => onInputChange(e, i)}/>
|
||||
}
|
||||
|
||||
const usedExistingValues = stateFieldData
|
||||
.filter(o => o.status === 'existing')
|
||||
.map(o => o.value);
|
||||
const usedExistingValues = useCallback(() => {
|
||||
return stateFieldData
|
||||
.filter(o => o.lookUpDataId > 0)
|
||||
.map(o => o.value)
|
||||
}, [stateFieldData]);
|
||||
|
||||
useEffect(() => {
|
||||
const storeFieldData = data[fieldName] ?? [];
|
||||
const newData = storeFieldData.map(o => ({ ...o, status: o.id ? 'existing' : 'new' }));
|
||||
setStateFieldData(newData);
|
||||
setStateFieldData(storeFieldData);
|
||||
register(fieldName, config);
|
||||
}, [])
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
setStateOptionsData([...options]);
|
||||
}, [options]);
|
||||
|
||||
useEffect(() => {
|
||||
setDataFn(fieldName, [...stateFieldData], { shouldValidate: true });
|
||||
@@ -100,7 +107,7 @@ const FormFieldRepeater = ({
|
||||
{properField(o, i)}
|
||||
<Button icon="pi pi-times" className="p-button-danger" onClick={() => removeItem(i)}/>
|
||||
</div>
|
||||
{o.status === 'new' && infoText ? <small>{infoText}</small> : null}
|
||||
{isNil(o.lookUpDataId) && infoText ? <small>{infoText}</small> : null}
|
||||
</div>)}
|
||||
<Menu model={menuItems} popup ref={forMenu} id="aimedForMenu"/>
|
||||
<Button type="button" iconPos="right" label={__('Aggiungi', 'gepafin')}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React, { useRef, useEffect, useState } from 'react';
|
||||
import React, { useRef, useEffect, useState, useCallback } from 'react';
|
||||
import { classNames } from 'primereact/utils';
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import { head } from 'ramda';
|
||||
import { head, isNil, pluck } from 'ramda';
|
||||
|
||||
// components
|
||||
import { InputText } from 'primereact/inputtext';
|
||||
@@ -23,20 +23,21 @@ const FormFieldRepeaterCriteria = ({
|
||||
}) => {
|
||||
const forMenu = useRef(null);
|
||||
const [stateFieldData, setStateFieldData] = useState([]);
|
||||
const [stateOptionsData, setStateOptionsData] = useState([]);
|
||||
const [threshold, setThreshold] = useState(0);
|
||||
const menuItems = [
|
||||
{
|
||||
type: 'existing',
|
||||
label: __('Esistente', 'gepafin'),
|
||||
command: (data) => {
|
||||
setStateFieldData([...stateFieldData, { id: null, value: '', status: data.item.type }]);
|
||||
setStateFieldData([...stateFieldData, { id: null, value: '', lookUpDataId: 0 }]);
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'new',
|
||||
label: __('Nuovo', 'gepafin'),
|
||||
command: (data) => {
|
||||
setStateFieldData([...stateFieldData, { id: null, value: '', status: data.item.type }]);
|
||||
setStateFieldData([...stateFieldData, { id: null, value: '', lookUpDataId: null }]);
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -47,17 +48,12 @@ const FormFieldRepeaterCriteria = ({
|
||||
}
|
||||
|
||||
const selectItem = (e, index) => {
|
||||
const targetedOption = head(options.filter(o => o.value === e.value));
|
||||
const targetedOption = head(stateOptionsData.filter(o => o.value === e.value));
|
||||
|
||||
if (targetedOption) {
|
||||
const newData = stateFieldData.map((o, i) => {
|
||||
if (i === index) {
|
||||
o.value = targetedOption.value;
|
||||
o.score = targetedOption.score;
|
||||
o.id = targetedOption.id;
|
||||
}
|
||||
return o;
|
||||
});
|
||||
console.log('newData', newData)
|
||||
return i === index ? targetedOption : o;
|
||||
})
|
||||
setStateFieldData(newData);
|
||||
}
|
||||
}
|
||||
@@ -78,32 +74,38 @@ const FormFieldRepeaterCriteria = ({
|
||||
}
|
||||
|
||||
const properField = (item, i) => {
|
||||
return item.status === 'new'
|
||||
? <InputText value={item.value} onInput={(e) => onInputChange(e.target.value, i, 'value')}/>
|
||||
: <Dropdown value={item.value}
|
||||
return !isNil(item.lookUpDataId)
|
||||
? <Dropdown value={item.value}
|
||||
onChange={(e) => selectItem(e, i)}
|
||||
optionDisabled={(opt) => usedExistingValues.includes(opt.value)}
|
||||
options={options} optionLabel="value"/>
|
||||
optionDisabled={(opt) => usedExistingValues().includes(opt.value)}
|
||||
options={stateOptionsData} optionLabel="value"/>
|
||||
: <InputText value={item.value} onInput={(e) => onInputChange(e.target.value, i, 'value')}/>
|
||||
}
|
||||
|
||||
const usedExistingValues = stateFieldData
|
||||
.filter(o => o.status === 'existing')
|
||||
.map(o => o.value);
|
||||
const usedExistingValues = useCallback(() => {
|
||||
return stateFieldData
|
||||
.filter(o => o.lookUpDataId > 0)
|
||||
.map(o => o.value)
|
||||
}, [stateFieldData]);
|
||||
|
||||
useEffect(() => {
|
||||
const storeFieldData = data[fieldName] ?? [];
|
||||
const newData = storeFieldData.map(o => ({ ...o, status: o.id ? 'existing' : 'new' }));
|
||||
setStateFieldData(newData);
|
||||
setStateFieldData(storeFieldData);
|
||||
setStateOptionsData([...options, ...storeFieldData]);
|
||||
setThreshold(data['threshold'])
|
||||
register(fieldName, config)
|
||||
register('threshold', {
|
||||
required: __('È obbligatorio', 'gepafin')
|
||||
})
|
||||
}, [])
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
setStateOptionsData([...options]);
|
||||
}, [options]);
|
||||
|
||||
useEffect(() => {
|
||||
setDataFn(fieldName, [...stateFieldData], { shouldValidate: true });
|
||||
}, [stateFieldData])
|
||||
}, [stateFieldData]);
|
||||
|
||||
return (
|
||||
<div className={classNames(['appForm__field', 'formfieldrepeater'])}>
|
||||
@@ -126,7 +128,7 @@ const FormFieldRepeaterCriteria = ({
|
||||
{properField(o, i)}
|
||||
<Button icon="pi pi-times" className="p-button-danger" onClick={() => removeItem(i)}/>
|
||||
</div>
|
||||
{o.status === 'new' && infoText ? <small>{infoText}</small> : null}
|
||||
{isNil(o.lookUpDataId) && infoText ? <small>{infoText}</small> : null}
|
||||
</div>
|
||||
<div>
|
||||
<label htmlFor="criterionMin">{__('Punteggio', 'gepafin')}</label>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import React, { useEffect, useState, useCallback } from 'react';
|
||||
import { classNames } from 'primereact/utils';
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import { isEmpty } from 'ramda';
|
||||
import { head } from 'ramda';
|
||||
|
||||
// components
|
||||
import { Button } from 'primereact/button';
|
||||
@@ -20,11 +20,10 @@ const FormFieldRepeaterFaq = ({
|
||||
errors,
|
||||
register,
|
||||
label,
|
||||
config = {},
|
||||
setError,
|
||||
clearErrors
|
||||
config = {}
|
||||
}) => {
|
||||
const [stateFieldData, setStateFieldData] = useState([]);
|
||||
const [stateOptionsData, setStateOptionsData] = useState([]);
|
||||
const [question, setQuestion] = useState('');
|
||||
const [answer, setAnswer] = useState('');
|
||||
const [editDataIndex, setEditDataIndex] = useState(null);
|
||||
@@ -36,12 +35,15 @@ const FormFieldRepeaterFaq = ({
|
||||
}
|
||||
|
||||
const selectItem = (e) => {
|
||||
const chosen = {...e.value};
|
||||
setStateFieldData([...stateFieldData, chosen]);
|
||||
const targetedOption = head(stateOptionsData.filter(o => o.question === e.value));
|
||||
|
||||
if (targetedOption) {
|
||||
setStateFieldData([...stateFieldData, targetedOption]);
|
||||
}
|
||||
}
|
||||
|
||||
const addNewItem = () => {
|
||||
const newItem = { id: 0, status: 'new', question: '', answer: '', visible: true };
|
||||
const newItem = { id: null, lookUpDataId: null, question: '', response: '', visible: true };
|
||||
setStateFieldData([...stateFieldData, newItem]);
|
||||
}
|
||||
|
||||
@@ -49,7 +51,7 @@ const FormFieldRepeaterFaq = ({
|
||||
e.preventDefault();
|
||||
const newData = stateFieldData.map((o, i) => {
|
||||
if (i === index) {
|
||||
o.visible = e.value;
|
||||
o.isVisible = e.value;
|
||||
}
|
||||
return o;
|
||||
});
|
||||
@@ -59,7 +61,7 @@ const FormFieldRepeaterFaq = ({
|
||||
const editItem = (e, index) => {
|
||||
e.stopPropagation();
|
||||
setQuestion(stateFieldData[index].question);
|
||||
setAnswer(stateFieldData[index].answer);
|
||||
setAnswer(stateFieldData[index].response);
|
||||
setEditDataIndex(index);
|
||||
setIsVisibleEditDialog(true);
|
||||
}
|
||||
@@ -83,7 +85,7 @@ const FormFieldRepeaterFaq = ({
|
||||
const newData = stateFieldData.map((o, i) => {
|
||||
if (i === editDataIndex) {
|
||||
o.question = question;
|
||||
o.answer = answer;
|
||||
o.response = answer;
|
||||
return o
|
||||
} else {
|
||||
return o;
|
||||
@@ -102,25 +104,31 @@ const FormFieldRepeaterFaq = ({
|
||||
|
||||
const footerEditDialog = () => {
|
||||
return <div>
|
||||
<Button type="button" label={__('Anulla', 'gepafin')} onClick={hideEditDialog} outlined />
|
||||
<Button type="button" label={__('Salva', 'gepafin')} onClick={saveEditDialog} />
|
||||
<Button type="button" label={__('Anulla', 'gepafin')} onClick={hideEditDialog} outlined/>
|
||||
<Button type="button" label={__('Salva', 'gepafin')} onClick={saveEditDialog}/>
|
||||
</div>
|
||||
}
|
||||
|
||||
const usedExistingValues = stateFieldData
|
||||
.filter(o => o.status === 'existing')
|
||||
.map(o => o.question);
|
||||
const usedExistingValues = useCallback(() => {
|
||||
return stateFieldData
|
||||
.filter(o => o.lookUpDataId)
|
||||
.map(o => o.question)
|
||||
}, [stateFieldData]);
|
||||
|
||||
useEffect(() => {
|
||||
const storeFieldData = data[fieldName] ?? [];
|
||||
const newData = storeFieldData.map(o => ({ ...o, status: o.id ? 'existing' : 'new' }))
|
||||
setStateFieldData(newData);
|
||||
setStateFieldData(storeFieldData);
|
||||
setStateOptionsData([...options, ...storeFieldData]);
|
||||
register(fieldName, config)
|
||||
}, [])
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
setStateOptionsData([...options]);
|
||||
}, [options]);
|
||||
|
||||
useEffect(() => {
|
||||
setDataFn(fieldName, [...stateFieldData], { shouldValidate: true });
|
||||
}, [stateFieldData])
|
||||
}, [stateFieldData]);
|
||||
|
||||
return (
|
||||
<div className={classNames(['appForm__field', 'formfieldrepeater'])}>
|
||||
@@ -131,8 +139,9 @@ const FormFieldRepeaterFaq = ({
|
||||
<Button type="button" iconPos="left" label={__('Aggiungi', 'gepafin')}
|
||||
icon="pi pi-plus" onClick={addNewItem}/>
|
||||
<Dropdown onChange={(e) => selectItem(e)}
|
||||
optionDisabled={(opt) => usedExistingValues.includes(opt.value)}
|
||||
options={options} optionLabel="question"/>
|
||||
optionDisabled={(opt) => usedExistingValues().includes(opt.value)}
|
||||
options={stateOptionsData}
|
||||
optionLabel="question"/>
|
||||
</div>
|
||||
<Accordion activeIndex={0}>
|
||||
{stateFieldData.map((o, i) => <AccordionTab key={i}
|
||||
@@ -144,7 +153,7 @@ const FormFieldRepeaterFaq = ({
|
||||
offIcon="pi pi-eye-slash"
|
||||
onLabel=""
|
||||
offLabel=""
|
||||
checked={o.visible}
|
||||
checked={o.isVisible}
|
||||
onChange={(e) => setChecked(e, i)}/>
|
||||
{o.question}
|
||||
</div>
|
||||
@@ -160,7 +169,7 @@ const FormFieldRepeaterFaq = ({
|
||||
}
|
||||
>
|
||||
<p className="m-0">
|
||||
{o.answer}
|
||||
{o.response}
|
||||
</p>
|
||||
</AccordionTab>)}
|
||||
</Accordion>
|
||||
@@ -170,14 +179,18 @@ const FormFieldRepeaterFaq = ({
|
||||
footer={footerEditDialog}
|
||||
style={{ maxWidth: '50rem' }}
|
||||
onHide={hideEditDialog}>
|
||||
<div className="appPage__spacer"></div>
|
||||
<div className="appForm__field">
|
||||
<label>{__('Titolo FAQ', 'gepafin')}</label>
|
||||
<InputText value={question} onChange={(e) => onChangeEditItem(e.target.value, 'question')}/>
|
||||
</div>
|
||||
<div className="appForm__field">
|
||||
<label>{__('Risposta', 'gepafin')}</label>
|
||||
<InputTextarea value={answer} onChange={(e) => onChangeEditItem(e.target.value, 'answer')} rows={5} cols={30} />
|
||||
<InputTextarea value={answer} onChange={(e) => onChangeEditItem(e.target.value, 'response')}
|
||||
rows={5}
|
||||
cols={30}/>
|
||||
</div>
|
||||
<div className="appPage__spacer"></div>
|
||||
</Dialog>
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -2,13 +2,14 @@ import React, { useRef } from 'react';
|
||||
import { __ } from '@wordpress/i18n';
|
||||
|
||||
// store
|
||||
import { storeSet } from '../../store';
|
||||
import { storeSet, useTrackedStore } from '../../store';
|
||||
|
||||
// components
|
||||
import { Menu } from 'primereact/menu';
|
||||
import { Avatar } from 'primereact/avatar';
|
||||
|
||||
const TopBarProfileMenu = ({ menuLeftRef }) => {
|
||||
const userData = useTrackedStore().main.userData();
|
||||
|
||||
let items = [
|
||||
{
|
||||
@@ -17,8 +18,8 @@ const TopBarProfileMenu = ({ menuLeftRef }) => {
|
||||
<div className="topBar__menuProfileItem">
|
||||
<Avatar image="https://primefaces.org/cdn/primereact/images/avatar/amyelsner.png" shape="circle" />
|
||||
<div className="userInfo">
|
||||
<span className="userName">Mario Rossi</span>
|
||||
<span className="userEmail">mario.rossi@example.com</span>
|
||||
<span className="userName">{`${userData.firstName} ${userData.lastName}`}</span>
|
||||
<span className="userEmail">{userData.email}</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -5,7 +5,7 @@ import equal from 'fast-deep-equal';
|
||||
// tools
|
||||
|
||||
const UnsavedChangesDetector = ({ initialData, getValuesFn }) => {
|
||||
const [initial] = useState(initialData);
|
||||
const [initial, setInitial] = useState(initialData);
|
||||
|
||||
const warnIfUnsavedChanges = useCallback((event) => {
|
||||
const updatedData = getValuesFn();
|
||||
@@ -16,7 +16,11 @@ const UnsavedChangesDetector = ({ initialData, getValuesFn }) => {
|
||||
}
|
||||
|
||||
return event.returnValue;
|
||||
}, [initial])
|
||||
}, [initialData]);
|
||||
|
||||
useEffect(() => {
|
||||
setInitial(initialData);
|
||||
}, [initialData])
|
||||
|
||||
useEffect(() => {
|
||||
window.addEventListener('beforeunload', (e) => {
|
||||
|
||||
Reference in New Issue
Block a user