fix: Improved handling of delete events from collection and document sockets (#1517)

* handle delete events fron collection and document sockets

* handle collection deletes to documents

* rework semantics to always reload after a delete

Co-authored-by: Tom Moor <tom.moor@gmail.com>
This commit is contained in:
Nan Yu
2020-09-07 19:05:10 -07:00
committed by GitHub
parent ceeac9b982
commit e7ab2939d4
4 changed files with 54 additions and 16 deletions

View File

@ -125,6 +125,8 @@ class SocketProvider extends React.Component<Props> {
if (document) { if (document) {
document.deletedAt = documentDescriptor.updatedAt; document.deletedAt = documentDescriptor.updatedAt;
} }
policies.remove(documentId);
continue; continue;
} }
@ -172,7 +174,21 @@ class SocketProvider extends React.Component<Props> {
const collection = collections.get(collectionId) || {}; const collection = collections.get(collectionId) || {};
if (event.event === "collections.delete") { if (event.event === "collections.delete") {
const collection = collections.get(collectionId);
if (collection) {
collection.deletedAt = collectionDescriptor.updatedAt;
}
const deletedDocuments = documents.inCollection(collectionId);
deletedDocuments.forEach((doc) => {
doc.deletedAt = collectionDescriptor.updatedAt;
policies.remove(doc.id);
});
documents.removeCollectionDocuments(collectionId); documents.removeCollectionDocuments(collectionId);
memberships.removeCollectionMemberships(collectionId);
collections.remove(collectionId);
policies.remove(collectionId);
continue; continue;
} }
@ -187,9 +203,10 @@ class SocketProvider extends React.Component<Props> {
await collections.fetch(collectionId, { force: true }); await collections.fetch(collectionId, { force: true });
} catch (err) { } catch (err) {
if (err.statusCode === 404 || err.statusCode === 403) { if (err.statusCode === 404 || err.statusCode === 403) {
collections.remove(collectionId);
documents.removeCollectionDocuments(collectionId); documents.removeCollectionDocuments(collectionId);
memberships.removeCollectionMemberships(collectionId); memberships.removeCollectionMemberships(collectionId);
collections.remove(collectionId);
policies.remove(collectionId);
return; return;
} }
} }

View File

@ -36,6 +36,7 @@ import Tab from "components/Tab";
import Tabs from "components/Tabs"; import Tabs from "components/Tabs";
import Tooltip from "components/Tooltip"; import Tooltip from "components/Tooltip";
import CollectionMenu from "menus/CollectionMenu"; import CollectionMenu from "menus/CollectionMenu";
import { AuthorizationError } from "utils/errors";
import { newDocumentUrl, collectionUrl } from "utils/routeHelpers"; import { newDocumentUrl, collectionUrl } from "utils/routeHelpers";
type Props = { type Props = {
@ -65,6 +66,15 @@ class CollectionScene extends React.Component<Props> {
componentDidUpdate(prevProps) { componentDidUpdate(prevProps) {
const { id } = this.props.match.params; const { id } = this.props.match.params;
if (this.collection) {
const { collection } = this;
const policy = this.props.policies.get(collection.id);
if (!policy) {
this.loadContent(collection.id);
}
}
if (id && id !== prevProps.match.params.id) { if (id && id !== prevProps.match.params.id) {
this.loadContent(id); this.loadContent(id);
} }
@ -75,18 +85,24 @@ class CollectionScene extends React.Component<Props> {
} }
loadContent = async (id: string) => { loadContent = async (id: string) => {
const collection = await this.props.collections.fetch(id); try {
const collection = await this.props.collections.fetch(id);
if (collection) { if (collection) {
this.props.ui.setActiveCollection(collection); this.props.ui.setActiveCollection(collection);
this.collection = collection; this.collection = collection;
await this.props.documents.fetchPinned({ await this.props.documents.fetchPinned({
collectionId: id, collectionId: id,
}); });
}
} catch (error) {
if (error instanceof AuthorizationError) {
this.collection = null;
}
} finally {
this.isFetching = false;
} }
this.isFetching = false;
}; };
onNewDocument = (ev: SyntheticEvent<>) => { onNewDocument = (ev: SyntheticEvent<>) => {

View File

@ -50,7 +50,8 @@ class DataLoader extends React.Component<Props> {
// reload from the server otherwise the UI will not know which authorizations // reload from the server otherwise the UI will not know which authorizations
// the user has // the user has
if (this.document) { if (this.document) {
const policy = this.props.policies.get(this.document.id); const document = this.document;
const policy = this.props.policies.get(document.id);
if (!policy && !this.error) { if (!policy && !this.error) {
this.loadDocument(); this.loadDocument();

View File

@ -407,11 +407,15 @@ async function loadDocument({ id, shareId, user }) {
authorize(user, "read", document); authorize(user, "read", document);
} }
} else { } else {
document = await Document.findByPk( document = await Document.findByPk(id, {
id, userId: user ? user.id : undefined,
user ? { userId: user.id } : undefined paranoid: false,
); });
authorize(user, "read", document); if (document.deletedAt) {
authorize(user, "restore", document);
} else {
authorize(user, "read", document);
}
} }
return document; return document;