Skip to content

Commit c3d48a3

Browse files
committed
Add object page
1 parent 1f86dd0 commit c3d48a3

File tree

4 files changed

+264
-3
lines changed

4 files changed

+264
-3
lines changed

src/components/App.js

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
import React, { Component } from 'react';
22
import PropTypes from 'prop-types';
3-
import Container from './common/Container';
4-
import CatalogPage from './catalog/CatalogPage';
3+
54
import { Route, NavLink } from 'react-router-dom';
65
import { Layout, Menu, Breadcrumb, Icon, LocaleProvider } from 'antd';
6+
7+
const { Header, Content, Footer } = Layout;
8+
79
import enUS from 'antd/lib/locale-provider/en_US';
810

11+
import Container from './common/Container';
12+
import CatalogPage from './catalog/CatalogPage';
913
import CatalogListPage from "./catalog/CatalogListPage";
10-
const { Header, Content, Footer } = Layout;
14+
import ManageCatalogPage from "./catalog/ManageCatalogPage";
1115

1216
class App extends Component {
1317
render() {
@@ -28,8 +32,11 @@ class App extends Component {
2832
</Header>
2933
<Container>
3034
<Content style={{ minHeight: "calc(100vh - 130px)", padding: "20px" }}>
35+
3136
<Route exact path={"/"} component={CatalogListPage}/>
3237
<Route exact path={"/catalog/:name"} component={CatalogPage}/>
38+
<Route exact path={"/catalog/:name/object/:id"} component={ManageCatalogPage}/>
39+
3340
</Content>
3441
<Footer style={{ textAlign: 'center' }}>
3542
Sergey Sarkisyan ©2017 Built with React and Ant Design

src/components/catalog/CatalogForm.js

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import React from 'react';
2+
import { Form } from 'antd';
3+
import PropTypes from 'prop-types';
4+
import GenericInput from '../common/GenericInput';
5+
import CatalogFormActions from './CatalogFormActions';
6+
7+
const CatalogForm = ({ inputList, formObject, collections,
8+
onSave, onClose, onChange, saving, errors }) => {
9+
inputList = inputList || [];
10+
return (
11+
<Form>
12+
{inputList.map((input, index) => {
13+
return (
14+
<GenericInput key={index}
15+
type={input.type}
16+
category={input.category}
17+
collectionType={input.collection}
18+
collection={collections[input.type]}
19+
name={input.name}
20+
value={formObject[input.name]}
21+
label={input.displayName}
22+
onChange={onChange}/>
23+
);
24+
})}
25+
<CatalogFormActions
26+
permissions={formObject.objpermissions}
27+
onSave={onSave}
28+
onClose={onClose}
29+
/>
30+
</Form>
31+
);
32+
};
33+
34+
CatalogForm.propTypes = {
35+
inputList: PropTypes.array,
36+
formObject: PropTypes.object.isRequired,
37+
onSave: PropTypes.func.isRequired,
38+
onChange: PropTypes.func.isRequired,
39+
onClose: PropTypes.func.isRequired,
40+
saving: PropTypes.bool,
41+
errors: PropTypes.object,
42+
collections: PropTypes.object
43+
};
44+
45+
export default CatalogForm;
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import React from 'react';
2+
import PropTypes from 'prop-types';
3+
import { Button } from 'antd';
4+
5+
const CatalogFormActions = ({ permissions, onClose, onSave }) => {
6+
return (
7+
<div style={{textAlign: 'right'}}>
8+
<Button style={{background: '#000', color: '#fff', marginRight: '7px'}} onClick={onClose}>Закрыть</Button>
9+
<Button type="primary" onClick={onSave}>Сохранить</Button>
10+
</div>
11+
);
12+
};
13+
14+
CatalogFormActions.propTypes = {
15+
permissions: PropTypes.string,
16+
onSave: PropTypes.func.isRequired,
17+
onClose: PropTypes.func.isRequired
18+
};
19+
20+
export default CatalogFormActions;
Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
import React from 'react';
2+
import PropTypes from 'prop-types';
3+
import { NavLink } from 'react-router-dom';
4+
import CatalogForm from '../../../../react2/src/components/catalog/CatalogForm';
5+
import CatalogApi from '../../api/catalogApi';
6+
import { Breadcrumb, Spin, notification, Modal } from 'antd';
7+
8+
9+
export class ManageCatalogPage extends React.Component {
10+
constructor(props) {
11+
super(props);
12+
13+
this.state = {
14+
catalog: { name: '', objpermissions: '' },
15+
catalogPath: `/catalog/${this.props.match.params.name}`,
16+
collections: {},
17+
isTouched: false,
18+
form: { name: '' },
19+
errors: {},
20+
saving: false,
21+
loading: true
22+
};
23+
}
24+
25+
componentWillMount() {
26+
CatalogApi.getCatalogInfo(this.props.match.params.name)
27+
.then((response) => {
28+
this.setState({catalog: response.data});
29+
30+
const collectionPromises = [];
31+
let fields = response.data.fields;
32+
fields.forEach((field) => {
33+
if (field.category === 'form') {
34+
collectionPromises.push(this.loadCollection(field.type));
35+
}
36+
});
37+
38+
return CatalogApi.getFormObjectById(this.props.match.params.name, this.props.match.params.id);
39+
})
40+
41+
.then((response) => {
42+
this.setState({form: response.data, loading: false});
43+
});
44+
}
45+
46+
loadCollection = (catalogClass) => {
47+
return CatalogApi.getCatalogExtendWithClass(catalogClass)
48+
.then(response => {
49+
const collection = response.data.children;
50+
const collections = Object.assign({}, this.state.collections, {[catalogClass]: collection});
51+
this.setState({collections});
52+
});
53+
};
54+
55+
updateCatalogState = (field, value) => {
56+
console.log(field, value);
57+
let form = this.state.form;
58+
form[field] = value;
59+
return this.setState({ form, isTouched: true });
60+
};
61+
62+
catalogFormIsValid() {
63+
let formIsValid = true;
64+
let errors = {};
65+
66+
/*
67+
if (this.state.form.title.length < 5) {
68+
errors.title = 'Title must be at least 5 characters.';
69+
formIsValid = false;
70+
}*/
71+
72+
this.setState({ errors });
73+
return formIsValid;
74+
}
75+
76+
77+
saveForm = (event) => {
78+
event.preventDefault();
79+
80+
if (!this.catalogFormIsValid()) {
81+
return;
82+
}
83+
84+
this.setState({ saving: true });
85+
86+
CatalogApi.saveCatalog(this.props.match.params.name, this.props.match.params.id, this.state.form)
87+
.then(() => {
88+
notification.success({
89+
message: 'Saved successfully!'
90+
});
91+
this.setState({ saving: false });
92+
this.props.history.push(this.state.catalogPath);
93+
})
94+
.catch(error => {
95+
notification.error({
96+
message: 'An error has occurred: ' + error.summary
97+
});
98+
this.setState({ saving: false });
99+
});
100+
};
101+
102+
goPath = (path) => {
103+
if (this.state.isTouched) {
104+
Modal.confirm({
105+
title: 'Do you really want to close this object?',
106+
content: 'All changes will be lost',
107+
onOk: () => {
108+
this.props.history.push(path);
109+
},
110+
style: {top: '40vh'}
111+
});
112+
} else {
113+
this.props.history.push(path);
114+
}
115+
};
116+
117+
goPathOnClick = (path) => {
118+
return (event) => {
119+
event.preventDefault();
120+
this.goPath(path);
121+
};
122+
};
123+
124+
closeForm = () => {
125+
this.goPath(this.state.catalogPath);
126+
};
127+
128+
render() {
129+
const container = (
130+
<div>
131+
<Breadcrumb style={{margin: '12px 0'}}>
132+
<Breadcrumb.Item><a onClick={this.goPathOnClick('/')}>Catalogs</a></Breadcrumb.Item>
133+
<Breadcrumb.Item>
134+
<a onClick={this.goPathOnClick(`/catalog/${this.props.match.params.name}`)}>{this.state.catalog.name}</a>
135+
</Breadcrumb.Item>
136+
<Breadcrumb.Item>{this.state.form.name || 'Создание объекта'}</Breadcrumb.Item>
137+
</Breadcrumb>
138+
139+
<div style={{background: '#fff', padding: 24, minHeight: 280}}>
140+
{this.state.loading &&
141+
<div style={{textAlign: 'center', marginTop: '100px'}}>
142+
<Spin />
143+
</div>
144+
}
145+
146+
{!this.state.loading &&
147+
<div>
148+
{!this.props.match.params.id && <h1>Создание объекта справочника '{this.state.catalog.name}'</h1>}
149+
150+
{this.props.match.params.id &&
151+
(this.state.catalog.objpermissions.indexOf('U') !== -1) &&
152+
<h1>Edit object: {this.state.form.name}</h1>}
153+
154+
{!this.props.match.params.id &&
155+
(this.state.catalog.objpermissions.indexOf('U') === -1 &&
156+
this.state.catalog.objpermissions.indexOf('R') !== -1) &&
157+
<h1>View object: {this.state.form.name}</h1>}
158+
159+
<CatalogForm
160+
inputList={this.state.catalog.fields}
161+
onChange={this.updateCatalogState}
162+
onSave={this.saveForm}
163+
onClose={this.closeForm}
164+
formObject={this.state.form}
165+
collections={this.state.collections}
166+
errors={this.state.errors}
167+
saving={this.state.saving}
168+
/>
169+
</div>
170+
}
171+
</div>
172+
</div>
173+
);
174+
175+
return (
176+
<Spin spinning={this.state.saving} style={{maxHeight: 'initial'}}>{container}</Spin>
177+
);
178+
}
179+
}
180+
181+
182+
ManageCatalogPage.propTypes = {
183+
history: PropTypes.object,
184+
match: PropTypes.object,
185+
location: PropTypes.object
186+
};
187+
188+
189+
export default ManageCatalogPage;

0 commit comments

Comments
 (0)