Skip to content
Merged
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
32 changes: 32 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,34 @@
# terminusdb-dashboard
Dashboard for TerminusDB
How to use the terminusdb dashboard source code with your local terminusdb instance.

**Clone the repository**
```sh
git clone https://github.com/terminusdb/terminusdb-dashboard.git
```

**Install all the dependency**
```sh
cd terminusdb-dashboard
npm install
```

**Build the dashboard**
Rename ENV.local to .env
```sh
cd terminusdb-dashboard/packages/tdb-dashboard
cp ENV.local .env

npm run build
```
You can find the builded version into terminusdb-dashboard/packages/tdb-dashboard/dist










4 changes: 4 additions & 0 deletions packages/tdb-dashboard/ENV.local
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
TERMINUSDB_SERVER=http://127.0.0.1:6363/
CONNECTION_TYPE=LOCAL
FEEDBACK_URL=https://cloud-dev.terminusdb.com/
BASE_URL=dashboard
12 changes: 7 additions & 5 deletions packages/tdb-dashboard/localSettings.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
const server = localStorage.getItem("terminusdb-server-override") || process.env.TERMINUSDB_SERVER

let key= localStorage.getItem("terminusdb-key-override") || process.env.TERMINUSDB_KEY
//there is no default key
//let key= localStorage.getItem("terminusdb-key-override") || process.env.TERMINUSDB_KEY

const userName= localStorage.getItem("terminusdb-user-override") || process.env.TERMINUSDB_USER
//const userName= localStorage.getItem("terminusdb-user-override") || process.env.TERMINUSDB_USER

const connection_type = process.env.CONNECTION_TYPE


