Skip to content

Fix subresources not updated when resource is deleted #1087 #1090

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion browser/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,11 @@ This changelog covers all five packages, as they are (for now) updated as a whol
- `resource.props` is now writeable: `resource.props.name = 'New Name'`.
- Added `store.preloadResourceTree()` method, see docs for more info.
- Fix generated ontologies not working in a Next.js server context.
- 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.
- Fix types masquerading as esm module in cjs build.
- `store.search()` now handles multiple values for the same property correctly.
- [#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.
- 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.
- BREAKING CHANGE: The `StoreEvents.ResourceRemoved` event callback now only receives the subject of the resource instead of the resource itself.

### @tomic/react

Expand Down
47 changes: 31 additions & 16 deletions browser/data-browser/src/handlers/sideBarHandler.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
import { Resource, Store, isString, dataBrowser, core } from '@tomic/react';
import {
Resource,
Store,
isString,
dataBrowser,
core,
CollectionBuilder,
} from '@tomic/react';

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

export function buildSideBarRemoveResourceHandler(store: Store) {
// When a resource is deleted remove it from the parents subResources list.
return async (resource: Resource) => {
const parentSubject = resource.get(core.properties.parent);
return async (subject: string) => {
const collection = new CollectionBuilder(store)
.setProperty(dataBrowser.properties.subResources)
.setValue(subject)
.build();

if (!isString(parentSubject)) {
throw new Error(`Resource doesn't have a parent: ${resource.subject} `);
}
for await (const member of collection) {
try {
const resource = await store.getResource(member);

const parent = await store.getResource(parentSubject);
const subResources = parent.getSubjects(
dataBrowser.properties.subResources,
);
if (!(await resource.canWrite(store.getAgent()?.subject))) {
continue;
}

const subResources = resource.getArray(
dataBrowser.properties.subResources,
) as string[];

if (subResources.length > 0) {
await parent.set(
dataBrowser.properties.subResources,
subResources.filter(r => r !== resource.subject),
);
await resource.set(
dataBrowser.properties.subResources,
subResources.filter(r => r !== subject),
);

await parent.save();
await resource.save();
} catch (e) {
console.error('Error removing resource from parent', e);
}
}
};
}
2 changes: 1 addition & 1 deletion browser/lib/src/search.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,6 @@ export function removeCachedSearchResults(store: Store) {
);

for (const resource of searchResources) {
store.removeResource(resource.subject);
store.removeResource(resource.subject, false);
}
}
13 changes: 8 additions & 5 deletions browser/lib/src/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import { initOntologies } from './ontologies/index.js';
type ResourceCallback<C extends OptionalClass = UnknownClass> = (
resource: Resource<C>,
) => void;
type SubjectCallback = (subject: string) => void;
/** Callback called when the stores agent changes */
type AgentCallback = (agent: Agent | undefined) => void;
type ErrorCallback = (e: Error) => void;
Expand Down Expand Up @@ -92,7 +93,7 @@ export interface ImportJsonADOptions {
*/
type StoreEventHandlers = {
[StoreEvents.ResourceSaved]: ResourceCallback;
[StoreEvents.ResourceRemoved]: ResourceCallback;
[StoreEvents.ResourceRemoved]: SubjectCallback;
[StoreEvents.ResourceManuallyCreated]: ResourceCallback;
[StoreEvents.AgentChanged]: AgentCallback;
[StoreEvents.ServerURLChanged]: ServerURLCallback;
Expand Down Expand Up @@ -662,13 +663,16 @@ export class Store {
});
}

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

if (resource) {
this.resources.delete(subject);
this.eventManager.emit(StoreEvents.ResourceRemoved, resource);

if (shouldNotify) {
this.eventManager.emit(StoreEvents.ResourceRemoved, subject);
}
}
}

Expand Down Expand Up @@ -1048,7 +1052,6 @@ export class Store {
}

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