Compare commits
15 Commits
master
...
feature/1_
| Author | SHA1 | Date |
|---|---|---|
|
|
cb5ea53d42 | |
|
|
7e0f7d16ff | |
|
|
c0c164638b | |
|
|
a75dcf97a9 | |
|
|
675e8b3452 | |
|
|
dcd885146a | |
|
|
fbc2632490 | |
|
|
9f90fa0ba2 | |
|
|
74de7cf0c8 | |
|
|
39dad010c6 | |
|
|
e357719578 | |
|
|
a8f55c540d | |
|
|
0131d75f8b | |
|
|
d2c3a9d272 | |
|
|
6f3e8f7e4d |
|
|
@ -1664,6 +1664,17 @@
|
||||||
"react-lifecycles-compat": "^3.0.4"
|
"react-lifecycles-compat": "^3.0.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@reduxjs/toolkit": {
|
||||||
|
"version": "1.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.5.0.tgz",
|
||||||
|
"integrity": "sha512-E/FUraRx+8guw9Hlg/Ja8jI/hwCrmIKed8Annt9YsZw3BQp+F24t5I5b2OWR6pkEHY4hn1BgP08FrTZFRKsdaQ==",
|
||||||
|
"requires": {
|
||||||
|
"immer": "^8.0.0",
|
||||||
|
"redux": "^4.0.0",
|
||||||
|
"redux-thunk": "^2.3.0",
|
||||||
|
"reselect": "^4.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@sideway/address": {
|
"@sideway/address": {
|
||||||
"version": "4.1.1",
|
"version": "4.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.1.tgz",
|
||||||
|
|
@ -8111,6 +8122,11 @@
|
||||||
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz",
|
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz",
|
||||||
"integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw=="
|
"integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw=="
|
||||||
},
|
},
|
||||||
|
"immer": {
|
||||||
|
"version": "8.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/immer/-/immer-8.0.1.tgz",
|
||||||
|
"integrity": "sha512-aqXhGP7//Gui2+UrEtvxZxSquQVXTpZ7KDxfCcKAF3Vysvw0CViVaW9RZ1j1xlIYqaaaipBoqdqeibkc18PNvA=="
|
||||||
|
},
|
||||||
"import-cwd": {
|
"import-cwd": {
|
||||||
"version": "2.1.0",
|
"version": "2.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/import-cwd/-/import-cwd-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/import-cwd/-/import-cwd-2.1.0.tgz",
|
||||||
|
|
@ -9144,6 +9160,11 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"loadash": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/loadash/-/loadash-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-xlX5HBsXB3KG0FJbJJG/3kYWCfsCyCSus3T+uHVu6QL6YxAdggmm3QeyLgn54N2yi5/UE6xxL5ZWJAAiHzHYEg=="
|
||||||
|
},
|
||||||
"loader-fs-cache": {
|
"loader-fs-cache": {
|
||||||
"version": "1.0.3",
|
"version": "1.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/loader-fs-cache/-/loader-fs-cache-1.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/loader-fs-cache/-/loader-fs-cache-1.0.3.tgz",
|
||||||
|
|
@ -12050,6 +12071,18 @@
|
||||||
"resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz",
|
||||||
"integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA=="
|
"integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA=="
|
||||||
},
|
},
|
||||||
|
"react-redux": {
|
||||||
|
"version": "7.2.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.2.2.tgz",
|
||||||
|
"integrity": "sha512-8+CQ1EvIVFkYL/vu6Olo7JFLWop1qRUeb46sGtIMDCSpgwPQq8fPLpirIB0iTqFe9XYEFPHssdX8/UwN6pAkEA==",
|
||||||
|
"requires": {
|
||||||
|
"@babel/runtime": "^7.12.1",
|
||||||
|
"hoist-non-react-statics": "^3.3.2",
|
||||||
|
"loose-envify": "^1.4.0",
|
||||||
|
"prop-types": "^15.7.2",
|
||||||
|
"react-is": "^16.13.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"react-refresh": {
|
"react-refresh": {
|
||||||
"version": "0.8.3",
|
"version": "0.8.3",
|
||||||
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.8.3.tgz",
|
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.8.3.tgz",
|
||||||
|
|
@ -12496,6 +12529,11 @@
|
||||||
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
|
||||||
"integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8="
|
"integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8="
|
||||||
},
|
},
|
||||||
|
"reselect": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/reselect/-/reselect-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-qUgANli03jjAyGlnbYVAV5vvnOmJnODyABz51RdBN7M4WaVu8mecZWgyQNkG8Yqe3KRGRt0l4K4B3XVEULC4CA=="
|
||||||
|
},
|
||||||
"resolve": {
|
"resolve": {
|
||||||
"version": "1.20.0",
|
"version": "1.20.0",
|
||||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz",
|
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz",
|
||||||
|
|
|
||||||
|
|
@ -15,10 +15,14 @@
|
||||||
"clean": "gatsby clean"
|
"clean": "gatsby clean"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@reduxjs/toolkit": "^1.5.0",
|
||||||
"gatsby": "^2.32.3",
|
"gatsby": "^2.32.3",
|
||||||
"gatsby-plugin-sass": "^3.2.0",
|
"gatsby-plugin-sass": "^3.2.0",
|
||||||
|
"loadash": "^1.0.0",
|
||||||
"react": "^16.13.1",
|
"react": "^16.13.1",
|
||||||
"react-dom": "^16.13.1",
|
"react-dom": "^16.13.1",
|
||||||
|
"react-redux": "^7.2.2",
|
||||||
|
"redux": "^4.0.5",
|
||||||
"sass": "^1.32.7"
|
"sass": "^1.32.7"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,158 @@
|
||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param { [ {}, {}, ...{} ] } inputList - list of dicts with info about input
|
||||||
|
* @param { [] } refList - react ref objects list for handler validation
|
||||||
|
* @param { } action - fetch method
|
||||||
|
*/
|
||||||
|
export const FormGenerator = ({
|
||||||
|
inputList, refList,
|
||||||
|
action
|
||||||
|
}) => {
|
||||||
|
|
||||||
|
const handler = async (event) => {
|
||||||
|
event.preventDefault()
|
||||||
|
for ( let i = 0; i < refList.length; i++ ) {
|
||||||
|
if (
|
||||||
|
refList[i].current.value === ''
|
||||||
|
&& inputList[0].action !== 'Update'
|
||||||
|
|| i === 0 && refList.length !== 1
|
||||||
|
) {
|
||||||
|
refList[i].current.focus()
|
||||||
|
} else if ( i === refList.length - 1 ) {
|
||||||
|
await action( refList )
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let info
|
||||||
|
|
||||||
|
return (
|
||||||
|
<form onSubmit={ event => handler( event ) }>
|
||||||
|
{
|
||||||
|
inputList.map( (input, key) => {
|
||||||
|
|
||||||
|
if ( input.type === 'info' ) {
|
||||||
|
info = input
|
||||||
|
} else if ( input.type === 'text' ) {
|
||||||
|
return (
|
||||||
|
<TextInputGenerator
|
||||||
|
input={ input }
|
||||||
|
info={ info }
|
||||||
|
key={ key }
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
} else if ( input.type === 'file' ) {
|
||||||
|
return (
|
||||||
|
<UploadInputGenerator
|
||||||
|
input={ input }
|
||||||
|
info={ info }
|
||||||
|
key={ key }
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
<button type='submit' />
|
||||||
|
</form>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Text input generator, example:
|
||||||
|
* @param {
|
||||||
|
* {
|
||||||
|
* type: 'text',
|
||||||
|
* name: 'name',
|
||||||
|
* ref: React.createRef()
|
||||||
|
* } } input - basic text input
|
||||||
|
* @param {
|
||||||
|
* {
|
||||||
|
* type: 'info',
|
||||||
|
* action: 'Update'
|
||||||
|
* endpoint: 'Album'
|
||||||
|
* } } info - information about form
|
||||||
|
*/
|
||||||
|
const TextInputGenerator = ({
|
||||||
|
input, info
|
||||||
|
}) => {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
{ input.name + ':' }
|
||||||
|
<input
|
||||||
|
id={ input.name + info.action + info.endpoint + 'Input' }
|
||||||
|
autoComplete='off'
|
||||||
|
ref={ input.ref }
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Upload file input generator, example:
|
||||||
|
* @param {
|
||||||
|
* {
|
||||||
|
* type: 'file',
|
||||||
|
* name: 'name',
|
||||||
|
* endpoint: 'Album',
|
||||||
|
* fileType: 'image' or 'audio',
|
||||||
|
* dropInfo: dropInfo, setDropInfo: setDropInfo(), #useState
|
||||||
|
* file: file, setFile: setFile() #useState
|
||||||
|
* } } input -
|
||||||
|
*/
|
||||||
|
const UploadInputGenerator = ({
|
||||||
|
input, info
|
||||||
|
}) => {
|
||||||
|
|
||||||
|
const onLoadFile = async ( event ) => {
|
||||||
|
event.preventDefault()
|
||||||
|
let data = event.target.files[0]
|
||||||
|
input.setFile( await toBase64( data ) )
|
||||||
|
setDropInfos(data.name, data.size)
|
||||||
|
}
|
||||||
|
|
||||||
|
const onLoadFileDrop = async ( event ) => {
|
||||||
|
event.preventDefault()
|
||||||
|
event.persist()
|
||||||
|
let data = event.dataTransfer.files[0]
|
||||||
|
input.setFile( await toBase64( data ) )
|
||||||
|
setDropInfos(data.name, data.size)
|
||||||
|
}
|
||||||
|
|
||||||
|
const toBase64 = ( file ) => new Promise( (resolve, reject) => {
|
||||||
|
let fileReader = new FileReader()
|
||||||
|
fileReader.readAsDataURL( file )
|
||||||
|
fileReader.onload = () => resolve( fileReader.result )
|
||||||
|
fileReader.onerror = error => reject( error )
|
||||||
|
})
|
||||||
|
|
||||||
|
const setDropInfos = (name, size) => {
|
||||||
|
input.setDropInfo(
|
||||||
|
'name: "'
|
||||||
|
+ name
|
||||||
|
+ '"\nsize: '
|
||||||
|
+ (Math.round(size / 100 + 'e-2') / 100 )
|
||||||
|
+ ' MB'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div onDrop={ event => onLoadFileDrop( event ) } >
|
||||||
|
<pre style={ {marginTop: '25px', marginLeft: '40px'} }>
|
||||||
|
{ input.dropInfo }
|
||||||
|
</pre>
|
||||||
|
<input
|
||||||
|
style={ { marginTop: '-55px' } }
|
||||||
|
id={ input.name + info.action + info.endpoint + 'Input' }
|
||||||
|
className='uploadInput'
|
||||||
|
type='file'
|
||||||
|
accept={ input.fileType + '/*' }
|
||||||
|
autoComplete='off'
|
||||||
|
onChange={ event => onLoadFile( event ) }
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default FormGenerator
|
||||||
|
|
@ -1,54 +0,0 @@
|
||||||
import * as React from "react"
|
|
||||||
import { Link } from "gatsby"
|
|
||||||
|
|
||||||
// styles
|
|
||||||
const pageStyles = {
|
|
||||||
color: "#232129",
|
|
||||||
padding: "96px",
|
|
||||||
fontFamily: "-apple-system, Roboto, sans-serif, serif",
|
|
||||||
}
|
|
||||||
const headingStyles = {
|
|
||||||
marginTop: 0,
|
|
||||||
marginBottom: 64,
|
|
||||||
maxWidth: 320,
|
|
||||||
}
|
|
||||||
|
|
||||||
const paragraphStyles = {
|
|
||||||
marginBottom: 48,
|
|
||||||
}
|
|
||||||
const codeStyles = {
|
|
||||||
color: "#8A6534",
|
|
||||||
padding: 4,
|
|
||||||
backgroundColor: "#FFF4DB",
|
|
||||||
fontSize: "1.25rem",
|
|
||||||
borderRadius: 4,
|
|
||||||
}
|
|
||||||
|
|
||||||
// markup
|
|
||||||
const NotFoundPage = () => {
|
|
||||||
return (
|
|
||||||
<main style={pageStyles}>
|
|
||||||
<title>Not found</title>
|
|
||||||
<h1 style={headingStyles}>Page not found</h1>
|
|
||||||
<p style={paragraphStyles}>
|
|
||||||
Sorry{" "}
|
|
||||||
<span role="img" aria-label="Pensive emoji">
|
|
||||||
😔
|
|
||||||
</span>{" "}
|
|
||||||
we couldn’t find what you were looking for.
|
|
||||||
<br />
|
|
||||||
{process.env.NODE_ENV === "development" ? (
|
|
||||||
<>
|
|
||||||
<br />
|
|
||||||
Try creating a page in <code style={codeStyles}>src/pages/</code>.
|
|
||||||
<br />
|
|
||||||
</>
|
|
||||||
) : null}
|
|
||||||
<br />
|
|
||||||
<Link to="/">Go home</Link>.
|
|
||||||
</p>
|
|
||||||
</main>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default NotFoundPage
|
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
import React, { useState, useEffect } from 'react'
|
||||||
|
|
||||||
|
const ModelCrudIndex = () => {
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ModelCrudIndex
|
||||||
|
|
@ -0,0 +1,190 @@
|
||||||
|
import React, { useState, useEffect } from 'react'
|
||||||
|
import { useSelector, useDispatch } from 'react-redux'
|
||||||
|
|
||||||
|
import { userAuthSelector } from '../../redux/slices/userAuthSlice'
|
||||||
|
import { userCrudSelector } from '../../redux/slices/userCrudSlice'
|
||||||
|
|
||||||
|
import userCrudAsyncThunk from '../../redux/asyncThunks/userCrudAsyncThunk'
|
||||||
|
|
||||||
|
|
||||||
|
const __setShowGeneral = ( view, key, movements ) => {
|
||||||
|
|
||||||
|
movements.user_view.setUserCrudView(
|
||||||
|
{
|
||||||
|
update_user: false,
|
||||||
|
delete_user: false
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
movements.model_view.setModelCrudView(
|
||||||
|
{
|
||||||
|
get_all_models: true,
|
||||||
|
get_one_model_and_download: false,
|
||||||
|
upload_model: false
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
movements.render_view.setRenderView(
|
||||||
|
{
|
||||||
|
show_ready_renders_and_download: false,
|
||||||
|
render_functionality: {
|
||||||
|
render_single_image: false,
|
||||||
|
render_single_set: false,
|
||||||
|
render_all: false,
|
||||||
|
render_image_by_vector: false,
|
||||||
|
render_set_by_vector: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
if (view === 'user_view') {
|
||||||
|
let new_move = movements.user_view.userCrudView
|
||||||
|
new_move[key] = true
|
||||||
|
movements.user_view.setUserCrudView(
|
||||||
|
new_move
|
||||||
|
)
|
||||||
|
} else if (view === 'model_view') {
|
||||||
|
let new_move = movements.user_view.modelCrudView
|
||||||
|
new_move[key] = true
|
||||||
|
movements.model_view.setModelCrudView(
|
||||||
|
new_move
|
||||||
|
)
|
||||||
|
} else if (view === 'render_view') {
|
||||||
|
let new_move = movements.render_view.renderView
|
||||||
|
if ( key in new_move ) {
|
||||||
|
new_move[key] = true
|
||||||
|
movements.model_view.setModelCrudView(
|
||||||
|
new_move
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
new_move['render_functionality'][key] = true
|
||||||
|
movements.model_view.setModelCrudView(
|
||||||
|
new_move
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const __styleChanger = ( bool ) => {
|
||||||
|
|
||||||
|
let display = {
|
||||||
|
display: 'block'
|
||||||
|
}
|
||||||
|
|
||||||
|
let hide = {
|
||||||
|
display: 'none'
|
||||||
|
}
|
||||||
|
|
||||||
|
return bool ? display : hide
|
||||||
|
}
|
||||||
|
|
||||||
|
const NavigationBar = ({ movements }) => {
|
||||||
|
|
||||||
|
const { user_get } = useSelector(userCrudSelector)
|
||||||
|
const { token, user } = useSelector(userAuthSelector)
|
||||||
|
|
||||||
|
const dispatch = useDispatch()
|
||||||
|
|
||||||
|
useEffect( () => {
|
||||||
|
if ( user_get !== {} && token !== '' && user.id > 0)
|
||||||
|
dispatch(
|
||||||
|
userCrudAsyncThunk.fetchGetOneUser(
|
||||||
|
{
|
||||||
|
user_id: user.id,
|
||||||
|
token: token
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
const [showAccount, setShowAccount] = useState(false)
|
||||||
|
const [showModels, setShowModels] = useState(false)
|
||||||
|
const [showRender, setShowRender] = useState(false)
|
||||||
|
const [showRenderFunc, setShowRenderFunc] = useState(false)
|
||||||
|
|
||||||
|
return(
|
||||||
|
<>
|
||||||
|
<div>
|
||||||
|
Menu
|
||||||
|
<div>
|
||||||
|
<div onClick={ () => setShowAccount( !showAccount ) }>
|
||||||
|
├── Account Settings
|
||||||
|
</div>
|
||||||
|
<div style={ __styleChanger( showAccount) }>
|
||||||
|
<div>
|
||||||
|
│ ├── User info
|
||||||
|
<div>
|
||||||
|
<div>
|
||||||
|
│ │ ├── Username: { user_get.username }
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
│ │ └── E-mail: { user_get.email }
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div onClick={ () => __setShowGeneral( 'user_view', 'update_user', movements ) }>
|
||||||
|
│ ├── Update User
|
||||||
|
</div>
|
||||||
|
<div onClick={ () => __setShowGeneral( 'user_view', 'delete_user', movements ) }>
|
||||||
|
│ └── Delete User
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div onClick={ () => setShowModels( !showModels ) }>
|
||||||
|
├── Models
|
||||||
|
</div>
|
||||||
|
<div style={ __styleChanger( showModels ) }>
|
||||||
|
<div onClick={ () => __setShowGeneral( 'model_view', 'get_all_models', movements ) }>
|
||||||
|
│ ├── Get All Models
|
||||||
|
</div>
|
||||||
|
<div onClick={ () => __setShowGeneral( 'model_view', 'get_one_model_and_download', movements )}>
|
||||||
|
│ ├── Get One Model & Download
|
||||||
|
</div>
|
||||||
|
<div onClick={ () => __setShowGeneral( 'model_view', 'upload_model', movements ) }>
|
||||||
|
│ └── Upload Model
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div onClick={ () => setShowRender( !showRender ) }>
|
||||||
|
├── Render
|
||||||
|
</div>
|
||||||
|
<div style={ __styleChanger( showRender ) }>
|
||||||
|
<div onClick={ () => __setShowGeneral( 'render_view', 'show_ready_renders_and_download', movements ) }>
|
||||||
|
│ ├── Show Ready Renders & Download
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div onClick={ () => setShowRenderFunc( !showRenderFunc ) }>
|
||||||
|
│ ├── Render Functionality
|
||||||
|
</div>
|
||||||
|
<div style={ __styleChanger( showRenderFunc ) }>
|
||||||
|
<div onClick={ () => __setShowGeneral( 'render_view', 'render_single_image', movements ) }>
|
||||||
|
│ │ ├── Render Single Image
|
||||||
|
</div>
|
||||||
|
<div onClick={ () => __setShowGeneral( 'render_view', 'render_single_set', movements ) }>
|
||||||
|
│ │ ├── Render Single Set
|
||||||
|
</div>
|
||||||
|
<div onClick={ () => __setShowGeneral( 'render_view', 'render_all', movements ) }>
|
||||||
|
│ │ ├── Render All Sets
|
||||||
|
</div>
|
||||||
|
<div onClick={ () => __setShowGeneral( 'render_view', 'render_image_by_vector', movements ) }>
|
||||||
|
│ │ ├── Render Image By Vector
|
||||||
|
</div>
|
||||||
|
<div onClick={ () => __setShowGeneral( 'render_view', 'render_set_by_vector', movements ) }>
|
||||||
|
│ │ └── Render Set By Vector
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
└── Logout
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default NavigationBar
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
import React, { useState, useEffect } from 'react'
|
||||||
|
|
||||||
|
const RenderCrudIndex = () => {
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default RenderCrudIndex
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
import React, { useState, useEffect } from 'react'
|
||||||
|
|
||||||
|
const RenderWebsocketIndex = () => {
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default RenderWebsocketIndex
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
import React, { useState, useEffect } from 'react'
|
||||||
|
|
||||||
|
import VerifyUserSession from './rootUtils'
|
||||||
|
|
||||||
|
import UserAuthIndex from './user_auth/userAuthIndex'
|
||||||
|
import UserCrudIndex from './user_crud/userCrudIndex'
|
||||||
|
import ModelCrudIndex from './model_crud/modelCrudIndex'
|
||||||
|
import RenderCrudIndex from './render_crud/renderCrudIndex'
|
||||||
|
import RenderWebsocketIndex from './render_websocket/renderWebsocketIndex'
|
||||||
|
|
||||||
|
|
||||||
|
const Root = () => {
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<VerifyUserSession />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Root
|
||||||
|
|
@ -0,0 +1,103 @@
|
||||||
|
import React, { useState } from 'react'
|
||||||
|
import { useSelector } from 'react-redux'
|
||||||
|
|
||||||
|
import { userAuthSelector } from '../../redux/slices/userAuthSlice'
|
||||||
|
|
||||||
|
import UserAuthIndex from './user_auth/userAuthIndex'
|
||||||
|
import UserCrudIndex from './user_crud/userCrudIndex'
|
||||||
|
import ModelCrudIndex from './model_crud/modelCrudIndex'
|
||||||
|
import RenderCrudIndex from './render_crud/renderCrudIndex'
|
||||||
|
import RenderWebsocketIndex from './render_websocket/renderWebsocketIndex'
|
||||||
|
|
||||||
|
import NavigationBar from './navigationBar'
|
||||||
|
|
||||||
|
|
||||||
|
const GeneralView = () => {
|
||||||
|
|
||||||
|
const [userCrudView, setUserCrudView] = useState(
|
||||||
|
{
|
||||||
|
update_user: false,
|
||||||
|
delete_user: false
|
||||||
|
}
|
||||||
|
)
|
||||||
|
const [modelCrudView, setModelCrudView] = useState(
|
||||||
|
{
|
||||||
|
get_all_models: false,
|
||||||
|
get_one_model_and_download: false,
|
||||||
|
upload_model: false
|
||||||
|
}
|
||||||
|
)
|
||||||
|
const [renderCrudView, setRenderCrudView] = useState(
|
||||||
|
{
|
||||||
|
show_ready_renders_and_download: false,
|
||||||
|
render_functionality: {
|
||||||
|
render_single_image: false,
|
||||||
|
render_single_set: false,
|
||||||
|
render_all: false,
|
||||||
|
render_image_by_vector: false,
|
||||||
|
render_set_by_vector: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
let movements = {
|
||||||
|
user_view: {
|
||||||
|
userCrudView: userCrudView,
|
||||||
|
setUserCrudView: setUserCrudView
|
||||||
|
},
|
||||||
|
model_view: {
|
||||||
|
modelCrudView: modelCrudView,
|
||||||
|
setModelCrudView: setModelCrudView
|
||||||
|
},
|
||||||
|
render_view: {
|
||||||
|
renderView: renderCrudView,
|
||||||
|
setRenderView: setRenderCrudView
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<NavigationBar
|
||||||
|
movements={ movements }
|
||||||
|
/>
|
||||||
|
<UserCrudIndex
|
||||||
|
movements={ movements }
|
||||||
|
/>
|
||||||
|
<ModelCrudIndex
|
||||||
|
movements={ movements }
|
||||||
|
/>
|
||||||
|
<RenderCrudIndex
|
||||||
|
movements={ movements }
|
||||||
|
/>
|
||||||
|
<RenderWebsocketIndex
|
||||||
|
movements={ movements }
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const __verifyUserSession = (token, user) => {
|
||||||
|
|
||||||
|
if ( user.id !== 0 && user.username !== '' && user.email !== '' && token !== '' )
|
||||||
|
return true
|
||||||
|
else
|
||||||
|
return true
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const VerifyUserSession = () => {
|
||||||
|
|
||||||
|
const { token, user } = useSelector(userAuthSelector)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{
|
||||||
|
__verifyUserSession(token, user)
|
||||||
|
? <GeneralView />
|
||||||
|
: <UserAuthIndex />
|
||||||
|
}
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default VerifyUserSession
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
import React, { useState, useEffect } from 'react'
|
||||||
|
|
||||||
|
const UserAuthIndex = () => {
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default UserAuthIndex
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
import React, { useState, useEffect } from 'react'
|
||||||
|
|
||||||
|
const UserCrudIndex = () => {
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default UserCrudIndex
|
||||||
|
|
@ -1,149 +1,19 @@
|
||||||
import * as React from "react"
|
import React from 'react';
|
||||||
|
// import ReactDOM from 'react-dom';
|
||||||
|
|
||||||
// styles
|
import { Provider } from 'react-redux';
|
||||||
const pageStyles = {
|
import { store } from '../redux/store';
|
||||||
color: "#232129",
|
|
||||||
padding: "96px",
|
|
||||||
fontFamily: "-apple-system, Roboto, sans-serif, serif",
|
|
||||||
}
|
|
||||||
const headingStyles = {
|
|
||||||
marginTop: 0,
|
|
||||||
marginBottom: 64,
|
|
||||||
maxWidth: 320,
|
|
||||||
}
|
|
||||||
const headingAccentStyles = {
|
|
||||||
color: "#663399",
|
|
||||||
}
|
|
||||||
const paragraphStyles = {
|
|
||||||
marginBottom: 48,
|
|
||||||
}
|
|
||||||
const codeStyles = {
|
|
||||||
color: "#8A6534",
|
|
||||||
padding: 4,
|
|
||||||
backgroundColor: "#FFF4DB",
|
|
||||||
fontSize: "1.25rem",
|
|
||||||
borderRadius: 4,
|
|
||||||
}
|
|
||||||
const listStyles = {
|
|
||||||
marginBottom: 96,
|
|
||||||
paddingLeft: 0,
|
|
||||||
}
|
|
||||||
const listItemStyles = {
|
|
||||||
fontWeight: "300",
|
|
||||||
fontSize: "24px",
|
|
||||||
maxWidth: "560px",
|
|
||||||
}
|
|
||||||
|
|
||||||
const linkStyle = {
|
import Root from './func_group/root';
|
||||||
color: "#8954A8",
|
|
||||||
fontWeight: "bold",
|
|
||||||
fontSize: "16px",
|
|
||||||
verticalAlign: "5%",
|
|
||||||
}
|
|
||||||
|
|
||||||
const docLinkStyle = {
|
// if you have problem with watchers - use it:
|
||||||
...linkStyle,
|
// echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p
|
||||||
listStyleType: "none",
|
|
||||||
marginBottom: 24,
|
|
||||||
}
|
|
||||||
|
|
||||||
const descriptionStyle = {
|
|
||||||
color: "#232129",
|
|
||||||
fontSize: "14px",
|
|
||||||
}
|
|
||||||
|
|
||||||
const docLink = {
|
|
||||||
text: "Documentation",
|
|
||||||
url: "https://www.gatsbyjs.com/docs/",
|
|
||||||
color: "#8954A8",
|
|
||||||
}
|
|
||||||
// data
|
|
||||||
const links = [
|
|
||||||
{
|
|
||||||
text: "Tutorial",
|
|
||||||
url: "https://www.gatsbyjs.com/docs/tutorial/",
|
|
||||||
description:
|
|
||||||
"A great place to get started if you're new to web development. Designed to guide you through setting up your first Gatsby site.",
|
|
||||||
color: "#E95800",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: "How to Guides",
|
|
||||||
url: "https://www.gatsbyjs.com/docs/how-to/",
|
|
||||||
description:
|
|
||||||
"Practical step-by-step guides to help you achieve a specific goal. Most useful when you're trying to get something done.",
|
|
||||||
color: "#1099A8",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: "Reference Guides",
|
|
||||||
url: "https://www.gatsbyjs.com/docs/reference/",
|
|
||||||
description:
|
|
||||||
"Nitty-gritty technical descriptions of how Gatsby works. Most useful when you need detailed information about Gatsby's APIs.",
|
|
||||||
color: "#BC027F",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: "Conceptual Guides",
|
|
||||||
url: "https://www.gatsbyjs.com/docs/conceptual/",
|
|
||||||
description:
|
|
||||||
"Big-picture explanations of higher-level Gatsby concepts. Most useful for building understanding of a particular topic.",
|
|
||||||
color: "#0D96F2",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: "Plugin Library",
|
|
||||||
url: "https://www.gatsbyjs.com/plugins",
|
|
||||||
description:
|
|
||||||
"Add functionality and customize your Gatsby site or app with thousands of plugins built by our amazing developer community.",
|
|
||||||
color: "#000000",
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
// markup
|
|
||||||
const IndexPage = () => {
|
const IndexPage = () => {
|
||||||
return (
|
return (
|
||||||
<main style={pageStyles}>
|
<Provider store={store}>
|
||||||
<title>Home Page</title>
|
<Root />
|
||||||
<h1 style={headingStyles}>
|
</Provider>
|
||||||
Congratulations
|
|
||||||
<br />
|
|
||||||
<span style={headingAccentStyles}>— you just made a Gatsby site! </span>
|
|
||||||
<span role="img" aria-label="Party popper emojis">
|
|
||||||
🎉🎉🎉
|
|
||||||
</span>
|
|
||||||
</h1>
|
|
||||||
<p style={paragraphStyles}>
|
|
||||||
Edit <code style={codeStyles}>src/pages/index.js</code> to see this page
|
|
||||||
update in real-time.{" "}
|
|
||||||
<span role="img" aria-label="Sunglasses smiley emoji">
|
|
||||||
😎
|
|
||||||
</span>
|
|
||||||
</p>
|
|
||||||
<ul style={listStyles}>
|
|
||||||
<li style={docLinkStyle}>
|
|
||||||
<a
|
|
||||||
style={linkStyle}
|
|
||||||
href={`${docLink.url}?utm_source=starter&utm_medium=start-page&utm_campaign=minimal-starter`}
|
|
||||||
>
|
|
||||||
{docLink.text}
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
{links.map(link => (
|
|
||||||
<li key={link.url} style={{ ...listItemStyles, color: link.color }}>
|
|
||||||
<span>
|
|
||||||
<a
|
|
||||||
style={linkStyle}
|
|
||||||
href={`${link.url}?utm_source=starter&utm_medium=start-page&utm_campaign=minimal-starter`}
|
|
||||||
>
|
|
||||||
{link.text}
|
|
||||||
</a>
|
|
||||||
<p style={descriptionStyle}>{link.description}</p>
|
|
||||||
</span>
|
|
||||||
</li>
|
|
||||||
))}
|
|
||||||
</ul>
|
|
||||||
<img
|
|
||||||
alt="Gatsby G Logo"
|
|
||||||
src="data:image/svg+xml,%3Csvg width='24' height='24' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M12 2a10 10 0 110 20 10 10 0 010-20zm0 2c-3.73 0-6.86 2.55-7.75 6L14 19.75c3.45-.89 6-4.02 6-7.75h-5.25v1.5h3.45a6.37 6.37 0 01-3.89 4.44L6.06 9.69C7 7.31 9.3 5.63 12 5.63c2.13 0 4 1.04 5.18 2.65l1.23-1.06A7.959 7.959 0 0012 4zm-8 8a8 8 0 008 8c.04 0 .09 0-8-8z' fill='%23639'/%3E%3C/svg%3E"
|
|
||||||
/>
|
|
||||||
</main>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
export const GeneralAddress = 'localhost:9090'
|
||||||
|
|
@ -0,0 +1,111 @@
|
||||||
|
import axios from 'axios'
|
||||||
|
import { GeneralAddress } from './abstractAddress'
|
||||||
|
|
||||||
|
const APIAddress = 'http://' + GeneralAddress
|
||||||
|
|
||||||
|
let defaultBody = {}
|
||||||
|
|
||||||
|
const _getList = async (endpoint, token) => {
|
||||||
|
return await responseAbstract(
|
||||||
|
endpoint,
|
||||||
|
'GET',
|
||||||
|
token,
|
||||||
|
defaultBody
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const _getOne = async (endpoint, objectId, token) => {
|
||||||
|
return await responseAbstract(
|
||||||
|
endpoint + objectId + '/',
|
||||||
|
'GET',
|
||||||
|
token,
|
||||||
|
defaultBody
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const _post = async (endpoint, body, token) => {
|
||||||
|
return await responseAbstract(
|
||||||
|
endpoint,
|
||||||
|
'POST',
|
||||||
|
token,
|
||||||
|
body
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const _patch = async (endpoint, objectId, body, token) => {
|
||||||
|
return await responseAbstract(
|
||||||
|
endpoint + objectId + '/',
|
||||||
|
'PATCH',
|
||||||
|
token,
|
||||||
|
body
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const _put = async (endpoint, objectId, body, token) => {
|
||||||
|
return await responseAbstract(
|
||||||
|
endpoint + objectId + '/',
|
||||||
|
'PUT',
|
||||||
|
token,
|
||||||
|
body
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const _delete = async (endpoint, objectId, token) => {
|
||||||
|
return await responseAbstract(
|
||||||
|
endpoint + objectId + '/',
|
||||||
|
'DELETE',
|
||||||
|
token,
|
||||||
|
defaultBody
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const responseAbstract = async (endpoint, method, token, body) => {
|
||||||
|
let response = await axios(
|
||||||
|
headerBuilder(
|
||||||
|
APIAddress + endpoint,
|
||||||
|
method,
|
||||||
|
token,
|
||||||
|
body,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return response
|
||||||
|
}
|
||||||
|
|
||||||
|
const headerBuilder = (url, method, token, body) => {
|
||||||
|
let headers_r = {
|
||||||
|
'Authorization': token,
|
||||||
|
'accept': 'application/json',
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
}
|
||||||
|
if ('file' in body) {
|
||||||
|
headers_r = {
|
||||||
|
'Authorization': token,
|
||||||
|
'accept': 'multipart/form-data',
|
||||||
|
'Content-Type': 'multipart/form-data',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let headers = {
|
||||||
|
url: url,
|
||||||
|
method: method,
|
||||||
|
headers: headers_r
|
||||||
|
}
|
||||||
|
if (method === 'PUT' || method === 'POST' || method === 'PATCH') {
|
||||||
|
headers = Object.assign({}, headers, {
|
||||||
|
data: JSON.stringify(body),
|
||||||
|
withCredentials: true,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return headers
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export default {
|
||||||
|
APIAddress,
|
||||||
|
_getList,
|
||||||
|
_getOne,
|
||||||
|
_post,
|
||||||
|
_put,
|
||||||
|
_patch,
|
||||||
|
_delete
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,63 @@
|
||||||
|
import { createAsyncThunk } from '@reduxjs/toolkit'
|
||||||
|
import abstractService from './abstracts/abstractService'
|
||||||
|
|
||||||
|
let endpoint = '/model/'
|
||||||
|
|
||||||
|
|
||||||
|
const fetchGetAllModels = createAsyncThunk(
|
||||||
|
'model/fetchGetAllModels',
|
||||||
|
async (
|
||||||
|
token,
|
||||||
|
thunkAPI
|
||||||
|
) => {
|
||||||
|
return await abstractService._getList(endpoint, token)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param body:
|
||||||
|
* param token: base64 token,
|
||||||
|
* param id: model id
|
||||||
|
*/
|
||||||
|
const fetchGetOneModelAndDownload = createAsyncThunk(
|
||||||
|
'model/fetchGetOneModelAndDownload',
|
||||||
|
async (
|
||||||
|
body,
|
||||||
|
thunkAPI
|
||||||
|
) => {
|
||||||
|
return await abstractService._getOne(
|
||||||
|
endpoint,
|
||||||
|
body.id,
|
||||||
|
body.token
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param body:
|
||||||
|
* param token: base64 token,
|
||||||
|
* param file: document.querySelector('#file').files[0]
|
||||||
|
* param user_id: user id
|
||||||
|
*/
|
||||||
|
const fetchUploadModel = createAsyncThunk(
|
||||||
|
'model/fetchUploadModel',
|
||||||
|
async (
|
||||||
|
body,
|
||||||
|
thunkAPI
|
||||||
|
) => {
|
||||||
|
let formData = FormData()
|
||||||
|
formData.append("blend", body.file)
|
||||||
|
body.file = formData
|
||||||
|
return await abstractService._post(
|
||||||
|
endpoint,
|
||||||
|
body,
|
||||||
|
body.token
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
export default {
|
||||||
|
fetchGetAllModels,
|
||||||
|
fetchGetOneModelAndDownload,
|
||||||
|
fetchUploadModel
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
import { createAsyncThunk } from '@reduxjs/toolkit'
|
||||||
|
import abstractService from './abstracts/abstractService'
|
||||||
|
|
||||||
|
let endpoint = '/render/'
|
||||||
|
|
||||||
|
|
||||||
|
const fetchGetAllRenders = createAsyncThunk(
|
||||||
|
'render/fetchGetAllRenders',
|
||||||
|
async (
|
||||||
|
token,
|
||||||
|
thunkAPI
|
||||||
|
) => {
|
||||||
|
return await abstractService._getList(endpoint, token)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param body:
|
||||||
|
* param token: base64 token,
|
||||||
|
* param id: render id
|
||||||
|
*/
|
||||||
|
const fetchGetOneRenderAndDownload = createAsyncThunk(
|
||||||
|
'render/fetchGetOneRenderAndDownload',
|
||||||
|
async (
|
||||||
|
body,
|
||||||
|
thunkAPI
|
||||||
|
) => {
|
||||||
|
return await abstractService._getOne(
|
||||||
|
endpoint,
|
||||||
|
body.id,
|
||||||
|
body.token
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
export default {
|
||||||
|
fetchGetAllRenders,
|
||||||
|
fetchGetOneRenderAndDownload
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,113 @@
|
||||||
|
import { createAsyncThunk } from '@reduxjs/toolkit'
|
||||||
|
import GeneralAddress from './abstracts/abstractAddress'
|
||||||
|
|
||||||
|
let endpoint_single_image = '/render/single/image/'
|
||||||
|
let endpoint_single_set = '/render/single/set/'
|
||||||
|
let endpoint_all = '/render/all/'
|
||||||
|
|
||||||
|
let endpoint_vector_single_image = '/render/vector/single/image/'
|
||||||
|
let endpoint_vector_single_set = '/render/vector/single/set/'
|
||||||
|
|
||||||
|
|
||||||
|
const __uuidv4 = () => {
|
||||||
|
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(
|
||||||
|
/[xy]/g,
|
||||||
|
(c) => {
|
||||||
|
var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
|
||||||
|
return v.toString(16);
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {string} endpoint:
|
||||||
|
* examples:
|
||||||
|
* 'image' - connect to single image ws renderer
|
||||||
|
* 'set' - connect to single set ws renderer
|
||||||
|
* 'all' - connect to all ws renderer
|
||||||
|
*
|
||||||
|
* 'vector/image' - connect to vector single image ws renderer
|
||||||
|
* 'vector/set' - connerct to vector single set ws renderer
|
||||||
|
*/
|
||||||
|
const __make_address = async (endpoint) => {
|
||||||
|
if (endpoint === 'image')
|
||||||
|
endpoint = endpoint_single_image
|
||||||
|
else if (endpoint === 'set')
|
||||||
|
endpoint = endpoint_single_set
|
||||||
|
else if (endpoint === 'all')
|
||||||
|
endpoint = endpoint_all
|
||||||
|
else if (endpoint === 'vector/image')
|
||||||
|
endpoint = endpoint_vector_single_image
|
||||||
|
else if (endpoint === 'vector/set')
|
||||||
|
endpoint = endpoint_vector_single_set
|
||||||
|
|
||||||
|
return GeneralAddress + endpoint
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param body:
|
||||||
|
* param token: token
|
||||||
|
* param endpoint:
|
||||||
|
* examples:
|
||||||
|
* 'image' - connect to single image ws renderer
|
||||||
|
* 'set' - connect to single set ws renderer
|
||||||
|
* 'all' - connect to all ws renderer
|
||||||
|
*
|
||||||
|
* 'vector/image' - connect to vector single image ws renderer
|
||||||
|
* 'vector/set' - connerct to vector single set ws renderer
|
||||||
|
*/
|
||||||
|
const fetchConnect = createAsyncThunk(
|
||||||
|
'render/async/fetchConnect',
|
||||||
|
async (
|
||||||
|
body,
|
||||||
|
thunkAPI
|
||||||
|
) => {
|
||||||
|
let uuid = __uuidv4()
|
||||||
|
let address = __make_address(body.endpoint)
|
||||||
|
return {
|
||||||
|
web_socket: new WebSocket(address + uuid),
|
||||||
|
address: address,
|
||||||
|
room_uuid: uuid
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param body:
|
||||||
|
* param token: token
|
||||||
|
* param message: message string
|
||||||
|
*/
|
||||||
|
const fetchSaveMessage = createAsyncThunk(
|
||||||
|
'render/async/fetchSaveMessage',
|
||||||
|
async (
|
||||||
|
body,
|
||||||
|
thunkAPI
|
||||||
|
) => {
|
||||||
|
return {
|
||||||
|
message: body.message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param body:
|
||||||
|
* param token: token
|
||||||
|
*/
|
||||||
|
const fetchDisconnect = createAsyncThunk(
|
||||||
|
'render/async/fetchDisconnect',
|
||||||
|
async (
|
||||||
|
token,
|
||||||
|
thunkAPI
|
||||||
|
) => {
|
||||||
|
return {
|
||||||
|
web_socket: null,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
export default {
|
||||||
|
fetchConnect,
|
||||||
|
fetchSaveMessage,
|
||||||
|
fetchDisconnect
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
import { createAsyncThunk } from '@reduxjs/toolkit'
|
||||||
|
import abstractService from './abstracts/abstractService'
|
||||||
|
|
||||||
|
let endpoint = '/user/auth'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param body:
|
||||||
|
* param username: username string
|
||||||
|
* param password: password string
|
||||||
|
*/
|
||||||
|
const fetchLogin = createAsyncThunk(
|
||||||
|
'user/auth/fetchLogin',
|
||||||
|
async (
|
||||||
|
body,
|
||||||
|
thunkAPI
|
||||||
|
) => {
|
||||||
|
return await abstractService._post(
|
||||||
|
endpoint,
|
||||||
|
body,
|
||||||
|
''
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param body:
|
||||||
|
* param token: user token
|
||||||
|
*/
|
||||||
|
const fetchLogout = createAsyncThunk(
|
||||||
|
'user/auth/fetchLogout',
|
||||||
|
async (
|
||||||
|
token,
|
||||||
|
thunkAPI
|
||||||
|
) => {
|
||||||
|
return await abstractService._delete(
|
||||||
|
endpoint,
|
||||||
|
'',
|
||||||
|
token
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
export default {
|
||||||
|
fetchLogin,
|
||||||
|
fetchLogout
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,108 @@
|
||||||
|
import { createAsyncThunk } from '@reduxjs/toolkit'
|
||||||
|
import abstractService from './abstracts/abstractService'
|
||||||
|
|
||||||
|
let endpoint = '/user/'
|
||||||
|
|
||||||
|
|
||||||
|
const fetchGetAllUsers = createAsyncThunk(
|
||||||
|
'user/fetchGetAllUsers',
|
||||||
|
async (
|
||||||
|
token,
|
||||||
|
thunkAPI
|
||||||
|
) => {
|
||||||
|
return await abstractService._getList(
|
||||||
|
endpoint,
|
||||||
|
token
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param body:
|
||||||
|
* param token: token
|
||||||
|
* param user_id: user_id
|
||||||
|
*/
|
||||||
|
const fetchGetOneUser = createAsyncThunk(
|
||||||
|
'user/fetchGetAllUsers',
|
||||||
|
async (
|
||||||
|
body,
|
||||||
|
thunkAPI
|
||||||
|
) => {
|
||||||
|
return await abstractService._getOne(
|
||||||
|
endpoint,
|
||||||
|
body.user_id,
|
||||||
|
body.token
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param body:
|
||||||
|
* param username: username string
|
||||||
|
* param password: password string
|
||||||
|
* param email: email string
|
||||||
|
*/
|
||||||
|
const fetchRegister = createAsyncThunk(
|
||||||
|
'user/fetchRegister',
|
||||||
|
async (
|
||||||
|
body,
|
||||||
|
thunkAPI
|
||||||
|
) => {
|
||||||
|
return await abstractService._post(
|
||||||
|
endpoint,
|
||||||
|
body,
|
||||||
|
''
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param body:
|
||||||
|
* param token: token
|
||||||
|
* param user_id: user_id
|
||||||
|
* param user:
|
||||||
|
* param username: username
|
||||||
|
* param password: password
|
||||||
|
* param email: email
|
||||||
|
*/
|
||||||
|
const fetchUpdateUser = createAsyncThunk(
|
||||||
|
'user/fetchRegister',
|
||||||
|
async (
|
||||||
|
body,
|
||||||
|
thunkAPI
|
||||||
|
) => {
|
||||||
|
return await abstractService._patch(
|
||||||
|
endpoint,
|
||||||
|
body.user_id,
|
||||||
|
body.user,
|
||||||
|
body.token
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param body:
|
||||||
|
* param user_id: user_id
|
||||||
|
* param token: user token
|
||||||
|
*/
|
||||||
|
const fetchDeleteUser = createAsyncThunk(
|
||||||
|
'user/fetchRegister',
|
||||||
|
async (
|
||||||
|
body,
|
||||||
|
thunkAPI
|
||||||
|
) => {
|
||||||
|
return await abstractService._delete(
|
||||||
|
endpoint,
|
||||||
|
body.user_id,
|
||||||
|
body.token
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
export default {
|
||||||
|
fetchGetAllUsers,
|
||||||
|
fetchGetOneUser,
|
||||||
|
fetchRegister,
|
||||||
|
fetchUpdateUser,
|
||||||
|
fetchDeleteUser
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
import { createSlice } from '@reduxjs/toolkit'
|
||||||
|
import modelCrudAsyncThunk from '../asyncThunks/modelCrudAsyncThunk'
|
||||||
|
|
||||||
|
const modelCrudSlice = createSlice(
|
||||||
|
{
|
||||||
|
name: 'model',
|
||||||
|
initialState: {
|
||||||
|
models_list: [],
|
||||||
|
download_blend_file: '',
|
||||||
|
upload_blend_file_status: ''
|
||||||
|
|
||||||
|
},
|
||||||
|
reducers: {},
|
||||||
|
extraReducers: {
|
||||||
|
[modelCrudAsyncThunk.fetchGetAllModels.fulfilled.type]: (state, action) => {
|
||||||
|
state.models_list = action.payload.data
|
||||||
|
},
|
||||||
|
[modelCrudAsyncThunk.fetchGetOneModelAndDownload.fulfilled.type]: (state, action) => {
|
||||||
|
state.download_blend_file = action.payload.data
|
||||||
|
},
|
||||||
|
[modelCrudAsyncThunk.fetchUploadModel.fulfilled.type]: (state, action) => {
|
||||||
|
state.upload_blend_file_status = action.payload.data
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
export const modelCrudReducer = modelCrudSlice.reducer
|
||||||
|
|
||||||
|
export const modelCrudSelector = state => state.modelCrudReducer
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
import { createSlice } from '@reduxjs/toolkit'
|
||||||
|
import renderCrudAsyncThunk from '../asyncThunks/renderCrudAsyncThunk'
|
||||||
|
|
||||||
|
const renderCrudSlice = createSlice(
|
||||||
|
{
|
||||||
|
name: 'render',
|
||||||
|
initialState: {
|
||||||
|
render_list: [],
|
||||||
|
download_zip_file: ''
|
||||||
|
},
|
||||||
|
reducers: {},
|
||||||
|
extraReducers: {
|
||||||
|
[renderCrudAsyncThunk.fetchGetAllRenders.fulfilled.type]: (state, action) => {
|
||||||
|
state.render_list = action.payload.data.render_list
|
||||||
|
},
|
||||||
|
[renderCrudAsyncThunk.fetchGetOneRenderAndDownload.fulfilled.type]: (state, action) => {
|
||||||
|
state.download_zip_file = action.payload.data
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
export const renderCrudReducer = renderCrudSlice.reducer
|
||||||
|
|
||||||
|
export const renderCrudSelector = state => state.renderCrudReducer
|
||||||
|
|
@ -0,0 +1,42 @@
|
||||||
|
import { createSlice } from '@reduxjs/toolkit'
|
||||||
|
import renderWebsocketAsyncThunk from '../asyncThunks/renderWebsocketAsyncThunk'
|
||||||
|
|
||||||
|
const renderWebsocketSlice = createSlice(
|
||||||
|
{
|
||||||
|
name: 'render/async',
|
||||||
|
initialState: {
|
||||||
|
web_socket: null,
|
||||||
|
address: '',
|
||||||
|
room_uuid: '',
|
||||||
|
messages: [],
|
||||||
|
connected: false
|
||||||
|
},
|
||||||
|
reducers: {},
|
||||||
|
extraReducers: {
|
||||||
|
[renderWebsocketAsyncThunk.fetchConnect.fulfilled.type]: (state, action) => {
|
||||||
|
state.web_socket = action.web_socket
|
||||||
|
state.address = action.address
|
||||||
|
state.room_uuid = action.room_uuid
|
||||||
|
state.messages = []
|
||||||
|
state.connected = true
|
||||||
|
},
|
||||||
|
[renderWebsocketAsyncThunk.fetchSaveMessage.fulfilled.type]: (state, action) => {
|
||||||
|
state.messages = [
|
||||||
|
...state.messages,
|
||||||
|
action.message
|
||||||
|
]
|
||||||
|
},
|
||||||
|
[renderWebsocketAsyncThunk.fetchDisconnect.fulfilled.type]: (state, action) => {
|
||||||
|
state.web_socket = action.web_socket
|
||||||
|
state.address = ''
|
||||||
|
state.room_uuid = ''
|
||||||
|
state.messages = []
|
||||||
|
state.connected = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
export const renderWebsocketReducer = renderWebsocketSlice.reducer
|
||||||
|
|
||||||
|
export const renderWebsocketSelector = state => state.renderWebsocketReducer
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
import { createSlice } from '@reduxjs/toolkit'
|
||||||
|
import userAuthAsyncThunk from '../asyncThunks/userAuthAsyncThunk'
|
||||||
|
|
||||||
|
const userAuthSlice = createSlice(
|
||||||
|
{
|
||||||
|
name: 'user/auth',
|
||||||
|
initialState: {
|
||||||
|
token: '',
|
||||||
|
user: {
|
||||||
|
id: 0,
|
||||||
|
username: '',
|
||||||
|
email: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
reducers: {},
|
||||||
|
extraReducers: {
|
||||||
|
[userAuthAsyncThunk.fetchLogin.fulfilled.type]: (state, action) => {
|
||||||
|
state.token = action.payload.data.Authorization
|
||||||
|
state.user.id = action.payload.data.user.id
|
||||||
|
state.user.username = action.payload.data.user.username
|
||||||
|
state.user.email = action.payload.data.user.email
|
||||||
|
state.info = 'login success'
|
||||||
|
},
|
||||||
|
[userAuthAsyncThunk.fetchLogout.fulfilled.type]: (state, action) => {
|
||||||
|
state.token = ''
|
||||||
|
state.user.id = 0
|
||||||
|
state.user.username = ''
|
||||||
|
state.user.email = ''
|
||||||
|
state.info = action.payload.data.info
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
export const userAuthReducer = userAuthSlice.reducer
|
||||||
|
|
||||||
|
export const userAuthSelector = state => state.userAuthReducer
|
||||||
|
|
@ -0,0 +1,41 @@
|
||||||
|
import { createSlice } from '@reduxjs/toolkit'
|
||||||
|
import userCrudAsyncThunk from '../asyncThunks/userCrudAsyncThunk'
|
||||||
|
|
||||||
|
const userCrudSlice = createSlice(
|
||||||
|
{
|
||||||
|
name: 'user',
|
||||||
|
initialState: {
|
||||||
|
users_list: [],
|
||||||
|
user_get: {},
|
||||||
|
user_register: {},
|
||||||
|
user_update: {},
|
||||||
|
user_delete: ''
|
||||||
|
},
|
||||||
|
reducers: {},
|
||||||
|
extraReducers: {
|
||||||
|
[userCrudAsyncThunk.fetchGetAllUsers.fulfilled.type]: (state, action) => {
|
||||||
|
state.users_list = action.payload.data
|
||||||
|
},
|
||||||
|
[userCrudAsyncThunk.fetchGetOneUser.fulfilled.type]: (state, action) => {
|
||||||
|
state.user_get = action.payload.data
|
||||||
|
},
|
||||||
|
[userCrudAsyncThunk.fetchRegister.fulfilled.type]: (state, action) => {
|
||||||
|
state.user_register = action.payload.data
|
||||||
|
},
|
||||||
|
[userCrudAsyncThunk.fetchUpdateUser.fulfilled.type]: (state, action) => {
|
||||||
|
state.user_update = action.payload.data
|
||||||
|
},
|
||||||
|
[userCrudAsyncThunk.fetchDeleteUser.fulfilled.type]: (state, action) => {
|
||||||
|
state.users_list = []
|
||||||
|
state.user_get = {}
|
||||||
|
state.user_register = {}
|
||||||
|
state.user_update = {}
|
||||||
|
state.user_delete = 'true'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
export const userCrudReducer = userCrudSlice.reducer
|
||||||
|
|
||||||
|
export const userCrudSelector = state => state.userCrudReducer
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
export const loadState = () => {
|
||||||
|
try {
|
||||||
|
const serializedState = localStorage.getItem('state')
|
||||||
|
|
||||||
|
if (serializedState === undefined || serializedState === null) {
|
||||||
|
return {}
|
||||||
|
} else {
|
||||||
|
return JSON.parse(serializedState)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err)
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const saveState = (state) => {
|
||||||
|
try {
|
||||||
|
|
||||||
|
const serializedState = JSON.stringify(state)
|
||||||
|
|
||||||
|
if (serializedState === null) {
|
||||||
|
return undefined
|
||||||
|
} else {
|
||||||
|
localStorage.setItem('state', serializedState)
|
||||||
|
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log('save in local storage error')
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
import { configureStore } from '@reduxjs/toolkit';
|
||||||
|
|
||||||
|
import { loadState, saveState } from './stateLoader'
|
||||||
|
import lodash from 'lodash'
|
||||||
|
|
||||||
|
import { modelCrudReducer } from './slices/modelCrudSlice'
|
||||||
|
import { renderCrudReducer } from './slices/renderCrudSlice'
|
||||||
|
import { renderWebsocketReducer } from './slices/renderWebsocketSlice'
|
||||||
|
import { userAuthReducer } from './slices/userAuthSlice'
|
||||||
|
import { userCrudReducer } from './slices/userCrudSlice'
|
||||||
|
|
||||||
|
|
||||||
|
let persistedState = loadState()
|
||||||
|
|
||||||
|
export const store = configureStore({
|
||||||
|
reducer: {
|
||||||
|
modelCrudReducer,
|
||||||
|
renderCrudReducer,
|
||||||
|
renderWebsocketReducer,
|
||||||
|
userAuthReducer,
|
||||||
|
userCrudReducer
|
||||||
|
},
|
||||||
|
preloadedState: persistedState
|
||||||
|
})
|
||||||
|
|
||||||
|
store.subscribe(() => {
|
||||||
|
saveState(store.getState());
|
||||||
|
});
|
||||||
|
|
||||||
|
store.subscribe(lodash.throttle(() => {
|
||||||
|
saveState(store.getState())
|
||||||
|
}, 100))
|
||||||
Loading…
Reference in New Issue