open5gs/webui/src/containers/Profile/Document.js

249 lines
6.3 KiB
JavaScript

import { Component } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import NProgress from 'nprogress';
import { MODEL, fetchProfiles, fetchProfile, createProfile, updateProfile } from 'modules/crud/profile';
import { clearActionStatus } from 'modules/crud/actions';
import { select, selectActionStatus } from 'modules/crud/selectors';
import * as Notification from 'modules/notification/actions';
import { Profile } from 'components';
import traverse from 'traverse';
const formData = {
"security": {
k: "465B5CE8 B199B49F AA5F0A2E E238A6BC",
amf: "8000",
op_value: "E8ED289D EBA952E4 283B54E8 8E6183CA",
},
"ambr": {
"downlink": 1024000,
"uplink": 1024000
},
"pdn": [
{
"apn": "internet",
"qos": {
"qci": 9,
"arp": {
"priority_level": 8,
"pre_emption_capability": 1,
"pre_emption_vulnerability": 1
}
},
}
]
}
class Document extends Component {
static propTypes = {
action: PropTypes.string,
visible: PropTypes.bool,
onHide: PropTypes.func
}
state = {
formData
}
componentWillMount() {
const { profile, dispatch } = this.props
if (profile.needsFetch) {
dispatch(profile.fetch)
}
}
componentWillReceiveProps(nextProps) {
const { profile, status } = nextProps
const { dispatch, action, onHide } = this.props
if (profile.needsFetch) {
dispatch(profile.fetch)
}
if (profile.data) {
// Mongoose library has a problem for 64bit-long type
//
// FETCH : the library returns 'Number' type for 64bit-long type
// CREATE/UPDATE : the library returns 'String' type for 64bit-long type
//
// In this case, I cannot avoid json-schema validation function
// So, I've changed the type from 'String' to 'Number' if the key name is 'downlink' and 'uplink'
//
// The followings are changed from 'String' to 'Number' after DB CREATE or UPDATE
// - ambr.downlink, ambr.uplink, qos.mbr.downlink, qos.mbr.uplink, qos.gbr.downlink, qos.gbr.uplink
//
traverse(profile.data).forEach(function(x) {
if (this.key == 'downlink') this.update(Number(x));
if (this.key == 'uplink') this.update(Number(x));
})
if (profile.data.security) {
if (profile.data.security.opc) {
profile.data.security.op_type = 0;
profile.data.security.op_value = profile.data.security.opc;
} else {
profile.data.security.op_type = 1;
profile.data.security.op_value = profile.data.security.op;
}
}
this.setState({ formData: profile.data })
} else {
this.setState({ formData });
}
if (status.response) {
NProgress.configure({
parent: 'body',
trickleSpeed: 5
});
NProgress.done(true);
// const message = action === 'create' ? "New profile created" : `${status.id} profile updated`;
const message = action === 'create' ? "New profile created" : `This profile updated`;
dispatch(Notification.success({
title: 'Profile',
message
}));
dispatch(clearActionStatus(MODEL, action));
onHide();
}
if (status.error) {
NProgress.configure({
parent: 'body',
trickleSpeed: 5
});
NProgress.done(true);
const response = ((status || {}).error || {}).response || {};
let title = 'Unknown Code';
let message = 'Unknown Error';
if (response.data && response.data.name && response.data.message) {
title = response.data.name;
message = response.data.message;
} else {
title = response.status;
message = response.statusText;
}
dispatch(Notification.error({
title,
message,
autoDismiss: 0,
action: {
label: 'Dismiss',
callback: () => onHide()
}
}));
dispatch(clearActionStatus(MODEL, action));
}
}
validate = (formData, errors) => {
const { profiles, action, status } = this.props;
if (formData.pdn) {
let apns = formData.pdn.map(pdn => { return pdn.apn } )
let duplicates = {};
for (let i = 0; i < apns.length; i++) {
if (duplicates.hasOwnProperty(apns[i])) {
duplicates[apns[i]].push(i);
} else if (apns.lastIndexOf(apns[i]) !== i) {
duplicates[apns[i]] = [i];
}
}
for (let key in duplicates) {
duplicates[key].forEach(index =>
errors.pdn[index].apn.addError(`'${key}' is duplicated`));
}
}
return errors;
}
handleSubmit = (formData) => {
const { dispatch, action } = this.props;
if (formData.security) {
if (formData.security.op_type === 1) {
formData.security.op = formData.security.op_value;
formData.security.opc = null;
} else {
formData.security.op = null;
formData.security.opc = formData.security.op_value;
}
}
NProgress.configure({
parent: '#nprogress-base-form',
trickleSpeed: 5
});
NProgress.start();
if (action === 'create') {
dispatch(createProfile({}, formData));
} else if (action === 'update') {
dispatch(updateProfile(formData._id, {}, formData));
} else {
throw new Error(`Action type '${action}' is invalid.`);
}
}
handleError = errors => {
const { dispatch } = this.props;
errors.map(error =>
dispatch(Notification.error({
title: 'Validation Error',
message: error.stack
}))
)
}
render() {
const {
validate,
handleSubmit,
handleError
} = this;
const {
visible,
action,
status,
profile,
onHide
} = this.props
return (
<Profile.Edit
visible={visible}
action={action}
formData={this.state.formData}
isLoading={profile.isLoading && !status.pending}
validate={validate}
onHide={onHide}
onSubmit={handleSubmit}
onError={handleError} />
)
}
}
Document = connect(
(state, props) => ({
profiles: select(fetchProfiles(), state.crud),
profile: select(fetchProfile(props._id), state.crud),
status: selectActionStatus(MODEL, state.crud, props.action)
})
)(Document);
export default Document;