lint: replace tslint with eslint and fix new warnings and errors.

master
Tom Hacohen 5 years ago
parent f29edf1563
commit 11dd883f5f

@ -0,0 +1 @@
EXTEND_ESLINT=true

@ -0,0 +1,98 @@
module.exports = {
"env": {
"browser": true,
"es6": true,
"node": true
},
"parser": "@typescript-eslint/parser",
"parserOptions": {
"sourceType": "module",
"ecmaFeatures": {
"jsx": true
}
},
"settings": {
"react": {
"version": "detect",
},
},
"plugins": [
"@typescript-eslint",
],
"extends": [
"eslint:recommended",
"plugin:react/recommended",
"plugin:@typescript-eslint/eslint-recommended",
"plugin:@typescript-eslint/recommended"
],
"rules": {
"@typescript-eslint/explicit-function-return-type": "off",
"@typescript-eslint/no-use-before-define": "off",
"@typescript-eslint/no-non-null-assertion": "off",
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/member-delimiter-style": ["error", {
"multiline": {
"delimiter": "semi",
"requireLast": true
},
"singleline": {
"delimiter": "comma",
"requireLast": false
}
}],
"@typescript-eslint/no-unused-vars": ["warn", {
"vars": "all",
"args": "after-used",
"ignoreRestSiblings": true,
"argsIgnorePattern": "^_",
}],
"react/display-name": "off",
"react/no-unescaped-entities": "off",
"react/jsx-tag-spacing": ["error", {
"closingSlash": "never",
"beforeSelfClosing": "always",
"afterOpening": "never",
"beforeClosing": "never"
}],
"react/jsx-boolean-value": ["error", "never"],
"react/jsx-curly-spacing": ["error", "never"],
"react/jsx-key": ["error", { "checkFragmentShorthand": true }],
"quotes": "off",
"@typescript-eslint/quotes": ["error", "single", { "allowTemplateLiterals": true }],
"semi": ["error", "always", { "omitLastInOneLineBlock": true }],
"camelcase": ["error"],
"comma-dangle": ["error", {
"arrays": "always-multiline",
"objects": "always-multiline",
"imports": "always-multiline",
"exports": "always-multiline",
"functions": "never"
}],
"eqeqeq": ["error", "smart"],
"indent": ["error", 2, {
"SwitchCase": 1,
}],
"no-multi-spaces": "error",
"object-curly-spacing": ["error", "always"],
"arrow-parens": "error",
"arrow-spacing": "error",
"key-spacing": "error",
"keyword-spacing": "error",
"func-call-spacing": "off",
"@typescript-eslint/func-call-spacing": ["error"],
"space-before-function-paren": ["error", {
"anonymous": "always",
"named": "never",
"asyncArrow": "always"
}],
"space-in-parens": ["error", "never"],
"space-before-blocks": "error",
"curly": ["error", "all"],
"space-infix-ops": "error",
"consistent-return": "error",
"brace-style": ["error", "1tbs", { "allowSingleLine": true }],
"jsx-quotes": ["error"],
}
};

2
.gitignore vendored

@ -21,5 +21,3 @@ Session.vim
npm-debug.log*
yarn-debug.log*
yarn-error.log*
/.env

@ -51,8 +51,6 @@
"@types/sjcl": "^1.0.28",
"@types/urijs": "^1.15.38",
"@types/uuid": "^3.4.3",
"tslint": "^5.12.1",
"tslint-react": "^3.6.0",
"typescript": "^3.3.3"
},
"browserslist": [

@ -11,5 +11,5 @@ it('renders without crashing', () => {
<Provider store={store}>
<App />
</Provider>
, div);
, div);
});

