Skip to content

Commit bc0f126

Browse files
committed
Fix subresources not updated when resource is deleted #1087
1 parent 094764d commit bc0f126

File tree

4 files changed

+42
-23
lines changed

4 files changed

+42
-23
lines changed

browser/CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,11 @@ This changelog covers all five packages, as they are (for now) updated as a whol
2424
- `resource.props` is now writeable: `resource.props.name = 'New Name'`.
2525
- Added `store.preloadResourceTree()` method, see docs for more info.
2626
- Fix generated ontologies not working in a Next.js server context.
27-
- SEMI BREAKING CHANGE: When using generated types by cli, @tomic/lib now requires them to be generated by @tomic/cli v0.41.0 or above.
2827
- Fix types masquerading as esm module in cjs build.
2928
- `store.search()` now handles multiple values for the same property correctly.
3029
- [#1077](https://github.com/atomicdata-dev/atomic-server/issues/1077) Fix bug where resource.new would not be set back to true when saving fails.
30+
- SEMI BREAKING CHANGE: When using generated types by cli, @tomic/lib now requires them to be generated by @tomic/cli v0.41.0 or above.
31+
- BREAKING CHANGE: The `StoreEvents.ResourceRemoved` event callback now only receives the subject of the resource instead of the resource itself.
3132

3233
### @tomic/react
3334

browser/data-browser/src/handlers/sideBarHandler.ts

Lines changed: 31 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
1-
import { Resource, Store, isString, dataBrowser, core } from '@tomic/react';
1+
import {
2+
Resource,
3+
Store,
4+
isString,
5+
dataBrowser,
6+
core,
7+
CollectionBuilder,
8+
} from '@tomic/react';
29

310
export function buildSideBarNewResourceHandler(store: Store) {
411
// When a resource is saved add it to the parents subResources list if it's not already there.
@@ -26,25 +33,33 @@ export function buildSideBarNewResourceHandler(store: Store) {
2633

2734
export function buildSideBarRemoveResourceHandler(store: Store) {
2835
// When a resource is deleted remove it from the parents subResources list.
29-
return async (resource: Resource) => {
30-
const parentSubject = resource.get(core.properties.parent);
36+
return async (subject: string) => {
37+
const collection = new CollectionBuilder(store)
38+
.setProperty(dataBrowser.properties.subResources)
39+
.setValue(subject)
40+
.build();
3141

32-
if (!isString(parentSubject)) {
33-
throw new Error(`Resource doesn't have a parent: ${resource.subject} `);
34-
}
42+
for await (const member of collection) {
43+
try {
44+
const resource = await store.getResource(member);
3545

36-
const parent = await store.getResource(parentSubject);
37-
const subResources = parent.getSubjects(
38-
dataBrowser.properties.subResources,
39-
);
46+
if (!(await resource.canWrite(store.getAgent()?.subject))) {
47+
continue;
48+
}
49+
50+
const subResources = resource.getArray(
51+
dataBrowser.properties.subResources,
52+
) as string[];
4053

41-
if (subResources.length > 0) {
42-
await parent.set(
43-
dataBrowser.properties.subResources,
44-
subResources.filter(r => r !== resource.subject),
45-
);
54+
await resource.set(
55+
dataBrowser.properties.subResources,
56+
subResources.filter(r => r !== subject),
57+
);
4658

47-
await parent.save();
59+
await resource.save();
60+
} catch (e) {
61+
console.error('Error removing resource from parent', e);
62+
}
4863
}
4964
};
5065
}

browser/lib/src/search.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,6 @@ export function removeCachedSearchResults(store: Store) {
115115
);
116116

117117
for (const resource of searchResources) {
118-
store.removeResource(resource.subject);
118+
store.removeResource(resource.subject, false);
119119
}
120120
}

browser/lib/src/store.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import { initOntologies } from './ontologies/index.js';
2727
type ResourceCallback<C extends OptionalClass = UnknownClass> = (
2828
resource: Resource<C>,
2929
) => void;
30+
type SubjectCallback = (subject: string) => void;
3031
/** Callback called when the stores agent changes */
3132
type AgentCallback = (agent: Agent | undefined) => void;
3233
type ErrorCallback = (e: Error) => void;
@@ -92,7 +93,7 @@ export interface ImportJsonADOptions {
9293
*/
9394
type StoreEventHandlers = {
9495
[StoreEvents.ResourceSaved]: ResourceCallback;
95-
[StoreEvents.ResourceRemoved]: ResourceCallback;
96+
[StoreEvents.ResourceRemoved]: SubjectCallback;
9697
[StoreEvents.ResourceManuallyCreated]: ResourceCallback;
9798
[StoreEvents.AgentChanged]: AgentCallback;
9899
[StoreEvents.ServerURLChanged]: ServerURLCallback;
@@ -662,13 +663,16 @@ export class Store {
662663
});
663664
}
664665

665-
/** Removes (destroys / deletes) resource from this store */
666-
public removeResource(subject: string): void {
666+
/** Removes resource from this store, does not delete it from the server, use `resource.destroy()` to delete it from the server. */
667+
public removeResource(subject: string, shouldNotify = true): void {
667668
const resource = this.resources.get(subject);
668669

669670
if (resource) {
670671
this.resources.delete(subject);
671-
this.eventManager.emit(StoreEvents.ResourceRemoved, resource);
672+
673+
if (shouldNotify) {
674+
this.eventManager.emit(StoreEvents.ResourceRemoved, subject);
675+
}
672676
}
673677
}
674678

@@ -1048,7 +1052,6 @@ export class Store {
10481052
}
10491053

10501054
/** Lets subscribers know that a resource has been changed. Time to update your views.
1051-
* Make sure the resource is a new reference, otherwise React will not rerender.
10521055
*/
10531056
private async notify(resource: Resource): Promise<void> {
10541057
const subject = resource.subject;

0 commit comments

Comments
 (0)