MobX RESTful table

MobX RESTful table

A Pagination Table & Scroll List component suite for CRUD operation, which is based on MobX RESTful & React.

MobX compatibility NPM Dependency CI & CD

NPM

SemVer status ES decorator MobX
>=2 ✅developing stage-3 >=6.11
<2 ❌deprecated stage-2 >=4 <6.11
  1. Image Preview
  2. File Preview
  3. File Picker
  4. File Uploader
  5. Form Field
  6. Range Input
  7. Badge Input
  8. REST Form
  9. Pager
  10. REST Table
  11. Scroll Boundary
  12. Scroll List
npm i react \
mobx \
mobx-react \
mobx-i18n \
mobx-restful \
mobx-restful-table

Some Node.js tips about the upstream mobx-restful you should know: https://github.com/idea2app/MobX-RESTful?tab=readme-ov-file#usage

{
"compilerOptions": {
"target": "ES6",
"module": "ES6",
"moduleResolution": "Node",
"useDefineForClassFields": true,
"jsx": "react-jsx",
"skipLibCheck": true,
"lib": ["ES2023", "DOM"]
}
}
  1. set up Text in UI
  2. import Text files
  1. set up HTTP client
  2. implement Model class

Inspired by Ant Design - Pro Table

import { computed } from 'mobx';
import { observer } from 'mobx-react';
import { PureComponent } from 'react';
import { Container, Button, Badge } from 'react-bootstrap';
import { Column, RestTable } from 'mobx-restful-table';

import repositoryStore, { Repository } from '../models/Repository';
import { i18n } from '../models/Translation';

@observer
export default class PaginationPage extends PureComponent {
@computed
get columns(): Column<Repository>[] {
const { t } = i18n;

return [
{
key: 'full_name',
renderHead: t('repository_name'),
renderBody: ({ html_url, full_name }) => (
<a target="_blank" href={html_url}>
{full_name}
</a>
),
},
{ key: 'homepage', type: 'url', renderHead: t('home_page') },
{ key: 'language', renderHead: t('programming_language') },
{
key: 'topics',
renderHead: t('topic'),
renderBody: ({ topics }) => (
<>
{topics?.map(topic => (
<Badge
key={topic}
className="me-2"
as="a"
target="_blank"
href={`https://github.com/topics/${topic}`}
>
{topic}
</Badge>
))}
</>
),
},
{ key: 'stargazers_count', type: 'number', renderHead: t('star_count') },
];
}

render() {
return (
<Container style={{ height: '91vh' }}>
<RestTable
className="text-center"
striped
hover
editable
deletable
columns={this.columns}
store={repositoryStore}
translator={i18n}
onCheck={console.log}
/>
</Container>
);
}
}

Preview Link

Source Code

import { observer } from 'mobx-react';
import { FC } from 'react';
import { Container, Row, Col } from 'react-bootstrap';
import { Loading } from 'idea-react';
import { ScrollList } from 'mobx-restful-table';

import { GitCard } from '../components/Git';
import repositoryStore from '../models/Repository';
import { i18n } from '../models/Translation';

const ScrollListPage: FC = observer(() => (
<Container>
<h1 className="my-4">{i18n.t('scroll_list')}</h1>

{repositoryStore.downloading > 0 && <Loading />}

<ScrollList
translator={i18n}
store={repositoryStore}
renderList={allItems => (
<Row as="ul" className="list-unstyled g-4" xs={1} sm={2}>
{allItems.map(item => (
<Col as="li" key={item.id}>
<GitCard className="h-100 shadow-sm" {...item} />
</Col>
))}
</Row>
)}
/>
</Container>
));

export default ScrollListPage;
import { toggle } from 'mobx-restful';
import { FileModel } from 'mobx-restful-table';

import { uploadFile } from '../utility';

export class AssetFileModel extends FileModel {
@toggle('uploading')
async upload(file: File) {
const URI = await uploadFile(file);

return super.upload(URI);
}
}

export default new AssetFileModel();
import { FileUploader } from 'mobx-restful-table';

import fileStore from '../model/File';

export const EditorPage = () => (
<FileUploader
store={fileStore}
accept="image/*"
name="images"
multiple
required
onChange={console.log}
/>
);
""