export const localSettings = {server : server,
key : key,
user: userName,
export const localSettings = {
server : server,
//key : key,
//user: userName,
connection_type :connection_type
}

2 changes: 1 addition & 1 deletion packages/tdb-dashboard/src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export function App (props){
}

if(connectionError) {
return <ServerError>{connectionError}</ServerError>
return <ServerError message={connectionError}/>
}

if(loading || loadingServer) {
Expand Down
2 changes: 1 addition & 1 deletion packages/tdb-dashboard/src/clientUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export function createClientUser(useAuth0,params){
clientUser.user = clientUser.agentName
clientUser.serverType = "TerminusX"
}catch(err){
const lastuser = localStorage.getItem("User") || params.user
const lastuser = localStorage.getItem("Terminusdb-USER") //|| params.user
clientUser = {email: lastuser }
clientUser.user = lastuser
clientUser.serverType = "TerminusDB"
Expand Down
12 changes: 6 additions & 6 deletions packages/tdb-dashboard/src/components/ChangeUser.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import {Button} from "react-bootstrap"
import {RiUser3Fill} from "react-icons/ri"
import { LoginModal } from "./LoginModal";

export const ChangeUser = ({css, label}) => {
const [showModal, setShowModal] = useState(false)
export const ChangeUser = ({css, label, showModalDefault, isClosable=true}) => {
const [showModal, setShowModal] = useState(showModalDefault || false)

function handleNew (evt) {
setShowModal(true)
Expand All @@ -15,9 +15,9 @@ export const ChangeUser = ({css, label}) => {
const labelStr = label || "Change User"

return <React.Fragment>
<Button id="new_data_product" variant="info" className={`mr-1 ml-1 pt-2 pb-2 pr-4 pl-4 btn ${extracss}`} title="Create New Data Product" onClick={handleNew}>
{!isClosable && <Button id="new_data_product" variant="info" className={`mr-1 ml-1 pt-2 pb-2 pr-4 pl-4 btn ${extracss}`} title="Create New Data Product" onClick={handleNew}>
<RiUser3Fill className="me-2"/>{labelStr}
</Button>
<LoginModal setShowModal={setShowModal} showModal={showModal}/>
</React.Fragment>
</Button>}
<LoginModal setShowModal={setShowModal} showModal={showModal} isClosable/>
</React.Fragment>
}
66 changes: 41 additions & 25 deletions packages/tdb-dashboard/src/components/LoginModal.js
Original file line number Diff line number Diff line change
@@ -1,63 +1,79 @@
import React, {useRef} from "react"
import React, {useRef,useState} from "react"
import {Modal, Button, Form} from "react-bootstrap"
import { WOQLClient } from "@terminusdb/terminusdb-client";
import {localSettings} from "../../localSettings"
import {formatErrorMessage } from '../hooks/hookUtils'
import { Alert } from "react-bootstrap";

export const LoginModal = ({showModal, setShowModal }) => {
export const LoginModal = ({showModal, setShowModal, isCloseble }) => {
const [errorMessage,setErrorMessage] = useState(false)
const nameRef = useRef(null);
const passwordRef = useRef(null);
const orgRef = useRef(null);
// const orgRef = useRef(null);
// to be review
const loading = false
const handleClose = () => setShowModal(false);
const handleClose = () => {
if(setShowModal)setShowModal(false);
}

const changeLoggeduser = async () => {
const name = nameRef.current.value
const password = passwordRef.current.value
const organization = orgRef.current.value
//const organization = orgRef.current.value
if(!name || name === "" || !password || password === "") {
setError("Team name and password are mandatory")
return
}else{
localStorage.setItem("User",name)
localStorage.setItem("Key",password)
localStorage.setItem("Org",organization)
// to be review using routing
const base = process.env.BASE_URL ? `/${process.env.BASE_URL}` : ""
window.location.replace(`${base}/${organization}`)
const client = new WOQLClient(localSettings.server,{user:name,key:password})
client.info().then(response=>{
if(response["api:info"] && response["api:info"]['authority'] === "anonymous"){
setErrorMessage("Incorrect authentication information, please enter your username and password again")
}else{
localStorage.setItem("Terminusdb-USER",name)
localStorage.setItem("Terminusdb-KEY",password)
//localStorage.setItem("Org",organization)
// to be review using routing
const base = process.env.BASE_URL ? `/${process.env.BASE_URL}` : ""
window.location.replace(`${base}`)
}
}).catch(err=>{
const message = formatErrorMessage(err)
setErrorMessage(message)
})


}
}

const onHide = isCloseble ? {onHide:handleClose} : {}


//<Loading message={`Deleting Data Product ${dataProductDetails.label} ...`} type={PROGRESS_BAR_COMPONENT}/>}
return <Modal size="lg" className="modal-dialog-right" show={showModal} onHide={handleClose}>
return <Modal size="lg" className="modal-dialog-right" show={showModal} {...onHide}>
<Modal.Header>
<Modal.Title className="h6">Login</Modal.Title>
<Button variant="close" aria-label="Close" onClick={handleClose} />
<Modal.Title className="h6">Login to TerminusDB</Modal.Title>
{isCloseble && <Button variant="close" aria-label="Close" onClick={handleClose} />}
</Modal.Header>
<Modal.Body className="p-5">
{/*errorMessage &&
<Alert variant="danger" onClose={() => setError(false)} dismissible>{errorMessage}</Alert>*/}
{errorMessage &&
<Alert variant="danger" onClose={() => setErrorMessage(false)} dismissible>{errorMessage}</Alert>}
<Form>
<Form.Group className="mb-3">
<Form.Control required
<Form.Control required
onBlur={()=>setErrorMessage(false)}
ref={nameRef}
id="add_element_name"
type="text"
placeholder={`Please type the user name`} />
</Form.Group>
<Form.Group className="mb-3">
<Form.Control required
onBlur={()=>setErrorMessage(false)}
ref={passwordRef}
id="add_element_password"
type="password"
placeholder={`Please type the user password`} />
</Form.Group>
<Form.Group className="mb-3">
<Form.Control required
ref={orgRef}
id="add_element_organization"
type="text"
placeholder={`Please type the user organization`} />
</Form.Group>
</Form>
</Modal.Body>
<Modal.Footer>
Expand All @@ -66,7 +82,7 @@ export const LoginModal = ({showModal, setShowModal }) => {
id ="add_element_button"
variant="info"
title={`Login With a different user`}
onClick={changeLoggeduser}>{loading ? 'Loading ...' : "Connect with the User"}
onClick={changeLoggeduser}>{loading ? 'Loading ...' : "Login"}
</Button>
</Modal.Footer>
</Modal>
Expand Down
4 changes: 2 additions & 2 deletions packages/tdb-dashboard/src/components/NewTeamModal.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ export const NewTeamModal = ({show, setShow}) => {
createNewTeam().then(done=>{
if(done === true){
setTeamCreated(true)
const basename = process.env.BASE_URL
window.location.replace(`${window.location.origin}/${basename}/${teamName}`)
const base = process.env.BASE_URL ? `/${process.env.BASE_URL}` : ""
window.location.replace(`${window.location.origin}${base}/${teamName}`)
}
})
}
Expand Down
2 changes: 1 addition & 1 deletion packages/tdb-dashboard/src/components/QueryPane.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ export const QueryPane = ({queryObj}) => {
<div className="query-pane-pallet mb-3 mt-3" >
<Row className="w-100">
<Col md={12}>
{queryError && <Alert variant="danger" onClose={() => setShowAlert(false)} dismissible>{queryError}</Alert>}
{queryError && <Alert className = "text-break" variant="danger" onClose={() => setShowAlert(false)} dismissible>{queryError}</Alert>}
</Col>
{/*<Col md={10}>
<h1 className="h5 ml-3">
Expand Down
33 changes: 21 additions & 12 deletions packages/tdb-dashboard/src/components/ServerError.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from "react"
import {Col} from "react-bootstrap"
import {Col,Button} from "react-bootstrap"
import {NoDataProductSelectedStyle} from "./constants"
import {WOQLClientObj} from '../init-woql-client'
import { ChangeUser } from "./ChangeUser"
Expand All @@ -8,25 +8,34 @@ export const ServerError = (props) => {
const {clientUser } = WOQLClientObj()
const serverType = clientUser ? clientUser.serverType : "TerminusX"

const gotoMainPage= ()=>{
const base = process.env.BASE_URL ? `/${process.env.BASE_URL}` : "/"
window.location.replace(`${base}`)
}

let returnToMainPage = false
if(props.message.startsWith("There is no organization with the name")){
returnToMainPage=true
}

return <div style={NoDataProductSelectedStyle}>
<Col xs={12} className="text-center d-block align-items-center justify-content-center">
<div className="card card-fil m-5 p-5">
<h4 className="text-muted mt-5 mb-3">
<p>Connection Server Error</p>
<p>{props.children}</p>
<a href="https://discuss.terminusdb.com/" targert="_blank">
{`Please contact the ${serverType} Team`}
</a>
<h4 className="text-white mt-5 mb-3">
<p>{props.message}</p>
{<Button id="go_to_team_list" variant="info" className={`mr-1 ml-1 pt-2 pb-2 pr-4 pl-4 btn `} title="Go to the team list" onClick={gotoMainPage}>
Go to Teams
</Button>}
{clientUser.connection_type !=="LOCAL" &&
<a href="https://discuss.terminusdb.com/" targert="_blank">
{`Please contact the ${serverType} Team`}
</a>
}
</h4>
{clientUser && clientUser.logout &&
<button title="Create New Data Product" type="button" onClick={()=>{ clientUser.logout()}}
className="mr-auto ml-auto pt-2 pb-2 pr-4 pl-4 btn btn-sm btn btn-info">Logout</button>
}
{clientUser && clientUser.connection_type ==="LOCAL" &&
<div>
<ChangeUser label="Login to TerminusDB"/>
</div>
}
</div>
</Col>
</div>
Expand Down
17 changes: 8 additions & 9 deletions packages/tdb-dashboard/src/components/UserMenu.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,16 @@ import {NavLink as RouterNavLink} from "react-router-dom"
import {AiOutlineUser, AiOutlinePoweroff,AiOutlineUsergroupAdd} from "react-icons/ai"
import {FaExchangeAlt} from "react-icons/fa"
import {WOQLClientObj} from '../init-woql-client'
import { LoginModal } from "./LoginModal";

export const UserMenu = ({organization}) => {
const { clientUser,accessControlDashboard} = WOQLClientObj()
const redirect_uri=`${window.location.origin}/`

const [showModal, setShowModal] = useState(false)

function handleNew (evt) {
setShowModal(true)
function logoutLocalUser (evt) {
localStorage.removeItem("Terminusdb-USER")
localStorage.removeItem("Terminusdb-KEY")
const base = process.env.BASE_URL ? `/${process.env.BASE_URL}` : "/"
window.location.replace(`${base}`)
}

const logoutWithRedirect = () =>
Expand Down Expand Up @@ -42,7 +42,6 @@ export const UserMenu = ({organization}) => {

if(clientUser.connection_type==="LOCAL"){
return <React.Fragment>
{showModal && <LoginModal setShowModal={setShowModal} showModal={showModal}/>}
<Dropdown className="mr-4" id="profile_menu">
<Button size="sm" className="bg-transparent border-0">
{clientUser.email}
Expand All @@ -58,9 +57,9 @@ export const UserMenu = ({organization}) => {
<AiOutlineUsergroupAdd className="mr-3 mb-1" />User Managment
</Nav.Link>
</Dropdown.Item>}
<Dropdown.Item onClick={handleNew} className="text-success">
<FaExchangeAlt className="mr-3 mb-1" />
Change User
<Dropdown.Item onClick={logoutLocalUser} >
<AiOutlinePoweroff className="mr-3 mb-1" />
Logout
</Dropdown.Item>
</Dropdown.Menu>
</Dropdown>
Expand Down
4 changes: 2 additions & 2 deletions packages/tdb-dashboard/src/hooks/hookUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ export function formatErrorMessage (err){
let message = err.message
if(err.data && err.data["api:message"]){
if( err.data["api:message"] === "Incorrect authentication information"){
return "Incorrect authentication information, please enter your username and password again"
}
return "Incorrect authentication information, wrong username or password"
}
message = err.data["api:message"]
}else if (message.indexOf("Network Error")>-1){
message = "Network Error"
Expand Down
7 changes: 6 additions & 1 deletion packages/tdb-dashboard/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ import {localSettings} from "../localSettings"
import {auth0_conf} from '../auth_config'
import {Auth0Provider} from "./react-auth0-spa"
import {BrowserRouter,useNavigate} from "react-router-dom"
import {LoginModal} from "./components/LoginModal"

require('./App.css')
require('./Colors.css')

function NavigationComponent(){

Expand All @@ -33,6 +34,10 @@ function NavigationComponent(){
</Auth0Provider>
}

if(localSettings && localSettings.connection_type=== "LOCAL" && !localStorage.getItem("Terminusdb-USER")){
return <LoginModal showModal={true} isCloseble={false}/>
}

return <WOQLClientProvider params={localSettings}>
<App />
</WOQLClientProvider>
Expand Down
4 changes: 2 additions & 2 deletions packages/tdb-dashboard/src/init-woql-client.js
Original file line number Diff line number Diff line change
Expand Up @@ -143,8 +143,8 @@ export const WOQLClientProvider = ({children, params}) => {
//and don't need auth0 too
if(opts.connection_type === 'LOCAL'){
setLoadingServer(true)
const user = localStorage.getItem("User") || opts.user
const key = localStorage.getItem("Key") || opts.key
const user = localStorage.getItem("Terminusdb-USER")
const key = localStorage.getItem("Terminusdb-KEY")
const credentials = {user ,key}
initWoqlClient(credentials,credentials)

Expand Down
2 changes: 1 addition & 1 deletion packages/tdb-dashboard/src/pages/Layout.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export const Layout = (props) => {
<div className="main-content h-100">
<MainNavBar setShowTimeTravel={setShowTimeTravel}/>
<div className="container-fluid " >
{ dataProduct && <TimeTravelContainer show={showTimeTravel} setShowTimeTravel={setShowTimeTravel}/>}
{ dataProduct && <TimeTravelContainer dataProduct={dataProduct} show={showTimeTravel} setShowTimeTravel={setShowTimeTravel}/>}
{props.children}
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export const makeWOQLFromString =(str, lang)=>{
let prelude = WOQL.emerge()
var nw = eval(prelude + "\n" + str)
// if(!nw) throw new Error("The ")
console.log(prelude)
//console.log(prelude)
return nw;
case "python":
throw "Python is not supported for editing queries through the console";
Expand Down