UNPKG

sugar-generate

Version:

Auto generate OAS 3.0 REST + GraphQL APIs (Node + MongoDB)

208 lines (181 loc) 7.01 kB
const fs = require('fs'); const mkdirp = require('mkdirp'); const { uppercase } = require('../../api/utils'); const getReactState = require('./getReactState'); const getTableColumns = require('./getTableColumns'); const textFieldsByType = require('./textFieldsByType'); const beautify = require('js-beautify').html; module.exports = async ({ destination, schema }) => { const dir = `${destination}/components/${uppercase(schema.name)}`; mkdirp.sync(dir); const fileName = `${dir}/${uppercase(schema.name)}Table.js`; const code = ` import React, { Component } from 'react'; import PropTypes from 'prop-types'; import MaterialTable from "material-table"; import { withStyles } from '@material-ui/core/styles'; import AddBox from '@material-ui/icons/AddBox'; import ArrowUpward from '@material-ui/icons/ArrowUpward'; import Check from '@material-ui/icons/Check'; import ChevronLeft from '@material-ui/icons/ChevronLeft'; import ChevronRight from '@material-ui/icons/ChevronRight'; import Clear from '@material-ui/icons/Clear'; import DeleteOutline from '@material-ui/icons/DeleteOutline'; import Edit from '@material-ui/icons/Edit'; import FilterList from '@material-ui/icons/FilterList'; import FirstPage from '@material-ui/icons/FirstPage'; import LastPage from '@material-ui/icons/LastPage'; import Remove from '@material-ui/icons/Remove'; import SaveAlt from '@material-ui/icons/SaveAlt'; import Search from '@material-ui/icons/Search'; import ViewColumn from '@material-ui/icons/ViewColumn'; import Refresh from '@material-ui/icons/RefreshOutlined'; import apiCall from '../../src/apiCall'; import Snackbar from '../Shared/Snackbar'; const styles = theme => ({ }); const tableIcons = { Add: AddBox, Check: Check, Clear: Clear, Delete: DeleteOutline, DetailPanel: ChevronRight, Edit: Edit, Export: SaveAlt, Filter: FilterList, FirstPage: FirstPage, LastPage: LastPage, NextPage: ChevronRight, PreviousPage: ChevronLeft, ResetSearch: Clear, Search: Search, SortArrow: ArrowUpward, ThirdStateCheck: Remove, ViewColumn: ViewColumn, Refresh: Refresh, }; class ${uppercase(schema.name)}Table extends Component { constructor(props) { super(props); this.state = ${getReactState(schema, true)} this.state.snackbar = { variant: 'success', message: '', } this.state.docs = []; this.state.limit = 10; this.state.totalDocs = 0; this.state.offset = 0; // this.schema = ${JSON.stringify(schema.schema)} this.tableRef = React.createRef(); } componentWillMount () { this.fetchData(); } fetchData = async (query) => { if (!query) query = {}; query.limit = query.pageSize || 10; const res = await apiCall({ url: '${schema.name}s', method: 'GET', params: query }); // prevent arrays from blowing the page res.${schema.name}s.docs = res.${schema.name}s.docs.map((doc) => { const _doc = Object.assign({}, doc); Object.keys(_doc).forEach((key) => { if (Array.isArray(_doc[key])) _doc[key] = JSON.stringify(_doc[key]); }); return _doc; }) return { data: res.${schema.name}s.docs, page: res.${schema.name}s.offset / res.${schema.name}s.limit, totalCount: res.${schema.name}s.totalDocs, } } onSnackbarClose = (e) => { this.setState({ snackbar: { message: '', variant: 'info' }}) } onRowAdd = async (newData) => { const res = await apiCall({ url: "${schema.name}", method: 'POST', data: newData }); if (!res.error) this.setState({ snackbar: { variant: 'success', message: '${uppercase(schema.name)} Created.' }}); else this.setState({ snackbar: { variant: 'error', message: res.error }}); } onRowUpdate = async (newData, oldData) => { const res = await apiCall({ url: \`${schema.name}/\${oldData._id}\`, method: 'PUT', data: newData }); if (!res.error) this.setState({ snackbar: { variant: 'success', message: '${uppercase(schema.name)} Updated.' }}); else this.setState({ snackbar: { variant: 'error', message: res.error }}); } onRowDelete = async (oldData) => { const res = await apiCall({ url: \`${schema.name}/\${oldData._id}\`, method: 'DELETE', }) if (!res.error) this.setState({ snackbar: { variant: 'success', message: '${uppercase(schema.name)} Deleted.' }}); else this.setState({ snackbar: { variant: 'error', message: res.error }}); } render () { /* Cant edit / delete when selection: true https://github.com/mbrn/material-table/issues/648 */ const { classes } = this.props; const { snackbar, ${getReactState(schema, true, true)} } = this.state; return ( <div className={classes.container}> <div className={classes.table}> <div style={{ maxWidth: "100%" }}> <MaterialTable columns={${getTableColumns(schema)}} data={this.fetchData} icons={tableIcons} title="${uppercase(schema.name)}s" options={{ filtering: true, selection: false, exportButton: true }} tableRef={this.tableRef} localization={{ body: { editRow: { deleteText: 'Delete this row?' } } }} editable={{ onRowAdd: this.onRowAdd, onRowUpdate: this.onRowUpdate, onRowDelete: this.onRowDelete, isEditable: (rowData) => { // console.log('ROWDATA', rowData) // const areUnique = []; // const columns = ${getTableColumns(schema)}; // console.log('COLUMNS', columns) // columns.forEach((column) => column.readonly ? areUnique.push(column.field) : ""); // console.log('AREUNIQUE', areUnique) return true; }, isDeletable: () => true, }} actions={[ { icon: Refresh, tooltip: 'Refresh Data', isFreeAction: true, onClick: () => this.tableRef.current && this.tableRef.current.onQueryChange(), } ]} /> </div> </div> <Snackbar variant={snackbar.variant} message={snackbar.message} handleClose={this.onSnackbarClose} /> </div> ); } } ${uppercase(schema.name)}Table.propTypes = { classes: PropTypes.object.isRequired, }; export default withStyles(styles, { withTheme: true })(${uppercase(schema.name)}Table); `; fs.writeFileSync(fileName, code); };