diff --git a/.eslintrc.js b/.eslintrc.js index b445957..3e03e20 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -65,7 +65,7 @@ module.exports = { "react/no-unknown-property": ["error"], "quotes": "off", - "@typescript-eslint/quotes": ["error", "single", { "allowTemplateLiterals": true, "avoidEscape": true }], + "@typescript-eslint/quotes": ["error", "double", { "allowTemplateLiterals": true, "avoidEscape": true }], "semi": "off", "@typescript-eslint/semi": ["error", "always", { "omitLastInOneLineBlock": true }], "comma-dangle": ["error", { diff --git a/src/App.test.tsx b/src/App.test.tsx index 8b416f5..3e7ae0e 100644 --- a/src/App.test.tsx +++ b/src/App.test.tsx @@ -1,15 +1,15 @@ // SPDX-FileCopyrightText: © 2017 EteSync Authors // SPDX-License-Identifier: AGPL-3.0-only -import * as React from 'react'; -import * as ReactDOM from 'react-dom'; -import { Provider } from 'react-redux'; -import App from './App'; +import * as React from "react"; +import * as ReactDOM from "react-dom"; +import { Provider } from "react-redux"; +import App from "./App"; -import { store } from './store'; +import { store } from "./store"; -it('renders without crashing', () => { - const div = document.createElement('div'); +it("renders without crashing", () => { + const div = document.createElement("div"); ReactDOM.render( diff --git a/src/App.tsx b/src/App.tsx index c4d401a..8bb6bd0 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,93 +1,93 @@ // SPDX-FileCopyrightText: © 2017 EteSync Authors // SPDX-License-Identifier: AGPL-3.0-only -import * as React from 'react'; -import { List as ImmutableList } from 'immutable'; -import { connect } from 'react-redux'; -import { withRouter } from 'react-router'; -import { BrowserRouter } from 'react-router-dom'; -import { MuiThemeProvider as ThemeProvider, createMuiTheme } from '@material-ui/core/styles'; // v1.x -import amber from '@material-ui/core/colors/amber'; -import lightBlue from '@material-ui/core/colors/lightBlue'; -import AppBar from '@material-ui/core/AppBar'; -import Toolbar from '@material-ui/core/Toolbar'; -import Drawer from '@material-ui/core/Drawer'; -import IconButton from '@material-ui/core/IconButton'; -import Badge from '@material-ui/core/Badge'; - -import NavigationMenu from '@material-ui/icons/Menu'; -import NavigationBack from '@material-ui/icons/ArrowBack'; -import NavigationRefresh from '@material-ui/icons/Refresh'; -import ErrorsIcon from '@material-ui/icons/Error'; - -import 'react-virtualized/styles.css'; // only needs to be imported once - -import './App.css'; - -import ConfirmationDialog from './widgets/ConfirmationDialog'; -import PrettyError from './widgets/PrettyError'; -import { List, ListItem } from './widgets/List'; -import withSpin from './widgets/withSpin'; -import ErrorBoundary from './components/ErrorBoundary'; -import SideMenu from './SideMenu'; -import LoginGate from './LoginGate'; -import { RouteResolver } from './routes'; - -import * as store from './store'; -import * as actions from './store/actions'; - -import { credentialsSelector } from './login'; - -import { History } from 'history'; +import * as React from "react"; +import { List as ImmutableList } from "immutable"; +import { connect } from "react-redux"; +import { withRouter } from "react-router"; +import { BrowserRouter } from "react-router-dom"; +import { MuiThemeProvider as ThemeProvider, createMuiTheme } from "@material-ui/core/styles"; // v1.x +import amber from "@material-ui/core/colors/amber"; +import lightBlue from "@material-ui/core/colors/lightBlue"; +import AppBar from "@material-ui/core/AppBar"; +import Toolbar from "@material-ui/core/Toolbar"; +import Drawer from "@material-ui/core/Drawer"; +import IconButton from "@material-ui/core/IconButton"; +import Badge from "@material-ui/core/Badge"; + +import NavigationMenu from "@material-ui/icons/Menu"; +import NavigationBack from "@material-ui/icons/ArrowBack"; +import NavigationRefresh from "@material-ui/icons/Refresh"; +import ErrorsIcon from "@material-ui/icons/Error"; + +import "react-virtualized/styles.css"; // only needs to be imported once + +import "./App.css"; + +import ConfirmationDialog from "./widgets/ConfirmationDialog"; +import PrettyError from "./widgets/PrettyError"; +import { List, ListItem } from "./widgets/List"; +import withSpin from "./widgets/withSpin"; +import ErrorBoundary from "./components/ErrorBoundary"; +import SideMenu from "./SideMenu"; +import LoginGate from "./LoginGate"; +import { RouteResolver } from "./routes"; + +import * as store from "./store"; +import * as actions from "./store/actions"; + +import { credentialsSelector } from "./login"; + +import { History } from "history"; export const routeResolver = new RouteResolver({ - home: '', + home: "", pim: { contacts: { _id: { - _base: ':itemUid', - edit: 'edit', - log: 'log', + _base: ":itemUid", + edit: "edit", + log: "log", }, - new: 'new', + new: "new", }, events: { _id: { - _base: ':itemUid', - edit: 'edit', - duplicate: 'duplicate', - log: 'log', + _base: ":itemUid", + edit: "edit", + duplicate: "duplicate", + log: "log", }, - new: 'new', + new: "new", }, tasks: { _id: { - _base: ':itemUid', - edit: 'edit', - log: 'log', + _base: ":itemUid", + edit: "edit", + log: "log", }, - new: 'new', + new: "new", }, }, journals: { _id: { - _base: ':journalUid', - edit: 'edit', + _base: ":journalUid", + edit: "edit", items: { _id: { - _base: ':itemUid', + _base: ":itemUid", }, }, entries: { _id: { - _base: ':entryUid', + _base: ":entryUid", }, }, members: { }, }, - new: 'new', - import: 'import', + new: "new", + import: "import", }, settings: { }, @@ -132,7 +132,7 @@ const AppBarWitHistory = withRouter( } -
+
{iconElementRight} @@ -145,8 +145,8 @@ const AppBarWitHistory = withRouter( private canGoBack() { return ( (this.props.history!.length > 1) && - (this.props.history!.location.pathname !== routeResolver.getRoute('pim')) && - (this.props.history!.location.pathname !== routeResolver.getRoute('home')) + (this.props.history!.location.pathname !== routeResolver.getRoute("pim")) && + (this.props.history!.location.pathname !== routeResolver.getRoute("home")) ); } @@ -191,13 +191,13 @@ class App extends React.PureComponent { const muiTheme = createMuiTheme({ palette: { - type: darkMode ? 'dark' : undefined, + type: darkMode ? "dark" : undefined, primary: amber, secondary: { light: lightBlue.A200, main: lightBlue.A400, dark: lightBlue.A700, - contrastText: '#fff', + contrastText: "#fff", }, }, }); @@ -213,7 +213,7 @@ class App extends React.PureComponent { return ( -
+
} iconElementRight={ @@ -245,7 +245,7 @@ class App extends React.PureComponent { {errors.map((error, index) => ( (window as any).navigator.clipboard.writeText(`${error.message}\n\n${error.stack}`)} > diff --git a/src/Debug.tsx b/src/Debug.tsx index 6f922dc..7330b3a 100644 --- a/src/Debug.tsx +++ b/src/Debug.tsx @@ -1,14 +1,14 @@ // SPDX-FileCopyrightText: © 2017 EteSync Authors // SPDX-License-Identifier: AGPL-3.0-only -import * as React from 'react'; -import * as EteSync from 'etesync'; -import Button from '@material-ui/core/Button'; -import TextField from '@material-ui/core/TextField'; +import * as React from "react"; +import * as EteSync from "etesync"; +import Button from "@material-ui/core/Button"; +import TextField from "@material-ui/core/TextField"; -import Container from './widgets/Container'; -import { useSelector } from 'react-redux'; -import { StoreState, CredentialsData, UserInfoData, EntriesListData } from './store'; +import Container from "./widgets/Container"; +import { useSelector } from "react-redux"; +import { StoreState, CredentialsData, UserInfoData, EntriesListData } from "./store"; interface PropsType { etesync: CredentialsData; @@ -16,9 +16,9 @@ interface PropsType { } export default function Debug(props: PropsType) { - const [stateJournalUid, setJournalUid] = React.useState(''); - const [entriesUids, setEntriesUids] = React.useState(''); - const [result, setResult] = React.useState(''); + const [stateJournalUid, setJournalUid] = React.useState(""); + const [entriesUids, setEntriesUids] = React.useState(""); + const [result, setResult] = React.useState(""); const journals = useSelector((state: StoreState) => state.cache.journals!); const journalEntries = useSelector((state: StoreState) => state.cache.entries); @@ -32,7 +32,7 @@ export default function Debug(props: PropsType) {
wantedEntries[ent.trim()] = true); + const wantAll = (entriesUids.trim() === "all"); + entriesUids.split("\n").forEach((ent) => wantedEntries[ent.trim()] = true); const cryptoManager = journal.getCryptoManager(derived, keyPair); let prevUid: string | null = null; @@ -79,7 +79,7 @@ export default function Debug(props: PropsType) { return (wantAll || wantedEntries[entry.uid]) ? syncEntry : undefined; }).filter((x) => x !== undefined); - setResult(syncEntries.map((ent) => ent?.content).join('\n\n')); + setResult(syncEntries.map((ent) => ent?.content).join("\n\n")); }} > Decrypt diff --git a/src/Journals/ImportDialog.tsx b/src/Journals/ImportDialog.tsx index b373f83..90fc35a 100644 --- a/src/Journals/ImportDialog.tsx +++ b/src/Journals/ImportDialog.tsx @@ -1,29 +1,29 @@ // SPDX-FileCopyrightText: © 2017 EteSync Authors // SPDX-License-Identifier: AGPL-3.0-only -import * as React from 'react'; +import * as React from "react"; -import Button from '@material-ui/core/Button'; -import Dialog from '@material-ui/core/Dialog'; -import DialogActions from '@material-ui/core/DialogActions'; -import DialogContent from '@material-ui/core/DialogContent'; -import DialogContentText from '@material-ui/core/DialogContentText'; -import DialogTitle from '@material-ui/core/DialogTitle'; +import Button from "@material-ui/core/Button"; +import Dialog from "@material-ui/core/Dialog"; +import DialogActions from "@material-ui/core/DialogActions"; +import DialogContent from "@material-ui/core/DialogContent"; +import DialogContentText from "@material-ui/core/DialogContentText"; +import DialogTitle from "@material-ui/core/DialogTitle"; -import Dropzone from 'react-dropzone'; +import Dropzone from "react-dropzone"; -import LoadingIndicator from '../widgets/LoadingIndicator'; +import LoadingIndicator from "../widgets/LoadingIndicator"; -import { SyncInfoJournal } from '../SyncGate'; +import { SyncInfoJournal } from "../SyncGate"; -import { store, CredentialsData, UserInfoData } from '../store'; -import { addEntries } from '../store/actions'; -import { createJournalEntry } from '../etesync-helpers'; -import * as EteSync from 'etesync'; +import { store, CredentialsData, UserInfoData } from "../store"; +import { addEntries } from "../store/actions"; +import { createJournalEntry } from "../etesync-helpers"; +import * as EteSync from "etesync"; -import * as uuid from 'uuid'; -import * as ICAL from 'ical.js'; -import { ContactType, EventType, TaskType, PimType } from '../pim-types'; +import * as uuid from "uuid"; +import * as ICAL from "ical.js"; +import { ContactType, EventType, TaskType, PimType } from "../pim-types"; interface PropsType { etesync: CredentialsData; @@ -55,14 +55,14 @@ class ImportDialog extends React.Component { let acceptTypes; let dropFunction; - if (collectionInfo.type === 'ADDRESS_BOOK') { - acceptTypes = ['text/vcard', 'text/directory', 'text/x-vcard', '.vcf']; + if (collectionInfo.type === "ADDRESS_BOOK") { + acceptTypes = ["text/vcard", "text/directory", "text/x-vcard", ".vcf"]; dropFunction = this.onFileDropContact; - } else if (collectionInfo.type === 'CALENDAR') { - acceptTypes = ['text/calendar', '.ics', '.ical']; + } else if (collectionInfo.type === "CALENDAR") { + acceptTypes = ["text/calendar", ".ics", ".ical"]; dropFunction = this.onFileDropEvent; - } else if (collectionInfo.type === 'TASKS') { - acceptTypes = ['text/calendar', '.ics', '.ical']; + } else if (collectionInfo.type === "TASKS") { + acceptTypes = ["text/calendar", ".ics", ".ical"]; dropFunction = this.onFileDropTask; } @@ -75,7 +75,7 @@ class ImportDialog extends React.Component { Import entries from file? {loading ? - + : { reader.onabort = () => { this.setState({ loading: false }); - console.error('Import Aborted'); - alert('file reading was aborted'); + console.error("Import Aborted"); + alert("file reading was aborted"); }; reader.onerror = (e) => { this.setState({ loading: false }); console.error(e); - alert('file reading has failed'); + alert("file reading has failed"); }; reader.onload = async () => { try { @@ -144,7 +144,7 @@ class ImportDialog extends React.Component { ); } catch (e) { console.error(e); - alert('An error has occurred, please contact developers.'); + alert("An error has occurred, please contact developers."); throw e; } finally { if (this.props.onClose) { @@ -160,8 +160,8 @@ class ImportDialog extends React.Component { reader.readAsText(file); }); } else { - alert('Failed importing file. Is the file type supported?'); - console.log('Failed importing files. Rejected:', rejectedFiles); + alert("Failed importing file. Is the file type supported?"); + console.log("Failed importing files. Rejected:", rejectedFiles); } } @@ -183,7 +183,7 @@ class ImportDialog extends React.Component { private onFileDropEvent(acceptedFiles: File[], rejectedFiles: File[]) { const itemsCreator = (fileText: string) => { const calendarComp = new ICAL.Component(ICAL.parse(fileText)); - return calendarComp.getAllSubcomponents('vevent').map((comp) => { + return calendarComp.getAllSubcomponents("vevent").map((comp) => { const ret = new EventType(comp); if (!ret.uid) { ret.uid = uuid.v4(); @@ -198,7 +198,7 @@ class ImportDialog extends React.Component { private onFileDropTask(acceptedFiles: File[], rejectedFiles: File[]) { const itemsCreator = (fileText: string) => { const calendarComp = new ICAL.Component(ICAL.parse(fileText)); - return calendarComp.getAllSubcomponents('vtodo').map((comp) => { + return calendarComp.getAllSubcomponents("vtodo").map((comp) => { const ret = new TaskType(comp); if (!ret.uid) { ret.uid = uuid.v4(); diff --git a/src/Journals/Journal.tsx b/src/Journals/Journal.tsx index 40e976b..7cc4a18 100644 --- a/src/Journals/Journal.tsx +++ b/src/Journals/Journal.tsx @@ -1,26 +1,26 @@ // SPDX-FileCopyrightText: © 2017 EteSync Authors // SPDX-License-Identifier: AGPL-3.0-only -import * as React from 'react'; -import IconButton from '@material-ui/core/IconButton'; -import IconEdit from '@material-ui/icons/Edit'; -import IconMembers from '@material-ui/icons/People'; -import IconImport from '@material-ui/icons/ImportExport'; +import * as React from "react"; +import IconButton from "@material-ui/core/IconButton"; +import IconEdit from "@material-ui/icons/Edit"; +import IconMembers from "@material-ui/icons/People"; +import IconImport from "@material-ui/icons/ImportExport"; -import AppBarOverride from '../widgets/AppBarOverride'; -import Container from '../widgets/Container'; +import AppBarOverride from "../widgets/AppBarOverride"; +import Container from "../widgets/Container"; -import JournalEntries from '../components/JournalEntries'; -import ImportDialog from './ImportDialog'; +import JournalEntries from "../components/JournalEntries"; +import ImportDialog from "./ImportDialog"; -import { SyncInfo, SyncInfoJournal } from '../SyncGate'; +import { SyncInfo, SyncInfoJournal } from "../SyncGate"; -import { Link } from 'react-router-dom'; +import { Link } from "react-router-dom"; -import { routeResolver } from '../App'; +import { routeResolver } from "../App"; -import { CredentialsData, UserInfoData } from '../store'; +import { CredentialsData, UserInfoData } from "../store"; interface PropsType { etesync: CredentialsData; @@ -61,14 +61,14 @@ class Journal extends React.Component { diff --git a/src/Journals/JournalEdit.tsx b/src/Journals/JournalEdit.tsx index dab7139..14d2997 100644 --- a/src/Journals/JournalEdit.tsx +++ b/src/Journals/JournalEdit.tsx @@ -1,26 +1,26 @@ // SPDX-FileCopyrightText: © 2017 EteSync Authors // SPDX-License-Identifier: AGPL-3.0-only -import * as React from 'react'; -import Button from '@material-ui/core/Button'; -import TextField from '@material-ui/core/TextField'; -import Select from '@material-ui/core/Select'; -import MenuItem from '@material-ui/core/MenuItem'; -import FormControl from '@material-ui/core/FormControl'; -import InputLabel from '@material-ui/core/InputLabel'; -import IconDelete from '@material-ui/icons/Delete'; -import IconCancel from '@material-ui/icons/Clear'; -import IconSave from '@material-ui/icons/Save'; -import * as colors from '@material-ui/core/colors'; - -import AppBarOverride from '../widgets/AppBarOverride'; -import Container from '../widgets/Container'; -import ConfirmationDialog from '../widgets/ConfirmationDialog'; - -import * as EteSync from 'etesync'; -import { SyncInfo } from '../SyncGate'; -import ColorPicker from '../widgets/ColorPicker'; -import { defaultColor, colorHtmlToInt, colorIntToHtml } from '../journal-processors'; +import * as React from "react"; +import Button from "@material-ui/core/Button"; +import TextField from "@material-ui/core/TextField"; +import Select from "@material-ui/core/Select"; +import MenuItem from "@material-ui/core/MenuItem"; +import FormControl from "@material-ui/core/FormControl"; +import InputLabel from "@material-ui/core/InputLabel"; +import IconDelete from "@material-ui/icons/Delete"; +import IconCancel from "@material-ui/icons/Clear"; +import IconSave from "@material-ui/icons/Save"; +import * as colors from "@material-ui/core/colors"; + +import AppBarOverride from "../widgets/AppBarOverride"; +import Container from "../widgets/Container"; +import ConfirmationDialog from "../widgets/ConfirmationDialog"; + +import * as EteSync from "etesync"; +import { SyncInfo } from "../SyncGate"; +import ColorPicker from "../widgets/ColorPicker"; +import { defaultColor, colorHtmlToInt, colorIntToHtml } from "../journal-processors"; interface PropsType { syncInfo: SyncInfo; @@ -39,7 +39,7 @@ export default function JournalEdit(props: PropsType) { const [errors, setErrors] = React.useState({}); const [showDeleteDialog, setShowDeleteDialog] = React.useState(false); const [info, setInfo] = React.useState(); - const [selectedColor, setSelectedColor] = React.useState(''); + const [selectedColor, setSelectedColor] = React.useState(""); React.useEffect(() => { if (props.item !== undefined) { @@ -50,9 +50,9 @@ export default function JournalEdit(props: PropsType) { } else { setInfo({ uid: EteSync.genUid(), - type: 'ADDRESS_BOOK', - displayName: '', - description: '', + type: "ADDRESS_BOOK", + displayName: "", + description: "", } as EteSync.CollectionInfo); } }, [props.item]); @@ -64,7 +64,7 @@ export default function JournalEdit(props: PropsType) { function onSubmit(e: React.FormEvent) { e.preventDefault(); const saveErrors: FormErrors = {}; - const fieldRequired = 'This field is required!'; + const fieldRequired = "This field is required!"; const { onSave } = props; @@ -76,7 +76,7 @@ export default function JournalEdit(props: PropsType) { } if (selectedColor && !color) { - saveErrors.color = 'Must be of the form #RRGGBB or #RRGGBBAA or empty'; + saveErrors.color = "Must be of the form #RRGGBB or #RRGGBBAA or empty"; } if (Object.keys(saveErrors).length > 0) { @@ -94,28 +94,28 @@ export default function JournalEdit(props: PropsType) { const { item, onDelete, onCancel } = props; - const pageTitle = (item !== undefined) ? item.displayName : 'New Journal'; + const pageTitle = (item !== undefined) ? item.displayName : "New Journal"; const styles = { fullWidth: { - width: '100%', + width: "100%", }, submit: { marginTop: 40, marginBottom: 20, - textAlign: 'right' as any, + textAlign: "right" as any, }, }; const journalTypes = { - ADDRESS_BOOK: 'Address Book', - CALENDAR: 'Calendar', - TASKS: 'Task List', + ADDRESS_BOOK: "Address Book", + CALENDAR: "Calendar", + TASKS: "Task List", }; let collectionColorBox: React.ReactNode; switch (info.type) { - case 'CALENDAR': - case 'TASKS': + case "CALENDAR": + case "TASKS": collectionColorBox = ( - +
@@ -180,7 +180,7 @@ export default function JournalEdit(props: PropsType) { {props.item && - {props.routePrefix === 'pim.events' && + {props.routePrefix === "pim.events" &&
diff --git a/src/components/ErrorBoundary.tsx b/src/components/ErrorBoundary.tsx index 7583cec..5146962 100644 --- a/src/components/ErrorBoundary.tsx +++ b/src/components/ErrorBoundary.tsx @@ -1,13 +1,13 @@ // SPDX-FileCopyrightText: © 2017 EteSync Authors // SPDX-License-Identifier: AGPL-3.0-only -import * as React from 'react'; +import * as React from "react"; -import { store, persistor } from '../store'; -import { resetKey } from '../store/actions'; +import { store, persistor } from "../store"; +import { resetKey } from "../store/actions"; -import { EncryptionPasswordError, IntegrityError } from 'etesync'; -import PrettyError from '../widgets/PrettyError'; +import { EncryptionPasswordError, IntegrityError } from "etesync"; +import PrettyError from "../widgets/PrettyError"; interface PropsType { children: React.ReactNode | React.ReactNode[]; diff --git a/src/components/Event.tsx b/src/components/Event.tsx index 892cdf4..60c9396 100644 --- a/src/components/Event.tsx +++ b/src/components/Event.tsx @@ -1,13 +1,13 @@ // SPDX-FileCopyrightText: © 2017 EteSync Authors // SPDX-License-Identifier: AGPL-3.0-only -import * as React from 'react'; +import * as React from "react"; -import PimItemHeader from './PimItemHeader'; +import PimItemHeader from "./PimItemHeader"; -import { formatDateRange, formatOurTimezoneOffset } from '../helpers'; +import { formatDateRange, formatOurTimezoneOffset } from "../helpers"; -import { EventType } from '../pim-types'; +import { EventType } from "../pim-types"; class Event extends React.PureComponent { public props: { @@ -16,7 +16,7 @@ class Event extends React.PureComponent { public render() { if (this.props.item === undefined) { - throw Error('Event should be defined!'); + throw Error("Event should be defined!"); } const style = { @@ -35,9 +35,9 @@ class Event extends React.PureComponent {
{this.props.item.location}
-

{this.props.item.description}

+

{this.props.item.description}

{(this.props.item.attendees.length > 0) && ( -
Attendees: {this.props.item.attendees.map((x) => (x.getFirstValue())).join(', ')}
)} +
Attendees: {this.props.item.attendees.map((x) => (x.getFirstValue())).join(", ")}
)}
); diff --git a/src/components/EventEdit.tsx b/src/components/EventEdit.tsx index c845e0a..372d761 100644 --- a/src/components/EventEdit.tsx +++ b/src/components/EventEdit.tsx @@ -1,45 +1,45 @@ // SPDX-FileCopyrightText: © 2017 EteSync Authors // SPDX-License-Identifier: AGPL-3.0-only -import * as React from 'react'; +import * as React from "react"; -import FormGroup from '@material-ui/core/FormGroup'; -import FormControlLabel from '@material-ui/core/FormControlLabel'; -import Switch from '@material-ui/core/Switch'; +import FormGroup from "@material-ui/core/FormGroup"; +import FormControlLabel from "@material-ui/core/FormControlLabel"; +import Switch from "@material-ui/core/Switch"; -import Button from '@material-ui/core/Button'; -import TextField from '@material-ui/core/TextField'; -import Select from '@material-ui/core/Select'; -import MenuItem from '@material-ui/core/MenuItem'; -import FormControl from '@material-ui/core/FormControl'; -import FormHelperText from '@material-ui/core/FormHelperText'; -import InputLabel from '@material-ui/core/InputLabel'; -import * as colors from '@material-ui/core/colors'; +import Button from "@material-ui/core/Button"; +import TextField from "@material-ui/core/TextField"; +import Select from "@material-ui/core/Select"; +import MenuItem from "@material-ui/core/MenuItem"; +import FormControl from "@material-ui/core/FormControl"; +import FormHelperText from "@material-ui/core/FormHelperText"; +import InputLabel from "@material-ui/core/InputLabel"; +import * as colors from "@material-ui/core/colors"; -import IconDelete from '@material-ui/icons/Delete'; -import IconCancel from '@material-ui/icons/Clear'; -import IconSave from '@material-ui/icons/Save'; +import IconDelete from "@material-ui/icons/Delete"; +import IconCancel from "@material-ui/icons/Clear"; +import IconSave from "@material-ui/icons/Save"; -import DateTimePicker from '../widgets/DateTimePicker'; +import DateTimePicker from "../widgets/DateTimePicker"; -import ConfirmationDialog from '../widgets/ConfirmationDialog'; -import TimezonePicker from '../widgets/TimezonePicker'; -import Toast from '../widgets/Toast'; +import ConfirmationDialog from "../widgets/ConfirmationDialog"; +import TimezonePicker from "../widgets/TimezonePicker"; +import Toast from "../widgets/Toast"; -import { Location } from 'history'; -import { withRouter } from 'react-router'; +import { Location } from "history"; +import { withRouter } from "react-router"; -import * as uuid from 'uuid'; -import * as ICAL from 'ical.js'; +import * as uuid from "uuid"; +import * as ICAL from "ical.js"; -import * as EteSync from 'etesync'; +import * as EteSync from "etesync"; -import { getCurrentTimezone } from '../helpers'; +import { getCurrentTimezone } from "../helpers"; -import { EventType, timezoneLoadFromName } from '../pim-types'; -import RRule, { RRuleOptions } from '../widgets/RRule'; +import { EventType, timezoneLoadFromName } from "../pim-types"; +import RRule, { RRuleOptions } from "../widgets/RRule"; -import { History } from 'history'; +import { History } from "history"; interface PropsType { collections: EteSync.CollectionInfo[]; @@ -73,14 +73,14 @@ class EventEdit extends React.PureComponent { constructor(props: any) { super(props); this.state = { - uid: '', - title: '', + uid: "", + title: "", allDay: false, - location: '', - description: '', + location: "", + description: "", timezone: null, - journalUid: '', + journalUid: "", showDeleteDialog: false, }; @@ -107,18 +107,18 @@ class EventEdit extends React.PureComponent { } if (this.props.duplicate) { - this.state.title = event.title ? `Copy of ${event.title}` : ''; + this.state.title = event.title ? `Copy of ${event.title}` : ""; } else { this.state.uid = event.uid; - this.state.title = event.title ? event.title : ''; + this.state.title = event.title ? event.title : ""; } this.state.allDay = allDay; this.state.start = event.startDate.convertToZone(ICAL.Timezone.localTimezone).toJSDate(); this.state.end = endDate.convertToZone(ICAL.Timezone.localTimezone).toJSDate(); - this.state.location = event.location ? event.location : ''; - this.state.description = event.description ? event.description : ''; + this.state.location = event.location ? event.location : ""; + this.state.description = event.description ? event.description : ""; this.state.timezone = event.timezone; - const rruleProp = this.props.item?.component.getFirstPropertyValue('rrule'); + const rruleProp = this.props.item?.component.getFirstPropertyValue("rrule"); if (rruleProp) { this.state.rrule = rruleProp.toJSON() as any; if (this.state.rrule && rruleProp.until) { @@ -165,7 +165,7 @@ class EventEdit extends React.PureComponent { this.setState({ allDay: !this.state.allDay }); } public toggleRecurring() { - const value = this.state.rrule ? undefined : { freq: 'WEEKLY', interval: 1 }; + const value = this.state.rrule ? undefined : { freq: "WEEKLY", interval: 1 }; this.setState({ rrule: value }); } @@ -175,18 +175,18 @@ class EventEdit extends React.PureComponent { } public handleCloseToast(_event?: React.SyntheticEvent, reason?: string) { - if (reason === 'clickaway') { + if (reason === "clickaway") { return; } - this.setState({ error: '' }); + this.setState({ error: "" }); } public onSubmit(e: React.FormEvent) { 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; } @@ -209,7 +209,7 @@ class EventEdit extends React.PureComponent { } 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; } @@ -233,10 +233,10 @@ class EventEdit extends React.PureComponent { } } if (this.state.rrule) { - event.component.updatePropertyWithValue('rrule', new ICAL.Recur(this.state.rrule!)); + event.component.updatePropertyWithValue("rrule", new ICAL.Recur(this.state.rrule!)); } - event.component.updatePropertyWithValue('last-modified', ICAL.Time.now()); + event.component.updatePropertyWithValue("last-modified", ICAL.Time.now()); this.props.onSave(event, this.state.journalUid, this.props.item) .then(() => { @@ -255,14 +255,14 @@ class EventEdit extends React.PureComponent { form: { }, fullWidth: { - width: '100%', - boxSizing: 'border-box' as any, + width: "100%", + boxSizing: "border-box" as any, marginTop: 16, }, submit: { marginTop: 40, marginBottom: 20, - textAlign: 'right' as any, + textAlign: "right" as any, }, }; @@ -272,11 +272,11 @@ class EventEdit extends React.PureComponent { return ( <>

- {(this.props.item && !this.props.duplicate) ? 'Edit Event' : 'New Event'} + {(this.props.item && !this.props.duplicate) ? "Edit Event" : "New Event"}

{recurring && (
- IMPORTANT: + IMPORTANT: This is a recurring event, for now, only editing the whole series (by editing the first instance) is supported.
@@ -385,7 +385,7 @@ class EventEdit extends React.PureComponent { {this.state.rrule && }
@@ -400,7 +400,7 @@ class EventEdit extends React.PureComponent { {this.props.item && - + {({ height, width }) => ( Error! {this.props.error.message}
)}
- {this.props.loading ? 'Loading…' : 'Log In'} + {this.props.loading ? "Loading…" : "Log In"}
diff --git a/src/components/PimItemHeader.tsx b/src/components/PimItemHeader.tsx index f33fbed..9429e28 100644 --- a/src/components/PimItemHeader.tsx +++ b/src/components/PimItemHeader.tsx @@ -1,10 +1,10 @@ // SPDX-FileCopyrightText: © 2017 EteSync Authors // SPDX-License-Identifier: AGPL-3.0-only -import * as React from 'react'; -import Color from 'color'; +import * as React from "react"; +import Color from "color"; -import { Theme, withTheme } from '@material-ui/core/styles'; +import { Theme, withTheme } from "@material-ui/core/styles"; export default withTheme((props: {text: string, backgroundColor?: string, children?: any, rightItem?: React.ReactNode, theme: Theme}) => { const backgroundColor = props.backgroundColor ?? props.theme.palette.secondary.main; @@ -14,8 +14,8 @@ export default withTheme((props: {text: string, backgroundColor?: string, childr backgroundColor, color: foregroundColor, padding: 15, - display: 'flex', - justifyContent: 'space-between', + display: "flex", + justifyContent: "space-between", }, headerText: { marginTop: 10, diff --git a/src/components/SearchableAddressBook.tsx b/src/components/SearchableAddressBook.tsx index 749f001..656b36c 100644 --- a/src/components/SearchableAddressBook.tsx +++ b/src/components/SearchableAddressBook.tsx @@ -1,17 +1,17 @@ // SPDX-FileCopyrightText: © 2017 EteSync Authors // SPDX-License-Identifier: AGPL-3.0-only -import * as React from 'react'; +import * as React from "react"; -import TextField from '@material-ui/core/TextField'; +import TextField from "@material-ui/core/TextField"; -import IconButton from '@material-ui/core/IconButton'; -import IconSearch from '@material-ui/icons/Search'; -import IconClear from '@material-ui/icons/Clear'; +import IconButton from "@material-ui/core/IconButton"; +import IconSearch from "@material-ui/icons/Search"; +import IconClear from "@material-ui/icons/Clear"; -import { ContactType } from '../pim-types'; +import { ContactType } from "../pim-types"; -import AddressBook from '../components/AddressBook'; +import AddressBook from "../components/AddressBook"; class SearchableAddressBook extends React.PureComponent { public props: { @@ -25,7 +25,7 @@ class SearchableAddressBook extends React.PureComponent { constructor(props: any) { super(props); - this.state = { searchQuery: '' }; + this.state = { searchQuery: "" }; this.handleInputChange = this.handleInputChange.bind(this); } @@ -43,19 +43,19 @@ class SearchableAddressBook extends React.PureComponent { ...rest } = this.props; - const reg = new RegExp(this.state.searchQuery, 'i'); + const reg = new RegExp(this.state.searchQuery, "i"); return ( {this.state.searchQuery && - this.setState({ searchQuery: '' })}> + this.setState({ searchQuery: "" })}> } diff --git a/src/components/Tasks/QuickAdd.tsx b/src/components/Tasks/QuickAdd.tsx index 90ea832..48684f7 100644 --- a/src/components/Tasks/QuickAdd.tsx +++ b/src/components/Tasks/QuickAdd.tsx @@ -1,17 +1,17 @@ // SPDX-FileCopyrightText: © 2017 EteSync Authors // SPDX-License-Identifier: AGPL-3.0-only -import * as React from 'react'; +import * as React from "react"; -import * as EteSync from 'etesync'; +import * as EteSync from "etesync"; -import ICAL from 'ical.js'; +import ICAL from "ical.js"; -import uuid from 'uuid'; +import uuid from "uuid"; -import TextField from '@material-ui/core/TextField'; +import TextField from "@material-ui/core/TextField"; -import { TaskType, PimType, TaskStatusType } from '../../pim-types'; +import { TaskType, PimType, TaskStatusType } from "../../pim-types"; interface PropsType { style: React.CSSProperties; @@ -20,7 +20,7 @@ interface PropsType { } function QuickAdd(props: PropsType) { - const [title, setTitle] = React.useState(''); + const [title, setTitle] = React.useState(""); const { style, onSubmit: save, defaultCollection } = props; @@ -39,7 +39,7 @@ function QuickAdd(props: PropsType) { save(task, defaultCollection.uid, undefined); - setTitle(''); + setTitle(""); } diff --git a/src/components/Tasks/Sidebar.tsx b/src/components/Tasks/Sidebar.tsx index 60c117c..677355f 100644 --- a/src/components/Tasks/Sidebar.tsx +++ b/src/components/Tasks/Sidebar.tsx @@ -1,16 +1,16 @@ -import * as React from 'react'; +import * as React from "react"; -import { useSelector, useDispatch } from 'react-redux'; +import { useSelector, useDispatch } from "react-redux"; -import InboxIcon from '@material-ui/icons/Inbox'; -import LabelIcon from '@material-ui/icons/LabelOutlined'; -import TodayIcon from '@material-ui/icons/Today'; +import InboxIcon from "@material-ui/icons/Inbox"; +import LabelIcon from "@material-ui/icons/LabelOutlined"; +import TodayIcon from "@material-ui/icons/Today"; -import { setSettings } from '../../store/actions'; -import { StoreState } from '../../store'; +import { setSettings } from "../../store/actions"; +import { StoreState } from "../../store"; -import { List, ListItem, ListSubheader } from '../../widgets/List'; -import { TaskType } from '../../pim-types'; +import { List, ListItem, ListSubheader } from "../../widgets/List"; +import { TaskType } from "../../pim-types"; interface ListItemPropsType { name: string | null; @@ -34,7 +34,7 @@ function SidebarListItem(props: ListItemPropsType) { onClick={handleClick} selected={name === filterBy} leftIcon={icon} - rightIcon={{(amount > 0) && amount}} + rightIcon={{(amount > 0) && amount}} primaryText={primaryText} /> ); diff --git a/src/components/Tasks/Task.tsx b/src/components/Tasks/Task.tsx index ed71e9e..2ddf95e 100644 --- a/src/components/Tasks/Task.tsx +++ b/src/components/Tasks/Task.tsx @@ -1,13 +1,13 @@ // SPDX-FileCopyrightText: © 2017 EteSync Authors // SPDX-License-Identifier: AGPL-3.0-only -import * as React from 'react'; +import * as React from "react"; -import PimItemHeader from '../PimItemHeader'; +import PimItemHeader from "../PimItemHeader"; -import { formatDate, formatOurTimezoneOffset } from '../../helpers'; +import { formatDate, formatOurTimezoneOffset } from "../../helpers"; -import { TaskType } from '../../pim-types'; +import { TaskType } from "../../pim-types"; class Task extends React.PureComponent { public props: { @@ -16,7 +16,7 @@ class Task extends React.PureComponent { public render() { if (this.props.item === undefined) { - throw Error('Task should be defined!'); + throw Error("Task should be defined!"); } const { item } = this.props; @@ -42,9 +42,9 @@ class Task extends React.PureComponent {
{this.props.item.location}
-

{this.props.item.description}

+

{this.props.item.description}

{(this.props.item.attendees.length > 0) && ( -
Attendees: {this.props.item.attendees.map((x) => (x.getFirstValue())).join(', ')}
)} +
Attendees: {this.props.item.attendees.map((x) => (x.getFirstValue())).join(", ")}
)}
); diff --git a/src/components/Tasks/TaskEdit.tsx b/src/components/Tasks/TaskEdit.tsx index 63f4657..e36a943 100644 --- a/src/components/Tasks/TaskEdit.tsx +++ b/src/components/Tasks/TaskEdit.tsx @@ -1,51 +1,51 @@ // SPDX-FileCopyrightText: © 2017 EteSync Authors // SPDX-License-Identifier: AGPL-3.0-only -import * as React from 'react'; +import * as React from "react"; -import FormGroup from '@material-ui/core/FormGroup'; -import FormControlLabel from '@material-ui/core/FormControlLabel'; -import Switch from '@material-ui/core/Switch'; +import FormGroup from "@material-ui/core/FormGroup"; +import FormControlLabel from "@material-ui/core/FormControlLabel"; +import Switch from "@material-ui/core/Switch"; -import Button from '@material-ui/core/Button'; -import TextField from '@material-ui/core/TextField'; -import Select from '@material-ui/core/Select'; -import MenuItem from '@material-ui/core/MenuItem'; -import FormControl from '@material-ui/core/FormControl'; -import FormHelperText from '@material-ui/core/FormHelperText'; -import InputLabel from '@material-ui/core/InputLabel'; -import * as colors from '@material-ui/core/colors'; -import FormLabel from '@material-ui/core/FormLabel'; -import RadioGroup from '@material-ui/core/RadioGroup'; +import Button from "@material-ui/core/Button"; +import TextField from "@material-ui/core/TextField"; +import Select from "@material-ui/core/Select"; +import MenuItem from "@material-ui/core/MenuItem"; +import FormControl from "@material-ui/core/FormControl"; +import FormHelperText from "@material-ui/core/FormHelperText"; +import InputLabel from "@material-ui/core/InputLabel"; +import * as colors from "@material-ui/core/colors"; +import FormLabel from "@material-ui/core/FormLabel"; +import RadioGroup from "@material-ui/core/RadioGroup"; -import Autocomplete from '@material-ui/lab/Autocomplete'; +import Autocomplete from "@material-ui/lab/Autocomplete"; -import IconDelete from '@material-ui/icons/Delete'; -import IconCancel from '@material-ui/icons/Clear'; -import IconSave from '@material-ui/icons/Save'; +import IconDelete from "@material-ui/icons/Delete"; +import IconCancel from "@material-ui/icons/Clear"; +import IconSave from "@material-ui/icons/Save"; -import DateTimePicker from '../../widgets/DateTimePicker'; +import DateTimePicker from "../../widgets/DateTimePicker"; -import ConfirmationDialog from '../../widgets/ConfirmationDialog'; -import TimezonePicker from '../../widgets/TimezonePicker'; -import Toast from '../../widgets/Toast'; +import ConfirmationDialog from "../../widgets/ConfirmationDialog"; +import TimezonePicker from "../../widgets/TimezonePicker"; +import Toast from "../../widgets/Toast"; -import { Location } from 'history'; -import { withRouter } from 'react-router'; +import { Location } from "history"; +import { withRouter } from "react-router"; -import * as uuid from 'uuid'; -import * as ICAL from 'ical.js'; +import * as uuid from "uuid"; +import * as ICAL from "ical.js"; -import * as EteSync from 'etesync'; +import * as EteSync from "etesync"; -import { getCurrentTimezone, mapPriority } from '../../helpers'; +import { getCurrentTimezone, mapPriority } from "../../helpers"; -import { TaskType, TaskStatusType, timezoneLoadFromName, TaskPriorityType, TaskTags } from '../../pim-types'; +import { TaskType, TaskStatusType, timezoneLoadFromName, TaskPriorityType, TaskTags } from "../../pim-types"; -import { History } from 'history'; +import { History } from "history"; -import ColoredRadio from '../../widgets/ColoredRadio'; -import RRule, { RRuleOptions } from '../../widgets/RRule'; +import ColoredRadio from "../../widgets/ColoredRadio"; +import RRule, { RRuleOptions } from "../../widgets/RRule"; interface PropsType { collections: EteSync.CollectionInfo[]; @@ -81,17 +81,17 @@ class TaskEdit extends React.PureComponent { constructor(props: any) { super(props); this.state = { - uid: '', - title: '', + uid: "", + title: "", status: TaskStatusType.NeedsAction, priority: TaskPriorityType.Undefined, includeTime: false, - location: '', - description: '', + location: "", + description: "", tags: [], timezone: null, - journalUid: '', + journalUid: "", showDeleteDialog: false, }; @@ -99,7 +99,7 @@ class TaskEdit extends React.PureComponent { const task = this.props.item; this.state.uid = task.uid; - this.state.title = task.title ? task.title : ''; + this.state.title = task.title ? task.title : ""; this.state.status = task.status ?? TaskStatusType.NeedsAction; this.state.priority = task.priority ?? TaskPriorityType.Undefined; if (task.startDate) { @@ -116,8 +116,8 @@ class TaskEdit extends React.PureComponent { this.state.rrule.until = rrule.until; } } - this.state.location = task.location ? task.location : ''; - this.state.description = task.description ? task.description : ''; + this.state.location = task.location ? task.location : ""; + this.state.description = task.description ? task.description : ""; this.state.timezone = task.timezone; this.state.tags = task.tags; } else { @@ -160,15 +160,15 @@ class TaskEdit extends React.PureComponent { } public handleCloseToast(_event?: React.SyntheticEvent, reason?: string) { - if (reason === 'clickaway') { + if (reason === "clickaway") { return; } - this.setState({ error: '' }); + this.setState({ error: "" }); } public toggleRecurring() { - const value = this.state.rrule ? undefined : { freq: 'WEEKLY', interval: 1 }; + const value = this.state.rrule ? undefined : { freq: "WEEKLY", interval: 1 }; this.setState({ rrule: value }); } @@ -180,7 +180,7 @@ class TaskEdit extends React.PureComponent { e.preventDefault(); if (this.state.rrule && !(this.state.start || this.state.due)) { - this.setState({ error: 'A recurring task must have either Hide Until or Due Date set!' }); + this.setState({ error: "A recurring task must have either Hide Until or Due Date set!" }); return; } @@ -203,7 +203,7 @@ class TaskEdit extends React.PureComponent { 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; } } @@ -243,7 +243,7 @@ class TaskEdit extends React.PureComponent { } } - task.component.updatePropertyWithValue('last-modified', ICAL.Time.now()); + task.component.updatePropertyWithValue("last-modified", ICAL.Time.now()); this.props.onSave(task, this.state.journalUid, this.props.item) .then(() => { @@ -258,7 +258,7 @@ class TaskEdit extends React.PureComponent { this.props.history.goBack(); }) .catch(() => { - this.setState({ error: 'Could not save task' }); + this.setState({ error: "Could not save task" }); }); } @@ -273,14 +273,14 @@ class TaskEdit extends React.PureComponent { form: { }, fullWidth: { - width: '100%', - boxSizing: 'border-box' as any, + width: "100%", + boxSizing: "border-box" as any, marginTop: 16, }, submit: { marginTop: 40, marginBottom: 20, - textAlign: 'right' as any, + textAlign: "right" as any, }, }; @@ -290,11 +290,11 @@ class TaskEdit extends React.PureComponent { return (

- {this.props.item ? 'Edit Task' : 'New Task'} + {this.props.item ? "Edit Task" : "New Task"}

{recurring && (
- IMPORTANT: + IMPORTANT: This is a recurring task, for now, only editing the whole series (by editing the first instance) is supported.
@@ -349,7 +349,7 @@ class TaskEdit extends React.PureComponent { this.handleChange('priority', Number(e.target.value))} + onChange={(e) => this.handleChange("priority", Number(e.target.value))} > @@ -418,7 +418,7 @@ class TaskEdit extends React.PureComponent { {this.state.rrule && } @@ -445,7 +445,7 @@ class TaskEdit extends React.PureComponent { multiple options={TaskTags} value={this.state.tags} - onChange={(_e, value) => this.handleChange('tags', value)} + onChange={(_e, value) => this.handleChange("tags", value)} renderInput={(params) => ( { {this.props.item && diff --git a/src/widgets/Container.tsx b/src/widgets/Container.tsx index f2982eb..f3d502c 100644 --- a/src/widgets/Container.tsx +++ b/src/widgets/Container.tsx @@ -1,10 +1,10 @@ // SPDX-FileCopyrightText: © 2017 EteSync Authors // SPDX-License-Identifier: AGPL-3.0-only -import * as React from 'react'; -import Paper from '@material-ui/core/Paper'; +import * as React from "react"; +import Paper from "@material-ui/core/Paper"; -import './Container.css'; +import "./Container.css"; export default (props: {style?: any, children: any}) => (
diff --git a/src/widgets/DateTimePicker.tsx b/src/widgets/DateTimePicker.tsx index fae67f9..530c4d4 100644 --- a/src/widgets/DateTimePicker.tsx +++ b/src/widgets/DateTimePicker.tsx @@ -1,12 +1,12 @@ // SPDX-FileCopyrightText: © 2017 EteSync Authors // SPDX-License-Identifier: AGPL-3.0-only -import * as React from 'react'; +import * as React from "react"; -import MomentUtils from '@date-io/moment'; -import { MuiPickersUtilsProvider, KeyboardDatePicker, KeyboardDateTimePicker } from '@material-ui/pickers'; +import MomentUtils from "@date-io/moment"; +import { MuiPickersUtilsProvider, KeyboardDatePicker, KeyboardDateTimePicker } from "@material-ui/pickers"; -import moment from 'moment'; +import moment from "moment"; interface PropsType { placeholder: string; @@ -23,7 +23,7 @@ class DateTimePicker extends React.PureComponent { public render() { const Picker = (this.props.dateOnly) ? KeyboardDatePicker : KeyboardDateTimePicker; - const dateFormat = (this.props.dateOnly) ? 'DD/MM/YYYY' : 'DD/MM/YYYY HH:mm'; + const dateFormat = (this.props.dateOnly) ? "DD/MM/YYYY" : "DD/MM/YYYY HH:mm"; return ( { ampm={false} showTodayButton KeyboardButtonProps={{ - 'aria-label': 'change date', + "aria-label": "change date", }} /> diff --git a/src/widgets/ExternalLink.tsx b/src/widgets/ExternalLink.tsx index bde1f6f..4f1e818 100644 --- a/src/widgets/ExternalLink.tsx +++ b/src/widgets/ExternalLink.tsx @@ -1,7 +1,7 @@ // SPDX-FileCopyrightText: © 2017 EteSync Authors // SPDX-License-Identifier: AGPL-3.0-only -import * as React from 'react'; +import * as React from "react"; export const ExternalLink = React.memo(({ children, ...props }: any) => ( diff --git a/src/widgets/List.tsx b/src/widgets/List.tsx index f34d407..f496ed6 100644 --- a/src/widgets/List.tsx +++ b/src/widgets/List.tsx @@ -1,17 +1,17 @@ // SPDX-FileCopyrightText: © 2017 EteSync Authors // SPDX-License-Identifier: AGPL-3.0-only -import * as React from 'react'; +import * as React from "react"; -import { createStyles, makeStyles } from '@material-ui/core/styles'; -import MuiList from '@material-ui/core/List'; -import MuiListItem from '@material-ui/core/ListItem'; -import MuiListSubheader from '@material-ui/core/ListSubheader'; -import ListItemIcon from '@material-ui/core/ListItemIcon'; -import ListItemText from '@material-ui/core/ListItemText'; -import Divider from '@material-ui/core/Divider'; +import { createStyles, makeStyles } from "@material-ui/core/styles"; +import MuiList from "@material-ui/core/List"; +import MuiListItem from "@material-ui/core/ListItem"; +import MuiListSubheader from "@material-ui/core/ListSubheader"; +import ListItemIcon from "@material-ui/core/ListItemIcon"; +import ListItemText from "@material-ui/core/ListItemText"; +import Divider from "@material-ui/core/Divider"; -import ExternalLink from './ExternalLink'; +import ExternalLink from "./ExternalLink"; const useStyles = makeStyles((theme) => (createStyles({ inset: { @@ -46,7 +46,7 @@ interface ListItemPropsType { insetChildren?: boolean; nestedItems?: React.ReactNode[]; selected?: boolean; - secondaryTextColor?: 'initial' | 'inherit' | 'primary' | 'secondary' | 'textPrimary' | 'textSecondary' | 'error'; + secondaryTextColor?: "initial" | "inherit" | "primary" | "secondary" | "textPrimary" | "textSecondary" | "error"; } export const ListItem = React.memo(function ListItem(_props: ListItemPropsType) { @@ -70,7 +70,7 @@ export const ListItem = React.memo(function ListItem(_props: ListItemPropsType) button: true, href, onClick, - component: (href) ? ExternalLink : 'div', + component: (href) ? ExternalLink : "div", } : undefined; return ( diff --git a/src/widgets/LoadingIndicator.tsx b/src/widgets/LoadingIndicator.tsx index a418bd7..b4cfc0a 100644 --- a/src/widgets/LoadingIndicator.tsx +++ b/src/widgets/LoadingIndicator.tsx @@ -1,8 +1,8 @@ // SPDX-FileCopyrightText: © 2017 EteSync Authors // SPDX-License-Identifier: AGPL-3.0-only -import * as React from 'react'; -import CircularProgress from '@material-ui/core/CircularProgress'; +import * as React from "react"; +import CircularProgress from "@material-ui/core/CircularProgress"; export default (props: any) => { return ( diff --git a/src/widgets/Menu.tsx b/src/widgets/Menu.tsx index 89a236b..db9c341 100644 --- a/src/widgets/Menu.tsx +++ b/src/widgets/Menu.tsx @@ -1,19 +1,19 @@ // SPDX-FileCopyrightText: © 2017 EteSync Authors // SPDX-License-Identifier: AGPL-3.0-only -import * as React from 'react'; +import * as React from "react"; -import MuiMenu, { MenuProps } from '@material-ui/core/Menu'; -import { PopoverOrigin } from '@material-ui/core/Popover'; +import MuiMenu, { MenuProps } from "@material-ui/core/Menu"; +import { PopoverOrigin } from "@material-ui/core/Popover"; const anchorOrigin: PopoverOrigin = { - vertical: 'bottom', - horizontal: 'right', + vertical: "bottom", + horizontal: "right", }; const transferOrigin: PopoverOrigin = { - vertical: 'top', - horizontal: 'right', + vertical: "top", + horizontal: "right", }; export default function Menu(props: MenuProps) { diff --git a/src/widgets/PrettyError.tsx b/src/widgets/PrettyError.tsx index adc0a53..561b13f 100644 --- a/src/widgets/PrettyError.tsx +++ b/src/widgets/PrettyError.tsx @@ -1,11 +1,11 @@ // SPDX-FileCopyrightText: © 2017 EteSync Authors // SPDX-License-Identifier: AGPL-3.0-only -import * as React from 'react'; +import * as React from "react"; export const PrettyError = React.memo((props: any) => (
-
+    
       {props.error.message}
     
diff --git a/src/widgets/PrettyFingerprint.tsx b/src/widgets/PrettyFingerprint.tsx index 9676f13..27f9bf4 100644 --- a/src/widgets/PrettyFingerprint.tsx +++ b/src/widgets/PrettyFingerprint.tsx @@ -1,10 +1,10 @@ // SPDX-FileCopyrightText: © 2017 EteSync Authors // SPDX-License-Identifier: AGPL-3.0-only -import * as React from 'react'; -import sjcl from 'sjcl'; +import * as React from "react"; +import sjcl from "sjcl"; -import { byte, base64 } from 'etesync'; +import { byte, base64 } from "etesync"; function byteArray4ToNumber(bytes: byte[], offset: number) { // tslint:disable:no-bitwise @@ -18,7 +18,7 @@ function byteArray4ToNumber(bytes: byte[], offset: number) { function getEncodedChunk(publicKey: byte[], offset: number) { const chunk = byteArray4ToNumber(publicKey, offset) % 100000; - return chunk.toString().padStart(5, '0'); + return chunk.toString().padStart(5, "0"); } interface PropsType { @@ -31,12 +31,12 @@ class PrettyFingerprint extends React.PureComponent { sjcl.hash.sha256.hash(sjcl.codec.base64.toBits(this.props.publicKey)) ); - const spacing = ' '; + const spacing = " "; const prettyPublicKey = getEncodedChunk(fingerprint, 0) + spacing + getEncodedChunk(fingerprint, 4) + spacing + getEncodedChunk(fingerprint, 8) + spacing + - getEncodedChunk(fingerprint, 12) + '\n' + + getEncodedChunk(fingerprint, 12) + "\n" + getEncodedChunk(fingerprint, 16) + spacing + getEncodedChunk(fingerprint, 20) + spacing + getEncodedChunk(fingerprint, 24) + spacing + diff --git a/src/widgets/RRule.tsx b/src/widgets/RRule.tsx index 64cbe4f..24859ee 100644 --- a/src/widgets/RRule.tsx +++ b/src/widgets/RRule.tsx @@ -1,10 +1,10 @@ // SPDX-FileCopyrightText: © 2017 EteSync Authors // SPDX-License-Identifier: AGPL-3.0-only -import * as React from 'react'; -import { TextField, Select, MenuItem, InputLabel, FormControl } from '@material-ui/core'; -import DateTimePicker from '../widgets/DateTimePicker'; -import * as ICAL from 'ical.js'; +import * as React from "react"; +import { TextField, Select, MenuItem, InputLabel, FormControl } from "@material-ui/core"; +import DateTimePicker from "../widgets/DateTimePicker"; +import * as ICAL from "ical.js"; export type RRuleOptions = ICAL.RecurData; @@ -53,13 +53,13 @@ const menuItemsEnds = [Ends.Forever, Ends.Until, Ends.After].map((key) => { let displayhName; switch (key) { case Ends.Forever: - displayhName = 'Forever'; + displayhName = "Forever"; break; case Ends.Until: - displayhName = 'Until'; + displayhName = "Until"; break; case Ends.After: - displayhName = 'For'; + displayhName = "For"; break; } @@ -67,7 +67,7 @@ const menuItemsEnds = [Ends.Forever, Ends.Until, Ends.After].map((key) => { {displayhName} ); }); -const menuItemsFrequency = ['YEARLY', 'MONTHLY', 'WEEKLY', 'DAILY'].map((value) => { +const menuItemsFrequency = ["YEARLY", "MONTHLY", "WEEKLY", "DAILY"].map((value) => { return ( {value.toLowerCase()} ); @@ -108,7 +108,7 @@ function sanitizeByDay(item: string | string[] | undefined) { } const styles = { - multiSelect: { minWidth: 120, maxWidth: '100%' }, + multiSelect: { minWidth: 120, maxWidth: "100%" }, width: { width: 120 }, }; @@ -146,12 +146,12 @@ export default function RRule(props: PropsType) { } } return ( -
-
+
+
Repeat - every + every ) => { event.preventDefault(); const inputNode = event.currentTarget as HTMLInputElement; - if (inputNode.value === '') { + if (inputNode.value === "") { updateRule({ interval: 1 }); } else if (inputNode.valueAsNumber) { updateRule({ interval: inputNode.valueAsNumber }); @@ -176,7 +176,7 @@ export default function RRule(props: PropsType) { }} />
- {(options.freq && options.freq !== 'DAILY') && + {(options.freq && options.freq !== "DAILY") &&
Weekdays @@ -194,8 +194,8 @@ export default function RRule(props: PropsType) {
} {!disableComplex && ( -
- {(options.freq === 'MONTHLY') && +
+ {(options.freq === "MONTHLY") && ) => { const value = Number((event.target as HTMLSelectElement).value); let updateOptions; @@ -296,19 +296,19 @@ export default function RRule(props: PropsType) { ) => { event.preventDefault(); const inputNode = event.currentTarget as HTMLInputElement; - if (inputNode.value === '') { + if (inputNode.value === "") { updateRule({ count: 1 }); } else if (inputNode.valueAsNumber) { updateRule({ count: inputNode.valueAsNumber }); } }} /> - events + events }
diff --git a/src/widgets/TimezonePicker.tsx b/src/widgets/TimezonePicker.tsx index e81ffac..09ff21b 100644 --- a/src/widgets/TimezonePicker.tsx +++ b/src/widgets/TimezonePicker.tsx @@ -1,12 +1,12 @@ // SPDX-FileCopyrightText: © 2017 EteSync Authors // SPDX-License-Identifier: AGPL-3.0-only -import * as React from 'react'; +import * as React from "react"; -import Autocomplete from '@material-ui/lab/Autocomplete'; -import TextField from '@material-ui/core/TextField'; +import Autocomplete from "@material-ui/lab/Autocomplete"; +import TextField from "@material-ui/core/TextField"; -import * as zones from '../data/zones.json'; +import * as zones from "../data/zones.json"; const zonelist = Object.keys(zones.zones).sort(); interface PropsType { @@ -21,7 +21,7 @@ export default React.memo(function TimezonePicker(props: PropsType) { options={zonelist} value={props.value} onChange={(_e: any, value: string) => props.onChange(value)} - getOptionLabel={(option) => option.replace('_', ' ')} + getOptionLabel={(option) => option.replace("_", " ")} style={props.style} renderInput={(params) => ( diff --git a/src/widgets/Toast.tsx b/src/widgets/Toast.tsx index 9894070..2a9ef3a 100644 --- a/src/widgets/Toast.tsx +++ b/src/widgets/Toast.tsx @@ -1,16 +1,16 @@ // SPDX-FileCopyrightText: © 2017 EteSync Authors // SPDX-License-Identifier: AGPL-3.0-only -import * as React from 'react'; +import * as React from "react"; -import Snackbar from '@material-ui/core/Snackbar'; -import Alert from '@material-ui/lab/Alert'; +import Snackbar from "@material-ui/core/Snackbar"; +import Alert from "@material-ui/lab/Alert"; export interface PropsType { open: boolean; children: React.ReactNode; onClose?: (event?: React.SyntheticEvent, reason?: string) => void; - severity?: 'error' | 'info' | 'success' | 'warning'; + severity?: "error" | "info" | "success" | "warning"; autoHideDuration?: number; } diff --git a/src/widgets/withSpin.tsx b/src/widgets/withSpin.tsx index 514802b..20de554 100644 --- a/src/widgets/withSpin.tsx +++ b/src/widgets/withSpin.tsx @@ -1,9 +1,9 @@ // SPDX-FileCopyrightText: © 2017 EteSync Authors // SPDX-License-Identifier: AGPL-3.0-only -import * as React from 'react'; +import * as React from "react"; -import './withSpin.css'; +import "./withSpin.css"; const withSpin = (Component: any) => { return React.memo((_props: any) => { @@ -12,7 +12,7 @@ const withSpin = (Component: any) => { ...props } = _props; return ( - + ); }); };