-
Notifications
You must be signed in to change notification settings - Fork 10
Expand file tree
/
Copy pathuseCreateAndNavigate.ts
More file actions
60 lines (55 loc) · 1.81 KB
/
useCreateAndNavigate.ts
File metadata and controls
60 lines (55 loc) · 1.81 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
import {
JSONValue,
properties,
Resource,
useResource,
useStore,
useTitle,
} from '@tomic/react';
import { useCallback } from 'react';
import toast from 'react-hot-toast';
import { useNavigate } from 'react-router-dom';
import { constructOpenURL } from '../../helpers/navigation';
/**
* Hook that builds a function that will create a new resource with the given
* properties and then navigate to it.
*
* @param klass The type of resource to create a new instance of.
* @param parent The parent resource of the new resource.
* @returns A createAndNavigate function.
*/
export function useCreateAndNavigate(klass: string, parent?: string) {
const store = useStore();
const classTypeResource = useResource(klass);
const [title] = useTitle(classTypeResource);
const navigate = useNavigate();
return useCallback(
async (
className: string,
propVals: Record<string, JSONValue>,
/** Query parameters for the resource / endpoint */
extraParams?: Record<string, string>,
/** Do not set a parent for the new resource. Useful for top-level resources */
noParent?: boolean,
): Promise<Resource> => {
const subject = store.createSubject(className, parent);
const resource = new Resource(subject, true);
await Promise.all([
...Object.entries(propVals).map(([key, val]) =>
resource.set(key, val, store),
),
!noParent && resource.set(properties.parent, parent, store),
]);
try {
await resource.save(store);
navigate(constructOpenURL(subject, extraParams));
toast.success(`${title} created`);
store.notifyResourceManuallyCreated(resource);
} catch (e) {
store.notifyError(e);
}
return resource;
},
[store, classTypeResource, title, navigate, parent],
);
}