Skip to content

Commit 953bc66

Browse files
committed
bootswatch selector
1 parent ab608d8 commit 953bc66

30 files changed

+334
-330
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,11 @@ packages/tdb-documents-ui/src/oneOfTypeFrames copy3
1515

1616
packages/tdb-documents-ui/mockTest
1717
packages/tdb-documents-ui/playground/.env
18+
packages/tdb-documents-ui/test
1819
packages/tdb-documents-ui/test/.env
20+
packages/tdb-documents-ui/diff
1921
packages/tdb-documents-ui/diff/.env
22+
packages/tdb-documents-ui/src_OLD
2023
packages/tdb-documents-ui/src/pending.md
2124

2225
*.DS_Store
Lines changed: 204 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,204 @@
1+
2+
# terminusdb-documents-ui
3+
SDK to build UI from terminusdb documents. This package includes a ``<FrameViewer/>`` component which displays a TerminusDB schema driven Form in three modes (Create/ Edit or View)
4+
5+
## Installation
6+
Install the dependancy from npm
7+
```npm install @terminusdb/terminusdb-documents-ui```
8+
9+
## Usage
10+
Then import dependancy as shown below
11+
```import {FrameViewer} from '@terminusdb/terminusdb-documents-ui'```
12+
13+
## Run sandbox
14+
15+
Run sandbox to get a demo on how to use ``<FrameViewer/>`` component.
16+
```npm run sandbox```
17+
In this project, for the purpose of the demo Frames & Data are provided in the form of JSONs in ``src/lego.constants.js``
18+
19+
Otherwise frames can be retrieved by using TerminusDB Client. Refer [getSchemaFrame()](https://terminusdb.com/docs/guides/reference-guides/javascript-client-reference/woqlclient#getschemaframe)
20+
21+
22+
### Create
23+
24+
```
25+
import { FrameViewer } from '@terminusdb/terminusdb-documents-ui'
26+
import { LEGO_FRAMES } from "./lego.constants"
27+
28+
let frame = LEGO_FRAMES
29+
30+
// Search component to be displayed in UI when user wants to link a document. This is just a
31+
// dummy example where the user can choose 3 Ids from the below table. Users can load GraphQL
32+
// search component as well to search for documents.
33+
const Search = ({ setSelected }) => {
34+
function handleClick(e){
35+
if(setSelected) setSelected({ id: e.target.id, label: e.target.name })
36+
}
37+
38+
return <React.Fragment>
39+
Search this dummy result ....
40+
<Row id={"ID 1"} name="first id" onClick={handleClick}>
41+
{"ID 1"}
42+
</Row>
43+
<Row id={"ID 2"} name="second id" onClick={handleClick}>
44+
{"ID 2"}
45+
</Row>
46+
<Row id={"ID 3"} name="third id" onClick={handleClick}>
47+
{"ID 3"}
48+
</Row>
49+
</React.Fragment>
50+
}
51+
52+
/**
53+
* @param {*} data extracted from Form on click of Submit button
54+
* function to handle on Submit of form
55+
*/
56+
function handleSubmit(data) {
57+
console.log(`Submitted data - ${data}`)
58+
}
59+
60+
return <FrameViewer
61+
frame={frame} // frames
62+
mode={"Create"} // mode in which to display the form
63+
onSelect={<Search/>} // displays a Search component
64+
formData={{}} // instance data - empty in create mode
65+
onSubmit={handleSubmit} // Callback submit function
66+
type={"Theme"}/> // type of document to display in form
67+
```
68+
69+
70+
### Edit
71+
72+
```
73+
import { FrameViewer } from '@terminusdb/terminusdb-documents-ui'
74+
import { LEGO_FRAMES, THEME_DATA } from "./lego.constants"
75+
76+
let frame = LEGO_FRAMES, data = THEME_DATA // filled data to display in Edit mode
77+
78+
// Search component to be displayed in UI when user wants to link a document. This is just a
79+
// dummy example where the user can choose 3 Ids from the below table. Users can load GraphQL
80+
// search component as well to search for documents.
81+
const Search = ({ setSelected }) => {
82+
function handleClick(e){
83+
if(setSelected) setSelected({ id: e.target.id, label: e.target.name })
84+
}
85+
86+
return <React.Fragment>
87+
Search this dummy result ....
88+
<Row id={"ID 1"} name="first id" onClick={handleClick}>
89+
{"ID 1"}
90+
</Row>
91+
<Row id={"ID 2"} name="second id" onClick={handleClick}>
92+
{"ID 2"}
93+
</Row>
94+
<Row id={"ID 3"} name="third id" onClick={handleClick}>
95+
{"ID 3"}
96+
</Row>
97+
</React.Fragment>
98+
}
99+
100+
/**
101+
* @param {*} data extracted from Form on click of Submit button
102+
* function to handle on Submit of form
103+
*/
104+
function handleSubmit(data) {
105+
console.log(`Submitted data - ${data}`)
106+
}
107+
108+
/**
109+
*
110+
* @param {*} clicked callback function which returns back the ID of element clicked
111+
* function which handles click on a document link. On click the function will
112+
* return back document ID clicked.
113+
*/
114+
function handleTraverse (clicked) {
115+
alert(`You have clicked on document ID ${clicked}`)
116+
}
117+
118+
return <FrameViewer
119+
frame={frame} // frames
120+
mode={"Edit"} // mode in which to display the form
121+
onTraverse={handleTraverse} // Callback traverse links function
122+
onSelect={<Search/>} // displays a Search component
123+
formData={data} // instance data
124+
onSubmit={handleSubmit} // Callback submit function
125+
type={"Theme"}/> // type of document to display in form
126+
```
127+
128+
129+
### View
130+
131+
```
132+
import { FrameViewer } from '@terminusdb/terminusdb-documents-ui'
133+
import { LEGO_FRAMES, THEME_DATA } from "./lego.constants"
134+
135+
let frame = LEGO_FRAMES, data = THEME_DATA // filled data to display in Edit mode
136+
137+
/**
138+
*
139+
* @param {*} clicked callback function which returns back the ID of element clicked
140+
* function which handles click on a document link. On click the function will
141+
* return back document ID clicked.
142+
*/
143+
function handleTraverse (clicked) {
144+
alert(`You have clicked on document ID ${clicked}`)
145+
}
146+
147+
return <FrameViewer
148+
frame={frame} // frames
149+
mode={"View"} // mode in which to display the form
150+
onTraverse={handleTraverse} // Callback traverse links function
151+
formData={data} // instance data
152+
type={"Theme"}/> // type of document to display in form
153+
```
154+
### Theme Selector
155+
FrameViewer is based on [Bootswatch](https://bootswatch.com/cosmo/) Themes. Use props ``theme`` in ``<FrameViewer/>`` component to change themes at an application level.
156+
```
157+
import { FrameViewer } from '@terminusdb/terminusdb-documents-ui'
158+
return <FrameViewer
159+
frame={frame} // frames
160+
mode={"View"} // mode in which to display the form
161+
onTraverse={handleTraverse} // Callback traverse links function
162+
formData={data} // instance data
163+
theme="darkly" // pass a bootswatch theme - like darkly/ pulse
164+
type={"Theme"}/> // type of document to display in form
165+
```
166+
167+
A Theme selector can also be enabled by passing ``showThemeSelector={true}``
168+
```
169+
import { FrameViewer } from '@terminusdb/terminusdb-documents-ui'
170+
return <FrameViewer
171+
frame={frame} // frames
172+
mode={"View"} // mode in which to display the form
173+
onTraverse={handleTraverse} // Callback traverse links function
174+
formData={data} // instance data
175+
showThemeSelector={true} // use the selector to swap themes
176+
type={"Theme"}/> // type of document to display in form
177+
```
178+
179+
### CSS
180+
If you dont want to use themes at an application level then import CSS to make the ``<FrameViewer/>`` component appear in dark or light mode.
181+
182+
#### Light mode
183+
```
184+
import { FrameViewer } from '@terminusdb/terminusdb-documents-ui'
185+
import "terminusdb__light.css"
186+
return <FrameViewer
187+
frame={frame} // frames
188+
mode={"View"} // mode in which to display the form
189+
onTraverse={handleTraverse} // Callback traverse links function
190+
formData={data} // instance data
191+
type={"Theme"}/> // type of document to display in form
192+
```
193+
194+
#### Dark mode
195+
```
196+
import { FrameViewer } from '@terminusdb/terminusdb-documents-ui'
197+
import "terminusdb__darkly.css"
198+
return <FrameViewer
199+
frame={frame} // frames
200+
mode={"View"} // mode in which to display the form
201+
onTraverse={handleTraverse} // Callback traverse links function
202+
formData={data} // instance data
203+
type={"Theme"}/> // type of document to display in form
204+
```
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
.accordion-button {
2+
background-color: #303030 !important;
3+
color: #fff !important;
4+
}

packages/tdb-documents-ui/sandbox/src/DocumentTypes.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ export const DocumentTypes = () => {
3030

3131
return <Nav
3232
activeKey={activeKey}
33-
className="mt-5 mb-3"
33+
variant="pills"
34+
className="mb-4"
3435
onSelect={(selectedKey) => handleNavClick(selectedKey)}
3536
>
3637
{docTypes}

packages/tdb-documents-ui/sandbox/src/Editors.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,14 @@ export const Editor = () => {
1313

1414
return <Accordion onSelect={handleSelect}>
1515
<Accordion.Item eventKey={"Frames"}>
16-
<Accordion.Header>{"Frames"}</Accordion.Header>
17-
<Accordion.Body>
16+
<Accordion.Header className='bg-secondary'>{"Frames"}</Accordion.Header>
17+
<Accordion.Body className='bg-secondary'>
1818
<FrameEditor/>
1919
</Accordion.Body>
2020
</Accordion.Item>
2121
<Accordion.Item eventKey={"Submitted Data"}>
22-
<Accordion.Header>{"Submitted Data"}</Accordion.Header>
23-
<Accordion.Body>
22+
<Accordion.Header className='bg-secondary'>{"Submitted Data"}</Accordion.Header>
23+
<Accordion.Body className='bg-secondary'>
2424
<SubmittedData/>
2525
</Accordion.Body>
2626
</Accordion.Item>

packages/tdb-documents-ui/sandbox/src/FrameEditor.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ export const FrameEditor = () => {
2121
locale={ locale }
2222
placeholder={frames}
2323
height= {"550px"}
24-
width= {"500px"}
24+
width= {"380px"}
2525
onBlur={handleInput}
2626
/>
2727

packages/tdb-documents-ui/sandbox/src/Layout.js

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,19 @@ import { MoreInfo } from "./MoreInfoCanvas"
99
const App= (props) =>{
1010

1111

12-
return <Container>
12+
return <Container fluid="xxl" className='mt-5'>
13+
<h3 className='text-success'>{`Parts & Components Inventory`}</h3>
14+
<h5 className='mb-4 text-muted'>{`This data product features Lego sets and their individual components and the relationships between them.
15+
It is an excellent example of organizations that have interconnected components and parts within their product offerings.`}
16+
</h5>
1317
<DocumentTypes/>
1418
<MoreInfo/>
15-
<ModeBar/>
1619
<Row>
17-
<Col md={5}><Editor/></Col>
18-
<Col md={7}><View/></Col>
20+
<Col md={4}>
21+
<ModeBar/>
22+
<Editor/>
23+
</Col>
24+
<Col md={8}><View/></Col>
1925
</Row>
2026
</Container>
2127

packages/tdb-documents-ui/sandbox/src/ModeBar.js

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import React, {useState} from "react"
22
import Stack from 'react-bootstrap/Stack'
33
import { CREATE, EDIT, VIEW, MODE_HELP_TEXT } from "./constants"
44
import { FrameObj } from "./frameInit"
5+
import { Card } from "react-bootstrap"
56

67
const RadioButtons = ({ mode, handleChange, checked }) => {
78
return <div>
@@ -32,16 +33,21 @@ export const ModeBar = () => {
3233
setMode(event.target.value)
3334
}
3435

35-
return <div className="mb-3">
36-
<Stack direction="horizontal" gap={3} className="p-3">
37-
<RadioButtons mode={CREATE} handleChange={handleChange} checked={checked} />
38-
<RadioButtons mode={EDIT} handleChange={handleChange} checked={checked}/>
39-
<RadioButtons mode={VIEW} handleChange={handleChange} checked={checked}/>
40-
</Stack>
41-
<Stack direction="horizontal" gap={1} >
42-
<div className="text-muted small">{`${MODE_HELP_TEXT}. `} </div>
43-
<div className="text-warning small">{`${mode}`}</div>
44-
<div className="text-muted small">{` mode selected.`} </div>
45-
</Stack>
46-
</div>
36+
return <Card className="mb-3">
37+
<Card.Header>
38+
<div>{`${MODE_HELP_TEXT}. `} </div>
39+
</Card.Header>
40+
<Card.Body>
41+
<Stack direction="horizontal" gap={1} className="mb-2" >
42+
<div className="text-warning">{`${mode}`}</div>
43+
<div className="text-muted">{` mode selected.`} </div>
44+
</Stack>
45+
<Stack direction="horizontal" gap={3}>
46+
<RadioButtons mode={CREATE} handleChange={handleChange} checked={checked} />
47+
<RadioButtons mode={EDIT} handleChange={handleChange} checked={checked}/>
48+
<RadioButtons mode={VIEW} handleChange={handleChange} checked={checked}/>
49+
</Stack>
50+
51+
</Card.Body>
52+
</Card>
4753
}

packages/tdb-documents-ui/sandbox/src/MoreInfoCanvas.js

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,25 @@
11
import React, { useState } from 'react'
22
import Stack from 'react-bootstrap/Stack'
33
import Offcanvas from 'react-bootstrap/Offcanvas'
4-
import {DisplayCode} from "./DisplayCode"
5-
/*import {Button} from "react-bootstrap"
6-
import {BsClipboard} from "react-icons/bs"
7-
import {copyToClipboard} from "./utils"*/
4+
import { DisplayCode } from "./DisplayCode"
5+
import { Button } from "react-bootstrap"
86
import { FrameObj } from "./frameInit"
97

8+
/**
9+
*
10+
* @param {*} code - function is called to copy example code to clipboard
11+
*/
12+
function copyToClipboard (code) {
13+
navigator.clipboard.writeText(code).then(() => {
14+
console.log("copied code", code)
15+
},(err) => {
16+
/* Rejected - clipboard failed */
17+
console.log("err", err)
18+
})
19+
}
20+
1021
export const MoreInfo = () => {
1122
const {
12-
frames,
13-
type,
14-
mode,
1523
code,
1624
setShowCode,
1725
showCode
@@ -25,16 +33,16 @@ export const MoreInfo = () => {
2533
<Offcanvas.Header closeButton className="bg-light text-dark">
2634
<Offcanvas.Title>Code</Offcanvas.Title>
2735
</Offcanvas.Header>
28-
<Offcanvas.Body>
36+
<Offcanvas.Body className='bg-secondary'>
2937
<Stack direction="horizontal" gap={3} className="mt-4 mb-4">
3038
{/*<h6>Click <a href={link}> here </a> to check out documentation</h6>*/}
31-
{/*<Button variant="primary"
39+
<Button variant="primary"
3240
title="Copy to clipboard"
3341
className="btn btn-sm ms-auto"
3442
style={{float: "right"}}
35-
onClick={(e) => copyToClipboard(exampleCode)}>
36-
<BsClipboard className="mr-2"/> <label>Copy Code</label>
37-
</Button>*/}
43+
onClick={(e) => copyToClipboard(code)}>
44+
<label>Copy Code</label>
45+
</Button>
3846
</Stack>
3947
<DisplayCode codeString={code}/>
4048
</Offcanvas.Body>

0 commit comments

Comments
 (0)