Improved Contacts window

This commit is contained in:
the-djmaze 2022-09-07 13:45:30 +02:00
parent 56d64b325c
commit 0c90875b61

View file

@ -24,13 +24,14 @@ const
CONTACTS_PER_PAGE = 50, CONTACTS_PER_PAGE = 50,
ScopeContacts = 'Contacts'; ScopeContacts = 'Contacts';
let
bOpenCompose = false,
sComposeRecipientsField = '';
export class ContactsPopupView extends AbstractViewPopup { export class ContactsPopupView extends AbstractViewPopup {
constructor() { constructor() {
super('Contacts'); super('Contacts');
this.bBackToCompose = false;
this.sLastComposeFocusedField = '';
this.addObservables({ this.addObservables({
search: '', search: '',
contactsCount: 0, contactsCount: 0,
@ -63,28 +64,22 @@ export class ContactsPopupView extends AbstractViewPopup {
this.selector.on('ItemGetUid', contact => contact ? contact.generateUid() : ''); this.selector.on('ItemGetUid', contact => contact ? contact.generateUid() : '');
this.bDropPageAfterDelete = false;
const
pagecount = () => Math.max(1, Math.ceil(this.contactsCount() / CONTACTS_PER_PAGE));
this.addComputables({ this.addComputables({
contactsPageCount: pagecount, contactsPaginator: computedPaginatorHelper(
this.contactsPage,
contactsPaginator: computedPaginatorHelper(this.contactsPage, pagecount), () => Math.max(1, Math.ceil(this.contactsCount() / CONTACTS_PER_PAGE))
),
contactsCheckedOrSelected: () => { contactsCheckedOrSelected: () => {
const checked = ContactUserStore.filter(item => item.checked?.()), const checked = ContactUserStore.filter(item => item.checked?.()),
selected = this.selectorContact(); selected = this.selectorContact();
return checked.length ? checked : (selected ? [selected] : []);
return selected
? [...checked, selected].unique()
: checked;
}, },
contactsCheckedOrSelectedUids: () => this.contactsCheckedOrSelected().map(contact => contact.id()), contactsSyncEnabled: () => ContactUserStore.allowSync() && ContactUserStore.syncMode(),
contactsSyncEnabled: () => ContactUserStore.allowSync() && ContactUserStore.syncMode() isBusy: () => ContactUserStore.syncing() | ContactUserStore.importing() | ContactUserStore.loading()
| this.isSaving()
}); });
this.search.subscribe(() => this.reloadContactList()); this.search.subscribe(() => this.reloadContactList());
@ -92,71 +87,67 @@ export class ContactsPopupView extends AbstractViewPopup {
this.saveCommand = this.saveCommand.bind(this); this.saveCommand = this.saveCommand.bind(this);
decorateKoCommands(this, { decorateKoCommands(this, {
deleteCommand: self => 0 < self.contactsCheckedOrSelected().length, deleteCommand: self => !self.isBusy() && 0 < self.contactsCheckedOrSelected().length,
newMessageCommand: self => 0 < self.contactsCheckedOrSelected().length, newMessageCommand: self => !self.isBusy() && 0 < self.contactsCheckedOrSelected().length,
saveCommand: self => !self.isSaving(), saveCommand: self => !self.isBusy(),
syncCommand: self => !self.contacts.syncing() && !self.contacts.importing() syncCommand: self => !self.isBusy()
}); });
} }
newContact() { newContact() {
this.populateViewContact(); this.populateViewContact(new ContactModel);
this.selectorContact(null); this.selectorContact(null);
} }
deleteCommand() { deleteCommand() {
this.deleteSelectedContacts(); const contacts = this.contactsCheckedOrSelected();
if (contacts.length) {
let selectorContact = this.selectorContact(),
Uids = [],
count = 0;
contacts.forEach(contact => {
Uids.push(contact.id());
if (selectorContact && selectorContact.id() === contact.id()) {
this.selectorContact(selectorContact = null);
}
contact.deleted(true);
++count;
});
Remote.request('ContactsDelete',
(iError, oData) => {
if (iError) {
alert(oData?.ErrorMessage || getNotification(iError));
} else {
const page = this.contactsPage();
if (page > Math.max(1, Math.ceil((this.contactsCount() - count) / CONTACTS_PER_PAGE))) {
this.contactsPage(page - 1);
}
// contacts.forEach(contact => ContactUserStore.remove(contact));
}
this.reloadContactList();
}, {
Uids: Uids.join(',')
}
);
}
} }
newMessageCommand() { newMessageCommand() {
let aE = [], let aE = [],
toEmails = null, recipients = {to:null,cc:null,bcc:null};
ccEmails = null,
bccEmails = null;
const aC = this.contactsCheckedOrSelected(); this.contactsCheckedOrSelected().forEach(oContact => {
if (arrayLength(aC)) { const data = oContact?.getNameAndEmailHelper(),
aE = aC.map(oItem => {
if (oItem) {
const data = oItem.getNameAndEmailHelper(),
email = data ? new EmailModel(data[0], data[1]) : null; email = data ? new EmailModel(data[0], data[1]) : null;
email?.validate() && aE.push(email);
if (email?.validate()) {
return email;
}
}
return null;
}); });
aE = aE.filter(value => !!value);
}
if (arrayLength(aE)) { if (arrayLength(aE)) {
this.bBackToCompose = false; bOpenCompose = false;
this.close(); this.close();
recipients[sComposeRecipientsField] = aE;
switch (this.sLastComposeFocusedField) { showMessageComposer([ComposeType.Empty, null, recipients.to, recipients.cc, recipients.bcc])
case 'cc':
ccEmails = aE;
break;
case 'bcc':
bccEmails = aE;
break;
default:
toEmails = aE;
break;
} }
this.sLastComposeFocusedField = '';
setTimeout(() =>
showMessageComposer([ComposeType.Empty, null, toEmails, ccEmails, bccEmails])
, 200);
}
return true;
} }
clearSearch() { clearSearch() {
@ -173,7 +164,6 @@ export class ContactsPopupView extends AbstractViewPopup {
this.isSaving(true); this.isSaving(true);
Remote.request('ContactSave', Remote.request('ContactSave',
(iError, oData) => { (iError, oData) => {
this.isSaving(false);
if (iError) { if (iError) {
alert(oData?.ErrorMessage || getNotification(iError)); alert(oData?.ErrorMessage || getNotification(iError));
} else if (oData.Result.ResultID) { } else if (oData.Result.ResultID) {
@ -184,6 +174,7 @@ export class ContactsPopupView extends AbstractViewPopup {
this.reloadContactList(); // TODO: remove when e-contact-foreach is dynamic this.reloadContactList(); // TODO: remove when e-contact-foreach is dynamic
} }
} }
this.isSaving(false);
}, data }, data
); );
} }
@ -204,50 +195,6 @@ export class ContactsPopupView extends AbstractViewPopup {
download(serverRequestRaw('ContactsCsv'), 'contacts.csv'); download(serverRequestRaw('ContactsCsv'), 'contacts.csv');
} }
removeCheckedOrSelectedContactsFromList() {
const contacts = this.contactsCheckedOrSelected();
let selectorContact = this.selectorContact(),
count = ContactUserStore.length;
if (contacts.length) {
contacts.forEach(contact => {
if (selectorContact && selectorContact.id() === contact.id()) {
selectorContact = null;
this.selectorContact(null);
}
contact.deleted(true);
--count;
});
if (0 >= count) {
this.bDropPageAfterDelete = true;
}
setTimeout(() => {
contacts.forEach(contact => ContactUserStore.remove(contact));
}, 500);
}
}
deleteSelectedContacts() {
if (this.contactsCheckedOrSelected().length) {
Remote.request('ContactsDelete',
(iError, oData) => {
if (500 < (!iError && oData?.Time) ? pInt(oData.Time) : 0) {
this.reloadContactList(this.bDropPageAfterDelete);
} else {
setTimeout(() => this.reloadContactList(this.bDropPageAfterDelete), 500);
}
}, {
Uids: this.contactsCheckedOrSelectedUids().join(',')
}
);
this.removeCheckedOrSelectedContactsFromList();
}
}
/** /**
* @param {?ContactModel} contact * @param {?ContactModel} contact
*/ */
@ -259,7 +206,7 @@ export class ContactsPopupView extends AbstractViewPopup {
() => this.saveContact(oldContact) () => this.saveContact(oldContact)
]); ]);
} }
this.contact(contact || new ContactModel); this.contact(contact);
} }
/** /**
@ -268,8 +215,6 @@ export class ContactsPopupView extends AbstractViewPopup {
reloadContactList(dropPagePosition = false) { reloadContactList(dropPagePosition = false) {
let offset = (this.contactsPage() - 1) * CONTACTS_PER_PAGE; let offset = (this.contactsPage() - 1) * CONTACTS_PER_PAGE;
this.bDropPageAfterDelete = false;
if (dropPagePosition) { if (dropPagePosition) {
this.contactsPage(1); this.contactsPage(1);
offset = 0; offset = 0;
@ -289,12 +234,10 @@ export class ContactsPopupView extends AbstractViewPopup {
item = ContactModel.reviveFromJson(item); item = ContactModel.reviveFromJson(item);
item && list.push(item); item && list.push(item);
}); });
count = pInt(data.Result.Count); count = pInt(data.Result.Count);
count = 0 < count ? count : 0;
} }
this.contactsCount(count); this.contactsCount(0 < count ? count : 0);
ContactUserStore(list); ContactUserStore(list);
@ -325,8 +268,8 @@ export class ContactsPopupView extends AbstractViewPopup {
dom.addEventListener('click', event => { dom.addEventListener('click', event => {
let el = event.target.closestWithin('.e-paginator a', dom); let el = event.target.closestWithin('.e-paginator a', dom);
if (el && ko.dataFor(el)) { if (el && (el = pInt(ko.dataFor(el)?.value))) {
self.contactsPage(pInt(ko.dataFor(el).value)); self.contactsPage(el);
self.reloadContactList(); self.reloadContactList();
} }
}); });
@ -371,9 +314,9 @@ export class ContactsPopupView extends AbstractViewPopup {
} }
} }
onShow(bBackToCompose, sLastComposeFocusedField) { onShow(bBackToCompose, sRecipientsField) {
this.bBackToCompose = !!bBackToCompose; bOpenCompose = !!bBackToCompose;
this.sLastComposeFocusedField = sLastComposeFocusedField; sComposeRecipientsField = ['to','cc','bcc'].includes(sRecipientsField) ? sRecipientsField : 'to';
this.reloadContactList(true); this.reloadContactList(true);
} }
@ -385,10 +328,6 @@ export class ContactsPopupView extends AbstractViewPopup {
ContactUserStore([]); ContactUserStore([]);
this.sLastComposeFocusedField = ''; bOpenCompose && showMessageComposer();
if (this.bBackToCompose) {
this.bBackToCompose = false;
showMessageComposer();
}
} }
} }