GenericChangeHistory: split the change history to its own component.

master
Tom Hacohen 4 years ago
parent da95830d9f
commit 1f00fbe8cc

@ -3,27 +3,19 @@
import * as React from "react";
import moment from "moment";
import * as Etebase from "etebase";
import { AutoSizer, List as VirtualizedList } from "react-virtualized";
import { List, ListItem } from "../widgets/List";
import Dialog from "@material-ui/core/Dialog";
import DialogTitle from "@material-ui/core/DialogTitle";
import DialogContent from "@material-ui/core/DialogContent";
import DialogActions from "@material-ui/core/DialogActions";
import Button from "@material-ui/core/Button";
import IconEdit from "@material-ui/icons/Edit";
import IconDelete from "@material-ui/icons/Delete";
import IconError from "@material-ui/icons/Error";
import { useCredentials } from "../credentials";
import { useItems } from "../etebase-helpers";
import { TaskType, EventType, ContactType, parseString } from "../pim-types";
import { CachedCollection } from "../Pim/helpers";
import LoadingIndicator from "../widgets/LoadingIndicator";
import GenericChangeHistory from "../components/GenericChangeHistory";
export interface CachedItem {
item: Etebase.Item;
@ -82,65 +74,8 @@ export default function CollectionChangeEntries(props: PropsType) {
return a - b;
});
const rowRenderer = (params: { index: number, key: string, style: React.CSSProperties }) => {
const { key, index, style } = params;
const cacheItem = entriesList[entriesList.length - index - 1]!;
let comp;
try {
comp = parseString(cacheItem.content);
} catch (e) {
const icon = (<IconError style={{ color: "red" }} />);
return (
<ListItem
key={key}
style={style}
leftIcon={icon}
primaryText="Failed parsing item"
secondaryText="Unknown"
onClick={() => setDialog(cacheItem)}
/>
);
}
let icon;
if (!cacheItem.item.isDeleted) {
icon = (<IconEdit style={{ color: "#16B14B" }} />);
} else {
icon = (<IconDelete style={{ color: "#F20C0C" }} />);
}
let name;
if (comp.name === "vcalendar") {
if (EventType.isEvent(comp)) {
const vevent = EventType.fromVCalendar(comp);
name = vevent.summary;
} else {
const vtodo = TaskType.fromVCalendar(comp);
name = vtodo.summary;
}
} else if (comp.name === "vcard") {
const vcard = new ContactType(comp);
name = vcard.fn;
} else {
name = "Error processing entry";
}
const mtime = (cacheItem.metadata.mtime) ? moment(cacheItem.metadata.mtime) : undefined;
return (
<ListItem
key={key}
style={style}
leftIcon={icon}
primaryText={name}
secondaryText={mtime && mtime.format("llll")}
onClick={() => setDialog(cacheItem)}
/>
);
};
return (
<div>
<div style={{ height: "calc(100vh - 300px)" }}>
<Dialog
open={dialog !== undefined}
onClose={() => setDialog(undefined)}
@ -163,19 +98,10 @@ export default function CollectionChangeEntries(props: PropsType) {
</Button>
</DialogActions>
</Dialog>
<List style={{ height: "calc(100vh - 300px)" }}>
<AutoSizer>
{({ height, width }) => (
<VirtualizedList
width={width}
height={height}
rowCount={entriesList.length}
rowHeight={56}
rowRenderer={rowRenderer}
/>
)}
</AutoSizer>
</List>
<GenericChangeHistory
items={entriesList}
onItemClick={setDialog}
/>
</div>
);
}

@ -0,0 +1,112 @@
// SPDX-FileCopyrightText: © 2017 EteSync Authors
// SPDX-License-Identifier: AGPL-3.0-only
import * as React from "react";
import moment from "moment";
import * as Etebase from "etebase";
import { AutoSizer, List as VirtualizedList } from "react-virtualized";
import { List, ListItem } from "../widgets/List";
import IconEdit from "@material-ui/icons/Edit";
import IconDelete from "@material-ui/icons/Delete";
import IconError from "@material-ui/icons/Error";
import { TaskType, EventType, ContactType, parseString } from "../pim-types";
export interface CachedItem {
item: Etebase.Item;
metadata: Etebase.ItemMetadata;
content: string;
}
interface PropsType {
items: CachedItem[];
onItemClick: (item: CachedItem) => void;
}
export default function GenericChangeHistory(props: PropsType) {
const entriesList = props.items.sort((a_, b_) => {
const a = a_.metadata.mtime ?? 0;
const b = b_.metadata.mtime ?? 0;
return a - b;
});
const onItemClick = props.onItemClick;
const rowRenderer = (params: { index: number, key: string, style: React.CSSProperties }) => {
const { key, index, style } = params;
const cacheItem = entriesList[entriesList.length - index - 1]!;
let comp;
try {
comp = parseString(cacheItem.content);
} catch (e) {
const icon = (<IconError style={{ color: "red" }} />);
return (
<ListItem
key={key}
style={style}
leftIcon={icon}
primaryText="Failed parsing item"
secondaryText="Unknown"
onClick={() => onItemClick(cacheItem)}
/>
);
}
let icon;
if (!cacheItem.item.isDeleted) {
icon = (<IconEdit style={{ color: "#16B14B" }} />);
} else {
icon = (<IconDelete style={{ color: "#F20C0C" }} />);
}
let name;
if (comp.name === "vcalendar") {
if (EventType.isEvent(comp)) {
const vevent = EventType.fromVCalendar(comp);
name = vevent.summary;
} else {
const vtodo = TaskType.fromVCalendar(comp);
name = vtodo.summary;
}
} else if (comp.name === "vcard") {
const vcard = new ContactType(comp);
name = vcard.fn;
} else {
name = "Error processing entry";
}
const mtime = (cacheItem.metadata.mtime) ? moment(cacheItem.metadata.mtime) : undefined;
return (
<ListItem
key={key}
style={style}
leftIcon={icon}
primaryText={name}
secondaryText={mtime && mtime.format("llll")}
onClick={() => onItemClick(cacheItem)}
/>
);
};
return (
<List style={{ height: "100%" }}>
<AutoSizer>
{({ height, width }) => (
<VirtualizedList
width={width}
height={height}
rowCount={entriesList.length}
rowHeight={56}
rowRenderer={rowRenderer}
/>
)}
</AutoSizer>
</List>
);
}
Loading…
Cancel
Save