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
29 changes: 29 additions & 0 deletions packages/tdb-dashboard/src/App.css
Original file line number Diff line number Diff line change
Expand Up @@ -1201,3 +1201,32 @@ pre.CodeMirror-line > span > span.cm-string {
/* line-height: 1.5 !important; */
min-height: 49px!important;
}

/** custom alert error message */
.alert_danger_text {
color: #842029 !important;
}

.alert_danger {
background-color: #f8d7da !important;
border: 1px solid #f5c2c7 !important;
}

.alert_danger_border {
border: 1px solid #842029 !important;
}

.alert_btn_close {
color: #842029 !important;
box-sizing: content-box;
width: 1em;
height: 1em;
padding: 0.25em 0.25em;
border: 0;
border-radius: 0.375rem;
opacity: 0.4;
}

.alert_expand_icons {
margin-top: -20px;
}
33 changes: 26 additions & 7 deletions packages/tdb-dashboard/src/components/Alerts.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,24 @@ import {AiOutlineCheckCircle, AiOutlineWarning} from "react-icons/ai"
import {BiErrorCircle} from "react-icons/bi"
import {BsInfoCircle} from "react-icons/bs"
import {queryTimeDisplay} from "./utils"
import { FaTimes, FaExclamationTriangle } from "react-icons/fa"


/**
*
* @param {*} type document Type
* @returns a close button icon
*/
const AlertCloseButton = ({ className, onClick }) => {
// on close button display document list table
return <Button variant="light"
className={`${className} d-contents`}
style={{display: "contents"}}
tilte={`Close`}
onClick={onClick}>
<FaTimes/>
</Button>
}

