From 6ab60f24efc29fa2a66bea06344216923f796bc0 Mon Sep 17 00:00:00 2001 From: Ramzan Date: Thu, 29 Oct 2020 18:25:54 -0400 Subject: [PATCH] Create GroupEdit --- src/App.tsx | 5 +- src/Contacts/ContactEdit.tsx | 439 +++++++++++++++++------------------ src/Contacts/GroupEdit.tsx | 288 +++++++++++++++++++++++ src/Contacts/Main.tsx | 51 ++-- 4 files changed, 541 insertions(+), 242 deletions(-) create mode 100644 src/Contacts/GroupEdit.tsx diff --git a/src/App.tsx b/src/App.tsx index cdd8cb5..6d63893 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -41,7 +41,10 @@ export const routeResolver = new RouteResolver({ contacts: { _id: { _base: ":itemUid", - edit: "edit", + edit: { + contact: "contact", + group: "group", + }, log: "log", }, new: { diff --git a/src/Contacts/ContactEdit.tsx b/src/Contacts/ContactEdit.tsx index 91b32a1..c307ed1 100644 --- a/src/Contacts/ContactEdit.tsx +++ b/src/Contacts/ContactEdit.tsx @@ -121,12 +121,11 @@ interface PropsType { collections: CachedCollection[]; initialCollection?: string; item?: ContactType; - newGroup?: boolean; onSave: (contact: ContactType, collectionUid: string, originalContact?: ContactType) => Promise; onDelete: (contact: ContactType, collectionUid: string) => void; onCancel: () => void; history: History; - groups: ContactType[]; + allGroups: ContactType[]; } class ContactEdit extends React.PureComponent { @@ -145,13 +144,12 @@ class ContactEdit extends React.PureComponent { org: string; note: string; title: string; - group: boolean; collectionUid: string; showDeleteDialog: boolean; - collectionGroups: ContactType[]; - newGroups: (string | ContactType)[]; - originalGroups: ContactType[]; + collectionGroups: {}; + newGroups: string[]; + originalGroups: string[]; }; constructor(props: PropsType) { @@ -171,11 +169,10 @@ class ContactEdit extends React.PureComponent { org: "", note: "", title: "", - group: false, collectionUid: "", showDeleteDialog: false, - collectionGroups: [], + collectionGroups: {}, newGroups: [], originalGroups: [], }; @@ -183,7 +180,6 @@ class ContactEdit extends React.PureComponent { if (this.props.item !== undefined) { const contact = this.props.item; - this.state.group = contact.group; this.state.uid = contact.uid; this.state.fn = contact.fn ? contact.fn : ""; if (contact.n) { @@ -244,16 +240,17 @@ class ContactEdit extends React.PureComponent { this.state.collectionUid = props.collections[0].collection.uid; } - this.state.collectionGroups = this.props.groups.filter((group) => this.state.collectionUid === group.collectionUid); - this.state.collectionGroups.forEach((group) => { + this.state.collectionGroups = this.getCollectionGroups(this.state.collectionUid); + Object.values(this.state.collectionGroups).forEach((group: ContactType) => { if (group.members.includes(this.state.uid)) { - this.state.newGroups.push(group); - this.state.originalGroups.push(group); + this.state.newGroups.push(group.fn); + this.state.originalGroups.push(group.fn); } }); this.onSubmit = this.onSubmit.bind(this); this.addMetadata = this.addMetadata.bind(this); + this.getCollectionGroups = this.getCollectionGroups.bind(this); this.handleChange = this.handleChange.bind(this); this.handleInputChange = this.handleInputChange.bind(this); this.handleCollectionChange = this.handleCollectionChange.bind(this); @@ -298,15 +295,25 @@ class ContactEdit extends React.PureComponent { }); } - public handleChange(name: string, value: string | (string | ContactType)[]) { + public handleChange(name: string, value: string | string[]) { this.setState({ [name]: value, }); } + public getCollectionGroups(collectionUid: string) { + const groups = {}; + this.props.allGroups.forEach((group) => { + if (collectionUid === group.collectionUid) { + groups[group.fn] = group; + } + }); + return groups; + } + public reloadGroupSuggestions(collectionUid: string) { this.setState({ - collectionGroups: this.props.groups.filter((group) => collectionUid === group.collectionUid), + collectionGroups: this.getCollectionGroups(collectionUid), newGroups: [], }); } @@ -324,7 +331,7 @@ class ContactEdit extends React.PureComponent { this.handleChange(name, value); } - public addMetadata(item: ContactType, uid: string, isGroup?: boolean) { + public addMetadata(item: ContactType, uid: string, isGroup: boolean) { const comp = item.comp; comp.updatePropertyWithValue("prodid", "-//iCal.js EteSync Web"); comp.updatePropertyWithValue("version", "4.0"); @@ -345,33 +352,34 @@ class ContactEdit extends React.PureComponent { ; const comp = contact.comp; - this.addMetadata(contact, this.state.uid, this.props.newGroup); + this.addMetadata(contact, this.state.uid, false); // Add new groups this.state.newGroups.forEach((group) => { - if (typeof(group) === "string") { + if (!this.state.collectionGroups[group]) { const newGroup = new ContactType(new ICAL.Component(["vcard", [], []])); this.addMetadata(newGroup, uuid.v4(), true); - newGroup.comp.updatePropertyWithValue("fn", group); + newGroup.comp.updatePropertyWithValue("fn", group.trim()); newGroup.comp.updatePropertyWithValue("member", `urn:uuid:${this.state.uid}`); this.props.onSave(newGroup, this.state.collectionUid, undefined); - } else if (!this.state.originalGroups.includes(group)) { - const updatedGroup = group.clone(); - updatedGroup.comp.updatePropertyWithValue("member", `urn:uuid:${this.state.uid}`); - this.props.onSave(updatedGroup, this.state.collectionUid, group); + } else if (!this.state.originalGroups[group]) { + const oldGroup = this.state.collectionGroups[group]; + const updatedGroup = oldGroup.clone(); + updatedGroup.comp.addPropertyWithValue("member", `urn:uuid:${this.state.uid}`); + this.props.onSave(updatedGroup, this.state.collectionUid, oldGroup); } }); // Remove deleted groups - this.state.originalGroups.filter((x) => !this.state.newGroups.includes(x)).forEach((deletedGroup) => { + this.state.originalGroups.filter((x) => !this.state.newGroups.includes(x)).forEach((removed) => { + const deletedGroup = this.state.collectionGroups[removed]; const updatedGroup = deletedGroup.clone(); - const members = updatedGroup.members.filter((uid) => uid !== this.state.uid); + const members = updatedGroup.members.filter((uid: string) => uid !== this.state.uid); updatedGroup.comp.removeAllProperties("member"); - members.forEach((m) => updatedGroup.comp.updatePropertyWithValue("member", `urn:uuid:${m}`)); + members.forEach((m: string) => updatedGroup.comp.addPropertyWithValue("member", `urn:uuid:${m}`)); this.props.onSave(updatedGroup, this.state.collectionUid, deletedGroup); }); - const lastName = this.state.lastName.trim(); const firstName = this.state.firstName.trim(); const middleName = this.state.middleName.trim(); @@ -411,6 +419,13 @@ class ContactEdit extends React.PureComponent { }); } + setProperties("tel", this.state.phone); + setProperties("email", this.state.email); + setProperties("adr", this.state.address); + setProperties("impp", this.state.impp.map((x) => ( + { type: x.type, value: x.type + ":" + x.value } + ))); + function setProperty(name: string, value: string) { comp.removeAllProperties(name); if (value !== "") { @@ -418,19 +433,9 @@ class ContactEdit extends React.PureComponent { } } - - if (!this.props.newGroup && !this.state.group) { - setProperties("tel", this.state.phone); - setProperties("email", this.state.email); - setProperties("adr", this.state.address); - setProperties("impp", this.state.impp.map((x) => ( - { type: x.type, value: x.type + ":" + x.value } - ))); - - setProperty("org", this.state.org); - setProperty("title", this.state.title); - setProperty("note", this.state.note); - } + setProperty("org", this.state.org); + setProperty("title", this.state.title); + setProperty("note", this.state.note); this.props.onSave(contact, this.state.collectionUid, this.props.item) .then(() => { @@ -462,7 +467,7 @@ class ContactEdit extends React.PureComponent { return (

- {this.props.item ? this.state.group ? "Edit Group" : "Edit Contact" : this.props.newGroup ? "New Group" : "New Contact"} + {this.props.item ? "Edit Contact" : "New Contact"}

@@ -480,193 +485,181 @@ class ContactEdit extends React.PureComponent { - {this.props.newGroup || this.state.group ? - + + + + + + + + + +
+ Phone numbers + this.addValueType("phone")} + title="Add phone number" + > + + +
+ {this.state.phone.map((x, idx) => ( + this.removeValueType(name, idx)} + onChange={(name: string, type: string, value: string) => ( + this.handleValueTypeChange(name, idx, { type, value }) + )} /> - : - <> - - - - - - - + ))} - - -
- Phone numbers - this.addValueType("phone")} - title="Add phone number" - > - - -
- {this.state.phone.map((x, idx) => ( - this.removeValueType(name, idx)} - onChange={(name: string, type: string, value: string) => ( - this.handleValueTypeChange(name, idx, { type, value }) - )} - /> - ))} - -
- Emails - this.addValueType("email")} - title="Add email address" - > - - -
- {this.state.email.map((x, idx) => ( - this.removeValueType(name, idx)} - onChange={(name: string, type: string, value: string) => ( - this.handleValueTypeChange(name, idx, { type, value }) - )} - /> - ))} - -
- IMPP - this.addValueType("impp", "jabber")} - title="Add impp address" - > - - -
- {this.state.impp.map((x, idx) => ( - this.removeValueType(name, idx)} - onChange={(name: string, type: string, value: string) => ( - this.handleValueTypeChange(name, idx, { type, value }) - )} - /> - ))} - -
- Addresses - this.addValueType("address")} - title="Add address" - > - - -
- {this.state.address.map((x, idx) => ( - this.removeValueType(name, idx)} - onChange={(name: string, type: string, value: string) => ( - this.handleValueTypeChange(name, idx, { type, value }) - )} - /> - ))} - - +
+ Emails + this.addValueType("email")} + title="Add email address" + > + + +
+ {this.state.email.map((x, idx) => ( + this.removeValueType(name, idx)} + onChange={(name: string, type: string, value: string) => ( + this.handleValueTypeChange(name, idx, { type, value }) + )} + /> + ))} - +
+ IMPP + this.addValueType("impp", "jabber")} + title="Add impp address" + > + + +
+ {this.state.impp.map((x, idx) => ( + this.removeValueType(name, idx)} + onChange={(name: string, type: string, value: string) => ( + this.handleValueTypeChange(name, idx, { type, value }) + )} + /> + ))} +
+ Addresses + this.addValueType("address")} + title="Add address" + > + + +
+ {this.state.address.map((x, idx) => ( + this.removeValueType(name, idx)} + onChange={(name: string, type: string, value: string) => ( + this.handleValueTypeChange(name, idx, { type, value }) + )} + /> + ))} + + + + + + + this.handleChange("newGroups", value)} + renderInput={(params) => ( - option.fn ?? option} - value={this.state.newGroups} - onChange={(_e, value) => this.handleChange("newGroups", value)} - renderInput={(params) => ( - - )} + {...params} + variant="standard" + label="Groups" + fullWidth /> - - } + )} + />
+ + {this.props.item && + + } + + +
+ + + this.props.onDelete(this.props.item!, this.props.initialCollection!)} + onCancel={() => this.setState({ showDeleteDialog: false })} + > + Are you sure you would like to delete this group? + +
+ ); + } +} + +export default GroupEdit; diff --git a/src/Contacts/Main.tsx b/src/Contacts/Main.tsx index 57ece9a..478bf02 100644 --- a/src/Contacts/Main.tsx +++ b/src/Contacts/Main.tsx @@ -18,6 +18,7 @@ import SearchableAddressBook from "./SearchableAddressBook"; import Contact from "./Contact"; import LoadingIndicator from "../widgets/LoadingIndicator"; import ContactEdit from "./ContactEdit"; +import GroupEdit from "./GroupEdit"; import PageNotFound, { PageNotFoundRoute } from "../PageNotFound"; import { CachedCollection, getItemNavigationUid, getDecryptCollectionsFunction, getDecryptItemsFunction, PimFab, itemSave, itemDelete } from "../Pim/helpers"; @@ -79,7 +80,7 @@ export default function ContactsMain() { } } - const groups = flatEntries.filter((x) => x.group); + const allGroups = flatEntries.filter((x) => x.group); const styles = { button: { @@ -115,14 +116,13 @@ export default function ContactsMain() { path={routeResolver.getRoute("pim.contacts.new.group")} exact > - x.uid === colUid)!; const readOnly = collection.accessLevel === Etebase.CollectionAccessLevel.ReadOnly; + const path = `pim.contacts._id.edit.${item.group ? "group" : "contact"}`; return ( - + {item.group ? + + : + + } - history.push(routeResolver.getRoute("pim.contacts._id.edit", { itemUid: getItemNavigationUid(item) })) + history.push(routeResolver.getRoute(path, { itemUid: getItemNavigationUid(item) })) } >