@ -97,11 +97,11 @@ export const routeResolver = new RouteResolver({
const AppBarWitHistory = withRouter(
class extends React.PureComponent {
public props: {
title: string,
toggleDrawerIcon: any,
title: string;
toggleDrawerIcon: any;
history?: History;
staticContext?: any;
iconElementRight: any,
iconElementRight: any;
};
constructor(props: any) {
@ -159,7 +159,7 @@ const IconRefreshWithSpin = withSpin(NavigationRefresh);
class App extends React.PureComponent {
public state: {
drawerOpen: boolean,
drawerOpen: boolean;
};
public props: {
@ -193,37 +193,37 @@ class App extends React.PureComponent {
return (
<ThemeProvider theme={muiTheme}>
<BrowserRouter>
<div style={styles.main}>
<AppBarWitHistory
toggleDrawerIcon={<IconButton onClick={this.toggleDrawer}><NavigationMenu /></IconButton>}
iconElementRight={
<IconButton disabled={!credentials || fetching} onClick={this.refresh} title="Refresh">
<IconRefreshWithSpin spin={fetching} />
</IconButton>}
/>
<Drawer
open={this.state.drawerOpen}
onClose={this.toggleDrawer}
>
<SideMenu etesync={credentials} onCloseDrawerRequest={this.closeDrawer} />
</Drawer>
<ErrorBoundary>
<LoginGate credentials={this.props.credentials} />
</ErrorBoundary>
</div>
<div style={styles.main}>
<AppBarWitHistory
toggleDrawerIcon={<IconButton onClick={this.toggleDrawer}><NavigationMenu /></IconButton>}
iconElementRight={
<IconButton disabled={!credentials || fetching} onClick={this.refresh} title="Refresh">
<IconRefreshWithSpin spin={fetching} />
</IconButton>}
/>
<Drawer
open={this.state.drawerOpen}
onClose={this.toggleDrawer}
>
<SideMenu etesync={credentials} onCloseDrawerRequest={this.closeDrawer} />
</Drawer>
<ErrorBoundary>
<LoginGate credentials={this.props.credentials} />
</ErrorBoundary>
</div>
</BrowserRouter>
</ThemeProvider>
);
}
private toggleDrawer() {
this.setState({drawerOpen: !this.state.drawerOpen});
this.setState({ drawerOpen: !this.state.drawerOpen });
}
private closeDrawer() {
this.setState({drawerOpen: false});
this.setState({ drawerOpen: false });
}
private refresh() {
@ -238,7 +238,7 @@ const credentialsSelector = createSelector(
(state: store.StoreState) => state.encryptionKey.key,
(value, error, fetching, encryptionKey) => {
if (value === null) {
return {value, error, fetching};
return { value, error, fetching };
}
return {

@ -71,14 +71,14 @@ class ImportDialog extends React.Component<PropsType> {
<DialogTitle>Import entries from file?</DialogTitle>
<DialogContent>
{ loading ?
<LoadingIndicator style={{display: 'block', margin: 'auto'}} />
<LoadingIndicator style={{ display: 'block', margin: 'auto' }} />
:
<Dropzone
onDrop={dropFunction}
multiple={false}
accept={acceptTypes}
>
{({getRootProps, getInputProps}) => (
{({ getRootProps, getInputProps }) => (
<section>
<div {...getRootProps()}>
<input {...getInputProps()} />
@ -87,7 +87,7 @@ class ImportDialog extends React.Component<PropsType> {
</DialogContentText>
</div>
</section>
)}
)}
</Dropzone>
}
</DialogContent>

@ -51,8 +51,8 @@ const JournalTaskList = journalView(TaskList, Task);
class Journal extends React.Component<PropsTypeInner> {
public state: {
tab: number,
importDialogOpen: boolean,
tab: number;
importDialogOpen: boolean;
};
constructor(props: PropsTypeInner) {
@ -87,7 +87,7 @@ class Journal extends React.Component<PropsTypeInner> {
itemsView =
<JournalAddressBook journal={journal} entries={syncEntriesToItemMap(collectionInfo, syncEntries)} />;
itemsTitle = 'Contacts';
} else if (collectionInfo.type === 'TASKS') {
} else if (collectionInfo.type === 'TASKS') {
itemsView = (
<JournalTaskList
journal={journal}
@ -110,14 +110,14 @@ class Journal extends React.Component<PropsTypeInner> {
<IconButton
component={Link}
title="Edit"
{...{to: routeResolver.getRoute('journals._id.edit', { journalUid: journal.uid })}}
{...{ to: routeResolver.getRoute('journals._id.edit', { journalUid: journal.uid }) }}
>
<IconEdit />
</IconButton>
<IconButton
component={Link}
title="Members"
{...{to: routeResolver.getRoute('journals._id.members', { journalUid: journal.uid })}}
{...{ to: routeResolver.getRoute('journals._id.members', { journalUid: journal.uid }) }}
>
<IconMembers />
</IconButton>

@ -54,7 +54,7 @@ class JournalEdit extends React.PureComponent<PropsTypeInner> {
if (this.props.item !== undefined) {
const collection = this.props.item;
this.state.info = {...collection};
this.state.info = { ...collection };
} else {
this.state.info.uid = EteSync.genUid();
this.state.info.type = 'ADDRESS_BOOK';
@ -86,9 +86,9 @@ class JournalEdit extends React.PureComponent<PropsTypeInner> {
return (
<>
<AppBarOverride title={pageTitle} />
<Container style={{maxWidth: '30rem'}}>
<Container style={{ maxWidth: '30rem' }}>
<form onSubmit={this.onSubmit}>
<FormControl disabled={this.props.item !== undefined} style={styles.fullWidth} >
<FormControl disabled={this.props.item !== undefined} style={styles.fullWidth}>
<InputLabel>
Collection type
</InputLabel>
@ -126,17 +126,17 @@ class JournalEdit extends React.PureComponent<PropsTypeInner> {
variant="contained"
onClick={onCancel}
>
<IconCancel style={{marginRight: 8}} />
<IconCancel style={{ marginRight: 8 }} />
Cancel
</Button>
{this.props.item &&
<Button
variant="contained"
style={{marginLeft: 15, backgroundColor: colors.red[500], color: 'white'}}
style={{ marginLeft: 15, backgroundColor: colors.red[500], color: 'white' }}
onClick={this.onDeleteRequest}
>
<IconDelete style={{marginRight: 8}} />
<IconDelete style={{ marginRight: 8 }} />
Delete
</Button>
}
@ -145,9 +145,9 @@ class JournalEdit extends React.PureComponent<PropsTypeInner> {
type="submit"
variant="contained"
color="secondary"
style={{marginLeft: 15}}
style={{ marginLeft: 15 }}
>
<IconSave style={{marginRight: 8}} />
<IconSave style={{ marginRight: 8 }} />
Save
</Button>
</div>
@ -158,7 +158,7 @@ class JournalEdit extends React.PureComponent<PropsTypeInner> {
labelOk="Delete"
open={this.state.showDeleteDialog}
onOk={() => onDelete(this.props.item!)}
onCancel={() => this.setState({showDeleteDialog: false})}
onCancel={() => this.setState({ showDeleteDialog: false })}
>
Are you sure you would like to delete this journal?
</ConfirmationDialog>

@ -119,7 +119,7 @@ class JournalMemberAddDialog extends React.PureComponent<PropsType> {
publicKey: userInfo.publicKey,
});
}).catch((error) => {
this.setState({error});
this.setState({ error });
});
}

@ -53,26 +53,26 @@ class JournalMembers extends React.PureComponent<PropsTypeInner> {
return (
<>
<AppBarOverride title={`${info.displayName} - Members`} />
<Container style={{maxWidth: '30rem'}}>
<Container style={{ maxWidth: '30rem' }}>
{ members ?
<List>
<ListItem rightIcon={<IconMemberAdd />} onClick={() => this.setState({ addMemberOpen: true })}>
<List>
<ListItem rightIcon={<IconMemberAdd />} onClick={() => this.setState({ addMemberOpen: true })}>
Add member
</ListItem>
{(members.length > 0 ?
members.map((member) => (
<ListItem key={member.user} onClick={() => this.onRevokeRequest(member.user)}>
{member.user}
</ListItem>
))
</ListItem>
{(members.length > 0 ?
members.map((member) => (
<ListItem key={member.user} onClick={() => this.onRevokeRequest(member.user)}>
{member.user}
</ListItem>
))
:
<ListItem>
<ListItem>
No members
</ListItem>
)}
</List>
</ListItem>
)}
</List>
:
<LoadingIndicator />
<LoadingIndicator />
}
</Container>
<ConfirmationDialog
@ -80,7 +80,7 @@ class JournalMembers extends React.PureComponent<PropsTypeInner> {
labelOk="OK"
open={revokeUser !== null}
onOk={this.onRevokeDo}
onCancel={() => this.setState({revokeUser: null})}
onCancel={() => this.setState({ revokeUser: null })}
>
Would you like to revoke {revokeUser}'s access?<br />
Please be advised that a malicious user would potentially be able to retain access to encryption keys. Please refer to the FAQ for more information.
@ -94,7 +94,7 @@ class JournalMembers extends React.PureComponent<PropsTypeInner> {
onOk={this.onMemberAdd}
onClose={() => this.setState({ addMemberOpen: false })}
/>
:
:
<ConfirmationDialog
title="Now Allowed"
labelOk="OK"

@ -56,7 +56,7 @@ class JournalsList extends React.PureComponent {
<IconButton
component={Link}
title="New"
{...{to: routeResolver.getRoute('journals.new')}}
{...{ to: routeResolver.getRoute('journals.new') }}
>
<IconAdd />
</IconButton>

@ -62,7 +62,7 @@ class Journals extends React.PureComponent {
/>
<Route
path={routeResolver.getRoute('journals._id')}
render={({match}) => {
render={({ match }) => {
const journalUid = match.params.journalUid;
const syncJournal = this.props.syncInfo.get(journalUid);

@ -14,9 +14,9 @@ function objValues(obj: any) {
export function journalView(JournalList: any, JournalItem: any) {
return withRouter(class extends React.PureComponent {
public props: {
journal: EteSync.Journal,
entries: {[key: string]: any},
history?: History,
journal: EteSync.Journal;
entries: {[key: string]: any};
history?: History;
};
constructor(props: any) {
@ -41,13 +41,13 @@ export function journalView(JournalList: any, JournalItem: any) {
exact
render={() => (
<JournalList entries={objValues(items)} onItemClick={this.itemClicked} />
)
)
}
/>
<Route
path={routeResolver.getRoute('journals._id.items._id')}
exact
render={({match}) => {
render={({ match }) => {
return (
<JournalItem item={items[`${match.params.journalUid}|${match.params.itemUid}`]} />

@ -35,7 +35,7 @@ function EncryptionPart(props: { credentials: CredentialsType, onEncryptionFormS
return (
<Container style={{maxWidth: '30rem'}}>
<Container style={{ maxWidth: '30rem' }}>
<h2>Encryption Password</h2>
{ (isNewUser) ?
<div>
@ -93,7 +93,7 @@ class LoginGate extends React.Component {
};
return (
<Container style={{maxWidth: '30rem'}}>
<Container style={{ maxWidth: '30rem' }}>
<h2>Please Log In</h2>
<LoginForm
onSubmit={this.onFormSubmit}

@ -43,7 +43,7 @@ class PimMain extends React.PureComponent<PropsType> {
constructor(props: any) {
super(props);
this.state = {tab: 1};
this.state = { tab: 1 };
this.eventClicked = this.eventClicked.bind(this);
this.taskClicked = this.taskClicked.bind(this);
this.contactClicked = this.contactClicked.bind(this);
@ -78,7 +78,7 @@ class PimMain extends React.PureComponent<PropsType> {
public newEvent(start?: Date, end?: Date) {
this.props.history!.push(
routeResolver.getRoute('pim.events.new'),
{start, end}
{ start, end }
);
}
@ -116,7 +116,7 @@ class PimMain extends React.PureComponent<PropsType> {
variant="fullWidth"
style={{ backgroundColor: theme.palette.primary.main }}
value={tab}
onChange={(event, value) => this.setState({tab: value})}
onChange={(event, value) => this.setState({ tab: value })}
>
<Tab
label={addressBookTitle}

@ -101,12 +101,12 @@ const ItemChangeLog = React.memo((props: any) => {
});
type CollectionRoutesPropsType = RouteComponentProps<{}> & {
syncInfo: SyncInfo,
routePrefix: string,
collections: EteSync.CollectionInfo[],
componentEdit: any,
componentView: any,
items: {[key: string]: PimType},
syncInfo: SyncInfo;
routePrefix: string;
collections: EteSync.CollectionInfo[];
componentEdit: any;
componentView: any;
items: {[key: string]: PimType};
onItemSave: (item: PimType, journalUid: string, originalContact?: PimType) => void;
onItemDelete: (item: PimType, journalUid: string) => void;
onItemCancel: () => void;
@ -135,8 +135,8 @@ const CollectionRoutes = withStyles(styles)(withRouter(
<Route
path={routeResolver.getRoute(props.routePrefix + '.new')}
exact
render={({match}) => (
<Container style={{maxWidth: '30rem'}}>
render={({ match }) => (
<Container style={{ maxWidth: '30rem' }}>
<ComponentEdit
collections={props.collections}
onSave={props.onItemSave}
@ -148,8 +148,8 @@ const CollectionRoutes = withStyles(styles)(withRouter(
<Route
path={routeResolver.getRoute(props.routePrefix + '._id.edit')}
exact
render={({match}) => (
<Container style={{maxWidth: '30rem'}}>
render={({ match }) => (
<Container style={{ maxWidth: '30rem' }}>
{(match.params.itemUid in props.items) &&
<ComponentEdit
initialCollection={(props.items[match.params.itemUid] as any).journalUid}
@ -166,7 +166,7 @@ const CollectionRoutes = withStyles(styles)(withRouter(
<Route
path={routeResolver.getRoute(props.routePrefix + '._id.log')}
exact
render={({match}) => (
render={({ match }) => (
<Container>
<ItemChangeLog
syncInfo={props.syncInfo}
@ -178,19 +178,19 @@ const CollectionRoutes = withStyles(styles)(withRouter(
<Route
path={routeResolver.getRoute(props.routePrefix + '._id')}
exact
render={({match, history}) => (
render={({ match, history }) => (
<Container>
<div style={{textAlign: 'right', marginBottom: 15}}>
<div style={{ textAlign: 'right', marginBottom: 15 }}>
<Button
variant="contained"
className={classes.button}
onClick={() =>
history.push(routeResolver.getRoute(
props.routePrefix + '._id.log',
{itemUid: match.params.itemUid}))
{ itemUid: match.params.itemUid }))
}
>
<IconChangeHistory className={classes.leftIcon} />
<IconChangeHistory className={classes.leftIcon} />
Change History
</Button>
@ -199,11 +199,11 @@ const CollectionRoutes = withStyles(styles)(withRouter(
variant="contained"
disabled={!props.componentEdit}
className={classes.button}
style={{marginLeft: 15}}
style={{ marginLeft: 15 }}
onClick={() =>
history.push(routeResolver.getRoute(
props.routePrefix + '._id.edit',
{itemUid: match.params.itemUid}))
{ itemUid: match.params.itemUid }))
}
>
<IconEdit className={classes.leftIcon} />
@ -254,20 +254,20 @@ class Pim extends React.PureComponent {
store.dispatch<any>(fetchEntries(this.props.etesync, journal.uid, prevUid))
.then((entriesAction: Action<EteSync.Entry[]>) => {
last = entriesAction.payload!.slice(-1).pop() as EteSync.Entry;
last = entriesAction.payload!.slice(-1).pop() as EteSync.Entry;
if (last) {
prevUid = last.uid;
}
if (last) {
prevUid = last.uid;
}
const saveEvent = store.dispatch(
addJournalEntry(
this.props.etesync, this.props.userInfo, journal,
prevUid, action, item.toIcal()));
(saveEvent as any).then(() => {
this.props.history.goBack();
const saveEvent = store.dispatch(
addJournalEntry(
this.props.etesync, this.props.userInfo, journal,
prevUid, action, item.toIcal()));
(saveEvent as any).then(() => {
this.props.history.goBack();
});
});
});
}
public onItemDelete(item: PimType, journalUid: string) {
@ -289,20 +289,20 @@ class Pim extends React.PureComponent {
store.dispatch<any>(fetchEntries(this.props.etesync, journal.uid, prevUid))
.then((entriesAction: Action<EteSync.Entry[]>) => {
last = entriesAction.payload!.slice(-1).pop() as EteSync.Entry;
last = entriesAction.payload!.slice(-1).pop() as EteSync.Entry;
if (last) {
prevUid = last.uid;
}
if (last) {
prevUid = last.uid;
}
const deleteItem = store.dispatch(
addJournalEntry(
this.props.etesync, this.props.userInfo, journal,
prevUid, action, item.toIcal()));
(deleteItem as any).then(() => {
this.props.history.push(routeResolver.getRoute('pim'));
const deleteItem = store.dispatch(
addJournalEntry(
this.props.etesync, this.props.userInfo, journal,
prevUid, action, item.toIcal()));
(deleteItem as any).then(() => {
this.props.history.push(routeResolver.getRoute('pim'));
});
});
});
}
public onCancel() {
@ -317,7 +317,7 @@ class Pim extends React.PureComponent {
<Route
path={routeResolver.getRoute('pim')}
exact
render={({history}) => (
render={({ history }) => (
<PimMain
contacts={objValues(addressBookItems)}
events={objValues(calendarItems)}

@ -35,7 +35,7 @@ class Settings extends React.PureComponent<PropsTypeInner> {
<AppBarOverride title="Settings" />
<Container>
<h1>Date & Time</h1>
<FormControl style={{width: '15em'}}>
<FormControl style={{ width: '15em' }}>
<InputLabel>
Locale
</InputLabel>
@ -62,7 +62,7 @@ class Settings extends React.PureComponent<PropsTypeInner> {
const value = event.target.value;
const { settings } = this.props;
store.dispatch(setSettings({ ...settings, [name]: value}));
store.dispatch(setSettings({ ...settings, [name]: value }));
}
}

@ -68,16 +68,16 @@ class SideMenu extends React.PureComponent<PropsTypeInner> {
this.props.history.push(routeResolver.getRoute('settings'));
}}
/>
<ListItem primaryText="Log Out" leftIcon={<LogoutIcon />} onClick={this.logout} />
<ListItem primaryText="Log Out" leftIcon={<LogoutIcon />} onClick={this.logout} />
</React.Fragment>
);
}
return (
<div style={{ overflowX: 'hidden', width: 250}}>
<div style={{ overflowX: 'hidden', width: 250 }}>
<div className="App-drawer-header">
<img alt="App logo" className="App-drawer-logo" src={logo} />
<div style={{ color: theme.palette.secondary.contrastText }} >
<div style={{ color: theme.palette.secondary.contrastText }}>
{username}
</div>
</div>

@ -123,7 +123,7 @@ class SyncGate extends React.PureComponent<PropsTypeInner> {
if (!journalAction.error) {
store.dispatch(fetchEntries(this.props.etesync, collection.uid));
}
});
});
});
});
};
@ -162,14 +162,14 @@ class SyncGate extends React.PureComponent<PropsTypeInner> {
const errors: Array<{journal: string, error: Error}> = [];
this.props.entries.forEach((entry, journal) => {
if (entry.error) {
errors.push({journal, error: entry.error});
errors.push({ journal, error: entry.error });
}
});
if (errors.length > 0) {
return (
<ul>
{errors.map((error) => (<li>{error.journal}: {error.error.toString()}</li>))}
{errors.map((error, idx) => (<li key={idx}>{error.journal}: {error.error.toString()}</li>))}
</ul>
);
}
@ -178,8 +178,8 @@ class SyncGate extends React.PureComponent<PropsTypeInner> {
if ((this.props.userInfo.value === null) || (journals === null) ||
((this.props.fetchCount > 0) &&
((entryArrays.size === 0) || !entryArrays.every((x: any) => (x.value !== null))))
) {
return (<LoadingIndicator style={{display: 'block', margin: '40px auto'}} />);
) {
return (<LoadingIndicator style={{ display: 'block', margin: '40px auto' }} />);
}
// FIXME: Shouldn't be here
@ -193,13 +193,13 @@ class SyncGate extends React.PureComponent<PropsTypeInner> {
<Route
path={routeResolver.getRoute('home')}
exact
render={({match}) => (
render={() => (
<Redirect to={routeResolver.getRoute('pim')} />
)}
/>
<Route
path={routeResolver.getRoute('pim')}
render={({match, history}) => (
render={({ history }) => (
<>
<AppBarOverride title="EteSync" />
<PimRouter
@ -227,7 +227,7 @@ class SyncGate extends React.PureComponent<PropsTypeInner> {
<Route
path={routeResolver.getRoute('settings')}
exact
render={({history}) => (
render={({ history }) => (
<Settings
history={history}
/>
@ -238,7 +238,7 @@ class SyncGate extends React.PureComponent<PropsTypeInner> {
}
}
const mapStateToProps = (state: StoreState, props: PropsType) => {
const mapStateToProps = (state: StoreState, _props: PropsType) => {
return {
settings: state.settings,
journals: state.cache.journals,

@ -30,7 +30,7 @@ it('Simple sync', async () => {
const uid1 = sjcl.codec.hex.fromBits(sjcl.hash.sha256.hash('id1'));
const cryptoManager = new EteSync.CryptoManager(keyBase64, USER);
const info1 = new EteSync.CollectionInfo({uid: uid1, content: 'test', displayName: 'Dislpay 1'});
const info1 = new EteSync.CollectionInfo({ uid: uid1, content: 'test', displayName: 'Dislpay 1' });
const journal = new EteSync.Journal();
journal.setInfo(cryptoManager, info1);
@ -66,7 +66,7 @@ it('Journal Entry sync', async () => {
const uid1 = sjcl.codec.hex.fromBits(sjcl.hash.sha256.hash('id1'));
const cryptoManager = new EteSync.CryptoManager(keyBase64, USER);
const info1 = new EteSync.CollectionInfo({uid: uid1, content: 'test', displayName: 'Dislpay 1'});
const info1 = new EteSync.CollectionInfo({ uid: uid1, content: 'test', displayName: 'Dislpay 1' });
const journal = new EteSync.Journal();
journal.setInfo(cryptoManager, info1);
@ -77,7 +77,7 @@ it('Journal Entry sync', async () => {
let entries = await entryManager.list(null);
expect(entries.length).toBe(0);
const syncEntry = new EteSync.SyncEntry({action: 'ADD', content: 'bla'});
const syncEntry = new EteSync.SyncEntry({ action: 'ADD', content: 'bla' });
let prevUid = null;
const entry = new EteSync.Entry();
entry.setSyncEntry(cryptoManager, syncEntry, prevUid);

@ -48,7 +48,7 @@ function CastJson(json: any, to: any) {
}
function hmacToHex(hmac: byte[]): string {
return sjcl.codec.hex.fromBits(sjcl.codec.bytes.toBits(hmac));
return sjcl.codec.hex.fromBits(sjcl.codec.bytes.toBits(hmac));
}
export class Credentials {
@ -497,7 +497,7 @@ export class EntryManager extends BaseManager {
super(credentials, apiBase, ['journals', journalId, 'entries', '']);
}
public list(lastUid: string | null, limit: number = 0): Promise<Entry[]> {
public list(lastUid: string | null, limit = 0): Promise<Entry[]> {
let apiBase = this.apiBase.clone();
apiBase = apiBase.search({
last: (lastUid !== null) ? lastUid : undefined,

@ -48,7 +48,7 @@ const AddressBookItem = React.memo((_props: any) => {
return (
<ListItem
leftIcon={
<Avatar style={{backgroundColor: getContactColor(entry)}}>
<Avatar style={{ backgroundColor: getContactColor(entry) }}>
{name && name[0].toUpperCase()}
</Avatar>}
primaryText={name}
@ -64,7 +64,7 @@ const sortSelector = createSelector(
const a = _a.fn;
const b = _b.fn;
return a.localeCompare(b, undefined, {sensitivity: 'base'});
return a.localeCompare(b, undefined, { sensitivity: 'base' });
});
}
);

@ -72,7 +72,7 @@ class Calendar extends React.PureComponent<PropsType> {
});
return (
<div style={{width: '100%', height: 'calc(100vh - 230px)', minHeight: 500}}>
<div style={{ width: '100%', height: 'calc(100vh - 230px)', minHeight: 500 }}>
<BigCalendar
defaultDate={new Date()}
scrollToTime={new Date(1970, 1, 1, 8)}
@ -81,7 +81,7 @@ class Calendar extends React.PureComponent<PropsType> {
selectable
onSelectEvent={this.props.onItemClick as any}
onSelectSlot={this.slotClicked as any}
formats={{agendaHeaderFormat: agendaHeaderFormat as any}}
formats={{ agendaHeaderFormat: agendaHeaderFormat as any }}
eventPropGetter={eventPropGetter}
date={this.state.currentDate}
onNavigate={this.onNavigate}
@ -93,11 +93,11 @@ class Calendar extends React.PureComponent<PropsType> {
}
private onNavigate(currentDate: Date) {
this.setState({currentDate});
this.setState({ currentDate });
}
private onView(view: string) {
this.setState({view});
this.setState({ view });
}
private slotClicked(slotInfo: {start: Date, end: Date}) {

@ -16,7 +16,7 @@ import { IconButton } from '@material-ui/core';
class Contact extends React.PureComponent {
public props: {
item?: ContactType,
item?: ContactType;
};
public render() {

@ -24,24 +24,24 @@ import * as EteSync from '../api/EteSync';
import { ContactType } from '../pim-types';
const telTypes = [
{type: 'Home'},
{type: 'Work'},
{type: 'Cell'},
{type: 'Other'},
{ type: 'Home' },
{ type: 'Work' },
{ type: 'Cell' },
{ type: 'Other' },
];
const emailTypes = telTypes;
const addressTypes = [
{type: 'Home'},
{type: 'Work'},
{type: 'Other'},
{ type: 'Home' },
{ type: 'Work' },
{ type: 'Other' },
];
const imppTypes = [
{type: 'Jabber'},
{type: 'Hangouts'},
{type: 'Other'},
{ type: 'Jabber' },
{ type: 'Hangouts' },
{ type: 'Other' },
];
const TypeSelector = (props: any) => {
@ -122,7 +122,7 @@ interface PropsType {
class ContactEdit extends React.PureComponent<PropsType> {
public state: {
uid: string,
uid: string;
fn: string;
phone: ValueType[];
email: ValueType[];
@ -297,7 +297,7 @@ class ContactEdit extends React.PureComponent<PropsType> {
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}
{ type: x.type, value: x.type + ':' + x.value }
)));
function setProperty(name: string, value: string) {
@ -341,7 +341,7 @@ class ContactEdit extends React.PureComponent<PropsType> {
{this.props.item ? 'Edit Contact' : 'New Contact'}
</h2>
<form style={styles.form} onSubmit={this.onSubmit}>
<FormControl disabled={this.props.item !== undefined} style={styles.fullWidth} >
<FormControl disabled={this.props.item !== undefined} style={styles.fullWidth}>
<InputLabel>
Saving to
</InputLabel>
@ -382,7 +382,7 @@ class ContactEdit extends React.PureComponent<PropsType> {
value={this.state.phone[idx]}
onClearRequest={(name: string) => this.removeValueType(name, idx)}
onChange={(name: string, type: string, value: string) => (
this.handleValueTypeChange(name, idx, {type, value})
this.handleValueTypeChange(name, idx, { type, value })
)}
/>
))}
@ -405,7 +405,7 @@ class ContactEdit extends React.PureComponent<PropsType> {
value={this.state.email[idx]}
onClearRequest={(name: string) => this.removeValueType(name, idx)}
onChange={(name: string, type: string, value: string) => (
this.handleValueTypeChange(name, idx, {type, value})
this.handleValueTypeChange(name, idx, { type, value })
)}
/>
))}
@ -428,7 +428,7 @@ class ContactEdit extends React.PureComponent<PropsType> {
value={this.state.impp[idx]}
onClearRequest={(name: string) => this.removeValueType(name, idx)}
onChange={(name: string, type: string, value: string) => (
this.handleValueTypeChange(name, idx, {type, value})
this.handleValueTypeChange(name, idx, { type, value })
)}
/>
))}
@ -451,7 +451,7 @@ class ContactEdit extends React.PureComponent<PropsType> {
value={this.state.address[idx]}
onClearRequest={(name: string) => this.removeValueType(name, idx)}
onChange={(name: string, type: string, value: string) => (
this.handleValueTypeChange(name, idx, {type, value})
this.handleValueTypeChange(name, idx, { type, value })
)}
/>
))}
@ -486,17 +486,17 @@ class ContactEdit extends React.PureComponent<PropsType> {
variant="contained"
onClick={this.props.onCancel}
>
<IconCancel style={{marginRight: 8}} />
<IconCancel style={{ marginRight: 8 }} />
Cancel
</Button>
{this.props.item &&
<Button
variant="contained"
style={{marginLeft: 15, backgroundColor: colors.red[500], color: 'white'}}
style={{ marginLeft: 15, backgroundColor: colors.red[500], color: 'white' }}
onClick={this.onDeleteRequest}
>
<IconDelete style={{marginRight: 8}} />
<IconDelete style={{ marginRight: 8 }} />
Delete
</Button>
}
@ -505,9 +505,9 @@ class ContactEdit extends React.PureComponent<PropsType> {
type="submit"
variant="contained"
color="secondary"
style={{marginLeft: 15}}
style={{ marginLeft: 15 }}
>
<IconSave style={{marginRight: 8}} />
<IconSave style={{ marginRight: 8 }} />
Save
</Button>
</div>
@ -518,15 +518,15 @@ class ContactEdit extends React.PureComponent<PropsType> {
</div>
</form>
<ConfirmationDialog
title="Delete Confirmation"
labelOk="Delete"
open={this.state.showDeleteDialog}
onOk={() => this.props.onDelete(this.props.item!, this.props.initialCollection!)}
onCancel={() => this.setState({showDeleteDialog: false})}
>
<ConfirmationDialog
title="Delete Confirmation"
labelOk="Delete"
open={this.state.showDeleteDialog}
onOk={() => this.props.onDelete(this.props.item!, this.props.initialCollection!)}
onCancel={() => this.setState({ showDeleteDialog: false })}
>
Are you sure you would like to delete this contact?
</ConfirmationDialog>
</ConfirmationDialog>
</React.Fragment>
);
}

@ -8,7 +8,7 @@ interface FormErrors {
class EncryptionLoginForm extends React.PureComponent {
public state: {
errors: FormErrors,
errors: FormErrors;
encryptionPassword: string;
};
@ -48,10 +48,10 @@ class EncryptionLoginForm extends React.PureComponent {
}
if (Object.keys(errors).length) {
this.setState({errors});
this.setState({ errors });
return;
} else {
this.setState({errors: {}});
this.setState({ errors: {} });
}
this.props.onSubmit(encryptionPassword);

@ -6,17 +6,21 @@ import { resetKey } from '../store/actions';
import { EncryptionPasswordError, IntegrityError } from '../api/EteSync';
import PrettyError from '../widgets/PrettyError';
class ErrorBoundary extends React.Component {
interface PropsType {
children: React.ReactNode | React.ReactNode[];
}
class ErrorBoundary extends React.Component<PropsType> {
public state: {
error?: Error;
};
constructor(props: any) {
constructor(props: PropsType) {
super(props);
this.state = { };
}
public componentDidCatch(error: Error, info: any) {
public componentDidCatch(error: Error, _info: any) {
if (error instanceof EncryptionPasswordError) {
store.dispatch(resetKey());
} else if (error instanceof IntegrityError) {
@ -46,7 +50,7 @@ class ErrorBoundary extends React.Component {
Please log out from the menu, refresh the page and try again, and if the problem persists, contact support.
</p>
<pre>
{error.message}
{error.message}
</pre>
</div>
);

@ -8,7 +8,7 @@ import { EventType } from '../pim-types';
class Event extends React.PureComponent {
public props: {
item?: EventType,
item?: EventType;
};
public render() {

@ -42,7 +42,7 @@ interface PropsType {
class EventEdit extends React.PureComponent<PropsType> {
public state: {
uid: string,
uid: string;
title: string;
allDay: boolean;
start?: Date;
@ -143,14 +143,14 @@ class EventEdit extends React.PureComponent<PropsType> {
}
public toggleAllDay() {
this.setState({allDay: !this.state.allDay});
this.setState({ allDay: !this.state.allDay });
}
public onSubmit(e: React.FormEvent<any>) {
e.preventDefault();
if ((!this.state.start) || (!this.state.end)) {
this.setState({error: 'Both start and end time must be set!'});
this.setState({ error: 'Both start and end time must be set!' });
return;
}
@ -173,7 +173,7 @@ class EventEdit extends React.PureComponent<PropsType> {
}
if (startDate.compare(endDate) >= 0) {
this.setState({error: 'End time must be later than start time!'});
this.setState({ error: 'End time must be later than start time!' });
return;
}
@ -242,7 +242,7 @@ class EventEdit extends React.PureComponent<PropsType> {
onChange={this.handleInputChange}
/>
<FormControl disabled={this.props.item !== undefined} style={styles.fullWidth} >
<FormControl disabled={this.props.item !== undefined} style={styles.fullWidth}>
<InputLabel>
Saving to
</InputLabel>
@ -277,7 +277,7 @@ class EventEdit extends React.PureComponent<PropsType> {
dateOnly={this.state.allDay}
placeholder="Start"
value={this.state.start}
onChange={(date?: Date) => this.setState({start: date})}
onChange={(date?: Date) => this.setState({ start: date })}
/>
</div>
@ -286,7 +286,7 @@ class EventEdit extends React.PureComponent<PropsType> {
dateOnly={this.state.allDay}
placeholder="End"
value={this.state.end}
onChange={(date?: Date) => this.setState({end: date})}
onChange={(date?: Date) => this.setState({ end: date })}
/>
</div>
@ -312,17 +312,17 @@ class EventEdit extends React.PureComponent<PropsType> {
variant="contained"
onClick={this.props.onCancel}
>
<IconCancel style={{marginRight: 8}} />
<IconCancel style={{ marginRight: 8 }} />
Cancel
</Button>
{this.props.item &&
<Button
variant="contained"
style={{marginLeft: 15, backgroundColor: colors.red[500], color: 'white'}}
style={{ marginLeft: 15, backgroundColor: colors.red[500], color: 'white' }}
onClick={this.onDeleteRequest}
>
<IconDelete style={{marginRight: 8}} />
<IconDelete style={{ marginRight: 8 }} />
Delete
</Button>
}
@ -331,9 +331,9 @@ class EventEdit extends React.PureComponent<PropsType> {
type="submit"
variant="contained"
color="secondary"
style={{marginLeft: 15}}
style={{ marginLeft: 15 }}
>
<IconSave style={{marginRight: 8}} />
<IconSave style={{ marginRight: 8 }} />
Save
</Button>
</div>
@ -344,15 +344,15 @@ class EventEdit extends React.PureComponent<PropsType> {
</div>
</form>
<ConfirmationDialog
title="Delete Confirmation"
labelOk="Delete"
open={this.state.showDeleteDialog}
onOk={() => this.props.onDelete(this.props.item!, this.props.initialCollection!)}
onCancel={() => this.setState({showDeleteDialog: false})}
>
<ConfirmationDialog
title="Delete Confirmation"
labelOk="Delete"
open={this.state.showDeleteDialog}
onOk={() => this.props.onDelete(this.props.item!, this.props.initialCollection!)}
onCancel={() => this.setState({ showDeleteDialog: false })}
>
Are you sure you would like to delete this event?
</ConfirmationDialog>
</ConfirmationDialog>
</React.Fragment>
);
}

@ -27,9 +27,9 @@ class JournalEntries extends React.PureComponent {
};
public props: {
journal: EteSync.Journal,
entries: Immutable.List<EteSync.SyncEntry>,
uid?: string,
journal: EteSync.Journal;
entries: Immutable.List<EteSync.SyncEntry>;
uid?: string;
};
constructor(props: any) {
@ -47,11 +47,11 @@ class JournalEntries extends React.PureComponent {
let icon;
if (syncEntry.action === EteSync.SyncEntryAction.Add) {
icon = (<IconAdd style={{color: '#16B14B'}} />);
icon = (<IconAdd style={{ color: '#16B14B' }} />);
} else if (syncEntry.action === EteSync.SyncEntryAction.Change) {
icon = (<IconEdit style={{color: '#FEB115'}} />);
icon = (<IconEdit style={{ color: '#FEB115' }} />);
} else if (syncEntry.action === EteSync.SyncEntryAction.Delete) {
icon = (<IconDelete style={{color: '#F20C0C'}} />);
icon = (<IconDelete style={{ color: '#F20C0C' }} />);
}
let name;
@ -91,7 +91,7 @@ class JournalEntries extends React.PureComponent {
});
}}
/>
);
);
}).reverse();
return (
@ -99,7 +99,7 @@ class JournalEntries extends React.PureComponent {
<Dialog
open={this.state.dialog !== undefined}
onClose={() => {
this.setState({dialog: undefined});
this.setState({ dialog: undefined });
}}
>
<DialogTitle>
@ -112,7 +112,7 @@ class JournalEntries extends React.PureComponent {
<Button
color="primary"
onClick={() => {
this.setState({dialog: undefined});
this.setState({ dialog: undefined });
}}
>
Close

@ -77,17 +77,17 @@ class LoginForm extends React.PureComponent {
}
if (Object.keys(errors).length) {
this.setState({errors});
this.setState({ errors });
return;
} else {
this.setState({errors: {}});
this.setState({ errors: {} });
}
this.props.onSubmit(username, password, server);
}
public toggleAdvancedSettings() {
this.setState({showAdvanced: !this.state.showAdvanced});
this.setState({ showAdvanced: !this.state.showAdvanced });
}
public render() {
@ -109,19 +109,19 @@ class LoginForm extends React.PureComponent {
let advancedSettings = null;
if (this.state.showAdvanced) {
advancedSettings = (
<React.Fragment>
<TextField
type="url"
style={styles.textField}
error={!!this.state.errors.errorServer}
helperText={this.state.errors.errorServer}
label="Server"
name="server"
value={this.state.server}
onChange={this.handleInputChange}
/>
<br />
</React.Fragment>
<React.Fragment>
<TextField
type="url"
style={styles.textField}
error={!!this.state.errors.errorServer}
helperText={this.state.errors.errorServer}
label="Server"
name="server"
value={this.state.server}
onChange={this.handleInputChange}
/>
<br />
</React.Fragment>
);
}

@ -3,23 +3,23 @@ import * as React from 'react';
import { Theme, withTheme } from '@material-ui/core/styles';
export default withTheme()((props: {text: string, backgroundColor?: string, children?: any, theme: Theme}) => {
const style = {
header: {
backgroundColor: (props.backgroundColor !== undefined) ?
props.backgroundColor : props.theme.palette.secondary.main,
color: props.theme.palette.secondary.contrastText,
padding: 15,
},
headerText: {
marginTop: 10,
marginBottom: 10,
},
};
const style = {
header: {
backgroundColor: (props.backgroundColor !== undefined) ?
props.backgroundColor : props.theme.palette.secondary.main,
color: props.theme.palette.secondary.contrastText,
padding: 15,
},
headerText: {
marginTop: 10,
marginBottom: 10,
},
};
return (
<div style={style.header}>
<h2 style={style.headerText}>{props.text}</h2>
{props.children}
</div>
);
return (
<div style={style.header}>
<h2 style={style.headerText}>{props.text}</h2>
{props.children}
</div>
);
});

@ -12,8 +12,8 @@ import AddressBook from '../components/AddressBook';
class SearchableAddressBook extends React.PureComponent {
public props: {
entries: ContactType[],
onItemClick: (contact: ContactType) => void,
entries: ContactType[];
onItemClick: (contact: ContactType) => void;
};
public state: {
@ -22,7 +22,7 @@ class SearchableAddressBook extends React.PureComponent {
constructor(props: any) {
super(props);
this.state = {searchQuery: ''};
this.state = { searchQuery: '' };
this.handleInputChange = this.handleInputChange.bind(this);
}
@ -47,12 +47,12 @@ class SearchableAddressBook extends React.PureComponent {
<TextField
name="searchQuery"
value={this.state.searchQuery}
style={{fontSize: '120%', marginLeft: 20}}
style={{ fontSize: '120%', marginLeft: 20 }}
placeholder="Find Contacts"
onChange={this.handleInputChange}
/>
{this.state.searchQuery &&
<IconButton onClick={() => this.setState({searchQuery: ''})}>
<IconButton onClick={() => this.setState({ searchQuery: '' })}>
<IconClear />
</IconButton>
}

@ -8,7 +8,7 @@ import { TaskType } from '../pim-types';
class Task extends React.PureComponent {
public props: {
item?: TaskType,
item?: TaskType;
};
public render() {

@ -42,7 +42,7 @@ interface PropsType {
class TaskEdit extends React.PureComponent<PropsType> {
public state: {
uid: string,
uid: string;
title: string;
status: TaskStatusType;
allDay: boolean;
@ -131,7 +131,7 @@ class TaskEdit extends React.PureComponent<PropsType> {
}
public toggleAllDay() {
this.setState({allDay: !this.state.allDay});
this.setState({ allDay: !this.state.allDay });
}
public onSubmit(e: React.FormEvent<any>) {
@ -156,7 +156,7 @@ class TaskEdit extends React.PureComponent<PropsType> {
if (startDate && dueDate) {
if (startDate.compare(dueDate) >= 0) {
this.setState({error: 'End time must be later than start time!'});
this.setState({ error: 'End time must be later than start time!' });
return;
}
}
@ -230,7 +230,7 @@ class TaskEdit extends React.PureComponent<PropsType> {
onChange={this.handleInputChange}
/>
<FormControl disabled={this.props.item !== undefined} style={styles.fullWidth} >
<FormControl disabled={this.props.item !== undefined} style={styles.fullWidth}>
<InputLabel>
Saving to
</InputLabel>
@ -246,7 +246,7 @@ class TaskEdit extends React.PureComponent<PropsType> {
</Select>
</FormControl>
<FormControl style={styles.fullWidth} >
<FormControl style={styles.fullWidth}>
<InputLabel>
Status
</InputLabel>
@ -281,16 +281,16 @@ class TaskEdit extends React.PureComponent<PropsType> {
dateOnly={this.state.allDay}
placeholder="Start"
value={this.state.start}
onChange={(date?: Date) => this.setState({start: date})}
onChange={(date?: Date) => this.setState({ start: date })}
/>
</div>
</div>
<div>
<DateTimePicker
dateOnly={this.state.allDay}
placeholder="End"
value={this.state.due}
onChange={(date?: Date) => this.setState({due: date})}
onChange={(date?: Date) => this.setState({ due: date })}
/>
</div>
@ -316,17 +316,17 @@ class TaskEdit extends React.PureComponent<PropsType> {
variant="contained"
onClick={this.props.onCancel}
>
<IconCancel style={{marginRight: 8}} />
<IconCancel style={{ marginRight: 8 }} />
Cancel
</Button>
{this.props.item &&
<Button
variant="contained"
style={{marginLeft: 15, backgroundColor: colors.red[500], color: 'white'}}
style={{ marginLeft: 15, backgroundColor: colors.red[500], color: 'white' }}
onClick={this.onDeleteRequest}
>
<IconDelete style={{marginRight: 8}} />
<IconDelete style={{ marginRight: 8 }} />
Delete
</Button>
}
@ -335,9 +335,9 @@ class TaskEdit extends React.PureComponent<PropsType> {
type="submit"
variant="contained"
color="secondary"
style={{marginLeft: 15}}
style={{ marginLeft: 15 }}
>
<IconSave style={{marginRight: 8}} />
<IconSave style={{ marginRight: 8 }} />
Save
</Button>
</div>
@ -348,15 +348,15 @@ class TaskEdit extends React.PureComponent<PropsType> {
</div>
</form>
<ConfirmationDialog
title="Delete Confirmation"
labelOk="Delete"
open={this.state.showDeleteDialog}
onOk={() => this.props.onDelete(this.props.item!, this.props.initialCollection!)}
onCancel={() => this.setState({showDeleteDialog: false})}
>
<ConfirmationDialog
title="Delete Confirmation"
labelOk="Delete"
open={this.state.showDeleteDialog}
onOk={() => this.props.onDelete(this.props.item!, this.props.initialCollection!)}
onCancel={() => this.setState({ showDeleteDialog: false })}
>
Are you sure you would like to delete this event?
</ConfirmationDialog>
</ConfirmationDialog>
</React.Fragment>
);
}

@ -41,8 +41,8 @@ const sortSelector = createSelector(
class TaskList extends React.PureComponent {
public props: {
entries: TaskType[],
onItemClick: (contact: TaskType) => void,
entries: TaskType[];
onItemClick: (contact: TaskType) => void;
};
public render() {

@ -91,7 +91,7 @@ export class TaskType extends EventType {
}
set status(status: TaskStatusType) {
this.component.updatePropertyWithValue('status', status);
this.component.updatePropertyWithValue('status', status);
}
get status(): TaskStatusType {

@ -26,9 +26,9 @@ it('translating routes', () => {
expect(routeResolver.getRoute('post')).toBe('/post');
expect(routeResolver.getRoute('post._id', { postId: 3 })).toBe('/post/3');
expect(routeResolver.getRoute('post._id.comment',
{ postId: 3, commentId: 5 })).toBe('/post/3/comment/5');
{ postId: 3, commentId: 5 })).toBe('/post/3/comment/5');
expect(routeResolver.getRoute('post._id.revision',
{ postId: 3, revisionId: 5, someOtherVar: 'a' })).toBe('/post/3/history/5/a/test');
{ postId: 3, revisionId: 5, someOtherVar: 'a' })).toBe('/post/3/history/5/a/test');
// Failing basic resolves
expect(() => {

@ -189,6 +189,6 @@ export function fetchAll(etesync: CredentialsData, currentEntries: EntriesType)
export const setSettings = createAction(
'SET_SETTINGS',
(settings: SettingsType) => {
return {...settings};
return { ...settings };
}
);

@ -73,14 +73,14 @@ const entriesSerialize = (state: FetchType<EntriesData>) => {
const entriesDeserialize = (state: EteSync.EntryJson[]): FetchType<EntriesData> => {
if (state === null) {
return new EntriesFetchRecord({value: null});
return new EntriesFetchRecord({ value: null });
}
return new EntriesFetchRecord({value: List(state.map((x: any) => {
return new EntriesFetchRecord({ value: List(state.map((x: any) => {
const ret = new EteSync.Entry();
ret.deserialize(x);
return ret;
}))});
})) });
};
const userInfoSerialize = (state: FetchType<UserInfoData>) => {
@ -125,9 +125,9 @@ const cacheDeserialize = (state: any, key: string) => {
});
return ImmutableMap(ret);
} else if (key === 'journals') {
return new JournalsFetchRecord({value: journalsDeserialize(state)});
return new JournalsFetchRecord({ value: journalsDeserialize(state) });
} else if (key === 'userInfo') {
return new UserInfoFetchRecord({value: userInfoDeserialize(state)});
return new UserInfoFetchRecord({ value: userInfoDeserialize(state) });
}
return state;
@ -147,7 +147,7 @@ const cachePersistConfig = {
version: 1,
storage: localforage,
transforms: [createTransform(cacheSerialize, cacheDeserialize)],
migrate: createMigrate(cacheMigrations, { debug: false}),
migrate: createMigrate(cacheMigrations, { debug: false }),
};
const reducers = combineReducers({

@ -17,7 +17,7 @@ it('Entries reducer', () => {
const action = {
type: fetchEntries.toString(),
meta: {journal: jId, prevUid: null as string | null},
meta: { journal: jId, prevUid: null as string | null },
payload: [entry],
};

@ -7,7 +7,7 @@ function isPromise(val: any) {
export default function promiseMiddleware({ dispatch }: any) {
return (next: any) => (action: any) => {
if (isPromise(action.payload)) {
dispatch({...action, payload: undefined});
dispatch({ ...action, payload: undefined });
return action.payload.then(
(result: any) => dispatch({ ...action, payload: result }),

@ -53,7 +53,7 @@ export type UserInfoType = FetchType<UserInfoData>;
export type UserInfoTypeImmutable = Record<UserInfoType>;
function fetchTypeIdentityReducer(
state: Record<FetchType<any>> = fetchTypeRecord<any>()(), action: any, extend: boolean = false) {
state: Record<FetchType<any>> = fetchTypeRecord<any>()(), action: any, extend = false) {
if (action.error) {
return state.set('error', action.payload);
} else {
@ -82,22 +82,22 @@ function fetchTypeIdentityReducer(
export const encryptionKeyReducer = handleActions(
{
[actions.deriveKey.toString()]: (state: {key: string | null}, action: any) => (
{key: action.payload}
{ key: action.payload }
),
[actions.resetKey.toString()]: (state: {key: string | null}, action: any) => (
{key: null}
{ key: null }
),
[actions.logout.toString()]: (state: {key: string | null}, action: any) => {
return {out: true, key: null};
return { out: true, key: null };
},
},
{key: null}
{ key: null }
);
export const credentials = handleActions(
{
[actions.fetchCredentials.toString()]: (
state: CredentialsTypeRemote, action: any, extend: boolean = false) => {
state: CredentialsTypeRemote, action: any, extend = false) => {
if (action.error) {
return {
value: null,
@ -119,10 +119,10 @@ export const credentials = handleActions(
}
},
[actions.logout.toString()]: (state: CredentialsTypeRemote, action: any) => {
return {out: true, value: null};
return { out: true, value: null };
},
},
{value: null}
{ value: null }
);
const setMapModelReducer = <T extends Record<any>, V extends BaseModel>(state: T, action: any) => {
@ -200,7 +200,7 @@ function fetchCreateEntriesReducer(state: EntriesTypeImmutable, action: any) {
const prevState = state.get(action.meta.journal);
const extend = action.meta.prevUid != null;
return state.set(action.meta.journal,
fetchTypeIdentityReducer(prevState, action, extend));
fetchTypeIdentityReducer(prevState, action, extend));
}
export const entries = handleActions(
@ -229,7 +229,7 @@ export const userInfo = handleAction(
actions.fetchUserInfo,
actions.createUserInfo
),
(state: Record<FetchType<any>> = fetchTypeRecord<any>()(), action: any, extend: boolean = false) => {
(state: Record<FetchType<any>> = fetchTypeRecord<any>()(), action: any, extend = false) => {
if (action.error) {
return state.set('error', action.payload);
} else {
@ -285,7 +285,7 @@ export interface SettingsType {
export const settingsReducer = handleActions(
{
[actions.setSettings.toString()]: (state: {key: string | null}, action: any) => (
{...action.payload}
{ ...action.payload }
),
},
{ locale: 'en-gb' }

@ -1,6 +1,6 @@
import * as React from 'react';
export const ExternalLink = React.memo(({children, ...props}: any) => (
export const ExternalLink = React.memo(({ children, ...props }: any) => (
<a target="_blank" rel="noopener" {...props}>
{children}
</a>

@ -8,7 +8,7 @@ function byteArray4ToNumber(bytes: byte[], offset: number) {
return (
((bytes[offset + 0] & 0xff) * (1 << 24)) +
((bytes[offset + 1] & 0xff) * (1 << 16)) +
((bytes[offset + 2] & 0xff) * (1 << 8)) +
((bytes[offset + 2] & 0xff) * (1 << 8)) +
((bytes[offset + 3] & 0xff))
);
}

@ -1,42 +0,0 @@
{
"extends": ["tslint:recommended", "tslint-react"],
"rules": {
"no-console": [true, "error"],
"interface-name": [true, "never-prefix"],
"ordered-imports": false,
"jsx-boolean-value": [true, "never"],
"jsx-curly-spacing": [true, "never"],
"jsx-no-bind": [true, "allowArrowFunctions"],
"jsx-no-lambda": [false],
"jsx-no-multiline-js": false,
"jsx-space-before-trailing-slash": true,
"jsx-key": true,
"max-classes-per-file": [false, 0],
"max-line-length": false,
"no-consecutive-blank-lines": false,
"no-conditional-assignment": false,
"object-literal-sort-keys": false,
"quotemark": [true, "single", "jsx-double", "avoid-escape", "avoid-template"],
"semicolon": [true, "always", "ignore-bound-class-methods"],
"variable-name": [true, "ban-keywords", "check-format", "allow-pascal-case", "allow-leading-underscore"],
"trailing-comma": [
true,
{
"multiline": {
"objects": "always",
"arrays": "always",
"functions": "never",
"typeLiterals": "ignore"
},
"esSpecCompliant": true
}
],
"whitespace": [true,"check-branch", "check-decl", "check-operator", "check-module", "check-separator", "check-rest-spread", "check-type", "check-typecast", "check-type-operator", "check-preblock"]
},
"linterOptions": {
"exclude": [
"config/**/*.js",
"node_modules/**/*.ts"
]
}
}

@ -2461,11 +2461,6 @@ buffer@^4.3.0:
ieee754 "^1.1.4"
isarray "^1.0.0"
builtin-modules@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f"
integrity sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=
builtin-status-codes@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8"
@ -2601,7 +2596,7 @@ caseless@~0.12.0:
resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=
chalk@2.4.2, chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.0, chalk@^2.4.1, chalk@^2.4.2:
chalk@2.4.2, chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.4.1, chalk@^2.4.2:
version "2.4.2"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
@ -2824,7 +2819,7 @@ commander@^2.11.0, commander@^2.20.0, commander@~2.20.3:
resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
commander@^2.12.1, commander@~2.19.0:
commander@~2.19.0:
version "2.19.0"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a"
integrity sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==
@ -3531,11 +3526,6 @@ diff-sequences@^24.9.0:
resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-24.9.0.tgz#5715d6244e2aa65f48bba0bc972db0b0b11e95b5"
integrity sha512-Dj6Wk3tWyTE+Fo1rW8v0Xhwk80um6yFYKbuAxc9c3EZxIHFDYwbi34Uk42u1CdnIiVorvt4RmlSDjIPyzGC2ew==
diff@^3.2.0:
version "3.5.0"
resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12"
integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==
diffie-hellman@^5.0.0:
version "5.0.3"
resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875"
@ -6010,7 +6000,7 @@ js-tokens@^3.0.2:
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b"
integrity sha1-mGbfOVECEw449/mWvOtlRDIJwls=
js-yaml@^3.13.1, js-yaml@^3.7.0:
js-yaml@^3.13.1:
version "3.13.1"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847"
integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==
@ -10182,48 +10172,11 @@ ts-pnp@1.1.4, ts-pnp@^1.1.2:
resolved "https://registry.yarnpkg.com/ts-pnp/-/ts-pnp-1.1.4.tgz#ae27126960ebaefb874c6d7fa4729729ab200d90"
integrity sha512-1J/vefLC+BWSo+qe8OnJQfWTYRS6ingxjwqmHMqaMxXMj7kFtKLgAaYW3JeX3mktjgUL+etlU8/B4VUAUI9QGw==
tslib@^1.8.0:
version "1.9.3"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286"
integrity sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==
tslib@^1.8.1, tslib@^1.9.0:
version "1.10.0"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a"
integrity sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==
tslint-react@^3.6.0:
version "3.6.0"
resolved "https://registry.yarnpkg.com/tslint-react/-/tslint-react-3.6.0.tgz#7f462c95c4a0afaae82507f06517ff02942196a1"
integrity sha512-AIv1QcsSnj7e9pFir6cJ6vIncTqxfqeFF3Lzh8SuuBljueYzEAtByuB6zMaD27BL0xhMEqsZ9s5eHuCONydjBw==
dependencies:
tsutils "^2.13.1"
tslint@^5.12.1:
version "5.12.1"
resolved "https://registry.yarnpkg.com/tslint/-/tslint-5.12.1.tgz#8cec9d454cf8a1de9b0a26d7bdbad6de362e52c1"
integrity sha512-sfodBHOucFg6egff8d1BvuofoOQ/nOeYNfbp7LDlKBcLNrL3lmS5zoiDGyOMdT7YsEXAwWpTdAHwOGOc8eRZAw==
dependencies:
babel-code-frame "^6.22.0"
builtin-modules "^1.1.1"
chalk "^2.3.0"
commander "^2.12.1"
diff "^3.2.0"
glob "^7.1.1"
js-yaml "^3.7.0"
minimatch "^3.0.4"
resolve "^1.3.2"
semver "^5.3.0"
tslib "^1.8.0"
tsutils "^2.27.2"
tsutils@^2.13.1, tsutils@^2.27.2:
version "2.29.0"
resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-2.29.0.tgz#32b488501467acbedd4b85498673a0812aca0b99"
integrity sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==
dependencies:
tslib "^1.8.1"
tsutils@^3.17.1:
version "3.17.1"
resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.17.1.tgz#ed719917f11ca0dee586272b2ac49e015a2dd759"

Loading…
Cancel
Save