mirror of
https://github.com/elyby/accounts-frontend.git
synced 2025-05-31 14:11:58 +05:30
Major deps updates: router, redux, intl, react-transition-group, flow-type, testing deps
This commit is contained in:
parent
6821bcfe40
commit
627d503d43
239
flow-typed/npm/react-intl_v2.x.x.js
vendored
239
flow-typed/npm/react-intl_v2.x.x.js
vendored
@ -1,5 +1,5 @@
|
|||||||
// flow-typed signature: e68caa23426dedefced5662fb92b4638
|
// flow-typed signature: 3902298e28ed22d8cd8d49828801a760
|
||||||
// flow-typed version: d13a175635/react-intl_v2.x.x/flow_>=v0.57.x
|
// flow-typed version: eb50783110/react-intl_v2.x.x/flow_>=v0.63.x
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Original implementation of this file by @marudor at https://github.com/marudor/flowInterfaces
|
* Original implementation of this file by @marudor at https://github.com/marudor/flowInterfaces
|
||||||
@ -7,112 +7,110 @@
|
|||||||
* https://github.com/marudor/flowInterfaces/issues/6
|
* https://github.com/marudor/flowInterfaces/issues/6
|
||||||
*/
|
*/
|
||||||
// Mostly from https://github.com/yahoo/react-intl/wiki/API#react-intl-api
|
// Mostly from https://github.com/yahoo/react-intl/wiki/API#react-intl-api
|
||||||
|
|
||||||
import type { Element, ChildrenArray } from "react";
|
|
||||||
|
|
||||||
type $npm$ReactIntl$LocaleData = {
|
|
||||||
locale: string,
|
|
||||||
[key: string]: any
|
|
||||||
};
|
|
||||||
|
|
||||||
type $npm$ReactIntl$MessageDescriptor = {
|
|
||||||
id: string,
|
|
||||||
description?: string,
|
|
||||||
defaultMessage?: string
|
|
||||||
};
|
|
||||||
|
|
||||||
type $npm$ReactIntl$IntlConfig = {
|
|
||||||
locale: string,
|
|
||||||
formats: Object,
|
|
||||||
messages: { [id: string]: string },
|
|
||||||
|
|
||||||
defaultLocale?: string,
|
|
||||||
defaultFormats?: Object
|
|
||||||
};
|
|
||||||
|
|
||||||
type $npm$ReactIntl$IntlProviderConfig = {
|
|
||||||
locale?: string,
|
|
||||||
formats?: Object,
|
|
||||||
messages?: { [id: string]: string },
|
|
||||||
|
|
||||||
defaultLocale?: string,
|
|
||||||
defaultFormats?: Object
|
|
||||||
};
|
|
||||||
|
|
||||||
type $npm$ReactIntl$IntlFormat = {
|
|
||||||
formatDate: (value: any, options?: Object) => string,
|
|
||||||
formatTime: (value: any, options?: Object) => string,
|
|
||||||
formatRelative: (value: any, options?: Object) => string,
|
|
||||||
formatNumber: (value: any, options?: Object) => string,
|
|
||||||
formatPlural: (value: any, options?: Object) => string,
|
|
||||||
formatMessage: (
|
|
||||||
messageDescriptor: $npm$ReactIntl$MessageDescriptor,
|
|
||||||
values?: Object
|
|
||||||
) => string,
|
|
||||||
formatHTMLMessage: (
|
|
||||||
messageDescriptor: $npm$ReactIntl$MessageDescriptor,
|
|
||||||
values?: Object
|
|
||||||
) => string
|
|
||||||
};
|
|
||||||
|
|
||||||
type $npm$ReactIntl$IntlShape = $npm$ReactIntl$IntlConfig &
|
|
||||||
$npm$ReactIntl$IntlFormat & { now: () => number };
|
|
||||||
|
|
||||||
type $npm$ReactIntl$DateTimeFormatOptions = {
|
|
||||||
localeMatcher?: "best fit" | "lookup",
|
|
||||||
formatMatcher?: "basic" | "best fit",
|
|
||||||
|
|
||||||
timeZone?: string,
|
|
||||||
hour12?: boolean,
|
|
||||||
|
|
||||||
weekday?: "narrow" | "short" | "long",
|
|
||||||
era?: "narrow" | "short" | "long",
|
|
||||||
year?: "numeric" | "2-digit",
|
|
||||||
month?: "numeric" | "2-digit" | "narrow" | "short" | "long",
|
|
||||||
day?: "numeric" | "2-digit",
|
|
||||||
hour?: "numeric" | "2-digit",
|
|
||||||
minute?: "numeric" | "2-digit",
|
|
||||||
second?: "numeric" | "2-digit",
|
|
||||||
timeZoneName?: "short" | "long"
|
|
||||||
};
|
|
||||||
|
|
||||||
type $npm$ReactIntl$RelativeFormatOptions = {
|
|
||||||
style?: "best fit" | "numeric",
|
|
||||||
units?: "second" | "minute" | "hour" | "day" | "month" | "year"
|
|
||||||
};
|
|
||||||
|
|
||||||
type $npm$ReactIntl$NumberFormatOptions = {
|
|
||||||
localeMatcher?: "best fit" | "lookup",
|
|
||||||
|
|
||||||
style?: "decimal" | "currency" | "percent",
|
|
||||||
|
|
||||||
currency?: string,
|
|
||||||
currencyDisplay?: "symbol" | "code" | "name",
|
|
||||||
|
|
||||||
useGrouping?: boolean,
|
|
||||||
|
|
||||||
minimumIntegerDigits?: number,
|
|
||||||
minimumFractionDigits?: number,
|
|
||||||
maximumFractionDigits?: number,
|
|
||||||
minimumSignificantDigits?: number,
|
|
||||||
maximumSignificantDigits?: number
|
|
||||||
};
|
|
||||||
|
|
||||||
type $npm$ReactIntl$PluralFormatOptions = {
|
|
||||||
style?: "cardinal" | "ordinal"
|
|
||||||
};
|
|
||||||
|
|
||||||
type $npm$ReactIntl$PluralCategoryString =
|
|
||||||
| "zero"
|
|
||||||
| "one"
|
|
||||||
| "two"
|
|
||||||
| "few"
|
|
||||||
| "many"
|
|
||||||
| "other";
|
|
||||||
|
|
||||||
type $npm$ReactIntl$DateParseable = number | string | Date;
|
|
||||||
|
|
||||||
declare module "react-intl" {
|
declare module "react-intl" {
|
||||||
|
import type { Element, ChildrenArray } from "react";
|
||||||
|
|
||||||
|
declare type $npm$ReactIntl$LocaleData = {
|
||||||
|
locale: string,
|
||||||
|
[key: string]: any
|
||||||
|
};
|
||||||
|
|
||||||
|
declare type $npm$ReactIntl$MessageDescriptor = {
|
||||||
|
id: string,
|
||||||
|
description?: string,
|
||||||
|
defaultMessage?: string
|
||||||
|
};
|
||||||
|
|
||||||
|
declare type $npm$ReactIntl$IntlConfig = {
|
||||||
|
locale: string,
|
||||||
|
formats: Object,
|
||||||
|
messages: { [id: string]: string },
|
||||||
|
|
||||||
|
defaultLocale?: string,
|
||||||
|
defaultFormats?: Object
|
||||||
|
};
|
||||||
|
|
||||||
|
declare type $npm$ReactIntl$IntlProviderConfig = {
|
||||||
|
locale?: string,
|
||||||
|
formats?: Object,
|
||||||
|
messages?: { [id: string]: string },
|
||||||
|
|
||||||
|
defaultLocale?: string,
|
||||||
|
defaultFormats?: Object
|
||||||
|
};
|
||||||
|
|
||||||
|
declare type $npm$ReactIntl$IntlFormat = {
|
||||||
|
formatDate: (value: any, options?: Object) => string,
|
||||||
|
formatTime: (value: any, options?: Object) => string,
|
||||||
|
formatRelative: (value: any, options?: Object) => string,
|
||||||
|
formatNumber: (value: any, options?: Object) => string,
|
||||||
|
formatPlural: (value: any, options?: Object) => string,
|
||||||
|
formatMessage: (
|
||||||
|
messageDescriptor: $npm$ReactIntl$MessageDescriptor,
|
||||||
|
values?: Object
|
||||||
|
) => string,
|
||||||
|
formatHTMLMessage: (
|
||||||
|
messageDescriptor: $npm$ReactIntl$MessageDescriptor,
|
||||||
|
values?: Object
|
||||||
|
) => string
|
||||||
|
};
|
||||||
|
|
||||||
|
declare type $npm$ReactIntl$IntlShape = $npm$ReactIntl$IntlConfig &
|
||||||
|
$npm$ReactIntl$IntlFormat & { now: () => number };
|
||||||
|
|
||||||
|
declare type $npm$ReactIntl$DateTimeFormatOptions = {
|
||||||
|
localeMatcher?: "best fit" | "lookup",
|
||||||
|
formatMatcher?: "basic" | "best fit",
|
||||||
|
|
||||||
|
timeZone?: string,
|
||||||
|
hour12?: boolean,
|
||||||
|
|
||||||
|
weekday?: "narrow" | "short" | "long",
|
||||||
|
era?: "narrow" | "short" | "long",
|
||||||
|
year?: "numeric" | "2-digit",
|
||||||
|
month?: "numeric" | "2-digit" | "narrow" | "short" | "long",
|
||||||
|
day?: "numeric" | "2-digit",
|
||||||
|
hour?: "numeric" | "2-digit",
|
||||||
|
minute?: "numeric" | "2-digit",
|
||||||
|
second?: "numeric" | "2-digit",
|
||||||
|
timeZoneName?: "short" | "long"
|
||||||
|
};
|
||||||
|
|
||||||
|
declare type $npm$ReactIntl$RelativeFormatOptions = {
|
||||||
|
style?: "best fit" | "numeric",
|
||||||
|
units?: "second" | "minute" | "hour" | "day" | "month" | "year"
|
||||||
|
};
|
||||||
|
|
||||||
|
declare type $npm$ReactIntl$NumberFormatOptions = {
|
||||||
|
localeMatcher?: "best fit" | "lookup",
|
||||||
|
|
||||||
|
style?: "decimal" | "currency" | "percent",
|
||||||
|
|
||||||
|
currency?: string,
|
||||||
|
currencyDisplay?: "symbol" | "code" | "name",
|
||||||
|
|
||||||
|
useGrouping?: boolean,
|
||||||
|
|
||||||
|
minimumIntegerDigits?: number,
|
||||||
|
minimumFractionDigits?: number,
|
||||||
|
maximumFractionDigits?: number,
|
||||||
|
minimumSignificantDigits?: number,
|
||||||
|
maximumSignificantDigits?: number
|
||||||
|
};
|
||||||
|
|
||||||
|
declare type $npm$ReactIntl$PluralFormatOptions = {
|
||||||
|
style?: "cardinal" | "ordinal"
|
||||||
|
};
|
||||||
|
|
||||||
|
declare type $npm$ReactIntl$PluralCategoryString =
|
||||||
|
| "zero"
|
||||||
|
| "one"
|
||||||
|
| "two"
|
||||||
|
| "few"
|
||||||
|
| "many"
|
||||||
|
| "other";
|
||||||
|
|
||||||
|
declare type $npm$ReactIntl$DateParseable = number | string | Date;
|
||||||
// PropType checker
|
// PropType checker
|
||||||
declare function intlShape(
|
declare function intlShape(
|
||||||
props: Object,
|
props: Object,
|
||||||
@ -123,7 +121,7 @@ declare module "react-intl" {
|
|||||||
data: $npm$ReactIntl$LocaleData | Array<$npm$ReactIntl$LocaleData>
|
data: $npm$ReactIntl$LocaleData | Array<$npm$ReactIntl$LocaleData>
|
||||||
): void;
|
): void;
|
||||||
declare function defineMessages<
|
declare function defineMessages<
|
||||||
T: { [key: string]: $npm$ReactIntl$MessageDescriptor }
|
T: { [key: string]: $Exact<$npm$ReactIntl$MessageDescriptor> }
|
||||||
>(
|
>(
|
||||||
messageDescriptors: T
|
messageDescriptors: T
|
||||||
): T;
|
): T;
|
||||||
@ -132,6 +130,10 @@ declare module "react-intl" {
|
|||||||
intl: $npm$ReactIntl$IntlShape
|
intl: $npm$ReactIntl$IntlShape
|
||||||
}
|
}
|
||||||
|
|
||||||
|
declare type InjectIntlVoidProps = {
|
||||||
|
intl: $npm$ReactIntl$IntlShape | void
|
||||||
|
}
|
||||||
|
|
||||||
declare type ComponentWithDefaultProps<DefaultProps: {}, Props: {}> =
|
declare type ComponentWithDefaultProps<DefaultProps: {}, Props: {}> =
|
||||||
| React$ComponentType<Props>
|
| React$ComponentType<Props>
|
||||||
| React$StatelessFunctionalComponent<Props>
|
| React$StatelessFunctionalComponent<Props>
|
||||||
@ -152,19 +154,12 @@ declare module "react-intl" {
|
|||||||
IntlInjectedComponent<TOwnProps, TDefaultProps>
|
IntlInjectedComponent<TOwnProps, TDefaultProps>
|
||||||
>;
|
>;
|
||||||
|
|
||||||
declare function injectIntl<OriginalProps: InjectIntlProvidedProps, DefaultProps: {}>
|
declare function injectIntl<P: {}, Component: React$ComponentType<P>>(
|
||||||
(
|
WrappedComponent: Component,
|
||||||
component: ComponentWithDefaultProps<DefaultProps, OriginalProps>,
|
|
||||||
options?: InjectIntlOptions,
|
options?: InjectIntlOptions,
|
||||||
):
|
): React$ComponentType<
|
||||||
IntlInjectedComponentClass<$Diff<OriginalProps, InjectIntlProvidedProps>, DefaultProps>
|
$Diff<React$ElementConfig<Component>, InjectIntlVoidProps>
|
||||||
|
>;
|
||||||
declare function injectIntl<OriginalProps: InjectIntlProvidedProps>
|
|
||||||
(
|
|
||||||
component: React$ComponentType<OriginalProps>,
|
|
||||||
options?: InjectIntlOptions,
|
|
||||||
):
|
|
||||||
IntlInjectedComponentClass<$Diff<OriginalProps, InjectIntlProvidedProps>>;
|
|
||||||
|
|
||||||
declare function formatMessage(
|
declare function formatMessage(
|
||||||
messageDescriptor: $npm$ReactIntl$MessageDescriptor,
|
messageDescriptor: $npm$ReactIntl$MessageDescriptor,
|
||||||
@ -202,7 +197,9 @@ declare module "react-intl" {
|
|||||||
$npm$ReactIntl$MessageDescriptor & {
|
$npm$ReactIntl$MessageDescriptor & {
|
||||||
values?: Object,
|
values?: Object,
|
||||||
tagName?: string,
|
tagName?: string,
|
||||||
children?: (...formattedMessage: Array<React$Node>) => React$Node
|
children?:
|
||||||
|
| ((...formattedMessage: Array<React$Node>) => React$Node)
|
||||||
|
| (string => React$Node)
|
||||||
}
|
}
|
||||||
> {}
|
> {}
|
||||||
declare class FormattedHTMLMessage extends React$Component<
|
declare class FormattedHTMLMessage extends React$Component<
|
||||||
|
334
flow-typed/npm/react-redux_v5.x.x.js
vendored
334
flow-typed/npm/react-redux_v5.x.x.js
vendored
@ -1,114 +1,276 @@
|
|||||||
// flow-typed signature: c5fac64666f9589a0c1b2de956dc7919
|
// flow-typed signature: f06f00c3ad0cfedb90c0c6de04b219f3
|
||||||
// flow-typed version: 81d6274128/react-redux_v5.x.x/flow_>=v0.53.x
|
// flow-typed version: 3a6d556e4b/react-redux_v5.x.x/flow_>=v0.89.x
|
||||||
|
|
||||||
// flow-typed signature: 8db7b853f57c51094bf0ab8b2650fd9c
|
/**
|
||||||
// flow-typed version: ab8db5f14d/react-redux_v5.x.x/flow_>=v0.30.x
|
The order of type arguments for connect() is as follows:
|
||||||
|
|
||||||
import type { Dispatch, Store } from "redux";
|
connect<Props, OwnProps, StateProps, DispatchProps, State, Dispatch>(…)
|
||||||
|
|
||||||
|
In Flow v0.89 only the first two are mandatory to specify. Other 4 can be repaced with the new awesome type placeholder:
|
||||||
|
|
||||||
|
connect<Props, OwnProps, _, _, _, _>(…)
|
||||||
|
|
||||||
|
But beware, in case of weird type errors somewhere in random places
|
||||||
|
just type everything and get to a green field and only then try to
|
||||||
|
remove the definitions you see bogus.
|
||||||
|
|
||||||
|
Decrypting the abbreviations:
|
||||||
|
WC = Component being wrapped
|
||||||
|
S = State
|
||||||
|
D = Dispatch
|
||||||
|
OP = OwnProps
|
||||||
|
SP = StateProps
|
||||||
|
DP = DispatchProps
|
||||||
|
MP = Merge props
|
||||||
|
RSP = Returned state props
|
||||||
|
RDP = Returned dispatch props
|
||||||
|
RMP = Returned merge props
|
||||||
|
CP = Props for returned component
|
||||||
|
Com = React Component
|
||||||
|
ST = Static properties of Com
|
||||||
|
EFO = Extra factory options (used only in connectAdvanced)
|
||||||
|
*/
|
||||||
|
|
||||||
declare module "react-redux" {
|
declare module "react-redux" {
|
||||||
/*
|
// ------------------------------------------------------------
|
||||||
|
// Typings for connect()
|
||||||
|
// ------------------------------------------------------------
|
||||||
|
|
||||||
S = State
|
declare export type Options<S, OP, SP, MP> = {|
|
||||||
A = Action
|
pure?: boolean,
|
||||||
OP = OwnProps
|
withRef?: boolean,
|
||||||
SP = StateProps
|
areStatesEqual?: (next: S, prev: S) => boolean,
|
||||||
DP = DispatchProps
|
areOwnPropsEqual?: (next: OP, prev: OP) => boolean,
|
||||||
|
areStatePropsEqual?: (next: SP, prev: SP) => boolean,
|
||||||
|
areMergedPropsEqual?: (next: MP, prev: MP) => boolean,
|
||||||
|
storeKey?: string,
|
||||||
|
|};
|
||||||
|
|
||||||
*/
|
declare type MapStateToProps<-S, -OP, +SP> =
|
||||||
|
| ((state: S, ownProps: OP) => SP)
|
||||||
|
// If you want to use the factory function but get a strange error
|
||||||
|
// like "function is not an object" then just type the factory function
|
||||||
|
// like this:
|
||||||
|
// const factory: (State, OwnProps) => (State, OwnProps) => StateProps
|
||||||
|
// and provide the StateProps type to the SP type parameter.
|
||||||
|
| ((state: S, ownProps: OP) => (state: S, ownProps: OP) => SP);
|
||||||
|
|
||||||
declare type MapStateToProps<S, OP: Object, SP: Object> = (
|
declare type Bind<D> = <A, R>((...A) => R) => (...A) => $Call<D, R>;
|
||||||
state: S,
|
|
||||||
ownProps: OP
|
|
||||||
) => SP | MapStateToProps<S, OP, SP>;
|
|
||||||
|
|
||||||
declare type MapDispatchToProps<A, OP: Object, DP: Object> =
|
declare type MapDispatchToPropsFn<D, -OP, +DP> =
|
||||||
| ((dispatch: Dispatch<A>, ownProps: OP) => DP)
|
| ((dispatch: D, ownProps: OP) => DP)
|
||||||
| DP;
|
// If you want to use the factory function but get a strange error
|
||||||
|
// like "function is not an object" then just type the factory function
|
||||||
|
// like this:
|
||||||
|
// const factory: (Dispatch, OwnProps) => (Dispatch, OwnProps) => DispatchProps
|
||||||
|
// and provide the DispatchProps type to the DP type parameter.
|
||||||
|
| ((dispatch: D, ownProps: OP) => (dispatch: D, ownProps: OP) => DP);
|
||||||
|
|
||||||
declare type MergeProps<SP, DP: Object, OP: Object, P: Object> = (
|
declare class ConnectedComponent<OP, +WC> extends React$Component<OP> {
|
||||||
|
static +WrappedComponent: WC;
|
||||||
|
getWrappedInstance(): React$ElementRef<WC>;
|
||||||
|
}
|
||||||
|
// The connection of the Wrapped Component and the Connected Component
|
||||||
|
// happens here in `MP: P`. It means that type wise MP belongs to P,
|
||||||
|
// so to say MP >= P.
|
||||||
|
declare type Connector<P, OP, MP: P> = <WC: React$ComponentType<P>>(
|
||||||
|
WC,
|
||||||
|
) => Class<ConnectedComponent<OP, WC>> & WC;
|
||||||
|
|
||||||
|
// No `mergeProps` argument
|
||||||
|
|
||||||
|
// Got error like inexact OwnProps is incompatible with exact object type?
|
||||||
|
// Just make the OP parameter for `connect()` an exact object.
|
||||||
|
declare type MergeOP<OP, D> = {| ...$Exact<OP>, dispatch: D |};
|
||||||
|
declare type MergeOPSP<OP, SP, D> = {| ...$Exact<OP>, ...SP, dispatch: D |};
|
||||||
|
declare type MergeOPDP<OP, DP> = {| ...$Exact<OP>, ...DP |};
|
||||||
|
declare type MergeOPSPDP<OP, SP, DP> = {| ...$Exact<OP>, ...SP, ...DP |};
|
||||||
|
|
||||||
|
declare export function connect<-P, -OP, -SP, -DP, -S, -D>(
|
||||||
|
mapStateToProps?: null | void,
|
||||||
|
mapDispatchToProps?: null | void,
|
||||||
|
mergeProps?: null | void,
|
||||||
|
options?: ?Options<S, OP, {||}, MergeOP<OP, D>>,
|
||||||
|
): Connector<P, OP, MergeOP<OP, D>>;
|
||||||
|
|
||||||
|
declare export function connect<-P, -OP, -SP, -DP, -S, -D>(
|
||||||
|
// If you get error here try adding return type to your mapStateToProps function
|
||||||
|
mapStateToProps: MapStateToProps<S, OP, SP>,
|
||||||
|
mapDispatchToProps?: null | void,
|
||||||
|
mergeProps?: null | void,
|
||||||
|
options?: ?Options<S, OP, SP, MergeOPSP<OP, SP, D>>,
|
||||||
|
): Connector<P, OP, MergeOPSP<OP, SP, D>>;
|
||||||
|
|
||||||
|
// In this case DP is an object of functions which has been bound to dispatch
|
||||||
|
// by the given mapDispatchToProps function.
|
||||||
|
declare export function connect<-P, -OP, -SP, -DP, S, D>(
|
||||||
|
mapStateToProps: null | void,
|
||||||
|
mapDispatchToProps: MapDispatchToPropsFn<D, OP, DP>,
|
||||||
|
mergeProps?: null | void,
|
||||||
|
options?: ?Options<S, OP, {||}, MergeOPDP<OP, DP>>,
|
||||||
|
): Connector<P, OP, MergeOPDP<OP, DP>>;
|
||||||
|
|
||||||
|
// In this case DP is an object of action creators not yet bound to dispatch,
|
||||||
|
// this difference is not important in the vanila redux,
|
||||||
|
// but in case of usage with redux-thunk, the return type may differ.
|
||||||
|
declare export function connect<-P, -OP, -SP, -DP, S, D>(
|
||||||
|
mapStateToProps: null | void,
|
||||||
|
mapDispatchToProps: DP,
|
||||||
|
mergeProps?: null | void,
|
||||||
|
options?: ?Options<S, OP, {||}, MergeOPDP<OP, DP>>,
|
||||||
|
): Connector<P, OP, MergeOPDP<OP, $ObjMap<DP, Bind<D>>>>;
|
||||||
|
|
||||||
|
declare export function connect<-P, -OP, -SP, -DP, S, D>(
|
||||||
|
// If you get error here try adding return type to your mapStateToProps function
|
||||||
|
mapStateToProps: MapStateToProps<S, OP, SP>,
|
||||||
|
mapDispatchToProps: MapDispatchToPropsFn<D, OP, DP>,
|
||||||
|
mergeProps?: null | void,
|
||||||
|
options?: ?Options<S, OP, SP, {| ...OP, ...SP, ...DP |}>,
|
||||||
|
): Connector<P, OP, {| ...OP, ...SP, ...DP |}>;
|
||||||
|
|
||||||
|
declare export function connect<-P, -OP, -SP, -DP, S, D>(
|
||||||
|
// If you get error here try adding return type to your mapStateToProps function
|
||||||
|
mapStateToProps: MapStateToProps<S, OP, SP>,
|
||||||
|
mapDispatchToProps: DP,
|
||||||
|
mergeProps?: null | void,
|
||||||
|
options?: ?Options<S, OP, SP, MergeOPSPDP<OP, SP, DP>>,
|
||||||
|
): Connector<P, OP, MergeOPSPDP<OP, SP, $ObjMap<DP, Bind<D>>>>;
|
||||||
|
|
||||||
|
// With `mergeProps` argument
|
||||||
|
|
||||||
|
declare type MergeProps<+P, -OP, -SP, -DP> = (
|
||||||
stateProps: SP,
|
stateProps: SP,
|
||||||
dispatchProps: DP,
|
dispatchProps: DP,
|
||||||
ownProps: OP
|
ownProps: OP,
|
||||||
) => P;
|
) => P;
|
||||||
|
|
||||||
declare type Context = { store: Store<*, *> };
|
declare export function connect<-P, -OP, -SP: {||}, -DP: {||}, S, D>(
|
||||||
|
mapStateToProps: null | void,
|
||||||
|
mapDispatchToProps: null | void,
|
||||||
|
// If you get error here try adding return type to you mapStateToProps function
|
||||||
|
mergeProps: MergeProps<P, OP, {||}, {| dispatch: D |}>,
|
||||||
|
options?: ?Options<S, OP, {||}, P>,
|
||||||
|
): Connector<P, OP, P>;
|
||||||
|
|
||||||
declare class ConnectedComponent<OP, P> extends React$Component<OP> {
|
declare export function connect<-P, -OP, -SP, -DP: {||}, S, D>(
|
||||||
static WrappedComponent: Class<React$Component<P>>,
|
mapStateToProps: MapStateToProps<S, OP, SP>,
|
||||||
getWrappedInstance(): React$Component<P>,
|
mapDispatchToProps: null | void,
|
||||||
props: OP,
|
// If you get error here try adding return type to you mapStateToProps function
|
||||||
state: void
|
mergeProps: MergeProps<P, OP, SP, {| dispatch: D |}>,
|
||||||
}
|
options?: ?Options<S, OP, SP, P>,
|
||||||
|
): Connector<P, OP, P>;
|
||||||
|
|
||||||
declare type ConnectedComponentClass<OP, P> = Class<
|
// In this case DP is an object of functions which has been bound to dispatch
|
||||||
ConnectedComponent<OP, P>
|
// by the given mapDispatchToProps function.
|
||||||
>;
|
declare export function connect<-P, -OP, -SP: {||}, -DP, S, D>(
|
||||||
|
mapStateToProps: null | void,
|
||||||
|
mapDispatchToProps: MapDispatchToPropsFn<D, OP, DP>,
|
||||||
|
mergeProps: MergeProps<P, OP, {||}, DP>,
|
||||||
|
options?: ?Options<S, OP, {||}, P>,
|
||||||
|
): Connector<P, OP, P>;
|
||||||
|
|
||||||
declare type Connector<OP, P> = (
|
// In this case DP is an object of action creators not yet bound to dispatch,
|
||||||
component: React$ComponentType<P>
|
// this difference is not important in the vanila redux,
|
||||||
) => ConnectedComponentClass<OP, P>;
|
// but in case of usage with redux-thunk, the return type may differ.
|
||||||
|
declare export function connect<-P, -OP, -SP: {||}, -DP, S, D>(
|
||||||
|
mapStateToProps: null | void,
|
||||||
|
mapDispatchToProps: DP,
|
||||||
|
mergeProps: MergeProps<P, OP, {||}, $ObjMap<DP, Bind<D>>>,
|
||||||
|
options?: ?Options<S, OP, {||}, P>,
|
||||||
|
): Connector<P, OP, P>;
|
||||||
|
|
||||||
declare class Provider<S, A> extends React$Component<{
|
// In this case DP is an object of functions which has been bound to dispatch
|
||||||
store: Store<S, A>,
|
// by the given mapDispatchToProps function.
|
||||||
children?: any
|
declare export function connect<-P, -OP, -SP, -DP, S, D>(
|
||||||
|
mapStateToProps: MapStateToProps<S, OP, SP>,
|
||||||
|
mapDispatchToProps: MapDispatchToPropsFn<D, OP, DP>,
|
||||||
|
mergeProps: MergeProps<P, OP, SP, DP>,
|
||||||
|
options?: ?Options<S, OP, SP, P>,
|
||||||
|
): Connector<P, OP, P>;
|
||||||
|
|
||||||
|
// In this case DP is an object of action creators not yet bound to dispatch,
|
||||||
|
// this difference is not important in the vanila redux,
|
||||||
|
// but in case of usage with redux-thunk, the return type may differ.
|
||||||
|
declare export function connect<-P, -OP, -SP, -DP, S, D>(
|
||||||
|
mapStateToProps: MapStateToProps<S, OP, SP>,
|
||||||
|
mapDispatchToProps: DP,
|
||||||
|
mergeProps: MergeProps<P, OP, SP, $ObjMap<DP, Bind<D>>>,
|
||||||
|
options?: ?Options<S, OP, SP, P>,
|
||||||
|
): Connector<P, OP, P>;
|
||||||
|
|
||||||
|
// ------------------------------------------------------------
|
||||||
|
// Typings for Provider
|
||||||
|
// ------------------------------------------------------------
|
||||||
|
|
||||||
|
declare export class Provider<Store> extends React$Component<{
|
||||||
|
store: Store,
|
||||||
|
children?: React$Node,
|
||||||
}> {}
|
}> {}
|
||||||
|
|
||||||
declare function createProvider(
|
declare export function createProvider(
|
||||||
storeKey?: string,
|
storeKey?: string,
|
||||||
subKey?: string
|
subKey?: string,
|
||||||
): Provider<*, *>;
|
): Class<Provider<*>>;
|
||||||
|
|
||||||
declare type ConnectOptions = {
|
// ------------------------------------------------------------
|
||||||
pure?: boolean,
|
// Typings for connectAdvanced()
|
||||||
withRef?: boolean
|
// ------------------------------------------------------------
|
||||||
|
|
||||||
|
declare type ConnectAdvancedOptions = {
|
||||||
|
getDisplayName?: (name: string) => string,
|
||||||
|
methodName?: string,
|
||||||
|
renderCountProp?: string,
|
||||||
|
shouldHandleStateChanges?: boolean,
|
||||||
|
storeKey?: string,
|
||||||
|
withRef?: boolean,
|
||||||
};
|
};
|
||||||
|
|
||||||
declare type Null = null | void;
|
declare type SelectorFactoryOptions<Com> = {
|
||||||
|
getDisplayName: (name: string) => string,
|
||||||
|
methodName: string,
|
||||||
|
renderCountProp: ?string,
|
||||||
|
shouldHandleStateChanges: boolean,
|
||||||
|
storeKey: string,
|
||||||
|
withRef: boolean,
|
||||||
|
displayName: string,
|
||||||
|
wrappedComponentName: string,
|
||||||
|
WrappedComponent: Com,
|
||||||
|
};
|
||||||
|
|
||||||
declare function connect<A, OP>(
|
declare type MapStateToPropsEx<S: Object, SP: Object, RSP: Object> = (
|
||||||
...rest: Array<void> // <= workaround for https://github.com/facebook/flow/issues/2360
|
state: S,
|
||||||
): Connector<OP, $Supertype<{ dispatch: Dispatch<A> } & OP>>;
|
props: SP,
|
||||||
|
) => RSP;
|
||||||
|
|
||||||
declare function connect<A, OP>(
|
declare type SelectorFactory<
|
||||||
mapStateToProps: Null,
|
Com: React$ComponentType<*>,
|
||||||
mapDispatchToProps: Null,
|
Dispatch,
|
||||||
mergeProps: Null,
|
S: Object,
|
||||||
options: ConnectOptions
|
OP: Object,
|
||||||
): Connector<OP, $Supertype<{ dispatch: Dispatch<A> } & OP>>;
|
EFO: Object,
|
||||||
|
CP: Object,
|
||||||
|
> = (
|
||||||
|
dispatch: Dispatch,
|
||||||
|
factoryOptions: SelectorFactoryOptions<Com> & EFO,
|
||||||
|
) => MapStateToPropsEx<S, OP, CP>;
|
||||||
|
|
||||||
declare function connect<S, A, OP, SP>(
|
declare export function connectAdvanced<
|
||||||
mapStateToProps: MapStateToProps<S, OP, SP>,
|
Com: React$ComponentType<*>,
|
||||||
mapDispatchToProps: Null,
|
D,
|
||||||
mergeProps: Null,
|
S: Object,
|
||||||
options?: ConnectOptions
|
OP: Object,
|
||||||
): Connector<OP, $Supertype<SP & { dispatch: Dispatch<A> } & OP>>;
|
CP: Object,
|
||||||
|
EFO: Object,
|
||||||
|
ST: { [_: $Keys<Com>]: any },
|
||||||
|
>(
|
||||||
|
selectorFactory: SelectorFactory<Com, D, S, OP, EFO, CP>,
|
||||||
|
connectAdvancedOptions: ?(ConnectAdvancedOptions & EFO),
|
||||||
|
): (component: Com) => React$ComponentType<OP> & $Shape<ST>;
|
||||||
|
|
||||||
declare function connect<A, OP, DP>(
|
declare export default {
|
||||||
mapStateToProps: Null,
|
Provider: typeof Provider,
|
||||||
mapDispatchToProps: MapDispatchToProps<A, OP, DP>,
|
createProvider: typeof createProvider,
|
||||||
mergeProps: Null,
|
connect: typeof connect,
|
||||||
options?: ConnectOptions
|
connectAdvanced: typeof connectAdvanced,
|
||||||
): Connector<OP, $Supertype<DP & OP>>;
|
};
|
||||||
|
|
||||||
declare function connect<S, A, OP, SP, DP>(
|
|
||||||
mapStateToProps: MapStateToProps<S, OP, SP>,
|
|
||||||
mapDispatchToProps: MapDispatchToProps<A, OP, DP>,
|
|
||||||
mergeProps: Null,
|
|
||||||
options?: ConnectOptions
|
|
||||||
): Connector<OP, $Supertype<SP & DP & OP>>;
|
|
||||||
|
|
||||||
declare function connect<S, A, OP, SP, DP, P>(
|
|
||||||
mapStateToProps: MapStateToProps<S, OP, SP>,
|
|
||||||
mapDispatchToProps: Null,
|
|
||||||
mergeProps: MergeProps<SP, DP, OP, P>,
|
|
||||||
options?: ConnectOptions
|
|
||||||
): Connector<OP, P>;
|
|
||||||
|
|
||||||
declare function connect<S, A, OP, SP, DP, P>(
|
|
||||||
mapStateToProps: MapStateToProps<S, OP, SP>,
|
|
||||||
mapDispatchToProps: MapDispatchToProps<A, OP, DP>,
|
|
||||||
mergeProps: MergeProps<SP, DP, OP, P>,
|
|
||||||
options?: ConnectOptions
|
|
||||||
): Connector<OP, P>;
|
|
||||||
}
|
}
|
||||||
|
176
flow-typed/npm/react-router-dom_v5.x.x.js
vendored
Normal file
176
flow-typed/npm/react-router-dom_v5.x.x.js
vendored
Normal file
@ -0,0 +1,176 @@
|
|||||||
|
// flow-typed signature: 9987f80c12a2cad7dfa2b08cc14d2edc
|
||||||
|
// flow-typed version: 2973a15489/react-router-dom_v5.x.x/flow_>=v0.98.x
|
||||||
|
|
||||||
|
declare module "react-router-dom" {
|
||||||
|
declare export var BrowserRouter: React$ComponentType<{|
|
||||||
|
basename?: string,
|
||||||
|
forceRefresh?: boolean,
|
||||||
|
getUserConfirmation?: GetUserConfirmation,
|
||||||
|
keyLength?: number,
|
||||||
|
children?: React$Node
|
||||||
|
|}>
|
||||||
|
|
||||||
|
declare export var HashRouter: React$ComponentType<{|
|
||||||
|
basename?: string,
|
||||||
|
getUserConfirmation?: GetUserConfirmation,
|
||||||
|
hashType?: "slash" | "noslash" | "hashbang",
|
||||||
|
children?: React$Node
|
||||||
|
|}>
|
||||||
|
|
||||||
|
declare export var Link: React$ComponentType<{
|
||||||
|
className?: string,
|
||||||
|
to: string | LocationShape,
|
||||||
|
replace?: boolean,
|
||||||
|
children?: React$Node
|
||||||
|
}>
|
||||||
|
|
||||||
|
declare export var NavLink: React$ComponentType<{
|
||||||
|
to: string | LocationShape,
|
||||||
|
activeClassName?: string,
|
||||||
|
className?: string,
|
||||||
|
activeStyle?: { +[string]: mixed },
|
||||||
|
style?: { +[string]: mixed },
|
||||||
|
isActive?: (match: Match, location: Location) => boolean,
|
||||||
|
children?: React$Node,
|
||||||
|
exact?: boolean,
|
||||||
|
strict?: boolean
|
||||||
|
}>
|
||||||
|
|
||||||
|
// NOTE: Below are duplicated from react-router. If updating these, please
|
||||||
|
// update the react-router and react-router-native types as well.
|
||||||
|
declare export type Location = {
|
||||||
|
pathname: string,
|
||||||
|
search: string,
|
||||||
|
hash: string,
|
||||||
|
state?: any,
|
||||||
|
key?: string
|
||||||
|
};
|
||||||
|
|
||||||
|
declare export type LocationShape = {
|
||||||
|
pathname?: string,
|
||||||
|
search?: string,
|
||||||
|
hash?: string,
|
||||||
|
state?: any
|
||||||
|
};
|
||||||
|
|
||||||
|
declare export type HistoryAction = "PUSH" | "REPLACE" | "POP";
|
||||||
|
|
||||||
|
declare export type RouterHistory = {
|
||||||
|
length: number,
|
||||||
|
location: Location,
|
||||||
|
action: HistoryAction,
|
||||||
|
listen(
|
||||||
|
callback: (location: Location, action: HistoryAction) => void
|
||||||
|
): () => void,
|
||||||
|
push(path: string | LocationShape, state?: any): void,
|
||||||
|
replace(path: string | LocationShape, state?: any): void,
|
||||||
|
go(n: number): void,
|
||||||
|
goBack(): void,
|
||||||
|
goForward(): void,
|
||||||
|
canGo?: (n: number) => boolean,
|
||||||
|
block(
|
||||||
|
callback: string | (location: Location, action: HistoryAction) => ?string
|
||||||
|
): () => void,
|
||||||
|
// createMemoryHistory
|
||||||
|
index?: number,
|
||||||
|
entries?: Array<Location>
|
||||||
|
};
|
||||||
|
|
||||||
|
declare export type Match = {
|
||||||
|
params: { [key: string]: ?string },
|
||||||
|
isExact: boolean,
|
||||||
|
path: string,
|
||||||
|
url: string
|
||||||
|
};
|
||||||
|
|
||||||
|
declare export type ContextRouter = {|
|
||||||
|
history: RouterHistory,
|
||||||
|
location: Location,
|
||||||
|
match: Match,
|
||||||
|
staticContext?: StaticRouterContext
|
||||||
|
|};
|
||||||
|
|
||||||
|
declare type ContextRouterVoid = {
|
||||||
|
history: RouterHistory | void,
|
||||||
|
location: Location | void,
|
||||||
|
match: Match | void,
|
||||||
|
staticContext?: StaticRouterContext | void
|
||||||
|
};
|
||||||
|
|
||||||
|
declare export type GetUserConfirmation = (
|
||||||
|
message: string,
|
||||||
|
callback: (confirmed: boolean) => void
|
||||||
|
) => void;
|
||||||
|
|
||||||
|
declare export type StaticRouterContext = {
|
||||||
|
url?: string
|
||||||
|
};
|
||||||
|
|
||||||
|
declare export var StaticRouter: React$ComponentType<{|
|
||||||
|
basename?: string,
|
||||||
|
location?: string | Location,
|
||||||
|
context: StaticRouterContext,
|
||||||
|
children?: React$Node
|
||||||
|
|}>
|
||||||
|
|
||||||
|
declare export var MemoryRouter: React$ComponentType<{|
|
||||||
|
initialEntries?: Array<LocationShape | string>,
|
||||||
|
initialIndex?: number,
|
||||||
|
getUserConfirmation?: GetUserConfirmation,
|
||||||
|
keyLength?: number,
|
||||||
|
children?: React$Node
|
||||||
|
|}>
|
||||||
|
|
||||||
|
declare export var Router: React$ComponentType<{|
|
||||||
|
history: RouterHistory,
|
||||||
|
children?: React$Node
|
||||||
|
|}>
|
||||||
|
|
||||||
|
declare export var Prompt: React$ComponentType<{|
|
||||||
|
message: string | ((location: Location) => string | boolean),
|
||||||
|
when?: boolean
|
||||||
|
|}>
|
||||||
|
|
||||||
|
declare export var Redirect: React$ComponentType<{|
|
||||||
|
to: string | LocationShape,
|
||||||
|
push?: boolean,
|
||||||
|
from?: string,
|
||||||
|
exact?: boolean,
|
||||||
|
strict?: boolean
|
||||||
|
|}>
|
||||||
|
|
||||||
|
declare export var Route: React$ComponentType<{|
|
||||||
|
component?: React$ComponentType<*>,
|
||||||
|
render?: (router: ContextRouter) => React$Node,
|
||||||
|
children?: React$ComponentType<ContextRouter> | React$Node,
|
||||||
|
path?: string | Array<string>,
|
||||||
|
exact?: boolean,
|
||||||
|
strict?: boolean,
|
||||||
|
location?: LocationShape,
|
||||||
|
sensitive?: boolean
|
||||||
|
|}>
|
||||||
|
|
||||||
|
declare export var Switch: React$ComponentType<{|
|
||||||
|
children?: React$Node,
|
||||||
|
location?: Location
|
||||||
|
|}>
|
||||||
|
|
||||||
|
declare export function withRouter<Props: {}, Component: React$ComponentType<Props>>(
|
||||||
|
WrappedComponent: Component
|
||||||
|
): React$ComponentType<$Diff<React$ElementConfig<Component>, ContextRouterVoid>>;
|
||||||
|
|
||||||
|
declare type MatchPathOptions = {
|
||||||
|
path?: string,
|
||||||
|
exact?: boolean,
|
||||||
|
sensitive?: boolean,
|
||||||
|
strict?: boolean
|
||||||
|
};
|
||||||
|
|
||||||
|
declare export function matchPath(
|
||||||
|
pathname: string,
|
||||||
|
options?: MatchPathOptions | string,
|
||||||
|
parent?: Match
|
||||||
|
): null | Match;
|
||||||
|
|
||||||
|
declare export function generatePath(pattern?: string, params?: { +[string]: mixed }): string;
|
||||||
|
}
|
139
flow-typed/npm/react-router_v4.x.x.js
vendored
139
flow-typed/npm/react-router_v4.x.x.js
vendored
@ -1,139 +0,0 @@
|
|||||||
// flow-typed signature: b45080e7e6a55f1c9092f07c205cd527
|
|
||||||
// flow-typed version: 3e35e41eb5/react-router_v4.x.x/flow_v0.53.x
|
|
||||||
|
|
||||||
// flow-typed signature: b701192ca557cf27adf1b295517299fd
|
|
||||||
// flow-typed version: b43dff3e0e/react-router_v4.x.x/flow_>=v0.53.x
|
|
||||||
import * as React from "react";
|
|
||||||
|
|
||||||
declare module "react-router" {
|
|
||||||
// NOTE: many of these are re-exported by react-router-dom and
|
|
||||||
// react-router-native, so when making changes, please be sure to update those
|
|
||||||
// as well.
|
|
||||||
declare export type Location = {
|
|
||||||
pathname: string,
|
|
||||||
search: string,
|
|
||||||
hash: string,
|
|
||||||
state?: any,
|
|
||||||
key?: string
|
|
||||||
};
|
|
||||||
|
|
||||||
declare export type LocationShape = {
|
|
||||||
pathname?: string,
|
|
||||||
search?: string,
|
|
||||||
hash?: string,
|
|
||||||
state?: any
|
|
||||||
};
|
|
||||||
|
|
||||||
declare export type HistoryAction = "PUSH" | "REPLACE" | "POP";
|
|
||||||
|
|
||||||
declare export type RouterHistory = {
|
|
||||||
length: number,
|
|
||||||
location: Location,
|
|
||||||
action: HistoryAction,
|
|
||||||
listen(
|
|
||||||
callback: (location: Location, action: HistoryAction) => void
|
|
||||||
): () => void,
|
|
||||||
push(path: string | LocationShape, state?: any): void,
|
|
||||||
replace(path: string | LocationShape, state?: any): void,
|
|
||||||
go(n: number): void,
|
|
||||||
goBack(): void,
|
|
||||||
goForward(): void,
|
|
||||||
canGo?: (n: number) => boolean,
|
|
||||||
block(
|
|
||||||
callback: (location: Location, action: HistoryAction) => boolean
|
|
||||||
): void,
|
|
||||||
// createMemoryHistory
|
|
||||||
index?: number,
|
|
||||||
entries?: Array<Location>
|
|
||||||
};
|
|
||||||
|
|
||||||
declare export type Match = {
|
|
||||||
params: { [key: string]: ?string },
|
|
||||||
isExact: boolean,
|
|
||||||
path: string,
|
|
||||||
url: string
|
|
||||||
};
|
|
||||||
|
|
||||||
declare export type ContextRouter = {
|
|
||||||
history: RouterHistory,
|
|
||||||
location: Location,
|
|
||||||
match: Match
|
|
||||||
};
|
|
||||||
|
|
||||||
declare export type GetUserConfirmation = (
|
|
||||||
message: string,
|
|
||||||
callback: (confirmed: boolean) => void
|
|
||||||
) => void;
|
|
||||||
|
|
||||||
declare type StaticRouterContext = {
|
|
||||||
url?: string
|
|
||||||
};
|
|
||||||
|
|
||||||
declare type StaticRouterProps = {
|
|
||||||
basename?: string,
|
|
||||||
location?: string | Location,
|
|
||||||
context: StaticRouterContext,
|
|
||||||
children?: React$Element<*>
|
|
||||||
};
|
|
||||||
declare export class StaticRouter extends React$Component<
|
|
||||||
StaticRouterProps
|
|
||||||
> {}
|
|
||||||
|
|
||||||
declare type MemoryRouterProps = {
|
|
||||||
initialEntries?: Array<LocationShape | string>,
|
|
||||||
initialIndex?: number,
|
|
||||||
getUserConfirmation?: GetUserConfirmation,
|
|
||||||
keyLength?: number,
|
|
||||||
children?: React$Element<*>
|
|
||||||
};
|
|
||||||
declare export class MemoryRouter extends React$Component<
|
|
||||||
MemoryRouterProps
|
|
||||||
> {}
|
|
||||||
|
|
||||||
declare type RouterProps = {
|
|
||||||
history: RouterHistory,
|
|
||||||
children?: React$Element<*>
|
|
||||||
};
|
|
||||||
declare export class Router extends React$Component<RouterProps> {}
|
|
||||||
|
|
||||||
declare type PromptProps = {
|
|
||||||
message: string | ((location: Location) => string | true),
|
|
||||||
when?: boolean
|
|
||||||
};
|
|
||||||
declare export class Prompt extends React$Component<PromptProps> {}
|
|
||||||
|
|
||||||
declare type RedirectProps = {
|
|
||||||
to: string | LocationShape,
|
|
||||||
push?: boolean
|
|
||||||
};
|
|
||||||
declare export class Redirect extends React$Component<RedirectProps> {}
|
|
||||||
|
|
||||||
declare type RouteProps = {
|
|
||||||
component?: React$ComponentType<*>,
|
|
||||||
render?: (router: ContextRouter) => React$Element<*>,
|
|
||||||
children?: (router: ContextRouter) => React$Element<*>,
|
|
||||||
path?: string,
|
|
||||||
exact?: boolean,
|
|
||||||
strict?: boolean
|
|
||||||
};
|
|
||||||
declare export class Route extends React$Component<RouteProps> {}
|
|
||||||
|
|
||||||
declare type SwithcProps = {
|
|
||||||
children?: Array<React$Element<*>>
|
|
||||||
};
|
|
||||||
declare export class Switch extends React$Component<SwithcProps> {}
|
|
||||||
|
|
||||||
declare export function withRouter<P>(
|
|
||||||
Component: React$ComponentType<ContextRouter & P>
|
|
||||||
): React$ComponentType<P>;
|
|
||||||
|
|
||||||
declare type MatchPathOptions = {
|
|
||||||
exact?: boolean,
|
|
||||||
strict?: boolean
|
|
||||||
};
|
|
||||||
declare export function matchPath(
|
|
||||||
pathname: string,
|
|
||||||
path: string,
|
|
||||||
options?: MatchPathOptions
|
|
||||||
): null | Match;
|
|
||||||
}
|
|
109
flow-typed/npm/redux_v3.x.x.js
vendored
109
flow-typed/npm/redux_v3.x.x.js
vendored
@ -1,109 +0,0 @@
|
|||||||
// flow-typed signature: 86993bd000012d3e1ef10d757d16952d
|
|
||||||
// flow-typed version: a165222d28/redux_v3.x.x/flow_>=v0.33.x
|
|
||||||
|
|
||||||
declare module 'redux' {
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
S = State
|
|
||||||
A = Action
|
|
||||||
D = Dispatch
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
declare type DispatchAPI<A> = (action: A) => A;
|
|
||||||
declare type Dispatch<A: { type: $Subtype<string> }> = DispatchAPI<A>;
|
|
||||||
|
|
||||||
declare type MiddlewareAPI<S, A, D = Dispatch<A>> = {
|
|
||||||
dispatch: D;
|
|
||||||
getState(): S;
|
|
||||||
};
|
|
||||||
|
|
||||||
declare type Store<S, A, D = Dispatch<A>> = {
|
|
||||||
// rewrite MiddlewareAPI members in order to get nicer error messages (intersections produce long messages)
|
|
||||||
dispatch: D;
|
|
||||||
getState(): S;
|
|
||||||
subscribe(listener: () => void): () => void;
|
|
||||||
replaceReducer(nextReducer: Reducer<S, A>): void
|
|
||||||
};
|
|
||||||
|
|
||||||
declare type Reducer<S, A> = (state: S, action: A) => S;
|
|
||||||
|
|
||||||
declare type CombinedReducer<S, A> = (state: $Shape<S> & {} | void, action: A) => S;
|
|
||||||
|
|
||||||
declare type Middleware<S, A, D = Dispatch<A>> =
|
|
||||||
(api: MiddlewareAPI<S, A, D>) =>
|
|
||||||
(next: D) => D;
|
|
||||||
|
|
||||||
declare type StoreCreator<S, A, D = Dispatch<A>> = {
|
|
||||||
(reducer: Reducer<S, A>, enhancer?: StoreEnhancer<S, A, D>): Store<S, A, D>;
|
|
||||||
(reducer: Reducer<S, A>, preloadedState: S, enhancer?: StoreEnhancer<S, A, D>): Store<S, A, D>;
|
|
||||||
};
|
|
||||||
|
|
||||||
declare type StoreEnhancer<S, A, D = Dispatch<A>> = (next: StoreCreator<S, A, D>) => StoreCreator<S, A, D>;
|
|
||||||
|
|
||||||
declare function createStore<S, A, D>(reducer: Reducer<S, A>, enhancer?: StoreEnhancer<S, A, D>): Store<S, A, D>;
|
|
||||||
declare function createStore<S, A, D>(reducer: Reducer<S, A>, preloadedState: S, enhancer?: StoreEnhancer<S, A, D>): Store<S, A, D>;
|
|
||||||
|
|
||||||
declare function applyMiddleware<S, A, D>(...middlewares: Array<Middleware<S, A, D>>): StoreEnhancer<S, A, D>;
|
|
||||||
|
|
||||||
declare type ActionCreator<A, B> = (...args: Array<B>) => A;
|
|
||||||
declare type ActionCreators<K, A> = { [key: K]: ActionCreator<A, any> };
|
|
||||||
|
|
||||||
declare function bindActionCreators<A, C: ActionCreator<A, any>, D: DispatchAPI<A>>(actionCreator: C, dispatch: D): C;
|
|
||||||
declare function bindActionCreators<A, K, C: ActionCreators<K, A>, D: DispatchAPI<A>>(actionCreators: C, dispatch: D): C;
|
|
||||||
|
|
||||||
declare function combineReducers<O: Object, A>(reducers: O): CombinedReducer<$ObjMap<O, <S>(r: Reducer<S, any>) => S>, A>;
|
|
||||||
|
|
||||||
declare function compose<A, B>(ab: (a: A) => B): (a: A) => B
|
|
||||||
declare function compose<A, B, C>(
|
|
||||||
bc: (b: B) => C,
|
|
||||||
ab: (a: A) => B
|
|
||||||
): (a: A) => C
|
|
||||||
declare function compose<A, B, C, D>(
|
|
||||||
cd: (c: C) => D,
|
|
||||||
bc: (b: B) => C,
|
|
||||||
ab: (a: A) => B
|
|
||||||
): (a: A) => D
|
|
||||||
declare function compose<A, B, C, D, E>(
|
|
||||||
de: (d: D) => E,
|
|
||||||
cd: (c: C) => D,
|
|
||||||
bc: (b: B) => C,
|
|
||||||
ab: (a: A) => B
|
|
||||||
): (a: A) => E
|
|
||||||
declare function compose<A, B, C, D, E, F>(
|
|
||||||
ef: (e: E) => F,
|
|
||||||
de: (d: D) => E,
|
|
||||||
cd: (c: C) => D,
|
|
||||||
bc: (b: B) => C,
|
|
||||||
ab: (a: A) => B
|
|
||||||
): (a: A) => F
|
|
||||||
declare function compose<A, B, C, D, E, F, G>(
|
|
||||||
fg: (f: F) => G,
|
|
||||||
ef: (e: E) => F,
|
|
||||||
de: (d: D) => E,
|
|
||||||
cd: (c: C) => D,
|
|
||||||
bc: (b: B) => C,
|
|
||||||
ab: (a: A) => B
|
|
||||||
): (a: A) => G
|
|
||||||
declare function compose<A, B, C, D, E, F, G, H>(
|
|
||||||
gh: (g: G) => H,
|
|
||||||
fg: (f: F) => G,
|
|
||||||
ef: (e: E) => F,
|
|
||||||
de: (d: D) => E,
|
|
||||||
cd: (c: C) => D,
|
|
||||||
bc: (b: B) => C,
|
|
||||||
ab: (a: A) => B
|
|
||||||
): (a: A) => H
|
|
||||||
declare function compose<A, B, C, D, E, F, G, H, I>(
|
|
||||||
hi: (h: H) => I,
|
|
||||||
gh: (g: G) => H,
|
|
||||||
fg: (f: F) => G,
|
|
||||||
ef: (e: E) => F,
|
|
||||||
de: (d: D) => E,
|
|
||||||
cd: (c: C) => D,
|
|
||||||
bc: (b: B) => C,
|
|
||||||
ab: (a: A) => B
|
|
||||||
): (a: A) => I
|
|
||||||
|
|
||||||
}
|
|
100
flow-typed/npm/redux_v4.x.x.js
vendored
Normal file
100
flow-typed/npm/redux_v4.x.x.js
vendored
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
// flow-typed signature: a49a6c96fe8a8bb3330cce2028588f4c
|
||||||
|
// flow-typed version: de5b3a01c6/redux_v4.x.x/flow_>=v0.89.x
|
||||||
|
|
||||||
|
declare module 'redux' {
|
||||||
|
/*
|
||||||
|
|
||||||
|
S = State
|
||||||
|
A = Action
|
||||||
|
D = Dispatch
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare export type Action<T> = {
|
||||||
|
type: T
|
||||||
|
}
|
||||||
|
|
||||||
|
declare export type DispatchAPI<A> = (action: A) => A;
|
||||||
|
|
||||||
|
declare export type Dispatch<A: { type: * }> = DispatchAPI<A>;
|
||||||
|
|
||||||
|
declare export type MiddlewareAPI<S, A, D = Dispatch<A>> = {
|
||||||
|
dispatch: D,
|
||||||
|
getState(): S,
|
||||||
|
};
|
||||||
|
|
||||||
|
declare export type Store<S, A, D = Dispatch<A>> = {
|
||||||
|
// rewrite MiddlewareAPI members in order to get nicer error messages (intersections produce long messages)
|
||||||
|
dispatch: D,
|
||||||
|
getState(): S,
|
||||||
|
subscribe(listener: () => void): () => void,
|
||||||
|
replaceReducer(nextReducer: Reducer<S, A>): void,
|
||||||
|
};
|
||||||
|
|
||||||
|
declare export type Reducer<S, A> = (state: S | void, action: A) => S;
|
||||||
|
|
||||||
|
declare export type CombinedReducer<S, A> = (
|
||||||
|
state: ($Shape<S> & {}) | void,
|
||||||
|
action: A
|
||||||
|
) => S;
|
||||||
|
|
||||||
|
declare export type Middleware<S, A, D = Dispatch<A>> = (
|
||||||
|
api: MiddlewareAPI<S, A, D>
|
||||||
|
) => (next: D) => D;
|
||||||
|
|
||||||
|
declare export type StoreCreator<S, A, D = Dispatch<A>> = {
|
||||||
|
(reducer: Reducer<S, A>, enhancer?: StoreEnhancer<S, A, D>): Store<S, A, D>,
|
||||||
|
(
|
||||||
|
reducer: Reducer<S, A>,
|
||||||
|
preloadedState: S,
|
||||||
|
enhancer?: StoreEnhancer<S, A, D>
|
||||||
|
): Store<S, A, D>,
|
||||||
|
};
|
||||||
|
|
||||||
|
declare export type StoreEnhancer<S, A, D = Dispatch<A>> = (
|
||||||
|
next: StoreCreator<S, A, D>
|
||||||
|
) => StoreCreator<S, A, D>;
|
||||||
|
|
||||||
|
declare export function createStore<S, A, D>(
|
||||||
|
reducer: Reducer<S, A>,
|
||||||
|
enhancer?: StoreEnhancer<S, A, D>
|
||||||
|
): Store<S, A, D>;
|
||||||
|
declare export function createStore<S, A, D>(
|
||||||
|
reducer: Reducer<S, A>,
|
||||||
|
preloadedState?: S,
|
||||||
|
enhancer?: StoreEnhancer<S, A, D>
|
||||||
|
): Store<S, A, D>;
|
||||||
|
|
||||||
|
declare export function applyMiddleware<S, A, D>(
|
||||||
|
...middlewares: Array<Middleware<S, A, D>>
|
||||||
|
): StoreEnhancer<S, A, D>;
|
||||||
|
|
||||||
|
declare export type ActionCreator<A, B> = (...args: Array<B>) => A;
|
||||||
|
declare export type ActionCreators<K, A> = {
|
||||||
|
[key: K]: ActionCreator<A, any>,
|
||||||
|
};
|
||||||
|
|
||||||
|
declare export function bindActionCreators<
|
||||||
|
A,
|
||||||
|
C: ActionCreator<A, any>,
|
||||||
|
D: DispatchAPI<A>
|
||||||
|
>(
|
||||||
|
actionCreator: C,
|
||||||
|
dispatch: D
|
||||||
|
): C;
|
||||||
|
declare export function bindActionCreators<
|
||||||
|
A,
|
||||||
|
K,
|
||||||
|
C: ActionCreators<K, A>,
|
||||||
|
D: DispatchAPI<A>
|
||||||
|
>(
|
||||||
|
actionCreators: C,
|
||||||
|
dispatch: D
|
||||||
|
): C;
|
||||||
|
|
||||||
|
declare export function combineReducers<O: {}, A>(
|
||||||
|
reducers: O
|
||||||
|
): CombinedReducer<$ObjMap<O, <S>(r: Reducer<S, any>) => S>, A>;
|
||||||
|
|
||||||
|
declare export var compose: $Compose;
|
||||||
|
}
|
29
package.json
29
package.json
@ -21,6 +21,7 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "yarn run clean && yarn run build:dll && NODE_PATH=./src webpack-dev-server --progress --colors",
|
"start": "yarn run clean && yarn run build:dll && NODE_PATH=./src webpack-dev-server --progress --colors",
|
||||||
"clean": "rm -rf dist/",
|
"clean": "rm -rf dist/",
|
||||||
|
"e2e": "yarn --cwd ./tests-e2e test",
|
||||||
"test": "yarn run build:dll && NODE_PATH=./src karma start ./karma.conf.js",
|
"test": "yarn run build:dll && NODE_PATH=./src karma start ./karma.conf.js",
|
||||||
"lint": "eslint ./src",
|
"lint": "eslint ./src",
|
||||||
"flow": "flow",
|
"flow": "flow",
|
||||||
@ -39,9 +40,7 @@
|
|||||||
"copy-to-clipboard": "^3.0.8",
|
"copy-to-clipboard": "^3.0.8",
|
||||||
"debounce": "^1.0.0",
|
"debounce": "^1.0.0",
|
||||||
"flag-icon-css": "^2.8.0",
|
"flag-icon-css": "^2.8.0",
|
||||||
"intl": "^1.2.2",
|
"intl": "^1.2.5",
|
||||||
"intl-format-cache": "^2.0.4",
|
|
||||||
"intl-messageformat": "^2.1.0",
|
|
||||||
"promise.prototype.finally": "3.1.0",
|
"promise.prototype.finally": "3.1.0",
|
||||||
"prop-types": "^15.6.2",
|
"prop-types": "^15.6.2",
|
||||||
"raf": "^3.4.1",
|
"raf": "^3.4.1",
|
||||||
@ -51,14 +50,14 @@
|
|||||||
"react-helmet": "^5.0.0",
|
"react-helmet": "^5.0.0",
|
||||||
"react-intl": "^2.7.2",
|
"react-intl": "^2.7.2",
|
||||||
"react-motion": "^0.5.0",
|
"react-motion": "^0.5.0",
|
||||||
"react-redux": "^5.0.6",
|
"react-redux": "^7.1.0",
|
||||||
"react-router-dom": "^4.3.1",
|
"react-router-dom": "^5.0.1",
|
||||||
"react-textarea-autosize": "^6.0.0",
|
"react-textarea-autosize": "^6.0.0",
|
||||||
"react-transition-group": "^1.1.3",
|
"react-transition-group": "^4.2.0",
|
||||||
"redux": "^3.0.4",
|
"redux": "^4.0.1",
|
||||||
"redux-localstorage": "^0.4.1",
|
"redux-localstorage": "^0.4.1",
|
||||||
"redux-thunk": "^2.0.0",
|
"redux-thunk": "^2.0.0",
|
||||||
"url-search-params-polyfill": "^5.0.0",
|
"url-search-params-polyfill": "^6.0.0",
|
||||||
"webfontloader": "^1.6.26",
|
"webfontloader": "^1.6.26",
|
||||||
"whatwg-fetch": "^3.0.0"
|
"whatwg-fetch": "^3.0.0"
|
||||||
},
|
},
|
||||||
@ -90,22 +89,22 @@
|
|||||||
"exports-loader": "^0.6.3",
|
"exports-loader": "^0.6.3",
|
||||||
"extract-text-webpack-plugin": "^1.0.0",
|
"extract-text-webpack-plugin": "^1.0.0",
|
||||||
"file-loader": "^0.11.0",
|
"file-loader": "^0.11.0",
|
||||||
"flow-bin": "~0.80.0",
|
"flow-bin": "~0.102.0",
|
||||||
"fontgen-loader": "^0.2.1",
|
"fontgen-loader": "^0.2.1",
|
||||||
"html-loader": "^0.4.3",
|
"html-loader": "^0.4.3",
|
||||||
"html-webpack-plugin": "^2.0.0",
|
"html-webpack-plugin": "^2.0.0",
|
||||||
"imports-loader": "^0.7.0",
|
"imports-loader": "^0.7.0",
|
||||||
"jsdom": "^9.8.3",
|
"jsdom": "^15.1.1",
|
||||||
"json-loader": "^0.5.4",
|
"json-loader": "^0.5.4",
|
||||||
"karma": "^1.1.0",
|
"karma": "^4.1.0",
|
||||||
"karma-jsdom-launcher": "^6.0.0",
|
"karma-jsdom-launcher": "^7.1.1",
|
||||||
"karma-mocha": "^1.0.0",
|
"karma-mocha": "^1.0.0",
|
||||||
"karma-nyan-reporter": "^0.2.3",
|
"karma-nyan-reporter": "^0.2.3",
|
||||||
"karma-sinon": "^1.0.4",
|
"karma-sinon": "^1.0.4",
|
||||||
"karma-sourcemap-loader": "*",
|
"karma-sourcemap-loader": "*",
|
||||||
"karma-webpack": "^2.0.0",
|
"karma-webpack": "^2.0.0",
|
||||||
"loader-utils": "^1.0.0",
|
"loader-utils": "^1.0.0",
|
||||||
"mocha": "^3.0.2",
|
"mocha": "^6.1.4",
|
||||||
"node-sass": "^4.7.2",
|
"node-sass": "^4.7.2",
|
||||||
"postcss-import": "^9.0.0",
|
"postcss-import": "^9.0.0",
|
||||||
"postcss-loader": "^1.2.0",
|
"postcss-loader": "^1.2.0",
|
||||||
@ -115,10 +114,10 @@
|
|||||||
"react-test-renderer": "^16.7.0",
|
"react-test-renderer": "^16.7.0",
|
||||||
"sass-loader": "^4.0.0",
|
"sass-loader": "^4.0.0",
|
||||||
"scripts": "file:./scripts",
|
"scripts": "file:./scripts",
|
||||||
"sinon": "^3.2.1",
|
"sinon": "^7.3.2",
|
||||||
"sitemap-webpack-plugin": "^0.5.1",
|
"sitemap-webpack-plugin": "^0.5.1",
|
||||||
"style-loader": "^0.18.0",
|
"style-loader": "^0.18.0",
|
||||||
"unexpected": "^10.33.2",
|
"unexpected": "^11.6.1",
|
||||||
"unexpected-sinon": "^10.5.1",
|
"unexpected-sinon": "^10.5.1",
|
||||||
"url-loader": "^0.5.7",
|
"url-loader": "^0.5.7",
|
||||||
"webpack": "^1.12.9",
|
"webpack": "^1.12.9",
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import expect from 'unexpected';
|
import expect from 'test/unexpected';
|
||||||
import sinon from 'sinon';
|
import sinon from 'sinon';
|
||||||
|
|
||||||
import { browserHistory } from 'services/history';
|
import { browserHistory } from 'services/history';
|
||||||
@ -445,8 +445,9 @@ describe('components/accounts/actions', () => {
|
|||||||
|
|
||||||
return logoutStrangers()(dispatch, getState)
|
return logoutStrangers()(dispatch, getState)
|
||||||
.then(() =>
|
.then(() =>
|
||||||
expect(dispatch, 'was always called with',
|
expect(dispatch, 'not to have calls satisfying',
|
||||||
expect.it('not to satisfy', activate(account)))
|
[activate(account)]
|
||||||
|
)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -511,8 +512,8 @@ describe('components/accounts/actions', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should not log out', () =>
|
it('should not log out', () =>
|
||||||
expect(dispatch, 'was always called with',
|
expect(dispatch, 'not to have calls satisfying',
|
||||||
expect.it('not to equal', {payload: foreignAccount})
|
[{payload: foreignAccount}]
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import expect from 'unexpected';
|
import expect from 'test/unexpected';
|
||||||
|
|
||||||
import accounts from 'components/accounts/reducer';
|
import accounts from 'components/accounts/reducer';
|
||||||
import {
|
import {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// @flow
|
// @flow
|
||||||
import type { User } from 'components/user';
|
import type { User } from 'components/user';
|
||||||
import type { AccountsState } from 'components/accounts';
|
import type { AccountsState } from 'components/accounts';
|
||||||
import type { Node, Element } from 'react';
|
import type { Element } from 'react';
|
||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
@ -24,6 +24,8 @@ const opacitySpringConfig = {stiffness: 300, damping: 20};
|
|||||||
const transformSpringConfig = {stiffness: 500, damping: 50, precision: 0.5};
|
const transformSpringConfig = {stiffness: 500, damping: 50, precision: 0.5};
|
||||||
const changeContextSpringConfig = {stiffness: 500, damping: 20, precision: 0.5};
|
const changeContextSpringConfig = {stiffness: 500, damping: 20, precision: 0.5};
|
||||||
|
|
||||||
|
type PanelId = string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Definition of relation between contexts and panels
|
* Definition of relation between contexts and panels
|
||||||
*
|
*
|
||||||
@ -35,7 +37,7 @@ const changeContextSpringConfig = {stiffness: 500, damping: 20, precision: 0.5};
|
|||||||
* - Panel index defines the direction of X transition of both panels
|
* - Panel index defines the direction of X transition of both panels
|
||||||
* (e.g. the panel with lower index will slide from left side, and with greater from right side)
|
* (e.g. the panel with lower index will slide from left side, and with greater from right side)
|
||||||
*/
|
*/
|
||||||
const contexts = [
|
const contexts: Array<PanelId[]> = [
|
||||||
['login', 'password', 'forgotPassword', 'mfa', 'recoverPassword'],
|
['login', 'password', 'forgotPassword', 'mfa', 'recoverPassword'],
|
||||||
['register', 'activation', 'resendActivation'],
|
['register', 'activation', 'resendActivation'],
|
||||||
['acceptRules'],
|
['acceptRules'],
|
||||||
@ -71,18 +73,27 @@ type AnimationProps = {|
|
|||||||
|};
|
|};
|
||||||
|
|
||||||
type AnimationContext = {
|
type AnimationContext = {
|
||||||
key: string,
|
key: PanelId,
|
||||||
style: AnimationProps,
|
style: AnimationProps,
|
||||||
data: {
|
data: {
|
||||||
Title: Node,
|
Title: Element<any>,
|
||||||
Body: Element<any>,
|
Body: Element<any>,
|
||||||
Footer: Node,
|
Footer: Element<any>,
|
||||||
Links: Node,
|
Links: Element<any>,
|
||||||
hasBackButton: bool,
|
hasBackButton: bool,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
type OwnProps = {|
|
||||||
|
Title: Element<any>,
|
||||||
|
Body: Element<any>,
|
||||||
|
Footer: Element<any>,
|
||||||
|
Links: Element<any>,
|
||||||
|
children?: Element<any>
|
||||||
|
|};
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
|
...OwnProps,
|
||||||
// context props
|
// context props
|
||||||
auth: {
|
auth: {
|
||||||
error: string | {
|
error: string | {
|
||||||
@ -98,20 +109,12 @@ type Props = {
|
|||||||
clearErrors: () => void,
|
clearErrors: () => void,
|
||||||
resolve: () => void,
|
resolve: () => void,
|
||||||
reject: () => void,
|
reject: () => void,
|
||||||
|
|
||||||
|
|
||||||
// local props
|
|
||||||
Title: Node,
|
|
||||||
Body: typeof Component,
|
|
||||||
Footer: Node,
|
|
||||||
Links: Node,
|
|
||||||
children: Node
|
|
||||||
};
|
};
|
||||||
|
|
||||||
type State = {
|
type State = {
|
||||||
contextHeight: number,
|
contextHeight: number,
|
||||||
panelId: string | void,
|
panelId: PanelId | void,
|
||||||
prevPanelId: string | void,
|
prevPanelId: PanelId | void,
|
||||||
isHeightDirty: bool,
|
isHeightDirty: bool,
|
||||||
forceHeight: 1 | 0,
|
forceHeight: 1 | 0,
|
||||||
direction: 'X' | 'Y',
|
direction: 'X' | 'Y',
|
||||||
@ -187,7 +190,7 @@ class PanelTransition extends Component<Props, State> {
|
|||||||
return {
|
return {
|
||||||
auth: this.props.auth,
|
auth: this.props.auth,
|
||||||
user: this.props.user,
|
user: this.props.user,
|
||||||
requestRedraw: () =>
|
requestRedraw: (): Promise<void> =>
|
||||||
new Promise((resolve) =>
|
new Promise((resolve) =>
|
||||||
this.setState(
|
this.setState(
|
||||||
{isHeightDirty: true},
|
{isHeightDirty: true},
|
||||||
@ -207,9 +210,9 @@ class PanelTransition extends Component<Props, State> {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillReceiveProps(nextProps) {
|
componentWillReceiveProps(nextProps: Props) {
|
||||||
const nextPanel = nextProps.Body && (nextProps.Body: any).type.panelId;
|
const nextPanel: PanelId = nextProps.Body && (nextProps.Body: any).type.panelId;
|
||||||
const prevPanel = this.props.Body && (this.props.Body: any).type.panelId;
|
const prevPanel: PanelId = this.props.Body && (this.props.Body: any).type.panelId;
|
||||||
|
|
||||||
if (nextPanel !== prevPanel) {
|
if (nextPanel !== prevPanel) {
|
||||||
const direction = this.getDirection(nextPanel, prevPanel);
|
const direction = this.getDirection(nextPanel, prevPanel);
|
||||||
@ -250,7 +253,7 @@ class PanelTransition extends Component<Props, State> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const {panelId, hasGoBack}: {
|
const {panelId, hasGoBack}: {
|
||||||
panelId: string,
|
panelId: PanelId,
|
||||||
hasGoBack: bool,
|
hasGoBack: bool,
|
||||||
} = (Body: any).type;
|
} = (Body: any).type;
|
||||||
|
|
||||||
@ -336,10 +339,10 @@ class PanelTransition extends Component<Props, State> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
onFormInvalid = (errors) => this.props.setErrors(errors);
|
onFormInvalid = (errors: { [key: string]: ValidationError }) => this.props.setErrors(errors);
|
||||||
|
|
||||||
willEnter = (config) => this.getTransitionStyles(config);
|
willEnter = (config: AnimationContext) => this.getTransitionStyles(config);
|
||||||
willLeave = (config) => this.getTransitionStyles(config, {isLeave: true});
|
willLeave = (config: AnimationContext) => this.getTransitionStyles(config, {isLeave: true});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {object} config
|
* @param {object} config
|
||||||
@ -349,7 +352,7 @@ class PanelTransition extends Component<Props, State> {
|
|||||||
*
|
*
|
||||||
* @return {object}
|
* @return {object}
|
||||||
*/
|
*/
|
||||||
getTransitionStyles({key}, options = {}): {|
|
getTransitionStyles({key}: AnimationContext, options: { isLeave?: bool } = {}): {|
|
||||||
transformSpring: number,
|
transformSpring: number,
|
||||||
opacitySpring: number,
|
opacitySpring: number,
|
||||||
|} {
|
|} {
|
||||||
@ -380,7 +383,7 @@ class PanelTransition extends Component<Props, State> {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
getDirection(next, prev): 'X' | 'Y' {
|
getDirection(next: PanelId, prev: PanelId): 'X' | 'Y' {
|
||||||
const context = contexts.find((context) => context.includes(prev));
|
const context = contexts.find((context) => context.includes(prev));
|
||||||
|
|
||||||
if (!context) {
|
if (!context) {
|
||||||
@ -390,7 +393,7 @@ class PanelTransition extends Component<Props, State> {
|
|||||||
return context.includes(next) ? 'X' : 'Y';
|
return context.includes(next) ? 'X' : 'Y';
|
||||||
}
|
}
|
||||||
|
|
||||||
onUpdateHeight = (height, key) => {
|
onUpdateHeight = (height: number, key: PanelId) => {
|
||||||
const heightKey = `formHeight${key}`;
|
const heightKey = `formHeight${key}`;
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
@ -398,13 +401,13 @@ class PanelTransition extends Component<Props, State> {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
onUpdateContextHeight = (height) => {
|
onUpdateContextHeight = (height: number) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
contextHeight: height
|
contextHeight: height
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
onGoBack = (event) => {
|
onGoBack = (event: SyntheticEvent<HTMLElement>) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
authFlow.goBack();
|
authFlow.goBack();
|
||||||
@ -415,7 +418,7 @@ class PanelTransition extends Component<Props, State> {
|
|||||||
*
|
*
|
||||||
* @param {number} length number of panels transitioned
|
* @param {number} length number of panels transitioned
|
||||||
*/
|
*/
|
||||||
tryToAutoFocus(length) {
|
tryToAutoFocus(length: number) {
|
||||||
if (!this.body) {
|
if (!this.body) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -588,7 +591,7 @@ class PanelTransition extends Component<Props, State> {
|
|||||||
*
|
*
|
||||||
* @return {object}
|
* @return {object}
|
||||||
*/
|
*/
|
||||||
translate(value, direction = 'X', unit = '%') {
|
translate(value: number, direction: 'X' | 'Y' = 'X', unit: '%' | 'px' = '%') {
|
||||||
return {
|
return {
|
||||||
WebkitTransform: `translate${direction}(${value}${unit})`,
|
WebkitTransform: `translate${direction}(${value}${unit})`,
|
||||||
transform: `translate${direction}(${value}${unit})`
|
transform: `translate${direction}(${value}${unit})`
|
||||||
@ -596,7 +599,7 @@ class PanelTransition extends Component<Props, State> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default connect((state) => {
|
export default connect<Props, OwnProps, _, _, _, _>((state) => {
|
||||||
const login = getLogin(state);
|
const login = getLogin(state);
|
||||||
let user = {
|
let user = {
|
||||||
...state.user
|
...state.user
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// @flow
|
// @flow
|
||||||
import type { OauthData } from 'services/api/oauth';
|
import type { OauthData, Client, Scope } from 'services/api/oauth';
|
||||||
import type { OAuthResponse } from 'services/api/authentication';
|
import type { OAuthResponse } from 'services/api/authentication';
|
||||||
import { browserHistory } from 'services/history';
|
import { browserHistory } from 'services/history';
|
||||||
import logger from 'services/logger';
|
import logger from 'services/logger';
|
||||||
@ -19,8 +19,14 @@ import signup from 'services/api/signup';
|
|||||||
import dispatchBsod from 'components/ui/bsod/dispatchBsod';
|
import dispatchBsod from 'components/ui/bsod/dispatchBsod';
|
||||||
import { create as createPopup } from 'components/ui/popup/actions';
|
import { create as createPopup } from 'components/ui/popup/actions';
|
||||||
import ContactForm from 'components/contact/ContactForm';
|
import ContactForm from 'components/contact/ContactForm';
|
||||||
|
|
||||||
import { getCredentials } from './reducer';
|
import { getCredentials } from './reducer';
|
||||||
|
|
||||||
|
type ValidationError = string | {
|
||||||
|
type: string,
|
||||||
|
payload: { [key: string]: any },
|
||||||
|
};
|
||||||
|
|
||||||
export { updateUser } from 'components/user/actions';
|
export { updateUser } from 'components/user/actions';
|
||||||
export {
|
export {
|
||||||
authenticate,
|
authenticate,
|
||||||
@ -212,7 +218,7 @@ export function resendActivation({
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function contactUs() {
|
export function contactUs() {
|
||||||
return createPopup(ContactForm);
|
return createPopup({ Popup: ContactForm });
|
||||||
}
|
}
|
||||||
|
|
||||||
export const SET_CREDENTIALS = 'auth:setCredentials';
|
export const SET_CREDENTIALS = 'auth:setCredentials';
|
||||||
@ -283,7 +289,7 @@ export function setAccountSwitcher(isOn: bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const ERROR = 'auth:error';
|
export const ERROR = 'auth:error';
|
||||||
export function setErrors(errors: ?{[key: string]: string}) {
|
export function setErrors(errors: ?{[key: string]: ValidationError}) {
|
||||||
return {
|
return {
|
||||||
type: ERROR,
|
type: ERROR,
|
||||||
payload: errors,
|
payload: errors,
|
||||||
@ -413,11 +419,7 @@ export function setClient({
|
|||||||
id,
|
id,
|
||||||
name,
|
name,
|
||||||
description
|
description
|
||||||
}: {
|
}: Client) {
|
||||||
id: string,
|
|
||||||
name: string,
|
|
||||||
description: string
|
|
||||||
}) {
|
|
||||||
return {
|
return {
|
||||||
type: SET_CLIENT,
|
type: SET_CLIENT,
|
||||||
payload: {id, name, description}
|
payload: {id, name, description}
|
||||||
@ -502,7 +504,7 @@ export function requirePermissionsAccept() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const SET_SCOPES = 'set_scopes';
|
export const SET_SCOPES = 'set_scopes';
|
||||||
export function setScopes(scopes: Array<string>) {
|
export function setScopes(scopes: Scope[]) {
|
||||||
if (!(scopes instanceof Array)) {
|
if (!(scopes instanceof Array)) {
|
||||||
throw new Error('Scopes must be array');
|
throw new Error('Scopes must be array');
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import sinon from 'sinon';
|
import sinon from 'sinon';
|
||||||
import expect from 'unexpected';
|
import expect from 'test/unexpected';
|
||||||
|
|
||||||
import request from 'services/request';
|
import request from 'services/request';
|
||||||
|
|
||||||
|
@ -19,10 +19,10 @@ type Credentials = {
|
|||||||
rememberMe?: bool,
|
rememberMe?: bool,
|
||||||
returnUrl?: string,
|
returnUrl?: string,
|
||||||
isRelogin?: bool,
|
isRelogin?: bool,
|
||||||
isTotpRequired?: bool,
|
isTotpRequired?: bool
|
||||||
};
|
};
|
||||||
|
|
||||||
export default combineReducers({
|
export default combineReducers<_, { action: string, payload?: mixed }>({
|
||||||
credentials,
|
credentials,
|
||||||
error,
|
error,
|
||||||
isLoading,
|
isLoading,
|
||||||
@ -32,10 +32,7 @@ export default combineReducers({
|
|||||||
scopes
|
scopes
|
||||||
});
|
});
|
||||||
|
|
||||||
function error(
|
function error(state = null, { type, payload = null, error = false }) {
|
||||||
state = null,
|
|
||||||
{type, payload = null, error = false}
|
|
||||||
) {
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case ERROR:
|
case ERROR:
|
||||||
if (!error) {
|
if (!error) {
|
||||||
@ -51,15 +48,16 @@ function error(
|
|||||||
|
|
||||||
function credentials(
|
function credentials(
|
||||||
state = {},
|
state = {},
|
||||||
{type, payload}: {
|
{
|
||||||
|
type,
|
||||||
|
payload
|
||||||
|
}: {
|
||||||
type: string,
|
type: string,
|
||||||
payload: ?Credentials
|
payload: ?Credentials
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
if (type === SET_CREDENTIALS) {
|
if (type === SET_CREDENTIALS) {
|
||||||
if (payload
|
if (payload && typeof payload === 'object') {
|
||||||
&& typeof payload === 'object'
|
|
||||||
) {
|
|
||||||
return {
|
return {
|
||||||
...payload
|
...payload
|
||||||
};
|
};
|
||||||
@ -71,10 +69,7 @@ function credentials(
|
|||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isSwitcherEnabled(
|
function isSwitcherEnabled(state = true, { type, payload = false }) {
|
||||||
state = true,
|
|
||||||
{type, payload = false}
|
|
||||||
) {
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case SET_SWITCHER:
|
case SET_SWITCHER:
|
||||||
if (typeof payload !== 'boolean') {
|
if (typeof payload !== 'boolean') {
|
||||||
@ -88,10 +83,7 @@ function isSwitcherEnabled(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function isLoading(
|
function isLoading(state = false, { type, payload = null }) {
|
||||||
state = false,
|
|
||||||
{type, payload = null}
|
|
||||||
) {
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case SET_LOADING_STATE:
|
case SET_LOADING_STATE:
|
||||||
return !!payload;
|
return !!payload;
|
||||||
@ -101,10 +93,7 @@ function isLoading(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function client(
|
function client(state = null, { type, payload = {} }) {
|
||||||
state = null,
|
|
||||||
{type, payload = {}}
|
|
||||||
) {
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case SET_CLIENT:
|
case SET_CLIENT:
|
||||||
return {
|
return {
|
||||||
@ -118,10 +107,7 @@ function client(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function oauth(
|
function oauth(state = null, { type, payload = {} }) {
|
||||||
state = null,
|
|
||||||
{type, payload = {}}
|
|
||||||
) {
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case SET_OAUTH:
|
case SET_OAUTH:
|
||||||
return {
|
return {
|
||||||
@ -153,10 +139,7 @@ function oauth(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function scopes(
|
function scopes(state = [], { type, payload = [] }) {
|
||||||
state = [],
|
|
||||||
{type, payload = []}
|
|
||||||
) {
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case SET_SCOPES:
|
case SET_SCOPES:
|
||||||
return payload;
|
return payload;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import expect from 'unexpected';
|
import expect from 'test/unexpected';
|
||||||
|
|
||||||
import auth from 'components/auth/reducer';
|
import auth from 'components/auth/reducer';
|
||||||
import {
|
import {
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
|
import { connect } from 'react-redux';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { FormattedMessage as Message } from 'react-intl';
|
import { FormattedMessage as Message } from 'react-intl';
|
||||||
|
|
||||||
import { Input, TextArea, Button, Form, FormModel, Dropdown } from 'components/ui/form';
|
import { Input, TextArea, Button, Form, FormModel, Dropdown } from 'components/ui/form';
|
||||||
import feedback from 'services/api/feedback';
|
import feedback from 'services/api/feedback';
|
||||||
import icons from 'components/ui/icons.scss';
|
import icons from 'components/ui/icons.scss';
|
||||||
@ -174,8 +173,6 @@ export class ContactForm extends Component {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
import { connect } from 'react-redux';
|
|
||||||
|
|
||||||
export default connect((state) => ({
|
export default connect((state) => ({
|
||||||
user: state.user
|
user: state.user
|
||||||
}))(ContactForm);
|
}))(ContactForm);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import expect from 'unexpected';
|
import expect from 'test/unexpected';
|
||||||
import sinon from 'sinon';
|
import sinon from 'sinon';
|
||||||
import { shallow, mount } from 'enzyme';
|
import { shallow, mount } from 'enzyme';
|
||||||
|
|
||||||
|
@ -1,16 +1,21 @@
|
|||||||
// @flow
|
// @flow
|
||||||
|
import type { ElementConfig } from 'react';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { create as createPopup } from 'components/ui/popup/actions';
|
import { create as createPopup } from 'components/ui/popup/actions';
|
||||||
import ContactForm from './ContactForm';
|
import ContactForm from './ContactForm';
|
||||||
|
|
||||||
|
type OwnProps = $Exact<ElementConfig<'a'>>;
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
...OwnProps,
|
||||||
|
createContactPopup: () => void,
|
||||||
|
};
|
||||||
|
|
||||||
function ContactLink({
|
function ContactLink({
|
||||||
createContactPopup,
|
createContactPopup,
|
||||||
...props
|
...props
|
||||||
}: {
|
}: Props) {
|
||||||
createContactPopup: () => void,
|
|
||||||
props: Object
|
|
||||||
}) {
|
|
||||||
return (
|
return (
|
||||||
<a
|
<a
|
||||||
href="#"
|
href="#"
|
||||||
@ -25,9 +30,9 @@ function ContactLink({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default connect(
|
export default connect<Props, OwnProps, _, _, _, _>(
|
||||||
null,
|
null,
|
||||||
{
|
{
|
||||||
createContactPopup: () => createPopup(ContactForm)
|
createContactPopup: () => createPopup({ Popup: ContactForm })
|
||||||
}
|
}
|
||||||
)(ContactLink);
|
)(ContactLink);
|
||||||
|
@ -97,7 +97,7 @@ export default class ApplicationForm extends Component<{
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{FormComponent && (
|
{!!FormComponent && (
|
||||||
<Button
|
<Button
|
||||||
color={COLOR_GREEN}
|
color={COLOR_GREEN}
|
||||||
block
|
block
|
||||||
|
@ -63,7 +63,7 @@ export default class ApplicationItem extends Component<
|
|||||||
[styles.appExpanded]: expand
|
[styles.appExpanded]: expand
|
||||||
})}
|
})}
|
||||||
data-e2e="appItem"
|
data-e2e="appItem"
|
||||||
data-e2e-app={app.clientId}
|
data-e2e-app-name={app.name}
|
||||||
>
|
>
|
||||||
<div className={styles.appItemTile} onClick={this.onTileToggle}>
|
<div className={styles.appItemTile} onClick={this.onTileToggle}>
|
||||||
<div className={styles.appTileTitle}>
|
<div className={styles.appTileTitle}>
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
// @flow
|
// @flow
|
||||||
import type { OauthAppResponse } from 'services/api/oauth';
|
import type { OauthAppResponse } from 'services/api/oauth';
|
||||||
|
|
||||||
import type { Action } from './actions';
|
import type { Action } from './actions';
|
||||||
|
|
||||||
export type Apps = {
|
export type Apps = {|
|
||||||
+available: Array<OauthAppResponse>,
|
+available: OauthAppResponse[],
|
||||||
};
|
|};
|
||||||
|
|
||||||
const defaults: Apps = {
|
const defaults: Apps = {
|
||||||
available: [],
|
available: [],
|
||||||
@ -13,7 +14,7 @@ const defaults: Apps = {
|
|||||||
export default function apps(
|
export default function apps(
|
||||||
state: Apps = defaults,
|
state: Apps = defaults,
|
||||||
action: Action
|
action: Action
|
||||||
) {
|
): Apps {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case 'apps:setAvailable':
|
case 'apps:setAvailable':
|
||||||
return {
|
return {
|
||||||
@ -23,7 +24,7 @@ export default function apps(
|
|||||||
|
|
||||||
case 'apps:addApp': {
|
case 'apps:addApp': {
|
||||||
const { payload } = action;
|
const { payload } = action;
|
||||||
const available: Array<OauthAppResponse> = [...state.available];
|
const available = [...state.available];
|
||||||
let index = available.findIndex((app) => app.clientId === payload.clientId);
|
let index = available.findIndex((app) => app.clientId === payload.clientId);
|
||||||
|
|
||||||
if (index === -1) {
|
if (index === -1) {
|
||||||
|
@ -10,10 +10,16 @@ import { ContactLink } from 'components/contact';
|
|||||||
import styles from './footerMenu.scss';
|
import styles from './footerMenu.scss';
|
||||||
import messages from './footerMenu.intl.json';
|
import messages from './footerMenu.intl.json';
|
||||||
|
|
||||||
class FooterMenu extends Component<{
|
type OwnProps = {|
|
||||||
createContactPopup: () => void,
|
createContactPopup: () => void,
|
||||||
|
|};
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
...OwnProps,
|
||||||
createLanguageSwitcherPopup: () => void,
|
createLanguageSwitcherPopup: () => void,
|
||||||
}> {
|
};
|
||||||
|
|
||||||
|
class FooterMenu extends Component<Props> {
|
||||||
static displayName = 'FooterMenu';
|
static displayName = 'FooterMenu';
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
@ -50,6 +56,6 @@ class FooterMenu extends Component<{
|
|||||||
|
|
||||||
// mark this component, as not pure, because it is stateless,
|
// mark this component, as not pure, because it is stateless,
|
||||||
// but should be re-rendered, if current lang was changed
|
// but should be re-rendered, if current lang was changed
|
||||||
export default connect(null, {
|
export default connect<Props, OwnProps, _, _, _, _>(null, {
|
||||||
createLanguageSwitcherPopup: () => createPopup(LanguageSwitcher),
|
createLanguageSwitcherPopup: () => createPopup({ Popup: LanguageSwitcher }),
|
||||||
}, null, {pure: false})(FooterMenu);
|
}, null, {pure: false})(FooterMenu);
|
||||||
|
@ -2,11 +2,13 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import { FormattedMessage as Message, intlShape } from 'react-intl';
|
import { FormattedMessage as Message, intlShape } from 'react-intl';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
import { changeLang } from 'components/user/actions';
|
||||||
import LANGS from 'i18n/index.json';
|
import LANGS from 'i18n/index.json';
|
||||||
import formStyles from 'components/ui/form/form.scss';
|
import formStyles from 'components/ui/form/form.scss';
|
||||||
import popupStyles from 'components/ui/popup/popup.scss';
|
import popupStyles from 'components/ui/popup/popup.scss';
|
||||||
import icons from 'components/ui/icons.scss';
|
import icons from 'components/ui/icons.scss';
|
||||||
|
|
||||||
import styles from './languageSwitcher.scss';
|
import styles from './languageSwitcher.scss';
|
||||||
import messages from './languageSwitcher.intl.json';
|
import messages from './languageSwitcher.intl.json';
|
||||||
import LanguageList from './LanguageList';
|
import LanguageList from './LanguageList';
|
||||||
@ -23,21 +25,27 @@ export type LocaleData = {
|
|||||||
|
|
||||||
export type LocalesMap = {[code: string]: LocaleData};
|
export type LocalesMap = {[code: string]: LocaleData};
|
||||||
|
|
||||||
class LanguageSwitcher extends Component<{
|
type OwnProps = {|
|
||||||
onClose: Function,
|
onClose: () => void,
|
||||||
selectedLocale: string,
|
|
||||||
changeLang: (lang: string) => void,
|
|
||||||
langs: LocalesMap,
|
langs: LocalesMap,
|
||||||
emptyCaptions: Array<{
|
emptyCaptions: Array<{
|
||||||
src: string,
|
src: string,
|
||||||
caption: string,
|
caption: string,
|
||||||
}>,
|
}>,
|
||||||
}, {
|
|};
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
...OwnProps,
|
||||||
|
selectedLocale: string,
|
||||||
|
changeLang: (lang: string) => void,
|
||||||
|
};
|
||||||
|
|
||||||
|
class LanguageSwitcher extends Component<Props, {
|
||||||
filter: string,
|
filter: string,
|
||||||
filteredLangs: LocalesMap,
|
filteredLangs: LocalesMap,
|
||||||
}> {
|
}> {
|
||||||
static contextTypes = {
|
static contextTypes = {
|
||||||
intl: intlShape.isRequired,
|
intl: intlShape,
|
||||||
};
|
};
|
||||||
|
|
||||||
state = {
|
state = {
|
||||||
@ -108,7 +116,7 @@ class LanguageSwitcher extends Component<{
|
|||||||
|
|
||||||
onChangeLang = this.changeLang.bind(this);
|
onChangeLang = this.changeLang.bind(this);
|
||||||
|
|
||||||
changeLang(lang) {
|
changeLang(lang: string) {
|
||||||
this.props.changeLang(lang);
|
this.props.changeLang(lang);
|
||||||
|
|
||||||
setTimeout(this.props.onClose, 300);
|
setTimeout(this.props.onClose, 300);
|
||||||
@ -153,10 +161,7 @@ class LanguageSwitcher extends Component<{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
import { connect } from 'react-redux';
|
export default connect<Props, OwnProps, _, _, _, _>((state) => ({
|
||||||
import { changeLang } from 'components/user/actions';
|
|
||||||
|
|
||||||
export default connect((state) => ({
|
|
||||||
selectedLocale: state.i18n.locale,
|
selectedLocale: state.i18n.locale,
|
||||||
}), {
|
}), {
|
||||||
changeLang,
|
changeLang,
|
||||||
|
@ -3,17 +3,27 @@ import React from 'react';
|
|||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { localeFlags } from 'components/i18n';
|
import { localeFlags } from 'components/i18n';
|
||||||
import LANGS from 'i18n/index.json';
|
import LANGS from 'i18n/index.json';
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
import { create as createPopup } from 'components/ui/popup/actions';
|
||||||
|
import LanguageSwitcher from 'components/languageSwitcher';
|
||||||
|
|
||||||
import styles from './link.scss';
|
import styles from './link.scss';
|
||||||
|
|
||||||
|
type OwnProps = {|
|
||||||
|
|};
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
...OwnProps,
|
||||||
|
userLang: string;
|
||||||
|
interfaceLocale: string;
|
||||||
|
showLanguageSwitcherPopup: Function;
|
||||||
|
};
|
||||||
|
|
||||||
function LanguageLink({
|
function LanguageLink({
|
||||||
userLang,
|
userLang,
|
||||||
interfaceLocale,
|
interfaceLocale,
|
||||||
showLanguageSwitcherPopup,
|
showLanguageSwitcherPopup,
|
||||||
}: {
|
}: Props) {
|
||||||
userLang: string;
|
|
||||||
interfaceLocale: string;
|
|
||||||
showLanguageSwitcherPopup: Function;
|
|
||||||
}) {
|
|
||||||
const localeDefinition = LANGS[userLang] || LANGS[interfaceLocale];
|
const localeDefinition = LANGS[userLang] || LANGS[interfaceLocale];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -31,13 +41,9 @@ function LanguageLink({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
import { connect } from 'react-redux';
|
export default connect<Props, OwnProps, _, _, _, _>((state) => ({
|
||||||
import { create as createPopup } from 'components/ui/popup/actions';
|
|
||||||
import LanguageSwitcher from 'components/languageSwitcher';
|
|
||||||
|
|
||||||
export default connect((state) => ({
|
|
||||||
userLang: state.user.lang,
|
userLang: state.user.lang,
|
||||||
interfaceLocale: state.i18n.locale,
|
interfaceLocale: state.i18n.locale,
|
||||||
}), {
|
}), {
|
||||||
showLanguageSwitcherPopup: () => createPopup(LanguageSwitcher),
|
showLanguageSwitcherPopup: () => createPopup({ Popup: LanguageSwitcher }),
|
||||||
})(LanguageLink);
|
})(LanguageLink);
|
||||||
|
@ -13,10 +13,16 @@ import RulesPage from 'pages/rules/RulesPage';
|
|||||||
|
|
||||||
import type { User } from 'components/user';
|
import type { User } from 'components/user';
|
||||||
|
|
||||||
class Profile extends Component<{
|
type OwnProps = {|
|
||||||
|
|};
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
...OwnProps,
|
||||||
user: User;
|
user: User;
|
||||||
interfaceLocale: string;
|
interfaceLocale: string;
|
||||||
}> {
|
};
|
||||||
|
|
||||||
|
class Profile extends Component<Props> {
|
||||||
UUID: ?HTMLElement;
|
UUID: ?HTMLElement;
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
@ -150,10 +156,7 @@ class Profile extends Component<{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default connect(({ user, i18n }): {
|
export default connect<Props, OwnProps, _, _, _, _>(({ user, i18n }) => ({
|
||||||
user: User;
|
|
||||||
interfaceLocale: string;
|
|
||||||
} => ({
|
|
||||||
user,
|
user,
|
||||||
interfaceLocale: i18n.locale,
|
interfaceLocale: i18n.locale,
|
||||||
}))(Profile);
|
}))(Profile);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import expect from 'unexpected';
|
import expect from 'test/unexpected';
|
||||||
import sinon from 'sinon';
|
import sinon from 'sinon';
|
||||||
|
|
||||||
import { shallow } from 'enzyme';
|
import { shallow } from 'enzyme';
|
||||||
|
@ -8,7 +8,7 @@ const ABORT_ERR = 20;
|
|||||||
|
|
||||||
export default function BsodMiddleware(dispatchBsod: Function, logger: Logger) {
|
export default function BsodMiddleware(dispatchBsod: Function, logger: Logger) {
|
||||||
return {
|
return {
|
||||||
catch<T: Resp<*> | InternalServerError | Error>(resp?: T): Promise<T> {
|
catch<T: Resp<any> | InternalServerError | Error>(resp?: T): Promise<T> {
|
||||||
const originalResponse: Object = (resp && resp.originalResponse) || {};
|
const originalResponse: Object = (resp && resp.originalResponse) || {};
|
||||||
|
|
||||||
if (
|
if (
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import expect from 'unexpected';
|
import expect from 'test/unexpected';
|
||||||
import sinon from 'sinon';
|
import sinon from 'sinon';
|
||||||
|
|
||||||
import BsodMiddleware from 'components/ui/bsod/BsodMiddleware';
|
import BsodMiddleware from 'components/ui/bsod/BsodMiddleware';
|
||||||
|
@ -16,7 +16,7 @@ export default class Captcha extends FormInputComponent<{
|
|||||||
}, {
|
}, {
|
||||||
code: string,
|
code: string,
|
||||||
}> {
|
}> {
|
||||||
el: ?HTMLDivElement;
|
elRef = React.createRef<HTMLDivElement>();
|
||||||
captchaId: CaptchaID;
|
captchaId: CaptchaID;
|
||||||
|
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
@ -26,7 +26,9 @@ export default class Captcha extends FormInputComponent<{
|
|||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.el && captcha.render(this.el, {
|
const {current: el} = this.elRef;
|
||||||
|
|
||||||
|
el && captcha.render(el, {
|
||||||
skin: this.props.skin,
|
skin: this.props.skin,
|
||||||
onSetCode: this.setCode
|
onSetCode: this.setCode
|
||||||
})
|
})
|
||||||
@ -48,7 +50,7 @@ export default class Captcha extends FormInputComponent<{
|
|||||||
<ComponentLoader />
|
<ComponentLoader />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div ref={this.setEl} className={classNames(
|
<div ref={this.elRef} className={classNames(
|
||||||
styles.captcha,
|
styles.captcha,
|
||||||
styles[`${skin}Captcha`]
|
styles[`${skin}Captcha`]
|
||||||
)} />
|
)} />
|
||||||
|
@ -19,6 +19,8 @@ export default class Checkbox extends FormInputComponent<{
|
|||||||
skin: SKIN_DARK,
|
skin: SKIN_DARK,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
elRef = React.createRef<HTMLInputElement>();
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { color, skin } = this.props;
|
const { color, skin } = this.props;
|
||||||
let { label } = this.props;
|
let { label } = this.props;
|
||||||
@ -30,7 +32,7 @@ export default class Checkbox extends FormInputComponent<{
|
|||||||
return (
|
return (
|
||||||
<div className={classNames(styles[`${color}MarkableRow`], styles[`${skin}MarkableRow`])}>
|
<div className={classNames(styles[`${color}MarkableRow`], styles[`${skin}MarkableRow`])}>
|
||||||
<label className={styles.markableContainer}>
|
<label className={styles.markableContainer}>
|
||||||
<input ref={this.setEl}
|
<input ref={this.elRef}
|
||||||
className={styles.markableInput}
|
className={styles.markableInput}
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
{...props}
|
{...props}
|
||||||
@ -44,13 +46,13 @@ export default class Checkbox extends FormInputComponent<{
|
|||||||
}
|
}
|
||||||
|
|
||||||
getValue() {
|
getValue() {
|
||||||
const { el } = this;
|
const { current: el } = this.elRef;
|
||||||
|
|
||||||
return el && el.checked ? 1 : 0;
|
return el && el.checked ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
focus() {
|
focus() {
|
||||||
const { el } = this;
|
const { current: el } = this.elRef;
|
||||||
|
|
||||||
el && el.focus();
|
el && el.focus();
|
||||||
}
|
}
|
||||||
|
@ -1,22 +1,20 @@
|
|||||||
// @flow
|
// @flow
|
||||||
|
import type { Node } from 'react';
|
||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
|
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
|
|
||||||
import logger from 'services/logger';
|
import logger from 'services/logger';
|
||||||
|
|
||||||
|
import type FormModel from './FormModel';
|
||||||
import styles from './form.scss';
|
import styles from './form.scss';
|
||||||
|
|
||||||
import type FormModel from './FormModel';
|
type Props = {|
|
||||||
|
|
||||||
type Props = {
|
|
||||||
id: string,
|
id: string,
|
||||||
isLoading: bool,
|
isLoading: bool,
|
||||||
form?: FormModel,
|
form?: FormModel,
|
||||||
onSubmit: Function,
|
onSubmit: (form: FormModel | FormData) => void | Promise<void>,
|
||||||
onInvalid: (errors: {[errorKey: string]: string}) => void,
|
onInvalid: (errors: {[errorKey: string]: string}) => void,
|
||||||
children: *
|
children: Node
|
||||||
};
|
|};
|
||||||
type State = {
|
type State = {
|
||||||
isTouched: bool,
|
isTouched: bool,
|
||||||
isLoading: bool
|
isLoading: bool
|
||||||
@ -130,7 +128,7 @@ export default class Form extends Component<Props, State> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const invalidEls = form.querySelectorAll(':invalid');
|
const invalidEls: NodeList<InputElement> = (form.querySelectorAll(':invalid'): any);
|
||||||
const errors = {};
|
const errors = {};
|
||||||
invalidEls[0].focus(); // focus on first error
|
invalidEls[0].focus(); // focus on first error
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ import { intlShape } from 'react-intl';
|
|||||||
|
|
||||||
export default class FormComponent<P, S = void> extends Component<P, S> {
|
export default class FormComponent<P, S = void> extends Component<P, S> {
|
||||||
static contextTypes = {
|
static contextTypes = {
|
||||||
intl: intlShape.isRequired
|
intl: intlShape,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -12,8 +12,6 @@ export default class FormInputComponent<P, S = void> extends FormComponent<P & {
|
|||||||
}, S & {
|
}, S & {
|
||||||
error?: Error,
|
error?: Error,
|
||||||
}> {
|
}> {
|
||||||
el: ?HTMLDivElement;
|
|
||||||
|
|
||||||
componentWillReceiveProps() {
|
componentWillReceiveProps() {
|
||||||
if (this.state && this.state.error) {
|
if (this.state && this.state.error) {
|
||||||
Reflect.deleteProperty(this.state, 'error');
|
Reflect.deleteProperty(this.state, 'error');
|
||||||
@ -22,10 +20,6 @@ export default class FormInputComponent<P, S = void> extends FormComponent<P & {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setEl = (el: ?HTMLDivElement) => {
|
|
||||||
this.el = el;
|
|
||||||
};
|
|
||||||
|
|
||||||
renderError() {
|
renderError() {
|
||||||
const error = this.state && this.state.error || this.props.error;
|
const error = this.state && this.state.error || this.props.error;
|
||||||
|
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
// @flow
|
// @flow
|
||||||
import FormInputComponent from './FormInputComponent';
|
import FormInputComponent from './FormInputComponent';
|
||||||
|
|
||||||
|
type LoadingListener = (isLoading: bool) => void;
|
||||||
|
|
||||||
export default class FormModel {
|
export default class FormModel {
|
||||||
fields = {};
|
fields = {};
|
||||||
errors = {};
|
errors = {};
|
||||||
handlers = [];
|
handlers: LoadingListener[] = [];
|
||||||
renderErrors: bool;
|
renderErrors: bool;
|
||||||
_isLoading: bool;
|
_isLoading: bool;
|
||||||
|
|
||||||
@ -145,7 +147,7 @@ export default class FormModel {
|
|||||||
*
|
*
|
||||||
* @return {object}
|
* @return {object}
|
||||||
*/
|
*/
|
||||||
serialize() {
|
serialize(): {[key: string]: any} {
|
||||||
return Object.keys(this.fields).reduce((acc, fieldId) => {
|
return Object.keys(this.fields).reduce((acc, fieldId) => {
|
||||||
const field = this.fields[fieldId];
|
const field = this.fields[fieldId];
|
||||||
|
|
||||||
@ -164,7 +166,7 @@ export default class FormModel {
|
|||||||
*
|
*
|
||||||
* @param {function} fn
|
* @param {function} fn
|
||||||
*/
|
*/
|
||||||
addLoadingListener(fn: Function) {
|
addLoadingListener(fn: LoadingListener) {
|
||||||
this.removeLoadingListener(fn);
|
this.removeLoadingListener(fn);
|
||||||
this.handlers.push(fn);
|
this.handlers.push(fn);
|
||||||
}
|
}
|
||||||
@ -174,7 +176,7 @@ export default class FormModel {
|
|||||||
*
|
*
|
||||||
* @param {function} fn
|
* @param {function} fn
|
||||||
*/
|
*/
|
||||||
removeLoadingListener(fn: Function) {
|
removeLoadingListener(fn: LoadingListener) {
|
||||||
this.handlers = this.handlers.filter((handler) => handler !== fn);
|
this.handlers = this.handlers.filter((handler) => handler !== fn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,6 +37,8 @@ export default class Input extends FormInputComponent<{
|
|||||||
wasCopied: false,
|
wasCopied: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
elRef = React.createRef<HTMLInputElement>();
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { color, skin, center } = this.props;
|
const { color, skin, center } = this.props;
|
||||||
let { icon, label, copy } = this.props;
|
let { icon, label, copy } = this.props;
|
||||||
@ -89,7 +91,7 @@ export default class Input extends FormInputComponent<{
|
|||||||
<div className={baseClass}>
|
<div className={baseClass}>
|
||||||
{label}
|
{label}
|
||||||
<div className={styles.textFieldContainer}>
|
<div className={styles.textFieldContainer}>
|
||||||
<input ref={this.setEl}
|
<input ref={this.elRef}
|
||||||
className={classNames(
|
className={classNames(
|
||||||
styles[`${skin}TextField`],
|
styles[`${skin}TextField`],
|
||||||
styles[`${color}TextField`],
|
styles[`${color}TextField`],
|
||||||
@ -108,11 +110,13 @@ export default class Input extends FormInputComponent<{
|
|||||||
}
|
}
|
||||||
|
|
||||||
getValue() {
|
getValue() {
|
||||||
return this.el && this.el.value;
|
const { current: el } = this.elRef;
|
||||||
|
|
||||||
|
return el && el.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
focus() {
|
focus() {
|
||||||
const el = this.el;
|
const { current: el } = this.elRef;
|
||||||
|
|
||||||
if (!el) {
|
if (!el) {
|
||||||
return;
|
return;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { mount } from 'enzyme';
|
import { mount } from 'enzyme';
|
||||||
import expect from 'unexpected';
|
import expect from 'test/unexpected';
|
||||||
import { IntlProvider } from 'react-intl';
|
import { IntlProvider } from 'react-intl';
|
||||||
|
|
||||||
import Input from './Input';
|
import Input from './Input';
|
||||||
|
@ -1,12 +1,15 @@
|
|||||||
// @flow
|
// @flow
|
||||||
import type { ElementProps } from 'react';
|
import type { ElementConfig } from 'react';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
|
|
||||||
import Button from './Button';
|
import Button from './Button';
|
||||||
|
|
||||||
export default function LinkButton(
|
export default function LinkButton(
|
||||||
props: ElementProps<typeof Button> & ElementProps<typeof Link>
|
props: {
|
||||||
|
...$Exact<ElementConfig<typeof Button>>,
|
||||||
|
...$Exact<ElementConfig<typeof Link>>
|
||||||
|
}
|
||||||
) {
|
) {
|
||||||
const { to, ...restProps } = props;
|
const { to, ...restProps } = props;
|
||||||
|
|
||||||
|
@ -19,6 +19,8 @@ export default class Radio extends FormInputComponent<{
|
|||||||
skin: SKIN_DARK,
|
skin: SKIN_DARK,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
elRef = React.createRef<HTMLInputElement>();
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { color, skin } = this.props;
|
const { color, skin } = this.props;
|
||||||
let { label } = this.props;
|
let { label } = this.props;
|
||||||
@ -30,7 +32,7 @@ export default class Radio extends FormInputComponent<{
|
|||||||
return (
|
return (
|
||||||
<div className={classNames(styles[`${color}MarkableRow`], styles[`${skin}MarkableRow`])}>
|
<div className={classNames(styles[`${color}MarkableRow`], styles[`${skin}MarkableRow`])}>
|
||||||
<label className={styles.markableContainer}>
|
<label className={styles.markableContainer}>
|
||||||
<input ref={this.setEl}
|
<input ref={this.elRef}
|
||||||
className={styles.markableInput}
|
className={styles.markableInput}
|
||||||
type="radio"
|
type="radio"
|
||||||
{...props}
|
{...props}
|
||||||
@ -44,13 +46,13 @@ export default class Radio extends FormInputComponent<{
|
|||||||
}
|
}
|
||||||
|
|
||||||
getValue() {
|
getValue() {
|
||||||
const { el } = this;
|
const { current: el } = this.elRef;
|
||||||
|
|
||||||
return el && el.checked ? 1 : 0;
|
return el && el.checked ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
focus() {
|
focus() {
|
||||||
const { el } = this;
|
const { current: el } = this.elRef;
|
||||||
|
|
||||||
el && el.focus();
|
el && el.focus();
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,8 @@ export default class TextArea extends FormInputComponent<{
|
|||||||
skin: SKIN_DARK,
|
skin: SKIN_DARK,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
elRef = React.createRef<HTMLTextAreaElement>();
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { color, skin } = this.props;
|
const { color, skin } = this.props;
|
||||||
let { label } = this.props;
|
let { label } = this.props;
|
||||||
@ -59,7 +61,7 @@ export default class TextArea extends FormInputComponent<{
|
|||||||
<div className={styles.formRow}>
|
<div className={styles.formRow}>
|
||||||
{label}
|
{label}
|
||||||
<div className={styles.textAreaContainer}>
|
<div className={styles.textAreaContainer}>
|
||||||
<TextareaAutosize inputRef={this.setEl}
|
<TextareaAutosize inputRef={this.elRef}
|
||||||
className={classNames(
|
className={classNames(
|
||||||
styles.textArea,
|
styles.textArea,
|
||||||
styles[`${skin}TextField`],
|
styles[`${skin}TextField`],
|
||||||
@ -74,11 +76,13 @@ export default class TextArea extends FormInputComponent<{
|
|||||||
}
|
}
|
||||||
|
|
||||||
getValue() {
|
getValue() {
|
||||||
return this.el && this.el.value;
|
const { current: el } = this.elRef;
|
||||||
|
|
||||||
|
return el && el.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
focus() {
|
focus() {
|
||||||
const { el } = this;
|
const { current: el } = this.elRef;
|
||||||
|
|
||||||
if (!el) {
|
if (!el) {
|
||||||
return;
|
return;
|
||||||
|
@ -1,19 +1,20 @@
|
|||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
|
import { TransitionGroup, CSSTransition } from 'react-transition-group';
|
||||||
import { CSSTransitionGroup } from 'react-transition-group';
|
|
||||||
import { browserHistory } from 'services/history';
|
import { browserHistory } from 'services/history';
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
import { destroy } from 'components/ui/popup/actions';
|
||||||
|
|
||||||
import styles from './popup.scss';
|
import styles from './popup.scss';
|
||||||
|
|
||||||
export class PopupStack extends Component {
|
export class PopupStack extends Component {
|
||||||
static displayName = 'PopupStack';
|
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
popups: PropTypes.arrayOf(PropTypes.shape({
|
popups: PropTypes.arrayOf(
|
||||||
type: PropTypes.func,
|
PropTypes.shape({
|
||||||
props: PropTypes.oneOfType([PropTypes.object, PropTypes.func])
|
type: PropTypes.func,
|
||||||
})),
|
props: PropTypes.oneOfType([PropTypes.object, PropTypes.func])
|
||||||
|
})
|
||||||
|
),
|
||||||
destroy: PropTypes.func.isRequired
|
destroy: PropTypes.func.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -28,31 +29,34 @@ export class PopupStack extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {popups} = this.props;
|
const { popups } = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<CSSTransitionGroup
|
<TransitionGroup>
|
||||||
transitionName={{
|
|
||||||
enter: styles.trEnter,
|
|
||||||
enterActive: styles.trEnterActive,
|
|
||||||
leave: styles.trLeave,
|
|
||||||
leaveActive: styles.trLeaveActive
|
|
||||||
}}
|
|
||||||
transitionEnterTimeout={500}
|
|
||||||
transitionLeaveTimeout={500}
|
|
||||||
>
|
|
||||||
{popups.map((popup, index) => {
|
{popups.map((popup, index) => {
|
||||||
const {Popup} = popup;
|
const { Popup } = popup;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.overlay} key={index}
|
<CSSTransition
|
||||||
onClick={this.onOverlayClick(popup)}
|
key={index}
|
||||||
|
classNames={{
|
||||||
|
enter: styles.trEnter,
|
||||||
|
enterActive: styles.trEnterActive,
|
||||||
|
exit: styles.trExit,
|
||||||
|
exitActive: styles.trExitActive
|
||||||
|
}}
|
||||||
|
timeout={500}
|
||||||
>
|
>
|
||||||
<Popup onClose={this.onClose(popup)} />
|
<div
|
||||||
</div>
|
className={styles.overlay}
|
||||||
|
onClick={this.onOverlayClick(popup)}
|
||||||
|
>
|
||||||
|
<Popup onClose={this.onClose(popup)} />
|
||||||
|
</div>
|
||||||
|
</CSSTransition>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</CSSTransitionGroup>
|
</TransitionGroup>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,7 +66,10 @@ export class PopupStack extends Component {
|
|||||||
|
|
||||||
onOverlayClick(popup) {
|
onOverlayClick(popup) {
|
||||||
return (event) => {
|
return (event) => {
|
||||||
if (event.target !== event.currentTarget || popup.disableOverlayClose) {
|
if (
|
||||||
|
event.target !== event.currentTarget
|
||||||
|
|| popup.disableOverlayClose
|
||||||
|
) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,7 +88,8 @@ export class PopupStack extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onKeyPress = (event) => {
|
onKeyPress = (event) => {
|
||||||
if (event.which === 27) { // ESC key
|
if (event.which === 27) {
|
||||||
|
// ESC key
|
||||||
this.popStack();
|
this.popStack();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -93,11 +101,11 @@ export class PopupStack extends Component {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
import { connect } from 'react-redux';
|
export default connect(
|
||||||
import { destroy } from 'components/ui/popup/actions';
|
(state) => ({
|
||||||
|
...state.popup
|
||||||
export default connect((state) => ({
|
}),
|
||||||
...state.popup
|
{
|
||||||
}), {
|
destroy
|
||||||
destroy
|
}
|
||||||
})(PopupStack);
|
)(PopupStack);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import sinon from 'sinon';
|
import sinon from 'sinon';
|
||||||
import expect from 'unexpected';
|
import expect from 'test/unexpected';
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
// @flow
|
// @flow
|
||||||
import type { ElementType } from 'react';
|
import type { ElementType } from 'react';
|
||||||
|
|
||||||
export const POPUP_CREATE = 'POPUP_CREATE';
|
export const POPUP_CREATE = 'POPUP_CREATE';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -9,16 +10,10 @@ export const POPUP_CREATE = 'POPUP_CREATE';
|
|||||||
*
|
*
|
||||||
* @return {object}
|
* @return {object}
|
||||||
*/
|
*/
|
||||||
export function create(payload: ElementType | {
|
export function create(payload: {
|
||||||
Popup: ElementType,
|
Popup: ElementType,
|
||||||
disableOverlayClose?: bool,
|
disableOverlayClose?: bool
|
||||||
}) {
|
}) {
|
||||||
if (typeof payload === 'function') {
|
|
||||||
payload = {
|
|
||||||
Popup: payload
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
type: POPUP_CREATE,
|
type: POPUP_CREATE,
|
||||||
payload
|
payload
|
||||||
|
@ -141,7 +141,7 @@ $popupInitPosition: translateY(10%) rotateX(-8deg);
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.trLeave {
|
.trExit {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
@ -163,7 +163,7 @@ $popupInitPosition: translateY(10%) rotateX(-8deg);
|
|||||||
}
|
}
|
||||||
|
|
||||||
.trEnter,
|
.trEnter,
|
||||||
.trLeave {
|
.trExit {
|
||||||
.close {
|
.close {
|
||||||
// do not show close during transition, because transform forces position: fixed
|
// do not show close during transition, because transform forces position: fixed
|
||||||
// to layout relative container, instead of body
|
// to layout relative container, instead of body
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import expect from 'unexpected';
|
import expect from 'test/unexpected';
|
||||||
|
|
||||||
import reducer from 'components/ui/popup/reducer';
|
import reducer from 'components/ui/popup/reducer';
|
||||||
import {create, destroy} from 'components/ui/popup/actions';
|
import {create, destroy} from 'components/ui/popup/actions';
|
||||||
@ -22,14 +22,6 @@ describe('popup/reducer', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should support shortcut popup creation', () => {
|
|
||||||
const actual = reducer(undefined, create(FakeComponent));
|
|
||||||
|
|
||||||
expect(actual.popups[0], 'to equal', {
|
|
||||||
Popup: FakeComponent
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create multiple popups', () => {
|
it('should create multiple popups', () => {
|
||||||
let actual = reducer(undefined, create({
|
let actual = reducer(undefined, create({
|
||||||
Popup: FakeComponent
|
Popup: FakeComponent
|
||||||
@ -44,7 +36,7 @@ describe('popup/reducer', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('throws when no type provided', () => {
|
it('throws when no type provided', () => {
|
||||||
expect(() => reducer(undefined, create()), 'to throw', 'Popup is required');
|
expect(() => reducer(undefined, create({})), 'to throw', 'Popup is required');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -53,7 +45,7 @@ describe('popup/reducer', () => {
|
|||||||
let popup;
|
let popup;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
state = reducer(state, create(FakeComponent));
|
state = reducer(state, create({ Popup: FakeComponent }));
|
||||||
popup = state.popups[0];
|
popup = state.popups[0];
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
// @flow
|
// @flow
|
||||||
|
import type { Location } from 'react-router-dom';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { withRouter } from 'react-router-dom';
|
import { withRouter } from 'react-router-dom';
|
||||||
import { restoreScroll } from './scroll';
|
import { restoreScroll } from './scroll';
|
||||||
|
|
||||||
class ScrollIntoView extends React.Component<{
|
class ScrollIntoView extends React.PureComponent<{
|
||||||
location: string,
|
location: Location,
|
||||||
top?: bool, // do not touch any DOM and simply scroll to top on location change
|
top?: bool, // do not touch any DOM and simply scroll to top on location change
|
||||||
}> {
|
}> {
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import expect from 'unexpected';
|
import expect from 'test/unexpected';
|
||||||
|
|
||||||
import bearerHeaderMiddleware from 'components/user/middlewares/bearerHeaderMiddleware';
|
import bearerHeaderMiddleware from 'components/user/middlewares/bearerHeaderMiddleware';
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import expect from 'unexpected';
|
import expect from 'test/unexpected';
|
||||||
import sinon from 'sinon';
|
import sinon from 'sinon';
|
||||||
|
|
||||||
import refreshTokenMiddleware from 'components/user/middlewares/refreshTokenMiddleware';
|
import refreshTokenMiddleware from 'components/user/middlewares/refreshTokenMiddleware';
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import sinon from 'sinon';
|
import sinon from 'sinon';
|
||||||
import expect from 'unexpected';
|
import expect from 'test/unexpected';
|
||||||
import { mount } from 'enzyme';
|
import { mount } from 'enzyme';
|
||||||
|
|
||||||
import authFlow from 'services/authFlow';
|
import authFlow from 'services/authFlow';
|
||||||
@ -18,15 +17,13 @@ describe('AuthFlowRouteContents', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
function Component() {
|
function Component() {
|
||||||
return (
|
return <div />;
|
||||||
<div />
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
it('should render component if route allowed', () => {
|
it('should render component if route allowed', () => {
|
||||||
const request = {
|
const request = {
|
||||||
path: '/path',
|
path: '/path',
|
||||||
params: {foo: 1},
|
params: { foo: 1 },
|
||||||
query: new URLSearchParams()
|
query: new URLSearchParams()
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -36,23 +33,25 @@ describe('AuthFlowRouteContents', () => {
|
|||||||
query: request.query
|
query: request.query
|
||||||
},
|
},
|
||||||
match: {
|
match: {
|
||||||
params: request.params,
|
params: request.params
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
authFlow.handleRequest.callsArg(2);
|
authFlow.handleRequest.callsArg(2);
|
||||||
|
|
||||||
const wrapper = mount(<AuthFlowRouteContents
|
const wrapper = mount(
|
||||||
routerProps={routerProps}
|
<AuthFlowRouteContents
|
||||||
component={Component}
|
routerProps={routerProps}
|
||||||
/>);
|
component={Component}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
const component = wrapper.find(Component);
|
const component = wrapper.find(Component);
|
||||||
|
|
||||||
expect(authFlow.handleRequest, 'to have a call satisfying', [
|
expect(authFlow.handleRequest, 'to have a call satisfying', [
|
||||||
request,
|
request,
|
||||||
function() {},
|
expect.it('to be a function'),
|
||||||
function() {}
|
expect.it('to be a function')
|
||||||
]);
|
]);
|
||||||
|
|
||||||
expect(component.exists(), 'to be true');
|
expect(component.exists(), 'to be true');
|
||||||
|
@ -1,26 +1,35 @@
|
|||||||
// @flow
|
// @flow
|
||||||
|
import type { ComponentType, ElementConfig } from 'react';
|
||||||
|
import type { Account } from 'components/accounts';
|
||||||
|
import type { Location } from 'react-router-dom';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Route, Redirect } from 'react-router-dom';
|
import { Route, Redirect } from 'react-router-dom';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { getActiveAccount } from 'components/accounts/reducer';
|
import { getActiveAccount } from 'components/accounts/reducer';
|
||||||
import type { ComponentType } from 'react';
|
|
||||||
import type { Account } from 'components/accounts';
|
|
||||||
|
|
||||||
const PrivateRoute = ({account, component: Component, ...rest}: {
|
type OwnProps = {|
|
||||||
|
...$Exact<ElementConfig<typeof Route>>,
|
||||||
component: ComponentType<any>,
|
component: ComponentType<any>,
|
||||||
|
|};
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
...OwnProps,
|
||||||
account: ?Account
|
account: ?Account
|
||||||
}) => (
|
};
|
||||||
<Route {...rest} render={(props: {location: string}) => (
|
|
||||||
!account || !account.token ? (
|
const PrivateRoute = ({ account, component: Component, ...rest }: Props) => (
|
||||||
<Redirect to="/login" />
|
<Route
|
||||||
) : (
|
{...rest}
|
||||||
<Component {...props}/>
|
render={(props: { location: Location }) =>
|
||||||
)
|
!account || !account.token ? (
|
||||||
)}/>
|
<Redirect to="/login" />
|
||||||
|
) : (
|
||||||
|
<Component {...props} />
|
||||||
|
)
|
||||||
|
}
|
||||||
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
export default connect((state): {
|
export default connect<Props, OwnProps, _, _, _, _>((state) => ({
|
||||||
account: ?Account,
|
|
||||||
} => ({
|
|
||||||
account: getActiveAccount(state)
|
account: getActiveAccount(state)
|
||||||
}))(PrivateRoute);
|
}))(PrivateRoute);
|
||||||
|
@ -18,6 +18,8 @@ import ForgotPassword from 'components/auth/forgotPassword/ForgotPassword';
|
|||||||
import RecoverPassword from 'components/auth/recoverPassword/RecoverPassword';
|
import RecoverPassword from 'components/auth/recoverPassword/RecoverPassword';
|
||||||
import Mfa from 'components/auth/mfa/Mfa';
|
import Mfa from 'components/auth/mfa/Mfa';
|
||||||
import Finish from 'components/auth/finish/Finish';
|
import Finish from 'components/auth/finish/Finish';
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
import { withRouter } from 'react-router-dom';
|
||||||
|
|
||||||
import styles from './auth.scss';
|
import styles from './auth.scss';
|
||||||
|
|
||||||
@ -27,13 +29,19 @@ import styles from './auth.scss';
|
|||||||
// so that it persist disregarding remounts
|
// so that it persist disregarding remounts
|
||||||
let isSidebarHiddenCache = false;
|
let isSidebarHiddenCache = false;
|
||||||
|
|
||||||
class AuthPage extends Component<{
|
type OwnProps = {|
|
||||||
|
|};
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
...OwnProps,
|
||||||
client: {
|
client: {
|
||||||
id: string,
|
id: string,
|
||||||
name: string,
|
name: string,
|
||||||
description: string
|
description: string
|
||||||
}
|
}
|
||||||
}, {
|
};
|
||||||
|
|
||||||
|
class AuthPage extends Component<Props, {
|
||||||
isSidebarHidden: bool
|
isSidebarHidden: bool
|
||||||
}> {
|
}> {
|
||||||
state = {
|
state = {
|
||||||
@ -91,20 +99,10 @@ function renderPanelTransition(factory) {
|
|||||||
Body={<Body {...props} />}
|
Body={<Body {...props} />}
|
||||||
Footer={<Footer />}
|
Footer={<Footer />}
|
||||||
Links={<Links />}
|
Links={<Links />}
|
||||||
{...props}
|
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
import { connect } from 'react-redux';
|
export default withRouter(connect<Props, OwnProps, _, _, _, _>((state) => ({
|
||||||
import { withRouter } from 'react-router';
|
|
||||||
|
|
||||||
export default withRouter(connect((state): {
|
|
||||||
client: {
|
|
||||||
id: string,
|
|
||||||
name: string,
|
|
||||||
description: string
|
|
||||||
}
|
|
||||||
} => ({
|
|
||||||
client: state.auth.client
|
client: state.auth.client
|
||||||
}))(AuthPage));
|
}))(AuthPage));
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// @flow
|
// @flow
|
||||||
import type { Location, RouterHistory } from 'react-router';
|
import type { Location, RouterHistory } from 'react-router-dom';
|
||||||
import type { User } from 'components/user';
|
import type { User } from 'components/user';
|
||||||
import type { OauthAppResponse } from 'services/api/oauth';
|
import type { OauthAppResponse } from 'services/api/oauth';
|
||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
@ -11,17 +11,21 @@ import {
|
|||||||
} from 'components/dev/apps/actions';
|
} from 'components/dev/apps/actions';
|
||||||
import ApplicationsIndex from 'components/dev/apps/ApplicationsIndex';
|
import ApplicationsIndex from 'components/dev/apps/ApplicationsIndex';
|
||||||
|
|
||||||
interface Props {
|
type OwnProps = {|
|
||||||
location: Location;
|
location: Location;
|
||||||
history: RouterHistory;
|
history: RouterHistory;
|
||||||
|
|};
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
...OwnProps,
|
||||||
user: User;
|
user: User;
|
||||||
apps: Array<OauthAppResponse>;
|
apps: OauthAppResponse[];
|
||||||
fetchAvailableApps: () => Promise<void>;
|
fetchAvailableApps: () => Promise<void>;
|
||||||
deleteApp: string => Promise<void>;
|
deleteApp: string => Promise<void>;
|
||||||
resetApp: (string, bool) => Promise<void>;
|
resetApp: (string, bool) => Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface State {
|
type State = {
|
||||||
isLoading: bool;
|
isLoading: bool;
|
||||||
forceUpdate: bool;
|
forceUpdate: bool;
|
||||||
}
|
}
|
||||||
@ -36,7 +40,7 @@ class ApplicationsListPage extends Component<Props, State> {
|
|||||||
!this.props.user.isGuest && this.loadApplicationsList();
|
!this.props.user.isGuest && this.loadApplicationsList();
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidUpdate({ user }) {
|
componentDidUpdate({ user }: Props) {
|
||||||
if (this.props.user !== user) {
|
if (this.props.user !== user) {
|
||||||
// eslint-disable-next-line react/no-did-update-set-state
|
// eslint-disable-next-line react/no-did-update-set-state
|
||||||
this.setState({ forceUpdate: true });
|
this.setState({ forceUpdate: true });
|
||||||
@ -80,10 +84,12 @@ class ApplicationsListPage extends Component<Props, State> {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export default connect((state) => ({
|
export default connect<Props, OwnProps, _, _, _, _>((state) => ({
|
||||||
user: state.user,
|
user: state.user,
|
||||||
apps: state.apps.available,
|
apps: state.apps.available,
|
||||||
}), {
|
}),
|
||||||
|
// $FlowFixMe: we need a better action typings for thunks
|
||||||
|
{
|
||||||
fetchAvailableApps,
|
fetchAvailableApps,
|
||||||
resetApp,
|
resetApp,
|
||||||
deleteApp,
|
deleteApp,
|
||||||
|
@ -11,18 +11,21 @@ import PageNotFound from 'pages/404/PageNotFound';
|
|||||||
import { getApp, fetchApp } from 'components/dev/apps/actions';
|
import { getApp, fetchApp } from 'components/dev/apps/actions';
|
||||||
import ApplicationForm from 'components/dev/apps/applicationForm/ApplicationForm';
|
import ApplicationForm from 'components/dev/apps/applicationForm/ApplicationForm';
|
||||||
|
|
||||||
type MatchType = {
|
type OwnProps = {|
|
||||||
match: {
|
match: {
|
||||||
params: {
|
params: {
|
||||||
clientId: string,
|
clientId: string,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
|}
|
||||||
|
|
||||||
class UpdateApplicationPage extends Component<{
|
type Props = {
|
||||||
|
...OwnProps,
|
||||||
app: ?OauthAppResponse,
|
app: ?OauthAppResponse,
|
||||||
fetchApp: (string) => Promise<void>,
|
fetchApp: (string) => Promise<void>,
|
||||||
} & MatchType, {
|
}
|
||||||
|
|
||||||
|
class UpdateApplicationPage extends Component<Props, {
|
||||||
isNotFound: bool,
|
isNotFound: bool,
|
||||||
}> {
|
}> {
|
||||||
form: FormModel = new FormModel();
|
form: FormModel = new FormModel();
|
||||||
@ -104,7 +107,7 @@ class UpdateApplicationPage extends Component<{
|
|||||||
goToMainPage = (hash?: string) => browserHistory.push(`/dev/applications${hash ? `#${hash}` : ''}`);
|
goToMainPage = (hash?: string) => browserHistory.push(`/dev/applications${hash ? `#${hash}` : ''}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default connect((state, props: MatchType) => ({
|
export default connect<Props, OwnProps, _, _, _, _>((state, props) => ({
|
||||||
app: getApp(state, props.match.params.clientId),
|
app: getApp(state, props.match.params.clientId),
|
||||||
}), {
|
}), {
|
||||||
fetchApp,
|
fetchApp,
|
||||||
|
@ -1,15 +1,13 @@
|
|||||||
// @flow
|
// @flow
|
||||||
import type { RouterHistory, Match } from 'react-router';
|
import type { RouterHistory, Match } from 'react-router-dom';
|
||||||
|
import type FormModel from 'components/ui/form/FormModel';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
|
import { connect } from 'react-redux';
|
||||||
import ChangeEmail from 'components/profile/changeEmail/ChangeEmail';
|
import ChangeEmail from 'components/profile/changeEmail/ChangeEmail';
|
||||||
|
|
||||||
import { requestEmailChange, setNewEmail, confirmNewEmail } from 'services/api/accounts';
|
import { requestEmailChange, setNewEmail, confirmNewEmail } from 'services/api/accounts';
|
||||||
|
|
||||||
interface Props {
|
type OwnProps = {|
|
||||||
lang: string;
|
|
||||||
email: string;
|
|
||||||
history: RouterHistory;
|
history: RouterHistory;
|
||||||
match: {
|
match: {
|
||||||
...Match;
|
...Match;
|
||||||
@ -18,6 +16,12 @@ interface Props {
|
|||||||
code: string;
|
code: string;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|};
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
...OwnProps,
|
||||||
|
lang: string;
|
||||||
|
email: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
class ChangeEmailPage extends Component<Props> {
|
class ChangeEmailPage extends Component<Props> {
|
||||||
@ -53,11 +57,11 @@ class ChangeEmailPage extends Component<Props> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
onChangeStep = (step) => {
|
onChangeStep = (step: number) => {
|
||||||
this.props.history.push(`/profile/change-email/step${++step}`);
|
this.props.history.push(`/profile/change-email/step${++step}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
onSubmit = (step: number, form) => {
|
onSubmit = (step: number, form: FormModel) => {
|
||||||
return this.context.onSubmit({
|
return this.context.onSubmit({
|
||||||
form,
|
form,
|
||||||
sendData: () => {
|
sendData: () => {
|
||||||
@ -102,10 +106,7 @@ function handleErrors(repeatUrl) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
import { connect } from 'react-redux';
|
export default connect<Props, OwnProps, _, _, _, _>((state) => ({
|
||||||
|
|
||||||
export default connect((state) => ({
|
|
||||||
email: state.user.email,
|
email: state.user.email,
|
||||||
lang: state.user.lang
|
lang: state.user.lang
|
||||||
}), {
|
}))(ChangeEmailPage);
|
||||||
})(ChangeEmailPage);
|
|
||||||
|
@ -7,7 +7,11 @@ import { changePassword } from 'services/api/accounts';
|
|||||||
import { FormModel } from 'components/ui/form';
|
import { FormModel } from 'components/ui/form';
|
||||||
import ChangePassword from 'components/profile/changePassword/ChangePassword';
|
import ChangePassword from 'components/profile/changePassword/ChangePassword';
|
||||||
|
|
||||||
interface Props {
|
type OwnProps = {|
|
||||||
|
|};
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
...OwnProps,
|
||||||
updateUser: (fields: $Shape<User>) => void;
|
updateUser: (fields: $Shape<User>) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,6 +49,6 @@ class ChangePasswordPage extends Component<Props> {
|
|||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { updateUser } from 'components/user/actions';
|
import { updateUser } from 'components/user/actions';
|
||||||
|
|
||||||
export default connect(null, {
|
export default connect<Props, OwnProps, _, _, _, _>(null, {
|
||||||
updateUser,
|
updateUser,
|
||||||
})(ChangePasswordPage);
|
})(ChangePasswordPage);
|
||||||
|
@ -6,14 +6,15 @@ import { changeUsername } from 'services/api/accounts';
|
|||||||
import { FormModel } from 'components/ui/form';
|
import { FormModel } from 'components/ui/form';
|
||||||
import ChangeUsername from 'components/profile/changeUsername/ChangeUsername';
|
import ChangeUsername from 'components/profile/changeUsername/ChangeUsername';
|
||||||
|
|
||||||
interface Props {
|
type OwnProps = {|
|
||||||
|
|};
|
||||||
|
|
||||||
|
type Props = {
|
||||||
username: string;
|
username: string;
|
||||||
updateUsername: (username: string) => void;
|
updateUsername: (username: string) => void;
|
||||||
}
|
};
|
||||||
|
|
||||||
class ChangeUsernamePage extends Component<Props> {
|
class ChangeUsernamePage extends Component<Props> {
|
||||||
static displayName = 'ChangeUsernamePage';
|
|
||||||
|
|
||||||
static contextTypes = {
|
static contextTypes = {
|
||||||
userId: PropTypes.number.isRequired,
|
userId: PropTypes.number.isRequired,
|
||||||
onSubmit: PropTypes.func.isRequired,
|
onSubmit: PropTypes.func.isRequired,
|
||||||
@ -42,7 +43,7 @@ class ChangeUsernamePage extends Component<Props> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
onUsernameChange = (username) => {
|
onUsernameChange = (username: string) => {
|
||||||
this.props.updateUsername(username);
|
this.props.updateUsername(username);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -70,7 +71,7 @@ class ChangeUsernamePage extends Component<Props> {
|
|||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { updateUser } from 'components/user/actions';
|
import { updateUser } from 'components/user/actions';
|
||||||
|
|
||||||
export default connect((state) => ({
|
export default connect<Props, OwnProps, _, _, _, _>((state) => ({
|
||||||
username: state.user.username,
|
username: state.user.username,
|
||||||
}), {
|
}), {
|
||||||
updateUsername: (username) => updateUser({username}),
|
updateUsername: (username) => updateUser({username}),
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// @flow
|
// @flow
|
||||||
import type { RouterHistory, Match } from 'react-router';
|
import type { RouterHistory, Match } from 'react-router-dom';
|
||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
@ -9,8 +9,7 @@ import type { MfaStep } from 'components/profile/multiFactorAuth';
|
|||||||
import type { FormModel } from 'components/ui/form';
|
import type { FormModel } from 'components/ui/form';
|
||||||
import type { User } from 'components/user';
|
import type { User } from 'components/user';
|
||||||
|
|
||||||
interface Props {
|
type OwnProps = {|
|
||||||
user: User;
|
|
||||||
history: RouterHistory;
|
history: RouterHistory;
|
||||||
match: {
|
match: {
|
||||||
...Match;
|
...Match;
|
||||||
@ -18,6 +17,11 @@ interface Props {
|
|||||||
step?: '1' | '2' | '3';
|
step?: '1' | '2' | '3';
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|};
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
...OwnProps,
|
||||||
|
user: User;
|
||||||
}
|
}
|
||||||
|
|
||||||
class MultiFactorAuthPage extends Component<Props> {
|
class MultiFactorAuthPage extends Component<Props> {
|
||||||
@ -86,4 +90,6 @@ class MultiFactorAuthPage extends Component<Props> {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export default connect(({user}): { user: User } => ({user}))(MultiFactorAuthPage);
|
export default connect<Props, OwnProps, _, _, _, _>(
|
||||||
|
({user}) => ({user})
|
||||||
|
)(MultiFactorAuthPage);
|
||||||
|
@ -20,7 +20,11 @@ import styles from './profile.scss';
|
|||||||
|
|
||||||
import type { FormModel } from 'components/ui/form';
|
import type { FormModel } from 'components/ui/form';
|
||||||
|
|
||||||
interface Props {
|
type OwnProps = {|
|
||||||
|
|};
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
...OwnProps,
|
||||||
userId: number;
|
userId: number;
|
||||||
onSubmit: ({form: FormModel, sendData: () => Promise<*>}) => void;
|
onSubmit: ({form: FormModel, sendData: () => Promise<*>}) => void;
|
||||||
fetchUserData: () => Promise<*>;
|
fetchUserData: () => Promise<*>;
|
||||||
@ -65,7 +69,7 @@ class ProfilePage extends Component<Props> {
|
|||||||
goToProfile = () => browserHistory.push('/');
|
goToProfile = () => browserHistory.push('/');
|
||||||
}
|
}
|
||||||
|
|
||||||
export default connect((state) => ({
|
export default connect<Props, OwnProps, _, _, _, _>((state) => ({
|
||||||
userId: state.user.id,
|
userId: state.user.id,
|
||||||
}), {
|
}), {
|
||||||
fetchUserData,
|
fetchUserData,
|
||||||
|
@ -4,7 +4,7 @@ import type { Account } from 'components/accounts/reducer';
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { resetAuth } from 'components/auth/actions';
|
import { resetAuth } from 'components/auth/actions';
|
||||||
import { withRouter } from 'react-router';
|
import { withRouter } from 'react-router-dom';
|
||||||
import { FormattedMessage as Message } from 'react-intl';
|
import { FormattedMessage as Message } from 'react-intl';
|
||||||
import { Route, Link, Switch } from 'react-router-dom';
|
import { Route, Link, Switch } from 'react-router-dom';
|
||||||
import Helmet from 'react-helmet';
|
import Helmet from 'react-helmet';
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import sinon from 'sinon';
|
import sinon from 'sinon';
|
||||||
import expect from 'unexpected';
|
import expect from 'test/unexpected';
|
||||||
import {shallow} from 'enzyme';
|
import {shallow} from 'enzyme';
|
||||||
|
|
||||||
import RulesPage from './RulesPage';
|
import RulesPage from './RulesPage';
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import expect from 'unexpected';
|
import expect from 'test/unexpected';
|
||||||
|
|
||||||
describe('promise.prototype.finally', () => {
|
describe('promise.prototype.finally', () => {
|
||||||
it('should be invoked after promise resolved', () =>
|
it('should be invoked after promise resolved', () =>
|
||||||
|
@ -41,37 +41,37 @@ export function changePassword(id: number, {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function acceptRules(id: number) {
|
export function acceptRules(id: number): Promise<{ success: bool }> {
|
||||||
return request.post(`/api/v1/accounts/${id}/rules`);
|
return request.post(`/api/v1/accounts/${id}/rules`);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function changeUsername(id: number, username: ?string, password: ?string) {
|
export function changeUsername(id: number, username: ?string, password: ?string): Promise<{ success: bool }> {
|
||||||
return request.post(`/api/v1/accounts/${id}/username`, {
|
return request.post(`/api/v1/accounts/${id}/username`, {
|
||||||
username,
|
username,
|
||||||
password,
|
password,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function changeLang(id: number, lang: string) {
|
export function changeLang(id: number, lang: string): Promise<{ success: bool }> {
|
||||||
return request.post(`/api/v1/accounts/${id}/language`, {
|
return request.post(`/api/v1/accounts/${id}/language`, {
|
||||||
lang,
|
lang,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function requestEmailChange(id: number, password: string) {
|
export function requestEmailChange(id: number, password: string): Promise<{ success: bool }> {
|
||||||
return request.post(`/api/v1/accounts/${id}/email-verification`, {
|
return request.post(`/api/v1/accounts/${id}/email-verification`, {
|
||||||
password,
|
password,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function setNewEmail(id: number, email: string, key: string) {
|
export function setNewEmail(id: number, email: string, key: string): Promise<{ success: bool }> {
|
||||||
return request.post(`/api/v1/accounts/${id}/new-email-verification`, {
|
return request.post(`/api/v1/accounts/${id}/new-email-verification`, {
|
||||||
email,
|
email,
|
||||||
key,
|
key,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function confirmNewEmail(id: number, key: string) {
|
export function confirmNewEmail(id: number, key: string): Promise<{ success: bool }> {
|
||||||
return request.post(`/api/v1/accounts/${id}/email`, {
|
return request.post(`/api/v1/accounts/${id}/email`, {
|
||||||
key,
|
key,
|
||||||
});
|
});
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import expect from 'unexpected';
|
import expect from 'test/unexpected';
|
||||||
import sinon from 'sinon';
|
import sinon from 'sinon';
|
||||||
|
|
||||||
import request from 'services/request';
|
import request from 'services/request';
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* eslint-disable camelcase */
|
/* eslint-disable camelcase */
|
||||||
import expect from 'unexpected';
|
import expect from 'test/unexpected';
|
||||||
import sinon from 'sinon';
|
import sinon from 'sinon';
|
||||||
|
|
||||||
import request from 'services/request';
|
import request from 'services/request';
|
||||||
|
@ -4,6 +4,18 @@ import type { Resp } from 'services/request';
|
|||||||
import type { ApplicationType } from 'components/dev/apps';
|
import type { ApplicationType } from 'components/dev/apps';
|
||||||
import request from 'services/request';
|
import request from 'services/request';
|
||||||
|
|
||||||
|
export type Scope =
|
||||||
|
| 'minecraft_server_session'
|
||||||
|
| 'offline_access'
|
||||||
|
| 'account_info'
|
||||||
|
| 'account_email';
|
||||||
|
|
||||||
|
export type Client = {|
|
||||||
|
id: string,
|
||||||
|
name: string,
|
||||||
|
description: string
|
||||||
|
|};
|
||||||
|
|
||||||
export type OauthAppResponse = {
|
export type OauthAppResponse = {
|
||||||
clientId: string,
|
clientId: string,
|
||||||
clientSecret: string,
|
clientSecret: string,
|
||||||
@ -24,7 +36,7 @@ type OauthRequestData = {
|
|||||||
redirect_uri: string,
|
redirect_uri: string,
|
||||||
response_type: string,
|
response_type: string,
|
||||||
description: string,
|
description: string,
|
||||||
scope: string,
|
scope: Scope,
|
||||||
prompt: string,
|
prompt: string,
|
||||||
login_hint?: string,
|
login_hint?: string,
|
||||||
state?: string,
|
state?: string,
|
||||||
@ -35,7 +47,7 @@ export type OauthData = {
|
|||||||
redirectUrl: string,
|
redirectUrl: string,
|
||||||
responseType: string,
|
responseType: string,
|
||||||
description: string,
|
description: string,
|
||||||
scope: string,
|
scope: Scope,
|
||||||
prompt: 'none' | 'consent' | 'select_account',
|
prompt: 'none' | 'consent' | 'select_account',
|
||||||
loginHint?: string,
|
loginHint?: string,
|
||||||
state?: string
|
state?: string
|
||||||
@ -51,19 +63,28 @@ type FormPayloads = {
|
|||||||
|
|
||||||
const api = {
|
const api = {
|
||||||
validate(oauthData: OauthData) {
|
validate(oauthData: OauthData) {
|
||||||
return request.get(
|
return request.get<{|
|
||||||
|
session: {|
|
||||||
|
scopes: Scope[],
|
||||||
|
|},
|
||||||
|
client: Client,
|
||||||
|
oAuth: {||},
|
||||||
|
|}>(
|
||||||
'/api/oauth2/v1/validate',
|
'/api/oauth2/v1/validate',
|
||||||
getOAuthRequest(oauthData)
|
getOAuthRequest(oauthData)
|
||||||
).catch(handleOauthParamsValidation);
|
).catch(handleOauthParamsValidation);
|
||||||
},
|
},
|
||||||
|
|
||||||
complete(oauthData: OauthData, params: {accept?: bool} = {}): Promise<Resp<{
|
complete(oauthData: OauthData, params: {accept?: bool} = {}): Promise<{
|
||||||
success: bool,
|
success: bool,
|
||||||
redirectUri: string,
|
redirectUri: string,
|
||||||
}>> {
|
}> {
|
||||||
const query = request.buildQuery(getOAuthRequest(oauthData));
|
const query = request.buildQuery(getOAuthRequest(oauthData));
|
||||||
|
|
||||||
return request.post(
|
return request.post<{
|
||||||
|
success: bool,
|
||||||
|
redirectUri: string,
|
||||||
|
}>(
|
||||||
`/api/oauth2/v1/complete?${query}`,
|
`/api/oauth2/v1/complete?${query}`,
|
||||||
typeof params.accept === 'undefined' ? {} : {accept: params.accept}
|
typeof params.accept === 'undefined' ? {} : {accept: params.accept}
|
||||||
).catch((resp = {}) => {
|
).catch((resp = {}) => {
|
||||||
@ -92,28 +113,28 @@ const api = {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
create(type: string, formParams: FormPayloads): Promise<Resp<{success: bool, data: OauthAppResponse}>> {
|
create(type: string, formParams: FormPayloads) {
|
||||||
return request.post(`/api/v1/oauth2/${type}`, formParams);
|
return request.post<{success: bool, data: OauthAppResponse}>(`/api/v1/oauth2/${type}`, formParams);
|
||||||
},
|
},
|
||||||
|
|
||||||
update(clientId: string, formParams: FormPayloads): Promise<Resp<{success: bool, data: OauthAppResponse}>> {
|
update(clientId: string, formParams: FormPayloads) {
|
||||||
return request.put(`/api/v1/oauth2/${clientId}`, formParams);
|
return request.put<{success: bool, data: OauthAppResponse}>(`/api/v1/oauth2/${clientId}`, formParams);
|
||||||
},
|
},
|
||||||
|
|
||||||
getApp(clientId: string): Promise<Resp<OauthAppResponse>> {
|
getApp(clientId: string) {
|
||||||
return request.get(`/api/v1/oauth2/${clientId}`);
|
return request.get<OauthAppResponse>(`/api/v1/oauth2/${clientId}`);
|
||||||
},
|
},
|
||||||
|
|
||||||
getAppsByUser(userId: number): Promise<Resp<Array<OauthAppResponse>>> {
|
getAppsByUser(userId: number): Promise<OauthAppResponse[]> {
|
||||||
return request.get(`/api/v1/accounts/${userId}/oauth2/clients`);
|
return request.get(`/api/v1/accounts/${userId}/oauth2/clients`);
|
||||||
},
|
},
|
||||||
|
|
||||||
reset(clientId: string, regenerateSecret: bool = false): Promise<Resp<{success: bool, data: OauthAppResponse}>> {
|
reset(clientId: string, regenerateSecret: bool = false) {
|
||||||
return request.post(`/api/v1/oauth2/${clientId}/reset${regenerateSecret ? '?regenerateSecret' : ''}`);
|
return request.post<{success: bool, data: OauthAppResponse}>(`/api/v1/oauth2/${clientId}/reset${regenerateSecret ? '?regenerateSecret' : ''}`);
|
||||||
},
|
},
|
||||||
|
|
||||||
delete(clientId: string): Promise<Resp<{success: bool}>> {
|
delete(clientId: string) {
|
||||||
return request.delete(`/api/v1/oauth2/${clientId}`);
|
return request.delete<{success: bool}>(`/api/v1/oauth2/${clientId}`);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import expect from 'unexpected';
|
import expect from 'test/unexpected';
|
||||||
import sinon from 'sinon';
|
import sinon from 'sinon';
|
||||||
import request from 'services/request';
|
import request from 'services/request';
|
||||||
import options from './options';
|
import options from './options';
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import expect from 'unexpected';
|
import expect from 'test/unexpected';
|
||||||
import sinon from 'sinon';
|
import sinon from 'sinon';
|
||||||
|
|
||||||
import AuthFlow from 'services/authFlow/AuthFlow';
|
import AuthFlow from 'services/authFlow/AuthFlow';
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import expect from 'unexpected';
|
import expect from 'test/unexpected';
|
||||||
import sinon from 'sinon';
|
import sinon from 'sinon';
|
||||||
|
|
||||||
import AuthFlow from 'services/authFlow/AuthFlow';
|
import AuthFlow from 'services/authFlow/AuthFlow';
|
||||||
@ -354,9 +354,9 @@ describe('AuthFlow', () => {
|
|||||||
|
|
||||||
flow.handleRequest(request);
|
flow.handleRequest(request);
|
||||||
|
|
||||||
expect(flow.getRequest(), 'to equal', {
|
expect(flow.getRequest(), 'to satisfy', {
|
||||||
...request,
|
...request,
|
||||||
query: new URLSearchParams(),
|
query: expect.it('to be an', URLSearchParams),
|
||||||
params: {}
|
params: {}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import expect from 'unexpected';
|
import expect from 'test/unexpected';
|
||||||
import sinon from 'sinon';
|
import sinon from 'sinon';
|
||||||
|
|
||||||
import CompleteState from 'services/authFlow/CompleteState';
|
import CompleteState from 'services/authFlow/CompleteState';
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import expect from 'unexpected';
|
import expect from 'test/unexpected';
|
||||||
import sinon from 'sinon';
|
import sinon from 'sinon';
|
||||||
|
|
||||||
import MfaState from './MfaState';
|
import MfaState from './MfaState';
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import expect from 'unexpected';
|
import expect from 'test/unexpected';
|
||||||
import sinon from 'sinon';
|
import sinon from 'sinon';
|
||||||
|
|
||||||
import PasswordState from 'services/authFlow/PasswordState';
|
import PasswordState from 'services/authFlow/PasswordState';
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* A helper wrapper service around window.history
|
* A helper wrapper service around window.history
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import createBrowserHistory from 'history/createBrowserHistory';
|
import { createBrowserHistory } from 'history';
|
||||||
|
|
||||||
export const browserHistory = createBrowserHistory();
|
export const browserHistory = createBrowserHistory();
|
||||||
|
|
||||||
@ -11,9 +11,9 @@ browserHistory.listen(() => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
function patchHistory(history) {
|
function patchHistory(history) {
|
||||||
Object.assign(history.location,
|
Object.assign(history.location, {
|
||||||
{query: new URLSearchParams(history.location.search)}
|
query: new URLSearchParams(history.location.search)
|
||||||
);
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
patchHistory(browserHistory);
|
patchHistory(browserHistory);
|
||||||
@ -27,7 +27,10 @@ export default {
|
|||||||
* @return {bool} - whether history.back() can be safetly called
|
* @return {bool} - whether history.back() can be safetly called
|
||||||
*/
|
*/
|
||||||
canGoBack() {
|
canGoBack() {
|
||||||
return document.referrer.includes(`${location.protocol}//${location.host}`)
|
return (
|
||||||
|| this.initialLength < window.history.length;
|
document.referrer.includes(
|
||||||
|
`${location.protocol}//${location.host}`
|
||||||
|
) || this.initialLength < window.history.length
|
||||||
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import sinon from 'sinon';
|
import sinon from 'sinon';
|
||||||
import expect from 'unexpected';
|
import expect from 'test/unexpected';
|
||||||
|
|
||||||
import PromiseMiddlewareLayer from 'services/request/PromiseMiddlewareLayer';
|
import PromiseMiddlewareLayer from 'services/request/PromiseMiddlewareLayer';
|
||||||
|
|
||||||
|
@ -6,8 +6,9 @@ import RequestAbortedError from './RequestAbortedError';
|
|||||||
const middlewareLayer = new PromiseMiddlewareLayer();
|
const middlewareLayer = new PromiseMiddlewareLayer();
|
||||||
|
|
||||||
export type Resp<T> = {
|
export type Resp<T> = {
|
||||||
|
...$Exact<T>,
|
||||||
originalResponse: Response
|
originalResponse: Response
|
||||||
} & T;
|
};
|
||||||
|
|
||||||
type Middleware = {
|
type Middleware = {
|
||||||
before?: () => Promise<*>,
|
before?: () => Promise<*>,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import expect from 'unexpected';
|
import expect from 'test/unexpected';
|
||||||
import sinon from 'sinon';
|
import sinon from 'sinon';
|
||||||
|
|
||||||
import request from 'services/request';
|
import request from 'services/request';
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
import 'polyfills';
|
import 'polyfills';
|
||||||
import { configure } from 'enzyme';
|
import { configure } from 'enzyme';
|
||||||
import Adapter from 'enzyme-adapter-react-16';
|
import Adapter from 'enzyme-adapter-react-16';
|
||||||
import expect from 'unexpected';
|
|
||||||
|
|
||||||
expect.use(require('unexpected-sinon'));
|
|
||||||
configure({ adapter: new Adapter() });
|
configure({ adapter: new Adapter() });
|
||||||
|
|
||||||
if (!window.localStorage) {
|
if (!window.localStorage) {
|
||||||
|
7
src/test/unexpected.js
Normal file
7
src/test/unexpected.js
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
import unexpected from 'unexpected';
|
||||||
|
|
||||||
|
const expect = unexpected.clone();
|
||||||
|
|
||||||
|
expect.use(require('unexpected-sinon'));
|
||||||
|
|
||||||
|
export default expect;
|
Loading…
x
Reference in New Issue
Block a user