Skip to content

Commit ffab951

Browse files
committed
Documentation, add Collections new form #747
1 parent b4d73b9 commit ffab951

File tree

6 files changed

+123
-17
lines changed

6 files changed

+123
-17
lines changed

browser/data-browser/src/components/forms/NewForm/CustomCreateActions/BasicInstanceHandlers.ts

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
import { dataBrowser, core, classes, server } from '@tomic/react';
22
import { registerBasicInstanceHandler } from '../useNewResourceUI';
33

4+
/**
5+
* These handlers do not show any UI / inputs when creating new instances.
6+
* This is where they can have hardcoded default values or custom logic.
7+
*/
48
export const registerBasicInstanceHandlers = () => {
59
registerBasicInstanceHandler(
610
dataBrowser.classes.folder,
@@ -29,20 +33,6 @@ export const registerBasicInstanceHandlers = () => {
2933
},
3034
);
3135

32-
registerBasicInstanceHandler(
33-
dataBrowser.classes.folder,
34-
async (parent, createAndNavigate) => {
35-
await createAndNavigate(
36-
dataBrowser.classes.folder,
37-
{
38-
[core.properties.name]: 'Untitled Folder',
39-
[dataBrowser.properties.displayStyle]: classes.displayStyles.list,
40-
},
41-
parent,
42-
);
43-
},
44-
);
45-
4636
registerBasicInstanceHandler(
4737
dataBrowser.classes.document,
4838
async (parent, createAndNavigate) => {
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
import { JSONValue, collections, core } from '@tomic/react';
2+
import { useState, useCallback, FormEvent, useEffect, FC } from 'react';
3+
import { Button } from '../../../../Button';
4+
import {
5+
useDialog,
6+
Dialog,
7+
DialogTitle,
8+
DialogContent,
9+
DialogActions,
10+
} from '../../../../Dialog';
11+
import Field from '../../../Field';
12+
import { InputWrapper, InputStyled } from '../../../InputStyles';
13+
import { CustomResourceDialogProps } from '../../useNewResourceUI';
14+
import { useCreateAndNavigate } from '../../../../../hooks/useCreateAndNavigate';
15+
import { ResourceSelector } from '../../../ResourceSelector';
16+
17+
export const NewCollectionDialog: FC<CustomResourceDialogProps> = ({
18+
parent,
19+
onClose,
20+
}) => {
21+
const [name, setName] = useState('New Collection');
22+
const [valueFilter, setValue] = useState<string | undefined>();
23+
const [propertyFilter, setProperty] = useState<string | undefined>();
24+
25+
const [dialogProps, show, hide] = useDialog({ onCancel: onClose });
26+
27+
const createResourceAndNavigate = useCreateAndNavigate();
28+
29+
const onDone = useCallback(
30+
(e: FormEvent) => {
31+
e.preventDefault();
32+
33+
createResourceAndNavigate(
34+
collections.classes.collection,
35+
{
36+
[core.properties.name]: name,
37+
[collections.properties.value]: valueFilter,
38+
[collections.properties.property]: propertyFilter,
39+
[collections.properties.pageSize]: 30,
40+
[collections.properties.currentPage]: 0,
41+
},
42+
parent,
43+
);
44+
45+
onClose();
46+
},
47+
[valueFilter, onClose, propertyFilter],
48+
);
49+
50+
useEffect(() => {
51+
show();
52+
}, []);
53+
54+
return (
55+
<Dialog {...dialogProps}>
56+
<DialogTitle>
57+
<h1>New Collection</h1>
58+
</DialogTitle>
59+
<DialogContent>
60+
<form onSubmit={onDone}>
61+
<Field required label='name'>
62+
<InputWrapper>
63+
<InputStyled
64+
placeholder='Name your Collection'
65+
value={name}
66+
autoFocus={true}
67+
onChange={e => setName(e.target.value)}
68+
/>
69+
</InputWrapper>
70+
</Field>
71+
<Field label='property'>
72+
<div>
73+
<ResourceSelector
74+
isA={core.classes.property}
75+
setSubject={setProperty}
76+
value={propertyFilter}
77+
/>
78+
</div>
79+
</Field>
80+
<Field label='value'>
81+
<InputWrapper>
82+
<InputStyled
83+
placeholder='Set a value filter (optional)'
84+
value={valueFilter}
85+
onChange={e => setValue(e.target.value)}
86+
/>
87+
</InputWrapper>
88+
</Field>
89+
</form>
90+
</DialogContent>
91+
<DialogActions>
92+
<Button onClick={() => hide(false)} subtle>
93+
Cancel
94+
</Button>
95+
<Button onClick={onDone} disabled={!propertyFilter && !valueFilter}>
96+
Ok
97+
</Button>
98+
</DialogActions>
99+
</Dialog>
100+
);
101+
};
Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
1-
import { dataBrowser, core } from '@tomic/react';
1+
import { dataBrowser, core, collections } from '@tomic/react';
22
import { registerNewResourceDialog } from '../../useNewResourceUI';
33
import { NewBookmarkDialog } from './NewBookmarkDialog';
44
import { NewOntologyDialog } from './NewOntologyDialog';
55
import { NewTableDialog } from './NewTableDialog';
6+
import { NewCollectionDialog } from './NewCollectionDialog';
67

78
export const registerCustomForms = () => {
89
registerNewResourceDialog(dataBrowser.classes.bookmark, NewBookmarkDialog);
910
registerNewResourceDialog(core.classes.ontology, NewOntologyDialog);
1011
registerNewResourceDialog(dataBrowser.classes.table, NewTableDialog);
12+
registerNewResourceDialog(
13+
collections.classes.collection,
14+
NewCollectionDialog,
15+
);
1116
};

browser/data-browser/src/components/forms/NewForm/NewFormTitle.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import { properties, useResource, useString, useTitle } from '@tomic/react';
22
import { useState } from 'react';
33
import { FaInfo } from 'react-icons/fa';
44
import { AtomicLink } from '../../AtomicLink';
5-
import { Button } from '../../Button';
65
import Markdown from '../../datatypes/Markdown';
76
import { Column, Row } from '../../Row';
87
import styled from 'styled-components';

browser/data-browser/src/components/forms/NewForm/useNewResourceUI.tsx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ export interface CustomResourceDialogProps {
2121
onClose: () => void;
2222
}
2323

24+
/** When creating a new resource, the matched handler is called */
2425
export type BasicInstanceHandler = (
2526
parent: string,
2627
createAndNavigate: CreateAndNavigate,
@@ -37,19 +38,28 @@ interface NewResourceUIContext {
3738
const dialogs = new Map<string, FC<CustomResourceDialogProps>>();
3839
const basicNewInstanceHandlers = new Map<string, BasicInstanceHandler>();
3940

41+
/**
42+
* Returns a function that when called, renders UI to create a new Resource of the given class.
43+
*
44+
* Use {@link registerNewResourceDialog} to register a custom dialog for a given class.
45+
*/
4046
export function useNewResourceUI() {
4147
const { showNewResourceUI } = useContext(NewResourceUIContext);
4248

4349
return showNewResourceUI;
4450
}
4551

52+
/** Call this when adding a new custom New Resource Form / Dialog. */
4653
export const registerNewResourceDialog = (
4754
classSubject: string,
4855
component: FC<CustomResourceDialogProps>,
4956
) => {
5057
dialogs.set(classSubject, component);
5158
};
5259

60+
/** Call this when adding a new custom action for a New Resource that does _not_ require inputs.
61+
* For example, creating a new Folder does not require any inputs, so it can be handled without any UI.
62+
*/
5363
export const registerBasicInstanceHandler = (
5464
classSubject: string,
5565
handler: BasicInstanceHandler,
@@ -61,6 +71,7 @@ const NewResourceUIContext = createContext<NewResourceUIContext>({
6171
showNewResourceUI: () => undefined,
6272
});
6373

74+
/** Renders the Dialog used when creating new resources. */
6475
export function NewResourceUIProvider({ children }: PropsWithChildren) {
6576
const store = useStore();
6677
const settings = useSettings();

browser/data-browser/src/hooks/useCreateAndNavigate.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ export type CreateAndNavigate = (
1616
* Hook that builds a function that will create a new resource with the given
1717
* properties and then navigate to it.
1818
*
19-
* @returns A createAndNavigate function.
19+
* @returns A {@link CreateAndNavigate} function.
2020
*/
2121
export function useCreateAndNavigate(): CreateAndNavigate {
2222
const store = useStore();

0 commit comments

Comments
 (0)