Make special types for events and calendars.

This will simplify extracting values and already removes some
redundancy.
master
Tom Hacohen 7 years ago
parent eb2075d0ec
commit 864dad372f

@ -1,18 +1,18 @@
import * as React from 'react'; import * as React from 'react';
import { List, ListItem } from 'material-ui/List'; import { List, ListItem } from 'material-ui/List';
import * as ICAL from 'ical.js'; import { ContactType } from './pim-types';
class AddressBook extends React.Component { class AddressBook extends React.Component {
props: { props: {
entries: Array<ICAL.Component>, entries: Array<ContactType>,
onItemClick: (contact: ICAL.Component) => void, onItemClick: (contact: ContactType) => void,
}; };
render() { render() {
let entries = this.props.entries.sort((_a, _b) => { let entries = this.props.entries.sort((_a, _b) => {
const a = _a.getFirstPropertyValue('fn'); const a = _a.fn;
const b = _b.getFirstPropertyValue('fn'); const b = _b.fn;
if (a < b) { if (a < b) {
return -1; return -1;
@ -24,8 +24,9 @@ class AddressBook extends React.Component {
}); });
let itemList = entries.map((entry) => { let itemList = entries.map((entry) => {
const uid = entry.getFirstPropertyValue('uid'); const uid = entry.uid;
const name = entry.getFirstPropertyValue('fn'); const name = entry.fn;
return ( return (
<ListItem key={uid} primaryText={name} onClick={() => (this.props.onItemClick(entry))} /> <ListItem key={uid} primaryText={name} onClick={() => (this.props.onItemClick(entry))} />
); );

@ -3,33 +3,18 @@ import BigCalendar from 'react-big-calendar';
import 'react-big-calendar/lib/css/react-big-calendar.css'; import 'react-big-calendar/lib/css/react-big-calendar.css';
import * as moment from 'moment'; import * as moment from 'moment';
import * as ICAL from 'ical.js'; import { EventType } from './pim-types';
BigCalendar.momentLocalizer(moment); BigCalendar.momentLocalizer(moment);
class EventWrapper extends ICAL.Event {
get title() {
return this.summary;
}
get start() {
return this.startDate.toJSDate();
}
get end() {
return this.endDate.toJSDate();
}
}
class Calendar extends React.Component { class Calendar extends React.Component {
state: { state: {
currentDate?: Date; currentDate?: Date;
}; };
props: { props: {
entries: Array<ICAL.Component>, entries: Array<EventType>,
onItemClick: (contact: ICAL.Event) => void, onItemClick: (contact: EventType) => void,
}; };
constructor(props: any) { constructor(props: any) {
@ -38,9 +23,7 @@ class Calendar extends React.Component {
} }
render() { render() {
let entries = this.props.entries.map((value) => ( let entries = this.props.entries.sort((a, b) => {
new EventWrapper(value)
)).sort((a, b) => {
if (a.summary < b.summary) { if (a.summary < b.summary) {
return -1; return -1;
} else if (a.summary > b.summary) { } else if (a.summary > b.summary) {

@ -6,11 +6,11 @@ import CommunicationChatBubble from 'material-ui/svg-icons/communication/chat-bu
import CommunicationEmail from 'material-ui/svg-icons/communication/email'; import CommunicationEmail from 'material-ui/svg-icons/communication/email';
import { indigo500 } from 'material-ui/styles/colors'; import { indigo500 } from 'material-ui/styles/colors';
import * as ICAL from 'ical.js'; import { ContactType } from './pim-types';
class Contact extends React.Component { class Contact extends React.Component {
props: { props: {
contact?: ICAL.Component, contact?: ContactType,
}; };
render() { render() {
@ -19,10 +19,10 @@ class Contact extends React.Component {
} }
const contact = this.props.contact; const contact = this.props.contact;
const uid = contact.getFirstPropertyValue('uid'); const uid = contact.comp.getFirstPropertyValue('uid');
const name = contact.getFirstPropertyValue('fn'); const name = contact.comp.getFirstPropertyValue('fn');
const phoneNumbers = contact.getAllProperties('tel').map((prop, idx) => { const phoneNumbers = contact.comp.getAllProperties('tel').map((prop, idx) => {
const json = prop.toJSON(); const json = prop.toJSON();
const values = prop.getValues().map((val) => ( const values = prop.getValues().map((val) => (
<ListItem <ListItem
@ -37,7 +37,7 @@ class Contact extends React.Component {
return values; return values;
}); });
const emails = contact.getAllProperties('email').map((prop, idx) => { const emails = contact.comp.getAllProperties('email').map((prop, idx) => {
const json = prop.toJSON(); const json = prop.toJSON();
const values = prop.getValues().map((val) => ( const values = prop.getValues().map((val) => (
<ListItem <ListItem
@ -52,7 +52,7 @@ class Contact extends React.Component {
}); });
const skips = ['tel', 'email', 'prodid', 'uid', 'fn', 'n', 'version', 'photo']; const skips = ['tel', 'email', 'prodid', 'uid', 'fn', 'n', 'version', 'photo'];
const theRest = contact.getAllProperties().filter((prop) => ( const theRest = contact.comp.getAllProperties().filter((prop) => (
skips.indexOf(prop.name) === -1 skips.indexOf(prop.name) === -1
)).map((prop, idx) => { )).map((prop, idx) => {
const values = prop.getValues().map((_val) => { const values = prop.getValues().map((_val) => {

@ -3,6 +3,8 @@ import * as moment from 'moment';
import * as ICAL from 'ical.js'; import * as ICAL from 'ical.js';
import { EventType } from './pim-types';
function formatDateRange(start: ICAL.Time, end: ICAL.Time) { function formatDateRange(start: ICAL.Time, end: ICAL.Time) {
const mStart = moment(start.toJSDate()); const mStart = moment(start.toJSDate());
const mEnd = moment(end.toJSDate()); const mEnd = moment(end.toJSDate());
@ -33,7 +35,7 @@ function formatDateRange(start: ICAL.Time, end: ICAL.Time) {
class Event extends React.Component { class Event extends React.Component {
props: { props: {
event?: ICAL.Event, event?: EventType,
}; };
render() { render() {

@ -1,8 +1,6 @@
import * as React from 'react'; import * as React from 'react';
import { Route, Switch, withRouter } from 'react-router'; import { Route, Switch, withRouter } from 'react-router';
import * as ICAL from 'ical.js';
import * as EteSync from './api/EteSync'; import * as EteSync from './api/EteSync';
import { routeResolver } from './App'; import { routeResolver } from './App';
@ -10,10 +8,12 @@ import { routeResolver } from './App';
import AddressBook from './AddressBook'; import AddressBook from './AddressBook';
import Contact from './Contact'; import Contact from './Contact';
import { ContactType } from './pim-types';
class JournalAddressBook extends React.Component { class JournalAddressBook extends React.Component {
props: { props: {
journal: EteSync.Journal, journal: EteSync.Journal,
entries: Map<string, ICAL.Component>, entries: Map<string, ContactType>,
history?: any, history?: any,
}; };
@ -22,8 +22,8 @@ class JournalAddressBook extends React.Component {
this.contactClicked = this.contactClicked.bind(this); this.contactClicked = this.contactClicked.bind(this);
} }
contactClicked(contact: ICAL.Component) { contactClicked(contact: ContactType) {
const uid = contact.getFirstPropertyValue('uid'); const uid = contact.uid;
this.props.history.push( this.props.history.push(
routeResolver.getRoute('journals._id.items._id', { journalUid: this.props.journal.uid, itemUid: uid })); routeResolver.getRoute('journals._id.items._id', { journalUid: this.props.journal.uid, itemUid: uid }));

@ -6,14 +6,14 @@ import { routeResolver } from './App';
import Calendar from './Calendar'; import Calendar from './Calendar';
import Event from './Event'; import Event from './Event';
import * as ICAL from 'ical.js'; import { EventType } from './pim-types';
import * as EteSync from './api/EteSync'; import * as EteSync from './api/EteSync';
class JournalCalendar extends React.Component { class JournalCalendar extends React.Component {
props: { props: {
journal: EteSync.Journal, journal: EteSync.Journal,
entries: Map<string, ICAL.Component>, entries: Map<string, EventType>,
history?: any, history?: any,
}; };
@ -22,7 +22,7 @@ class JournalCalendar extends React.Component {
this.eventClicked = this.eventClicked.bind(this); this.eventClicked = this.eventClicked.bind(this);
} }
eventClicked(event: ICAL.Event) { eventClicked(event: EventType) {
const uid = event.uid; const uid = event.uid;
this.props.history.push( this.props.history.push(
@ -48,7 +48,7 @@ class JournalCalendar extends React.Component {
render={({match}) => { render={({match}) => {
return ( return (
<Event event={new ICAL.Event(items.get(match.params.itemUid))} /> <Event event={items.get(match.params.itemUid)} />
); );
}} }}
/> />

@ -8,6 +8,8 @@ import IconEdit from 'material-ui/svg-icons/editor/mode-edit';
import * as ICAL from 'ical.js'; import * as ICAL from 'ical.js';
import { EventType, ContactType } from './pim-types';
import * as EteSync from './api/EteSync'; import * as EteSync from './api/EteSync';
class JournalEntries extends React.Component { class JournalEntries extends React.Component {
@ -49,13 +51,13 @@ class JournalEntries extends React.Component {
let name; let name;
let uid; let uid;
if (comp.name === 'vcalendar') { if (comp.name === 'vcalendar') {
const vevent = new ICAL.Event(comp.getFirstSubcomponent('vevent')); const vevent = new EventType(comp.getFirstSubcomponent('vevent'));
name = vevent.summary; name = vevent.summary;
uid = vevent.uid; uid = vevent.uid;
} else if (comp.name === 'vcard') { } else if (comp.name === 'vcard') {
const vcard = comp; const vcard = new ContactType(comp);
name = vcard.getFirstPropertyValue('fn'); name = vcard.fn;
uid = vcard.getFirstPropertyValue('uid'); uid = vcard.uid;
} else { } else {
name = 'Error processing entry'; name = 'Error processing entry';
uid = ''; uid = '';

@ -1,8 +1,6 @@
import * as React from 'react'; import * as React from 'react';
import { Route, Switch } from 'react-router'; import { Route, Switch } from 'react-router';
import * as ICAL from 'ical.js';
import * as EteSync from './api/EteSync'; import * as EteSync from './api/EteSync';
import Contact from './Contact'; import Contact from './Contact';
@ -91,7 +89,7 @@ class Pim extends React.Component {
path={routeResolver.getRoute('pim.events._id')} path={routeResolver.getRoute('pim.events._id')}
exact={true} exact={true}
render={({match}) => ( render={({match}) => (
<Event event={new ICAL.Event(calendarItems.get(match.params.eventUid))} /> <Event event={calendarItems.get(match.params.eventUid)} />
)} )}
/> />
</Switch> </Switch>

@ -6,12 +6,14 @@ import * as ICAL from 'ical.js';
import AddressBook from './AddressBook'; import AddressBook from './AddressBook';
import Calendar from './Calendar'; import Calendar from './Calendar';
import { EventType, ContactType } from './pim-types';
import { routeResolver } from './App'; import { routeResolver } from './App';
class Pim extends React.Component { class Pim extends React.Component {
props: { props: {
contacts: Array<ICAL.Component>, contacts: Array<ContactType>,
events: Array<ICAL.Component>, events: Array<EventType>,
history?: any, history?: any,
}; };
@ -28,8 +30,8 @@ class Pim extends React.Component {
routeResolver.getRoute('pim.events._id', { eventUid: uid })); routeResolver.getRoute('pim.events._id', { eventUid: uid }));
} }
contactClicked(contact: ICAL.Component) { contactClicked(contact: ContactType) {
const uid = contact.getFirstPropertyValue('uid'); const uid = contact.uid;
this.props.history.push( this.props.history.push(
routeResolver.getRoute('pim.contacts._id', { contactUid: uid })); routeResolver.getRoute('pim.contacts._id', { contactUid: uid }));

@ -1,14 +1,16 @@
import * as ICAL from 'ical.js'; import * as ICAL from 'ical.js';
import { EventType, ContactType } from './pim-types';
import * as EteSync from './api/EteSync'; import * as EteSync from './api/EteSync';
export function syncEntriesToItemMap(entries: EteSync.SyncEntry[]) { export function syncEntriesToItemMap(entries: EteSync.SyncEntry[]) {
let items: Map<string, ICAL.Component> = new Map(); let items: Map<string, ContactType> = new Map();
for (const syncEntry of entries) { for (const syncEntry of entries) {
let comp = new ICAL.Component(ICAL.parse(syncEntry.content)); let comp = new ContactType(new ICAL.Component(ICAL.parse(syncEntry.content)));
const uid = comp.getFirstPropertyValue('uid'); const uid = comp.uid;
if ((syncEntry.action === EteSync.SyncEntryAction.Add) || if ((syncEntry.action === EteSync.SyncEntryAction.Add) ||
(syncEntry.action === EteSync.SyncEntryAction.Change)) { (syncEntry.action === EteSync.SyncEntryAction.Change)) {
@ -22,16 +24,16 @@ export function syncEntriesToItemMap(entries: EteSync.SyncEntry[]) {
} }
export function syncEntriesToCalendarItemMap(entries: EteSync.SyncEntry[]) { export function syncEntriesToCalendarItemMap(entries: EteSync.SyncEntry[]) {
let items: Map<string, ICAL.Component> = new Map(); let items: Map<string, EventType> = new Map();
for (const syncEntry of entries) { for (const syncEntry of entries) {
let comp = new ICAL.Component(ICAL.parse(syncEntry.content)).getFirstSubcomponent('vevent'); let comp = new EventType(new ICAL.Component(ICAL.parse(syncEntry.content)).getFirstSubcomponent('vevent'));
if (comp === null) { if (comp === null) {
continue; continue;
} }
const uid = comp.getFirstPropertyValue('uid'); const uid = comp.uid;
if ((syncEntry.action === EteSync.SyncEntryAction.Add) || if ((syncEntry.action === EteSync.SyncEntryAction.Add) ||
(syncEntry.action === EteSync.SyncEntryAction.Change)) { (syncEntry.action === EteSync.SyncEntryAction.Change)) {

@ -0,0 +1,31 @@
import * as ICAL from 'ical.js';
export class EventType extends ICAL.Event {
get title() {
return this.summary;
}
get start() {
return this.startDate.toJSDate();
}
get end() {
return this.endDate.toJSDate();
}
}
export class ContactType {
comp: ICAL.Component;
constructor(comp: ICAL.Component) {
this.comp = comp;
}
get uid() {
return this.comp.getFirstPropertyValue('uid');
}
get fn() {
return this.comp.getFirstPropertyValue('fn');
}
}
Loading…
Cancel
Save