Created
October 27, 2017 21:20
-
-
Save pioh/59819d6fbb137c4b5a568b9b49cf390b to your computer and use it in GitHub Desktop.
RenderPropsExample
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import * as React from 'react' | |
import {observer} from 'mobx-react' | |
import {FormGroup, Col, Label} from 'reactstrap' | |
import {OrderProvider} from 'components/OrderProvider/OrderProvider' | |
import {Input} from 'components/Input/Input' | |
import {Select} from 'components/Select/Select' | |
import {FieldFormat, InputAddon} from 'const/ReportForm/Field' | |
import {YesNoTable} from './YesNoTable' | |
import * as s from './Order.scss' | |
const yandexLink = ({address, lat, lon}) => | |
`https://yandex.ru/maps/?ll=${lon}%2C${lat}&pt=${lon}%2C${lat}&text=${ | |
encodeURIComponent(address) | |
}` | |
export const OrderFields = observer<{orderID: string}>(props => | |
<OrderProvider id={props.orderID}> | |
{({order, isLoading, loadError, reload}) => ( | |
isLoading ? <Loader /> : | |
loadError ? <ErrorBlock message={loadError.error} reload={reload} /> : | |
<FormGroup className={s.fields}> | |
<FormGroup> | |
<Label> | |
<Col sm={4}><span>Адрес</span></Col> | |
<Col sm={8}> | |
<Input disabled format={FieldFormat.TEXT} store={order} path='address' /> | |
<a href={yandexLink(order)} target='_blank'>Яндекс карты</a> | |
</Col> | |
</Label> | |
</FormGroup> | |
<FormGroup> | |
<Label> | |
<Col sm={4}><span>Тип объекта</span></Col> | |
<Col sm={8}> | |
<Select store={order} path='objectType' options={{ | |
disabled: true, | |
dictionary: [], | |
}} /> | |
</Col> | |
</Label> | |
</FormGroup> | |
<FormGroup> | |
<Label> | |
<Col sm={4}><span>Предполагаемая цена</span></Col> | |
<Col sm={8}> | |
<Input | |
disabled | |
format={FieldFormat.PRICE} | |
store={order} | |
path='objectSalePrice' | |
addon={InputAddon.RUBLE} | |
/> | |
</Col> | |
</Label> | |
</FormGroup> | |
<FormGroup> | |
<Col><h5>Заказчик</h5></Col> | |
<Label> | |
<Col sm={4}><span>ФИО 1</span></Col> | |
<Col sm={8}> | |
<Input | |
disabled | |
format={FieldFormat.TEXT} | |
store={order} | |
path='customerName' | |
/> | |
</Col> | |
</Label> | |
<Label> | |
<Col sm={4}><span>Телефон 1</span></Col> | |
<Col sm={8}> | |
<Input | |
disabled | |
format={FieldFormat.PHONE} | |
store={order} | |
path='customerPhone' | |
/> | |
</Col> | |
</Label> | |
</FormGroup> | |
<FormGroup> | |
<Col> | |
<YesNoTable | |
title='Дополнительные данные' | |
disabled | |
fields={[{ | |
store: order, | |
path: 'legalPersonOwner', | |
title: 'Собственником является юридическое лицо', | |
},{ | |
store: order, | |
path: 'minorOwner', | |
title: 'Собственником является несовершеннолетнее лицо', | |
},{ | |
store: order, | |
path: 'onerousTransaction', | |
title: 'Объект недвижимости был приобретен продавцом в период брака на основании возмездной сделки', | |
}]} | |
/> | |
</Col> | |
</FormGroup> | |
<FormGroup> | |
<Col><h5>Комментарий клиента</h5></Col> | |
<Col> | |
<Input | |
disabled | |
format={FieldFormat.TEXT} | |
store={order} | |
path='comment' | |
textarea | |
/> | |
</Col> | |
</FormGroup> | |
</FormGroup> | |
)} | |
</OrderProvider> | |
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import * as React from 'react' | |
import {observable, action} from 'mobx' | |
import {observer} from 'mobx-react' | |
import {FileType} from 'const/FileType' | |
import {InspectionTime} from 'const/InspectionTime' | |
import {ApiEndpoint} from 'const/Api' | |
import {OrderStatus} from 'const/OrderStatus' | |
export interface IOrderProviderProps { | |
id: string|number, | |
children: (props: IChildrenProps) => any, | |
} | |
type IChildrenProps = OrderProvider['childrenProps'] | |
const providers = new Map<string|number, [IChildrenProps,number]>() | |
export interface IOrderFile { | |
filePath: string|null, | |
created: string|null, | |
originalFilename: string|null, | |
size: number, | |
contentType: string|null, | |
fileType: FileType, | |
} | |
export const nullOrder = { | |
id: null as string|null, | |
address: null as string|null, | |
lat: null as number|null, | |
lon:null as number|null, | |
objectSalePrice: null as number|null, | |
customerName: null as string|null, | |
customerPhone: null as string|null, | |
legalPersonOwner: true, | |
minorOwner: false, | |
onerousTransaction: false, | |
crmId: null as number|string|null, | |
comment: null as string|null, | |
status: null as OrderStatus|null, | |
attachedFileList: [] as IOrderFile[], | |
inspectionDate: null as string|null, | |
inspectionTime: null as InspectionTime|null | |
} | |
export type IOrder = typeof nullOrder | |
@observer | |
class OrderProvider extends React.Component<IOrderProviderProps> { | |
@action reload = async () => { | |
this.childrenProps.isLoading = true | |
this.childrenProps.loadError = null | |
try { | |
let response = await fetch(`${ApiEndpoint}order/${this.props.id}`) | |
let order = await response.json() | |
if (order.error) return await this.receiveReloadError(order) | |
await this.receiveReloadOrder(order) | |
} catch (e) { | |
await this.receiveReloadError(e) | |
} | |
} | |
@action receiveReloadOrder = async (order: IChildrenProps['order']) => { | |
this.childrenProps.order = order | |
this.childrenProps.isLoading = false | |
this.childrenProps.loadError = null | |
} | |
@action receiveReloadError = async (e = {} as any) => { | |
if (!e.error) e.error = 'Что-то пошло не так' | |
this.childrenProps.isLoading = false | |
this.childrenProps.loadError = e | |
console.error(e.stack || e.message) | |
} | |
@observable childrenProps = { | |
isLoading: false, | |
loadError: null as null|{message:string, error: string}, | |
order: nullOrder, | |
reload: this.reload, | |
} | |
componentWillMount () { | |
let provider = providers.get(this.props.id) | |
if (provider) { | |
provider[1]++ | |
return | |
} | |
providers.set(this.props.id, [this.childrenProps,1]) | |
this.reload() | |
} | |
componentWillUnmount () { | |
let provider = providers.get(this.props.id) | |
if (!provider) return | |
provider[1]-- | |
if (provider[1] === 0) providers.delete(this.props.id) | |
} | |
render () { | |
let provider = providers.get(this.props.id) | |
if (provider) return this.props.children(provider[0]) | |
return this.props.children(this.childrenProps) | |
} | |
} | |
export {OrderProvider} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment