Implment item and collection change history.
parent
1f00fbe8cc
commit
485b65cb69
@ -0,0 +1,109 @@
|
|||||||
|
// SPDX-FileCopyrightText: © 2017 EteSync Authors
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
import * as React from "react";
|
||||||
|
|
||||||
|
import * as Etebase from "etebase";
|
||||||
|
|
||||||
|
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 { useCredentials } from "../credentials";
|
||||||
|
import LoadingIndicator from "../widgets/LoadingIndicator";
|
||||||
|
import GenericChangeHistory from "../components/GenericChangeHistory";
|
||||||
|
import { useItems } from "../etebase-helpers";
|
||||||
|
import { CachedCollection } from "./helpers";
|
||||||
|
|
||||||
|
export interface CachedItem {
|
||||||
|
item: Etebase.Item;
|
||||||
|
metadata: Etebase.ItemMetadata;
|
||||||
|
content: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function loadRevisions(etebase: Etebase.Account, col: Etebase.Collection, item: Etebase.Item) {
|
||||||
|
const ret: CachedItem[] = [];
|
||||||
|
const colMgr = etebase.getCollectionManager();
|
||||||
|
const itemManager = colMgr.getItemManager(col);
|
||||||
|
|
||||||
|
let iterator: string | null = null;
|
||||||
|
let done = false;
|
||||||
|
while (!done) {
|
||||||
|
// FIXME: shouldn't be any
|
||||||
|
const revisions: any = await itemManager.itemRevisions(item, { iterator, limit: 30 });
|
||||||
|
iterator = revisions.iterator;
|
||||||
|
done = revisions.done;
|
||||||
|
|
||||||
|
for (const item of revisions.data) {
|
||||||
|
ret.push({
|
||||||
|
item,
|
||||||
|
metadata: await item.getMeta(),
|
||||||
|
content: await item.getContent(Etebase.OutputFormat.String),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface PropsType {
|
||||||
|
collection: CachedCollection;
|
||||||
|
itemUid: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function ItemChangeHistory(props: PropsType) {
|
||||||
|
const [entries, setEntries] = React.useState<CachedItem[]>();
|
||||||
|
const [dialog, setDialog] = React.useState<CachedItem>();
|
||||||
|
const etebase = useCredentials()!;
|
||||||
|
const { collection, metadata } = props.collection;
|
||||||
|
const items = useItems(etebase, metadata.type);
|
||||||
|
|
||||||
|
const item = items?.get(collection.uid)?.get(props.itemUid);
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
if (item) {
|
||||||
|
loadRevisions(etebase, collection, item)
|
||||||
|
.then((entries) => setEntries(entries));
|
||||||
|
}
|
||||||
|
}, [etebase, collection, item]);
|
||||||
|
|
||||||
|
if (!entries) {
|
||||||
|
return (
|
||||||
|
<LoadingIndicator />
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div style={{ height: "calc(100vh - 300px)" }}>
|
||||||
|
<Dialog
|
||||||
|
open={dialog !== undefined}
|
||||||
|
onClose={() => setDialog(undefined)}
|
||||||
|
>
|
||||||
|
<DialogTitle>
|
||||||
|
Raw Content
|
||||||
|
</DialogTitle>
|
||||||
|
<DialogContent>
|
||||||
|
<div>Revision UID: <pre className="d-inline-block">{dialog?.item.etag}</pre></div>
|
||||||
|
<div>Content:
|
||||||
|
<pre>{dialog?.content}</pre>
|
||||||
|
</div>
|
||||||
|
</DialogContent>
|
||||||
|
<DialogActions>
|
||||||
|
<Button
|
||||||
|
color="primary"
|
||||||
|
onClick={() => setDialog(undefined)}
|
||||||
|
>
|
||||||
|
Close
|
||||||
|
</Button>
|
||||||
|
</DialogActions>
|
||||||
|
</Dialog>
|
||||||
|
<GenericChangeHistory
|
||||||
|
items={entries}
|
||||||
|
onItemClick={setDialog}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue