Skip to content

Commit

Permalink
Fix cancel button does not revert the form values
Browse files Browse the repository at this point in the history
  • Loading branch information
Rochmar Nicolas (DevExpress) committed Apr 8, 2024
1 parent a150cc5 commit 17e9e22
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
<ng-container *ngIf="!isLoading">
<dx-toolbar class="panel-toolbar">
<dxi-item location="before">
<span class="contact-name value">{{ user.name }}</span>
<span class="contact-name value">{{ formData.name }}</span>
</dxi-item>
<dxi-item location="before">
<contact-status [value]="user.status"></contact-status>
<contact-status [value]="formData.status"></contact-status>
</dxi-item>
<dxi-item location="after" [visible]="isPinEnabled">
<dx-button
Expand Down Expand Up @@ -35,7 +35,7 @@
<dxo-col-count-by-screen [xs]="2"></dxo-col-count-by-screen>
<dxi-item cssClass="photo-box">
<div *dxTemplate>
<form-photo [link]="user.image"></form-photo>
<form-photo [link]="formData.image"></form-photo>
</div>
</dxi-item>

Expand All @@ -44,7 +44,7 @@
<div *dxTemplate>
<form-textbox
label="Company"
[(value)]="user.company"
[(value)]="formData.company"
[isEditing]="isEditing"
></form-textbox>
</div>
Expand All @@ -54,7 +54,7 @@
<div *dxTemplate>
<form-textbox
label="Position"
[(value)]="user.position"
[(value)]="formData.position"
[isEditing]="isEditing"
></form-textbox>
</div>
Expand All @@ -64,7 +64,7 @@
<div *dxTemplate>
<form-textbox
label="Assigned to"
[(value)]="user.manager"
[(value)]="formData.manager"
[isEditing]="isEditing"
></form-textbox>
</div>
Expand All @@ -78,7 +78,7 @@
<form-textbox
icon="tel"
mask="+1(000)000-0000"
[(value)]="user.phone"
[(value)]="formData.phone"
[isEditing]="isEditing"
>
</form-textbox>
Expand All @@ -88,7 +88,7 @@
<div *dxTemplate>
<form-textbox
icon="email"
[(value)]="user.email"
[(value)]="formData.email"
[isEditing]="isEditing"
[validators]="[{ type: 'email' }]"
></form-textbox>
Expand All @@ -98,7 +98,7 @@
<div *dxTemplate>
<form-textbox
icon="home"
[(value)]="user.address"
[(value)]="formData.address"
[isEditing]="isEditing"
[validators]="[]"
>
Expand Down Expand Up @@ -153,7 +153,7 @@
text="Cancel"
stylingMode="outlined"
type="normal"
(onClick)="toggleEdit()"
(onClick)="cancelHandler()"
></dx-button>
</dxi-item>
<dxi-item
Expand Down Expand Up @@ -181,7 +181,7 @@
<div *dxTemplate="let i of 'item'">
<div
class="opportunities"
*ngFor="let opportunity of user.opportunities"
*ngFor="let opportunity of formData.opportunities"
>
<span class="value">{{ opportunity.name }} </span>
<br />
Expand All @@ -194,7 +194,7 @@
</dxi-item>

<dxi-item title="Activities">
<card-activities [activities]="user.activities"></card-activities>
<card-activities [activities]="formData.activities"></card-activities>
</dxi-item>
</dx-accordion>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,9 @@ export class ContactPanelComponent implements OnInit, OnChanges, AfterViewChecke

private pinEventSubject = new Subject<boolean>();

user: Contact;
formData: Contact;

contactData: Contact;

pinned = false;

Expand Down Expand Up @@ -97,7 +99,8 @@ export class ContactPanelComponent implements OnInit, OnChanges, AfterViewChecke
this.isLoading = true;

this.service.getContact(id).subscribe((data) => {
this.user = data;
this.formData = data;
this.contactData = { ...this.formData };
this.isLoading = false;
this.isEditing = false;
})
Expand All @@ -115,6 +118,7 @@ export class ContactPanelComponent implements OnInit, OnChanges, AfterViewChecke

