Skip to content
This repository has been archived by the owner on Feb 6, 2024. It is now read-only.

Commit

Permalink
SchemaForm sketching
Browse files Browse the repository at this point in the history
  • Loading branch information
japsu committed Feb 2, 2019
1 parent 9b79001 commit 2c271f8
Show file tree
Hide file tree
Showing 11 changed files with 180 additions and 8 deletions.
4 changes: 2 additions & 2 deletions src/components/App.tsx
Expand Up @@ -13,8 +13,8 @@ class App extends React.Component {
<div className='Application'>
<Navigation />
<Switch>
<Route exact={true} path="/" render={FrontPage} />
<Route path="/forms/:formSlug" render={() => <FormView />} />
<Route exact={true} path="/" component={FrontPage} />
<Route path="/forms/:formSlug" component={FormView} />
<Route render={NotFound} />
</Switch>
</div>
Expand Down
6 changes: 3 additions & 3 deletions src/components/DataTable/index.tsx
Expand Up @@ -10,7 +10,7 @@ import Session from '../SessionContext/Session';
interface DataTableProps {
endpoint: string;
columns: string[];
namespaces?: string[];
ns?: string[];
}

interface DataTableState<ItemType> {
Expand Down Expand Up @@ -41,10 +41,10 @@ export default class DataTable<ItemType> extends React.PureComponent<DataTablePr

const { columns } = this.props;
const { items } = this.state;
const namespaces = this.props.namespaces ? this.props.namespaces.concat([this.defaultNamespace]) : [this.defaultNamespace];
const ns = this.props.ns ? this.props.ns.concat([this.defaultNamespace]) : [this.defaultNamespace];

return (
<NamespacesConsumer ns={namespaces}>
<NamespacesConsumer ns={ns}>
{(t) => (
<Table>
<thead>
Expand Down
47 changes: 45 additions & 2 deletions src/components/FormView.tsx
@@ -1,8 +1,51 @@
import * as React from 'react';
import { RouteComponentProps } from 'react-router';

import MainViewContainer from './MainViewContainer';
import SchemaForm from './SchemaForm';
import { Field } from './SchemaForm/models';



interface FormViewRouterProps {
formSlug: string;
}

interface FormViewState {
title?: string;
introductionText?: string;
fields: Field[];
}


export default class FormView extends React.Component<RouteComponentProps<FormViewRouterProps>, FormViewState> {
state: FormViewState = {
title: 'Dynaamine lomake höhöhö',
introductionText: 'Lorem ipsum höhöhö sit amet.\n\nWith paragraphs!',
fields: [
{
type: 'Input',
name: 'foo',
title: 'Foo',
},
{
type: 'TextArea',
name: 'bar',
title: 'Bar',
},
],
};

export default class FormView extends React.Component<{}, {}> {
render() {
return <div>form view</div>;
const { title, fields, introductionText } = this.state;

return (
<MainViewContainer>
{title ? <h1>{title}</h1> : null}
{introductionText ? introductionText.split('\n\n').map((paragraph, index) => <p key={index}>{paragraph}</p>) : null}

<SchemaForm fields={fields} layout="horizontal" />
</MainViewContainer>
);
}
}
2 changes: 1 addition & 1 deletion src/components/FrontPage.tsx
Expand Up @@ -12,7 +12,7 @@ export default () => (
<DataTable
endpoint="events"
columns={['name', 'headline']}
namespaces={["Event"]}
ns={["Event"]}
/>
</Container>
);
3 changes: 3 additions & 0 deletions src/components/MainViewContainer/index.css
@@ -0,0 +1,3 @@
.MainViewContainer {
padding-top: 2em;
}
12 changes: 12 additions & 0 deletions src/components/MainViewContainer/index.tsx
@@ -0,0 +1,12 @@
import React from 'react';

import Container from "reactstrap/lib/Container";

import './index.css';


export default class MainViewContainer extends React.Component<{}, {}> {
render() {
return <Container className='MainViewContainer'>{this.props.children}</Container>;
}
}
78 changes: 78 additions & 0 deletions src/components/SchemaForm/index.tsx
@@ -0,0 +1,78 @@
import React from 'react';
import { NamespacesConsumer } from 'react-i18next';

import Button from 'reactstrap/lib/Button';
import ButtonGroup from 'reactstrap/lib/ButtonGroup';
import Col from 'reactstrap/lib/Col';
import Form from 'reactstrap/lib/Form';
import FormGroup from 'reactstrap/lib/FormGroup';
import Input from 'reactstrap/lib/Input';
import Label from 'reactstrap/lib/Label';

import { Field, FieldType } from './models';


interface SchemaFormProps {
fields: Field[];
layout?: 'vertical' | 'horizontal';
ns?: string[];
}


interface SchemaFormState { }


export default class SchemaForm extends React.PureComponent<SchemaFormProps, SchemaFormState> {
static defaultNamespace = 'SchemaForm';

render() {
const { layout } = this.props;
const ns = (this.props.ns || []).concat(['SchemaForm']);

return (
<NamespacesConsumer ns={ns}>
{t => (
<Form className={layout === 'horizontal' ? 'form-horizontal' : ''}>
{this.props.fields.map(this.renderField)}

<ButtonGroup className="float-md-right">
<Button color="primary">{t('submit')}</Button>
</ButtonGroup>
</Form>
)}
</NamespacesConsumer>
);
}

renderField = (field: Field) => {
const { layout } = this.props;
const { name, title, helpText } = field;

switch (layout) {
case 'horizontal':
return (
<FormGroup key={name} className="row">
<Label for={name} className="col-md-3 col-form-label">{title}</Label>
<Col md={9}>{this.renderInput(field)}</Col>
</FormGroup>
);
case 'vertical':
default:
return (
<FormGroup key={name} className="row">
<Label for={name}>{title}</Label>
{this.renderInput(field)}
</FormGroup>
);
}
}

renderInput = (field: Field) => {
switch (field.type) {
case 'Input':
return <Input name={field.name} />;
case 'TextArea':
return <Input type="textarea" name={field.name} rows={field.rows || 10} />;
}
}
}
23 changes: 23 additions & 0 deletions src/components/SchemaForm/models.ts
@@ -0,0 +1,23 @@
export type FieldType = 'Input' | 'TextArea';

interface BaseField {
type: FieldType;
name: string;
title: string;
helpText?: string;
required?: boolean;
}


export interface Input extends BaseField {
type: 'Input';
}


export interface TextArea extends BaseField {
type: 'TextArea';
rows?: number;
cols?: number;
}

export type Field = Input | TextArea;
3 changes: 3 additions & 0 deletions src/translations/en.ts
Expand Up @@ -9,6 +9,9 @@ const translations: Translations = {
logIn: 'Log in',
logOut: 'Log out',
},
SchemaForm: {
submit: 'Submit',
}
};

export default translations;
3 changes: 3 additions & 0 deletions src/translations/fi.ts
Expand Up @@ -9,5 +9,8 @@ const translations: Translations = {
logIn: 'Kirjaudu sisään',
logOut: 'Kirjaudu ulos',
},
SchemaForm: {
submit: 'Lähetä',
},
};
export default translations;
7 changes: 7 additions & 0 deletions src/translations/index.ts
Expand Up @@ -7,10 +7,17 @@ import fi from './fi';

export interface Translations {
[index: string]: i18n.ResourceKey;
Event: {
name: string;
headline: string;
};
Navigation: {
logIn: string;
logOut: string;
};
SchemaForm: {
submit: string;
};
}

const resources: i18n.Resource = { fi, en };
Expand Down

0 comments on commit 2c271f8

Please sign in to comment.