Some basic components for building forms.

This commit is contained in:
Tomas Bures 2017-06-04 13:16:29 +02:00
parent d13fc65ce2
commit 4504d539c5
22 changed files with 827 additions and 246 deletions

View file

@ -0,0 +1,20 @@
'use strict';
import React, { Component } from 'react';
import { translate } from 'react-i18next';
import { Title } from "../lib/page";
import csfrToken from 'csfrToken';
@translate()
export default class Create extends Component {
render() {
const t = this.props.t;
console.log('csfrToken = ' + csfrToken);
return (
<div>
<Title>{t('Create Namespace')}</Title>
</div>
);
}
}

View file

@ -0,0 +1,60 @@
'use strict';
import React, { Component } from 'react';
import { translate } from 'react-i18next';
import csfrToken from 'csfrToken';
import { withForm, Form, InputField, TextArea, ButtonRow, Button } from '../lib/form';
import { Title } from "../lib/page";
@translate()
@withForm
export default class Edit extends Component {
constructor(props) {
super(props);
this.nsId = parseInt(this.props.match.params.nsId);
this.initFormState();
this.populateFormStateFromURL(`/namespaces/rest/namespaces/${this.nsId}`);
}
validateFormState(state) {
const t = this.props.t;
if (!state.getIn(['name','value']).trim()) {
state.setIn(['name', 'error'], t('Name must not be empty'));
} else {
state.setIn(['name', 'error'], null);
}
}
submitHandler(evt) {
evt.preventDefault();
this.showFormValidation();
}
deleteHandler() {
this.hideFormValidation();
}
render() {
const t = this.props.t;
return (
<div>
<Title>{t('Edit Namespace')}</Title>
<Form stateOwner={this} onSubmit={::this.submitHandler}>
<InputField id="name" label={t('Name')} description={t('Namespace Name')}/>
<TextArea id="description" label={t('Description')} description={t('Description')}/>
<ButtonRow>
<Button type="submit" className="btn-primary" icon="ok" label={t('Update')}/>
<Button className="btn-danger" icon="remove" label={t('Delete Namespace')} onClick={::this.deleteHandler}/>
</ButtonRow>
</Form>
</div>
);
}
}

View file

@ -0,0 +1,25 @@
'use strict';
import React, { Component } from 'react';
import { translate } from 'react-i18next';
import NamespacesTreeTable from './NamespacesTreeTable';
import { Title, Toolbar, NavButton } from "../lib/page";
@translate()
export default class List extends Component {
render() {
const t = this.props.t;
return (
<div>
<Toolbar>
<NavButton linkTo="/namespaces/create" className="btn-primary" icon="plus" label={t('Create Namespace')}/>
</Toolbar>
<Title>{t('Namespaces')}</Title>
<NamespacesTreeTable />
</div>
);
}
}

View file

@ -7,30 +7,29 @@ import jQuery from 'jquery';
import '../../public/jquery/jquery-ui-1.12.1.min.js';
import '../../public/fancytree/jquery.fancytree-all.min.js';
import '../../public/fancytree/skin-bootstrap/ui.fancytree.min.css';
import axios from 'axios';
translate();
class NamespacesTreeTable extends Component {
@translate()
export default class NamespacesTreeTable extends Component {
constructor(props) {
super(props);
this.state = {
treeData: [
{title: 'A', key: '1', expanded: true},
{title: 'B', key: '2', expanded: true, folder: true, children: [
{title: 'BA', key: '3', expanded: true, folder: true, children: [
{title: 'BAA', key: '4', expanded: true},
{title: 'BAB', key: '5', expanded: true}
]},
{title: 'BB', key: '6', expanded: true, folder: true, children: [
{title: 'BBA', key: '7', expanded: true},
{title: 'BBB', key: '8', expanded: true}
]}
]}
]
treeData: []
};
axios.get('/namespaces/rest/namespacesTree')
.then(response => {
this.setState({
treeData: response.data
});
});
}
componentDidMount() {
const history = this.props.history;
const glyphOpts = {
map: {
expanderClosed: 'glyphicon glyphicon-menu-right',
@ -49,8 +48,15 @@ class NamespacesTreeTable extends Component {
source: this.state.treeData,
table: {
nodeColumnIdx: 0
},
createNode: (event, data) => {
const node = data.node;
const tdList = jQuery(node.tr).find(">td");
tdList.eq(1).html('<a href="#">Edit</a>').click(() => {
history.push('/namespaces/edit/' + node.key);
});
}
});
}).fancytree("getTree");
}
componentDidUpdate() {
@ -58,13 +64,15 @@ class NamespacesTreeTable extends Component {
}
render() {
const t = this.props.t;
const container =
<div ref={(domElem) => { this.domTableContainer = domElem; }} style={{ height: '100px', overflow: 'auto'}}>
<table ref={(domElem) => { this.domTable = domElem; }} className="table table-hover table-striped table-condensed">
<thead>
<tr>
<th>Name</th>
<th>B</th>
<th>{t('Name')}</th>
<th></th>
</tr>
</thead>
<tbody>
@ -81,6 +89,4 @@ class NamespacesTreeTable extends Component {
);
}
}
export default NamespacesTreeTable;
}

View file

@ -0,0 +1,46 @@
'use strict';
import React from 'react';
import ReactDOM from 'react-dom';
import { I18nextProvider } from 'react-i18next';
import i18n from '../lib/i18n';
import { Section } from '../lib/page'
import Create from './Create'
import Edit from './Edit'
import List from './List'
const getStructure = t => ({
'': {
title: t('Home'),
externalLink: '/',
children: {
'namespaces': {
title: t('Namespaces'),
link: '/namespaces',
component: List,
children: {
'edit' : {
title: t('Edit Namespace'),
params: [':nsId'],
component: Edit
},
'create' : {
title: t('Create Namespace'),
link: '/namespaces/create',
component: Create
}
}
}
}
}
});
export default function() {
ReactDOM.render(
<I18nextProvider i18n={ i18n }><Section structure={getStructure}/></I18nextProvider>,
document.getElementById('root')
);
};