onSaveClick = ({ validationGroup } : DxButtonTypes.ClickEvent) => {
if (!validationGroup.validate().isValid) return;
this.contactData = { ...this.formData };
this.isEditing = !this.isEditing;
}

Expand All @@ -129,6 +133,11 @@ export class ContactPanelComponent implements OnInit, OnChanges, AfterViewChecke
this.isEditing = !this.isEditing;
};

cancelHandler() {
this.toggleEdit();
this.formData = { ...this.contactData };
}

navigateToDetails = () => {
this.router.navigate(['/crm-contact-details']);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,12 @@ const ContactPanelWithLoadPanel = withLoadPanel(ContactPanelDetails);
export const ContactPanel = ({ contactId, isOpened, changePanelOpened, changePanelPinned } : { contactId: number | null, isOpened: boolean, changePanelOpened:(value: boolean)=> void, changePanelPinned: () => void }) => {

const [data, setData] = useState<Contact>();
const [defaultData, setDefaultData] = useState<Contact | null>(null);

const loadData = useCallback(() => {
if (!contactId) return;

getContact(contactId)
.then((data) => {
setDefaultData(data);
setData(data);
})
.catch((error) => console.log(error));
Expand All @@ -37,7 +35,7 @@ export const ContactPanel = ({ contactId, isOpened, changePanelOpened, changePan

return (
<ContactPanelWithLoadPanel
defaultContact={defaultData}
key={data?.id}
contact={data}
hasData={!!data}
isOpened={isOpened}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,19 @@ const formatPrice = (price) => {
});
};

export const ContactPanelDetails = ({ defaultContact, contact, isOpened, changePanelOpened, onDataChanged, changePanelPinned } : { defaultContact: Contact | null, contact: Contact, isOpened: boolean, changePanelOpened:(value: boolean)=> void, onDataChanged:(data)=> void, changePanelPinned:() => void }) => {
export const ContactPanelDetails = ({ contact, isOpened, changePanelOpened, onDataChanged, changePanelPinned } : { contact: Contact, isOpened: boolean, changePanelOpened:(value: boolean)=> void, onDataChanged:(data)=> void, changePanelPinned:() => void }) => {
const [isPinned, setIsPinned] = useState(false);
const [isEditing, setIsEditing] = useState(false);
const { isLarge, isMedium } = useScreenSize();

const navigate = useNavigate();
const [formData, setFormData] = useState(contact);

const updateField = (field: string) => (value) => {
onDataChanged({ ...contact, ...{ [field]: value } });
setFormData({
...formData,
[field]: value
});
};

useEffect(() => {
Expand All @@ -54,14 +58,19 @@ export const ContactPanelDetails = ({ defaultContact, contact, isOpened, changeP
}, []);

const toggleEditHandler = useCallback(() => {
if (isEditing) onDataChanged(defaultContact);
setIsEditing(!isEditing);
}, [isEditing]);

const cancelHandler = useCallback(() => {
toggleEditHandler();
setFormData(contact);
}, [contact, toggleEditHandler]);

const onSaveClick = useCallback(({ validationGroup } : ButtonTypes.ClickEvent) => {
if(!validationGroup.validate().isValid) return;
onDataChanged(formData);
setIsEditing(!isEditing);
}, [isEditing]);
}, [formData, isEditing]);

const navigateToDetails = useCallback(() => {
navigate('/crm-contact-details');
Expand Down Expand Up @@ -127,23 +136,23 @@ export const ContactPanelDetails = ({ defaultContact, contact, isOpened, changeP
<FormItem cssClass='accent'>
<FormTextbox
label='Company'
value={contact.company}
value={formData.company}
isEditing={!isEditing}
onValueChange={updateField('company')}
/>
</FormItem>
<FormItem>
<FormTextbox
label='Position'
value={contact.position}
value={formData.position}
isEditing={!isEditing}
onValueChange={updateField('position')}
/>
</FormItem>
<FormItem cssClass='accent'>
<FormTextbox
label='Assigned to'
value={contact.manager}
value={formData.manager}
isEditing={!isEditing}
onValueChange={updateField('manager')}
/>
Expand All @@ -154,7 +163,7 @@ export const ContactPanelDetails = ({ defaultContact, contact, isOpened, changeP
<GroupItem cssClass='contact-fields-group'>
<FormItem>
<FormTextbox
value={contact.phone}
value={formData.phone}
isEditing={!isEditing}
onValueChange={updateField('phone')}
icon='tel'
Expand All @@ -163,15 +172,15 @@ export const ContactPanelDetails = ({ defaultContact, contact, isOpened, changeP
</FormItem>
<FormItem>
<FormTextbox
value={contact.email}
value={formData.email}
isEditing={!isEditing}
onValueChange={updateField('email')}
icon='email'
/>
</FormItem>
<FormItem>
<FormTextbox
value={contact.address}
value={formData.address}
isEditing={!isEditing}
onValueChange={updateField('address')}
icon='home'
Expand All @@ -193,7 +202,7 @@ export const ContactPanelDetails = ({ defaultContact, contact, isOpened, changeP
<Button text='Save' icon='save' stylingMode='contained' type='default' onClick={onSaveClick} />
</ToolbarItem>
<ToolbarItem location='after' visible={isEditing}>
<Button text='Cancel' stylingMode='outlined' type='normal' onClick={toggleEditHandler} />
<Button text='Cancel' stylingMode='outlined' type='normal' onClick={cancelHandler} />
</ToolbarItem>
<ToolbarItem location='before'
widget='dxDropDownButton'
Expand Down
11 changes: 8 additions & 3 deletions packages/testing/tests/crm-contact-list.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,16 @@ fixture`Contact List`;
await t.click(Selector('.dx-icon-pin'));
}

const inputs = Selector('.panel-scroll .form-editor-input');

await t.click(Selector('.dx-button[aria-label=Edit]'));
await takeScreenshot(`crm-contact-list-form-edit${postfix}`, Selector('.data-wrapper'));
await t.typeText(inputs.nth(1), 'unwanted text');
await t.click(Selector('.dx-button[aria-label=Cancel]'));
await t.expect(inputs.nth(1).value).notContains('unwanted text');

const input = Selector('.panel-scroll .form-editor-input').nth(0);
await t.typeText(input, 'test 0');
await t.click(Selector('.dx-button[aria-label=Edit]'));
await takeScreenshot(`crm-contact-list-form-edit${postfix}`, Selector('.data-wrapper'));
await t.typeText(inputs.nth(0), 'test 0');

await t.click(Selector('.dx-button[aria-label=Save]'));
await takeScreenshot(`crm-contact-list-form-saved${postfix}`, Selector('.data-wrapper'));
Expand Down
23 changes: 19 additions & 4 deletions packages/vue/src/components/library/contact-panel.vue
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@
>
<dx-button
text="Cancel"
@click="toggleEdit()"
@click="cancelHandler()"
styling-mode="outlined"
type="normal"
/>
Expand Down Expand Up @@ -246,13 +246,24 @@ const props = withDefaults(defineProps<{
contactId: number | null
}>(), { isPanelOpened: false, contactId: null });
const toggleEdit = () => {
let contactData: Contact | null = null;
const toggleEdit = async () => {
isEditing.value = !isEditing.value;
};
const cancelHandler = () => {
toggleEdit();
panelData.value = structuredClone(contactData);
};
const emit = defineEmits(['close', 'pinChanged']);
const underContactFields = [
const underContactFields: {
name: 'phone' | 'email' | 'address'
icon: string
mask?: string
}[] = [
{
name: 'phone',
mask: '+1(000)000-0000',
Expand All @@ -278,13 +289,17 @@ watch(
);
const loadContact = async (contactId: number) => {
isEditing.value = false;
isLoading.value = true;
panelData.value = await getContact(contactId);
const contactPanelData = await getContact(contactId);
panelData.value = contactPanelData;
contactData = structuredClone(contactPanelData);
isLoading.value = false;
};
function handleSaveClick({ validationGroup }: DxButtonTypes.ClickEvent) {
if (validationGroup.validate().isValid) {
contactData = structuredClone(panelData.value);
isEditing.value = false;
}
}
Expand Down

0 comments on commit 17e9e22

Please sign in to comment.