export const Alerts = ({message, type, onCancel, time}) => {
const [hiddenAlerts, setHiddenAlerts] = React.useState([])
Expand Down Expand Up @@ -38,17 +56,18 @@ export const Alerts = ({message, type, onCancel, time}) => {

if(type == TERMINUS_DANGER)
return <Alert
className="text-break"
variant="danger"
//className="text-break"
//variant="danger"
className="alert_danger alert_danger_text"
show={shouldShowAlert("danger")}
onClose={() => onClose("danger")}>

<div className="d-flex justify-content-between">
<div>
<BiErrorCircle className="me-1" />
<strong>Error: </strong> {message}
</div>
<Button variant="close" size="xs" onClick={() => onClose("danger")} />
<div className="w-100">
<FaExclamationTriangle className="me-1 mb-1" />
<strong>Oops! Something went wrong.</strong> {message}
</div>
<AlertCloseButton className={"alert_btn_close alert_danger_text"} onClick={() => onClose("danger")}/>
</div>
</Alert>

Expand Down
73 changes: 73 additions & 0 deletions packages/tdb-dashboard/src/components/ErrorDisplay.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import React, {useContext} from "react"
import Accordion from 'react-bootstrap/Accordion';
import { useAccordionButton } from 'react-bootstrap/AccordionButton';
import Card from 'react-bootstrap/Card';
import AccordionContext from 'react-bootstrap/AccordionContext';
import * as CONST from "./constants"
import { MdKeyboardArrowDown, MdKeyboardArrowRight } from "react-icons/md"

// function to show custom buttons on Show/Hide in Accordians
function ToggleErrorDisplay({ children, eventKey, expandComponent, hideComponent, css }) {
const { activeEventKey } = useContext(AccordionContext);

const onExpand = useAccordionButton(eventKey, () => {});

const isCurrentEventKey = activeEventKey === eventKey;

return (
<button
type="button"
className={css}
onClick={onExpand}
>
{ isCurrentEventKey ? hideComponent : expandComponent }
</button>
);
}

// function displays accordians per property error
/**
*
* @param {*} propertyName property name
* @param {*} errorType error description per property
* @param {*} message message per property
* @returns
*/
export const DisplayErrorPerProperty = ({ propertyName, errorType, message }) => {
return <Accordion className="bg-transparent border-0 w-100">
<Accordion.Item eventKey={propertyName} className={"bg-transparent border-0 alert_danger_text"}>
<div className="mb-3">
<div className="fw-bold d-flex">
<ToggleErrorDisplay eventKey={propertyName}
css={CONST.ERROR_DOC_EXPAND_ICON_CLASSNAME}
expandComponent={<MdKeyboardArrowRight/>}
hideComponent={<MdKeyboardArrowDown/>}/>
{errorType}
<pre className="alert_danger_border ml-1 p-1 rounded">{propertyName}</pre>
</div>
</div>
</Accordion.Item>
<Accordion.Collapse eventKey={propertyName} className={"bg-transparent"}>
<div style={{ whiteSpace: "pre-wrap" }}>{message}</div>
</Accordion.Collapse>
</Accordion>
}


// function display error messages
export const ErrorDisplay = ({ errorData, message, css }) => {
return <Accordion className="bg-transparent border-0 w-100">
<Card className="bg-transparent border-0">
<Card.Header className="bg-transparent">
<span className="text-uppercase">{message} </span>
<ToggleErrorDisplay eventKey="0" expandComponent={"More Info" } hideComponent={"Hide"} css={css}/>
</Card.Header>
<Accordion.Collapse eventKey="0">
<Card.Body>
{/*<pre>{JSON.stringify(errorData, null, 2)}</pre>*/}
{errorData}
</Card.Body>
</Accordion.Collapse>
</Card>
</Accordion>
}
1 change: 1 addition & 0 deletions packages/tdb-dashboard/src/components/JsonFrameViewer.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ export const JsonFrameViewer = ({jsonData, mode, setExtracted}) => {
if(setExtracted) setExtracted(data)
}

// onBlur
return <React.Fragment>
<CodeMirror
value={JSON.stringify(data, null, 2)}
Expand Down
3 changes: 3 additions & 0 deletions packages/tdb-dashboard/src/components/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -499,3 +499,6 @@ export const DELETE="Delete"
export const VIEW_LIST="List"


//ERROR MESSAGE CONSTANTS
export const ERROR_MORE_INFO_CLASSNAME = "float-right alert_danger alert_danger_text rounded alert_danger_border"
export const ERROR_DOC_EXPAND_ICON_CLASSNAME = "mr-4 alert_expand_icons bg-transparent border-0 alert_danger_text"
15 changes: 10 additions & 5 deletions packages/tdb-dashboard/src/components/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@ import {format, subSeconds} from "date-fns"
//import deAT from 'date-fns/locale/de-AT/index'
//import {XSD_DATA_TYPE_PREFIX, XDD_DATA_TYPE_PREFIX} from "./constants"
import {FiCopy} from "react-icons/fi"
import React from "react"
import React, {useState} from "react"
import {VscGitPullRequestDraft} from "react-icons/vsc"
import {VscGitPullRequest} from "react-icons/vsc"
import {VscCheck} from "react-icons/vsc"
import {AiOutlineCheck} from "react-icons/ai"
import Stack from 'react-bootstrap/Stack';
import Badge from "react-bootstrap/Badge"
import Button from "react-bootstrap/Button"
import {
Expand Down Expand Up @@ -320,11 +321,15 @@ export function sortAlphabetically (list, byID) {
})
}

// function which displays CR Conflict errors
export function getCRConflictError (errorData) {
// function which displays CR Conflict errors
export const getCRConflictError = (errorData) => {

let message = "It looks like there are conflicts, fix these conflicts and then update or exit the Change Request"
return <div>
{message}
return <div className="w-100">
<Stack direction="horizontal" gap={3} className="w-100">
<div>{message}</div>
</Stack>

<pre>{JSON.stringify(errorData, null, 2)}</pre>
</div>
}
Expand Down
50 changes: 49 additions & 1 deletion packages/tdb-dashboard/src/hooks/DocumentControlContext.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ export const DocumentControlContext = React.createContext()
export const DocumentControlObj = () => useContext(DocumentControlContext)
import {WOQLClientObj} from '../init-woql-client'
import * as CONST from "../components/constants"
import { ErrorDisplay } from "../components/ErrorDisplay"
import { DisplayErrorPerProperty } from "../components/ErrorDisplay"

export const DocumentControlProvider = ({children}) => {

Expand Down Expand Up @@ -37,6 +39,51 @@ export const DocumentControlProvider = ({children}) => {



// function to format and display errors in document Interface
function formatErrorMessages (error) {

if(!error.hasOwnProperty("api:message")) return error

let message = error["api:message"]
let errorElements = []
if(error["api:error"]) {
if(Array.isArray(error["api:error"]["api:witnesses"])) {
error["api:error"]["api:witnesses"].map(err => {

if(err.hasOwnProperty("constraint_name")) {
// CONSTRAINT ERRORS
let propertyName = err["constraint_name"]
let errorType = `${err["@type"]} on `
let message = err.message

errorElements.push(
<DisplayErrorPerProperty propertyName={propertyName} message={message} errorType={errorType}/>
)
}
else {
if(err.hasOwnProperty("@type")) {
errorElements.push(
<pre>{JSON.stringify(err, null, 2)}</pre>
)
}
else {
// OTHER TYPE ERRORS
for(let items in err) {
let propertyName = items
let errorType = err[propertyName].hasOwnProperty("@type") ? `${err[propertyName]["@type"]} on ` : `Error occured on`
let message = JSON.stringify(err[propertyName], null, 2)
errorElements.push(
<DisplayErrorPerProperty propertyName={propertyName} message={message} errorType={errorType}/>
)
}
}
}
})
}
}
return <ErrorDisplay errorData={errorElements} message={message} css={CONST.ERROR_MORE_INFO_CLASSNAME}/>
}

return (
<DocumentControlContext.Provider
value={{
Expand All @@ -46,7 +93,8 @@ export const DocumentControlProvider = ({children}) => {
jsonContent,
setJsonContent,
showFrames,
setShowFrames
setShowFrames,
formatErrorMessages
}}
>
{children}
Expand Down
17 changes: 14 additions & 3 deletions packages/tdb-dashboard/src/hooks/DocumentHook.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { useNavigate, useParams } from "react-router-dom";
import { ChangeRequest } from "./ChangeRequest";
import { WOQLClientObj } from "../init-woql-client";


// to be review this
export function CheckStatusObj() {
const {currentChangeRequest} = WOQLClientObj()
Expand All @@ -22,6 +23,14 @@ export function CheckStatusObj() {

}

// function to set error
function setErrorMessage(setErrorMsg, err) {
if(setErrorMsg) {
if(err.hasOwnProperty("data")) setErrorMsg(err.data)
else setErrorMsg(err.message)
}
}

/**
* Create a new document
* @param {*} client TerminusDB Client
Expand All @@ -47,7 +56,7 @@ export function CreateDocumentHook(client,document, setLoading, setErrorMsg) {
}
catch(err){
setLoading(false)
if(setErrorMsg) setErrorMsg(err.message)
setErrorMessage(setErrorMsg, err)
}
}

Expand Down Expand Up @@ -114,7 +123,8 @@ export function GetDocumentHook(client, documentId, setData, setLoading, setErro
}
catch(err){
if(setLoading) setLoading(false)
if(setErrorMsg) setErrorMsg(err.message)
setErrorMessage(setErrorMsg, err)
//if(setErrorMsg) setErrorMsg(err.message)
}
}

Expand Down Expand Up @@ -152,7 +162,8 @@ export function EditDocumentHook(client, extractedUpdate, setLoading, setErrorMs
navigate(-1)
}
catch(err){
setErrorMsg(err.message)
//setErrorMsg(err.message)
setErrorMessage(setErrorMsg, err)
setLoading(false)
}
}
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 @@ -43,9 +43,9 @@ export function formatErrorMessage (err){
}else if(err.data){
if( err.data["api:message"] === "Incorrect authentication information"){
message = "Incorrect authentication information, wrong username or password"
}else if (err.data["api:status"]==="api:conflict"){
}else if (err.data["api:status"]==="api:conflict") {
message = getCRConflictError(err.data["api:witnesses"])
}else if (err.data["api:message"]=== "Schema check failure"){
}else if (err.data["api:message"]=== "Schema check failure") {
message = `${err.data["api:message"]} ${JSON.stringify(err.data["system:witnesses"], null, 2)}`
}else{
message = err.data["api:message"]
Expand Down
2 changes: 1 addition & 1 deletion packages/tdb-dashboard/src/pages/ChangeDiff.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ const CRAction = ({}) => {
return <ChangeDiffComponent/>

// if needRebase
return <React.Fragment>
return <React.Fragment>
{errorMessage && <Alerts message={errorMessage} type={CONST.TERMINUS_DANGER} onCancel={setError}/>}
<Card className="update__change__request__card">
<Card.Header className="w-100">
Expand Down
10 changes: 8 additions & 2 deletions packages/tdb-dashboard/src/pages/DocumentEdit.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {DocumentControlObj} from "../hooks/DocumentControlContext"
import {CreateChangeRequestModal} from "../components/CreateChangeRequestModal"
import {UTILS} from "@terminusdb/terminusdb-client"
import {decodeUrl} from "../components/utils"
import { Alerts } from "../components/Alerts"

const checkIfPrefix =(id)=>{
if(id.indexOf(":")>-1){
Expand Down Expand Up @@ -116,6 +117,10 @@ export const DocumentEdit = () => {
setChangeRequestBranch, branch
} = WOQLClientObj()

const {
formatErrorMessages
} = DocumentControlObj()

const {type, id} = useParams()
let documentID=decodeUrl(id)
// constants to display document body in Form or JSON View
Expand All @@ -140,9 +145,10 @@ export const DocumentEdit = () => {

return <main className="content w-100 document__interface__main">

{errorMsg && <Alert variant={"danger"} className="mr-3">
{/*errorMsg && <Alert variant={"danger"} className="mr-3">
{errorMsg}
</Alert>}
</Alert>*/}
{errorMsg && <Alerts message={formatErrorMessages(errorMsg)} type={CONST.TERMINUS_DANGER} onCancel={setErrorMsg}/>}
{showModal && <CreateChangeRequestModal showModal={showModal}
type={type}
setShowModal={setShowModal}
Expand Down
Loading