Implement crude version of all CRUD endpoints

master
Joshua Sigona 4 years ago
parent e0e5b81166
commit 66f97f4d84
  1. 8
      package-lock.json
  2. 1
      package.json
  3. 5
      src/App.css
  4. 67
      src/App.js
  5. 28
      src/style.css
  6. 3
      src/web-icons/x.svg
  7. 3
      src/x.svg

8
package-lock.json generated

@ -12649,6 +12649,14 @@
"whatwg-fetch": "^3.4.1"
}
},
"react-bootstrap-icons": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/react-bootstrap-icons/-/react-bootstrap-icons-1.5.0.tgz",
"integrity": "sha512-QC5q4meHQG0cO9RJzeDLSqZ1gbVa9jxFCpONCE3GYl2FkbAKSyJAEsONlzTApbZ8/oG87gPWq0xAyn5SZ/Jafw==",
"requires": {
"prop-types": "^15.7.2"
}
},
"react-dev-utils": {
"version": "11.0.4",
"resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-11.0.4.tgz",

@ -11,6 +11,7 @@
"axios": "^0.21.1",
"gh-pages": "^3.2.3",
"react": "^17.0.2",
"react-bootstrap-icons": "^1.5.0",
"react-dom": "^16.14.0",
"react-router": "^5.2.0",
"react-router-dom": "^5.2.0",

@ -347,4 +347,9 @@ button{
text-align: center;
-webkit-font-smoothing: antialiased;
text-shadow: -1px 1px 0 #000,1px 1px 0 #000,1px -1px 0 #000,-1px -1px 0 #000;
}
.w-25{
min-width:25%;
width:25%;
}

@ -1,10 +1,12 @@
//import './App.css'; Old CSS
import './reset.css'; // Generic reset
import './style.css'; // The new new
import React, {useState,useEffect,useRef} from 'react';
import React, {useState,useEffect,useRef,useReducer} from 'react';
import ReactWindow from 'reactjs-windows'
import 'reactjs-windows/dist/index.css'
import {XSquareFill} from 'react-bootstrap-icons'
import {
BrowserRouter as Router,
Switch,
@ -390,18 +392,26 @@ function EditableBackendBox(p) {
const [update,setUpdate] = useState(false)
const [edit,setEdit] = useState(false)
const [value,setValue] = useState(p.children)
const [originalValue,setOriginalValue] = useState(p.children)
useEffect(()=>{
if (p.callback&&update) {
p.callback(value)
setUpdate(false)
.then(()=>{
setUpdate(false)
setOriginalValue(value)
})
.catch(()=>{
setUpdate(false)
setValue(originalValue)
})
}
},[update])
return <>
<div className="hover" onClick={(f)=>{setEdit(true)}}>
<div className="hover table-padding" onClick={(f)=>{setEdit(true)}}>
{edit?
<EditBackendBox maxlength={p.maxlength} setUpdate={setUpdate} setEdit={setEdit} originalName={value} setName={setValue} value={value}/>
<EditBackendBox maxlength={p.maxlength} setUpdate={setUpdate} setEdit={setEdit} originalName={originalValue} setName={setValue} value={value}/>
:<>{value}</>}
</div>
</>
@ -409,10 +419,22 @@ function EditableBackendBox(p) {
function TableEditor(p) {
const initialVals={}
function updateVals(state,update) {
if (update==='Clear') {
return initialVals
}
state[update.field]=update.value
return state
}
const [fields,setFields] = useState([])
const [data,setData] = useState([])
const [update,setUpdate] = useState(false)
const [submitVals,setSubmitVal] = useReducer(updateVals,initialVals)
useEffect(()=>{
function updateData() {
axios.get(BACKEND_URL+p.path)
.then((data)=>{
var cols = data.data.fields
@ -421,19 +443,48 @@ function TableEditor(p) {
setFields(cols.filter((col)=>col.name!=="id").map((col)=>col.name))
setData(rows)
})
}
function SubmitBoxes() {
axios.post(BACKEND_URL+p.path,submitVals)
.then(()=>{
setUpdate(true)
})
.catch((err)=>{
alert(JSON.stringify(err.response.data))
})
}
useEffect(()=>{
updateData()
},[p.path])
useEffect(()=>{
if (update) {
updateData()
setUpdate(false)
}
},[update])
return <>
<div className="table-responsive">
<table className="table text-light">
<table cellPadding="10" className="table text-light table-padding">
<caption>List of users</caption>
<thead>
<tr>
{fields.map((field,i)=><React.Fragment key={i}><th scope="col">{field}</th></React.Fragment>)}
<th className="table-padding"></th>
{fields.map((field,i)=><React.Fragment key={i}><th scope="col" className="table-padding">{field}</th></React.Fragment>)}
</tr>
</thead>
<tbody>
{data.map((dat,i)=><tr key={i}>{fields.map((col,i)=><td key={i}><EditableBackendBox callback={(value)=>{console.log(value)}}>{String(dat[col])}</EditableBackendBox></td>)}</tr>)}
{data.map((dat)=><tr key={dat.id}>
<td><XSquareFill className="webicon" onClick={()=>{axios.delete(BACKEND_URL+p.path,{data:{id:dat.id}}).then(()=>{setUpdate(true)}).catch((err)=>{alert(err.response.data)})}}/></td>{fields.map((col,i)=><td key={dat.id+"_"+i} className="table-padding table"><EditableBackendBox callback={(value)=>{
return axios.patch(BACKEND_URL+p.path,{
[col]:value,
id:dat.id
})
}}>{String(dat[col])}</EditableBackendBox></td>)}</tr>)}
{<tr><td></td>{fields.map((col,i)=><td key={i}>{<input id={"submitField"+i} onBlur={(i==fields.length-1)?(f)=>{setSubmitVal({field:col,value:f.currentTarget.value});SubmitBoxes();document.getElementById("submitField0").focus()}:(f)=>{setSubmitVal({field:col,value:f.currentTarget.value})}}/>}</td>)}</tr>}
</tbody>
</table>
</div>

@ -856,4 +856,32 @@ button{
text-align: center;
-webkit-font-smoothing: antialiased;
text-shadow: -1px 1px 0 #000,1px 1px 0 #000,1px -1px 0 #000,-1px -1px 0 #000;
}
.w-25{
min-width:240px;
max-width:24%;
}
.w-75{
min-width:75%;
max-width:75%;
}
.table-responsive{;
color:rgba(220,220,220);
overflow-y:hidden;
overflow-x:scroll;
}
.table{
border: 1px solid black;
border-spacing:1px;
}
.table-padding{
padding: 4px;
}
.webicon{
color:maroon;
}
.webicon:hover{
color:rgba(200,0,0,1);
cursor:pointer;
}

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-x" viewBox="0 0 16 16">
<path d="M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708z"/>
</svg>

After

Width:  |  Height:  |  Size: 332 B

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-x" viewBox="0 0 16 16">
<path d="M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708z"/>
</svg>

After

Width:  |  Height:  |  Size: 332 B

Loading…
Cancel
Save