restmin
v0.0.7
Published
Admin page restful platform
Downloads
1
Readme
RESTMIN
Library for build manager application client
VERSION 0.0.7
Video Demo
https://www.youtube.com/watch?v=13b8enfdhk0
Feature
- Create manager web app
- Search
- Create
- Update
- Delete
Platform
- Restful
- React
Get started
App
We will build book manager app.
Models
We will create restful server with models:
Category = {
id : <integer>,
name: <string>,
description: <string>
}
Book = {
id: <integer>,
category: <Category>,
name: <string>,
description: <string>,
content: <string>
}
BookItem = {
id: <integer>,
book: <Book>,
order: <Order>,
quantity: <integer>
}
Order = {
id: <integer>,
book_items: [<BookItem>]
}
Create manager config
category.js
import React from 'react'
import {render} from 'react-dom';
import {getDefaultCRUD} from 'restmin'
import {progressRequest, Request} from 'restmin'
import {
CharField,
TextField,
NumberField,
SelectField,
FileField,
ImageField,
MultiFileField,
MultiImageField,
ReferenceField as BaseReferenceField,
ObjectField as BaseObjectField
} from 'restmin'
// ------------------------------
const URL = 'http://localhost:8080/api/categories/'
const getObjectURL = (id) => `${URL}${id}/`
const SEARCH_URL = `${URL}search`
const SUGGEST_URL = `${URL}search`
// -----------------------------------
const request = progressRequest.args({mode: 'cors', credentials: 'include'})
const suggestRequest = (key) => {
return new Request().url(SUGGEST_URL).query({name: key}).successJson().resolve(json => json.results)
}
const searchRequest = (keys, page, pageSize) => {
return request.url(SEARCH_URL).method('GET').updateQuery({page: page, page_size: pageSize}).updateQuery(keys).successJson().resolve((json) => {
return {items: json.results, currentPage: json.currentPage, maxPage: json.pageCount}
})
}
const getRequest = (id) => {
return request.url(getObjectURL(id)).method('GET').successJson()
}
const createRequest = (formData) => {
return request.url(URL).method('POST').body(formData).successJson().failJson()
}
const updateRequest = (id, formData) => {
return request.url(getObjectURL(id)).method('PUT').body(formData).successJson().failJson()
}
const deleteRequest = (id) => {
return request.url(getObjectURL(id)).method('DELETE')
}
// -------------------------------------
const renderFieldItem = (item) => {
return <div>{item.id}: {item.name}</div>
}
const renderReadItem = (item) => {
if (!item)
return null;
return (
<div>
<div>{item.id}</div>
<div>{item.name}</div>
<div>{item.description}</div>
</div>
)
}
const renderDeleteItem = (item) => {
if (!item)
return null;
return (
<div>
<div>{item.id}</div>
<div>{item.name}</div>
<div>{item.description}</div>
</div>
)
}
// -------------------------------------
const fields = {
name: <CharField/>,
description: <TextField/>
}
const cols = [
{
label: "select",
type: 'select',
width: '5%'
}, {
label: "Id",
type: 'value',
search: {
name: 'id',
type: 'number'
},
value: (item) => item.id,
width: '5%'
}, {
label: "Ten",
type: 'value',
search: {
name: 'name',
type: 'text'
},
value: (item) => item.name,
width: '30%'
}, {
label: "Mo ta",
type: 'value',
search: {
name: 'description',
type: 'text'
},
value: (item) => item.description,
width: '40%'
}, {
label: "Option",
type: "option",
read: true,
update: true,
delete: true,
width: '20%'
}
]
// -------------------------------
const {
Manager,
Search,
Create,
Read,
Update,
Delete,
ReferenceField
} = getDefaultCRUD({
fields,
cols,
suggestRequest,
searchRequest,
getRequest,
createRequest,
updateRequest,
deleteRequest,
renderFieldItem,
renderReadItem,
renderDeleteItem
})
export {
Manager,
Search,
Create,
Read,
Update,
Delete,
ReferenceField
}
book.js
import React from 'react'
import {render} from 'react-dom';
import {getDefaultCRUD} from 'restmin'
import {progressRequest, Request} from 'restmin'
import {
CharField,
TextField,
NumberField,
SelectField,
FileField,
ImageField,
MultiFileField,
MultiImageField,
ReferenceField as BaseReferenceField,
ObjectField as BaseObjectField
} from 'restmin'
import {ReferenceField as CategoryField} from './category'
// ------------------------------
const URL = 'http://localhost:8080/api/books/'
const getObjectURL = (id) => `${URL}${id}/`
const SEARCH_URL = `${URL}search`
const SUGGEST_URL = `${URL}search`
// -----------------------------------
const request = progressRequest.args({mode: 'cors', credentials: 'include'})
const suggestRequest = (key) => {
return new Request().url(SUGGEST_URL).query({name: key}).successJson().resolve(json => json.results)
}
const searchRequest = (keys, page, pageSize) => {
return request.url(SEARCH_URL).method('GET').updateQuery({page: page, page_size: pageSize}).updateQuery(keys).successJson().resolve((json) => {
return {items: json.results, currentPage: json.currentPage, maxPage: json.pageCount}
})
}
const getRequest = (id) => {
return request.url(getObjectURL(id)).method('GET').successJson()
}
const createRequest = (formData) => {
return request.url(URL).method('POST').body(formData).successJson().failJson()
}
const updateRequest = (id, formData) => {
return request.url(getObjectURL(id)).method('PUT').body(formData).successJson().failJson()
}
const deleteRequest = (id) => {
return request.url(getObjectURL(id)).method('DELETE')
}
// -------------------------------------
const renderFieldItem = (item) => {
return <div>{item.id}: {item.name}</div>
}
const renderReadItem = (item) => {
if (!item)
return null;
return (
<div>
<div>{item.id}</div>
<div>{item.category
? item.category.name
: "no category"}</div>
<div>{item.name}</div>
<div>{item.description}</div>
<div>{item.content}</div>
</div>
)
}
const renderDeleteItem = (item) => {
if (!item)
return null;
return (
<div>
<div>{item.id}</div>
<div>{item.name}</div>
</div>
)
}
// -------------------------------------
const fields = {
category: <CategoryField outputName='category_id' outputType='id'/>,
name: <CharField/>,
description: <TextField/>,
content: <TextField/>
}
const cols = [
{
label: "select",
type: 'select',
width: '5%'
}, {
label: "Id",
type: 'value',
search: {
name: 'id',
type: 'number'
},
value: (item) => item.id,
width: '5%'
}, {
label: "Ten",
type: 'value',
search: {
name: 'name',
type: 'text'
},
value: (item) => item.name,
width: '20%'
}, {
label: "Category",
type: 'value',
search: {
name: 'category',
type: 'text'
},
value: (item) => item.category
? item.category.name
: null,
width: '20%'
}, {
label: "Mo ta",
type: 'value',
search: {
name: 'description',
type: 'text'
},
value: (item) => item.description,
width: '35%'
}, {
label: "Option",
type: "option",
read: true,
update: true,
delete: true,
width: '15%'
}
]
const {
Manager,
Search,
Create,
Read,
Update,
Delete,
ReferenceField
} = getDefaultCRUD({
fields,
cols,
suggestRequest,
searchRequest,
getRequest,
createRequest,
updateRequest,
deleteRequest,
renderFieldItem,
renderReadItem,
renderDeleteItem
})
export {
Manager,
Search,
Create,
Read,
Update,
Delete,
ReferenceField
}
order.js
import React from 'react'
import {render} from 'react-dom';
import {getDefaultCRUD} from 'restmin'
import {progressRequest, Request} from 'restmin'
import {
CharField,
TextField,
NumberField,
SelectField,
FileField,
ImageField,
MultiFileField,
MultiImageField,
ReferenceField as BaseReferenceField,
ObjectField as BaseObjectField
} from 'restmin'
import {ReferenceField as BookField} from './book'
// ------------------------------
const URL = 'http://localhost:8080/api/orders/'
const getObjectURL = (id) => `${URL}${id}/`
const SEARCH_URL = `${URL}search`
const SUGGEST_URL = `${URL}search`
// -----------------------------------
const request = progressRequest.args({mode: 'cors', credentials: 'include'})
const suggestRequest = (key) => {
return new Request().url(SUGGEST_URL).query({name: key}).successJson().resolve(json => json.results)
}
const searchRequest = (keys, page, pageSize) => {
return request.url(SEARCH_URL).method('GET').updateQuery({page: page, page_size: pageSize}).updateQuery(keys).successJson().resolve((json) => {
return {items: json.results, currentPage: json.currentPage, maxPage: json.pageCount}
})
}
const getRequest = (id) => {
return request.url(getObjectURL(id)).method('GET').successJson()
}
const createRequest = (formData) => {
return request.url(URL).method('POST').body(formData).successJson().failJson()
}
const updateRequest = (id, formData) => {
return request.url(getObjectURL(id)).method('PUT').body(formData).successJson().failJson()
}
const deleteRequest = (id) => {
return request.url(getObjectURL(id)).method('DELETE')
}
// -------------------------------------
const renderFieldItem = (item) => {
return <div>{item.id}</div>
}
const renderReadItem = (item) => {
if (!item)
return null;
return (
<div>
<div>{item.id}</div>
<div>{item.quantity}</div>
<div>{item.book_items.map((item) => <div key={item.id}>{item.book.name}: {item.quantity}</div>)}</div>
</div>
)
}
const renderDeleteItem = (item) => {
if (!item)
return null;
return (
<div>
<div>{item.id}</div>
<div>{item.quantity}</div>
<div>{item.book_items.map((item) => <div>{item.book.name}: {item.quantity}</div>)}</div>
</div>
)
}
// -------------------------------------
const fields = {
book_items: <BaseObjectField multiple outputName='book_items_json' outputType='text' fields={{
book: <BookField/>,
quantity: <NumberField/>
}} outputMap={{
id: i => i.id,
book_id: i => i.book.id,
quantity: i => i.quantity
}} renderItem={(item) => <div>{item.book
? item.book.name
: null}: {item.quantity}</div>}/>
}
const cols = [
{
label: "select",
type: 'select',
width: '5%'
}, {
label: "Id",
type: 'value',
search: {
name: 'id',
type: 'number'
},
value: (item) => item.id,
width: '25%'
}, {
label: "Bookds",
type: 'value',
value: (item) => item.book_items.length,
width: '50%'
}, {
label: "Option",
type: "option",
read: true,
update: true,
delete: true,
width: '20%'
}
]
// -------------------------------
const {
Manager,
Search,
Create,
Read,
Update,
Delete,
ReferenceField
} = getDefaultCRUD({
fields,
cols,
suggestRequest,
searchRequest,
getRequest,
createRequest,
updateRequest,
deleteRequest,
renderFieldItem,
renderReadItem,
renderDeleteItem
})
export {
Manager,
Search,
Create,
Read,
Update,
Delete,
ReferenceField
}
index.js
import React from 'react'
import {render} from 'react-dom';
import {requestProgressBar} from 'restmin'
import {Manager, CombineApp, Request} from 'restmin'
import {Manager as BookManager} from './book'
import {Manager as CategoryManager} from './category'
import {Manager as OrderManager} from './order'
class TestBookManager extends React.Component {
constructor(props) {
super(props);
this.state = {
selectedItemsMap: {
3: true,
4: true
}
}
}
render() {
return <div>
<BookManager pageSize={15} selectedItemsMap={this.state.selectedItemsMap} onSelectItem={item => {
console.log("manager select item ");
console.log(item);
this.state.selectedItemsMap[item.id] = true;
this.forceUpdate()
}} onDeselectItem={item => {
console.log("manager deselect item ");
console.log(item);
if (this.state.selectedItemsMap[item.id])
delete this.state.selectedItemsMap[item.id];
this.forceUpdate()
}}/>
</div>
}
}
const apps = [
{
name: 'book',
title: 'Books',
element: <TestBookManager/>
}, {
name: 'category',
title: 'Categories',
element: <CategoryManager/>
}, {
name: 'order',
title: 'Orders',
element: <OrderManager/>
}
]
render(
<div>
{requestProgressBar}
<CombineApp apps ={apps}/>
</div>, document.getElementById('test'));