Bump more navigator frontend deps (#8141)

changelog_begin
changelog_end
This commit is contained in:
Moritz Kiefer 2020-12-03 15:58:43 +01:00 committed by GitHub
parent 56c876ba46
commit 92e4c1f6d4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 1116 additions and 1117 deletions

View File

@ -20,23 +20,22 @@
"lint": "tslint --project tslint.json" "lint": "tslint --project tslint.json"
}, },
"devDependencies": { "devDependencies": {
"@types/modernizr": "^3.5.3", "@bazel/hide-bazel-files": "^1.7.0",
"@bazel/hide-bazel-files": "1.6.0", "@types/async": "^3.2.5",
"@types/async": "2.0.39",
"@types/babel-core": "^6.25.3", "@types/babel-core": "^6.25.3",
"@types/classnames": "0.0.32", "@types/classnames": "^2.2.11",
"@types/color": "1.0.3", "@types/color": "^3.0.1",
"@types/deep-equal": "1.0.0", "@types/deep-equal": "^1.0.1",
"@types/lodash": "4.14.76", "@types/lodash": "^4.14.76",
"@types/react": "^16.9.41", "@types/modernizr": "^3.5.3",
"@types/react-autosuggest": "8.0.1", "@types/react": "^17.0.0",
"@types/react-dom": "^16.9.8", "@types/react-autosuggest": "^10.0.1",
"@types/react-dom": "^17.0.0",
"@types/react-overlays": "0.8.4", "@types/react-overlays": "0.8.4",
"@types/react-redux": "^5.0.8 <5.0.13", "@types/react-redux": "^7.1.11",
"@types/react-virtualized": "9.7.4", "@types/react-virtualized": "9.7.4",
"@types/route-parser": "0.0.0", "@types/route-parser": "0.0.0",
"@types/styled-components": "^5.1.0", "@types/styled-components": "^5.1.0",
"@types/uuidjs": "3.3.2",
"apollo": "^2.31.1", "apollo": "^2.31.1",
"case-sensitive-paths-webpack-plugin": "2.2.0", "case-sensitive-paths-webpack-plugin": "2.2.0",
"css-loader": "3.2.0", "css-loader": "3.2.0",
@ -50,7 +49,7 @@
"style-loader": "1.0.0", "style-loader": "1.0.0",
"ts-loader": "6.2.1", "ts-loader": "6.2.1",
"tsconfig-paths-webpack-plugin": "3.2.0", "tsconfig-paths-webpack-plugin": "3.2.0",
"tslint": "5.20.1", "tslint": "^5.20.1",
"tslint-loader": "3.5.4", "tslint-loader": "3.5.4",
"tslint-react": "4.1.0", "tslint-react": "4.1.0",
"typescript": "4.1.2", "typescript": "4.1.2",
@ -60,33 +59,34 @@
"webpack-dev-server": "3.9.0" "webpack-dev-server": "3.9.0"
}, },
"dependencies": { "dependencies": {
"@apollo/client": "^3.2.9", "@apollo/client": "^3.3.2",
"babel-standalone": "^6.26.0", "babel-standalone": "^6.26.0",
"color": "1.0.3", "color": "^3.0.1",
"deep-equal": "~1.0.1", "deep-equal": "^2.0.5",
"enzyme": "^3.11.0", "enzyme": "^3.11.0",
"es6-promise": "^4.1.1", "es6-promise": "^4.1.1",
"graphql": "^15.4.0", "graphql": "^15.4.0",
"jpeg-js": "^0.4.1",
"lodash": "^4.17.19", "lodash": "^4.17.19",
"modernizr": "^3.11.4", "modernizr": "^3.11.4",
"moment": "^2.23.0", "moment": "^2.23.0",
"normalize.css": "^7.0.0", "normalize.css": "^7.0.0",
"react": "^16.13.1", "react": "^17.0.1",
"react-autosuggest": "9.3.2", "react-autosuggest": "^10.0.4",
"react-dom": "^16.13.1", "react-dom": "^17.0.1",
"react-is": "^16.13.1", "react-is": "^17.0.1",
"react-markdown": "2.5.0", "react-markdown": "2.5.0",
"react-overlays": "1.0.0-beta.2", "react-overlays": "1.0.0-beta.2",
"react-redux": "^5.0.5", "react-redux": "^7.2.2",
"react-virtualized": "^9.9.0", "react-virtualized": "^9.9.0",
"redux": "^3.7.0", "redux": "^4.0.5",
"redux-thunk": "~2.2.0", "redux-thunk": "^2.3.0",
"route-parser": "0.0.5", "route-parser": "0.0.5",
"styled-components": "^5.1.1", "styled-components": "^5.1.1",
"subscriptions-transport-ws": "^0.9.18", "subscriptions-transport-ws": "^0.9.18",
"typescript-collections": "1.2.5", "typescript-collections": "1.2.5",
"uuidjs": "3.5.3", "uuidjs": "^4.2.6",
"whatwg-fetch": "^2.0.3" "whatwg-fetch": "^3.5.0"
}, },
"resolutions": { "resolutions": {
"**/elliptic": "^6.5.3", "**/elliptic": "^6.5.3",

View File

@ -1,11 +1,10 @@
// Copyright (c) 2020 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. // Copyright (c) 2020 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
import { Dispatch, styled, ThunkAction } from '@da/ui-core'; import { Dispatch, styled } from '@da/ui-core';
import * as React from 'react'; import * as React from 'react';
import { connect } from 'react-redux'; import { connect, ConnectedComponent } from 'react-redux';
import { compose } from 'redux'; import { ThunkAction, ThunkDispatch } from 'redux-thunk';
import { Connect } from '../../types';
import * as App from '../app'; import * as App from '../app';
export type Action export type Action
@ -38,7 +37,7 @@ export interface State {
backendVersionInfo: BackendVersionInfoResult; backendVersionInfo: BackendVersionInfoResult;
} }
export type ToSelf = (action: Action | ThunkAction<void>) => App.Action; export type ToSelf = (action: Action | ThunkAction<void, App.State, undefined, Action>) => App.Action;
export function init(): State { export function init(): State {
return { return {
@ -46,7 +45,7 @@ export function init(): State {
}; };
} }
export function reloadBackendInfo(toSelf: ToSelf): ThunkAction<void> { export function reloadBackendInfo(toSelf: ToSelf): ThunkAction<void, App.State, undefined, App.Action> {
return (dispatch) => { return (dispatch) => {
dispatch(toSelf(setBackendInfoLoading())); dispatch(toSelf(setBackendInfoLoading()));
@ -65,13 +64,13 @@ export function reloadBackendInfo(toSelf: ToSelf): ThunkAction<void> {
}; };
} }
function handleBackendInfoResponse(to: ToSelf, dispatch: Dispatch<Action>) { function handleBackendInfoResponse(to: ToSelf, dispatch: Dispatch<App.Action>) {
return (source: BackendVersionInfo): void => { return (source: BackendVersionInfo): void => {
dispatch(to(setBackendInfoResult(source))); dispatch(to(setBackendInfoResult(source)));
}; };
} }
function handleBackendInfoFetchError(to: ToSelf, dispatch: Dispatch<Action>) { function handleBackendInfoFetchError(to: ToSelf, dispatch: Dispatch<App.Action>) {
// tslint:disable-next-line no-any // tslint:disable-next-line no-any
return (reason: any) => { return (reason: any) => {
if (reason instanceof Error) { if (reason instanceof Error) {
@ -119,12 +118,12 @@ interface OwnProps {
toSelf: ToSelf; toSelf: ToSelf;
} }
interface ReduxProps { interface ReduxProps {
dispatch: Dispatch<App.Action>; dispatch: ThunkDispatch<App.State, undefined, App.Action>;
} }
type Props = OwnProps & ReduxProps; type Props = OwnProps & ReduxProps;
const BackendInfo: React.StatelessComponent<{info: BackendVersionInfoResult}> const BackendInfo: React.FC<{info: BackendVersionInfoResult}>
= ({info}) => { = ({info}) => {
switch (info.type) { switch (info.type) {
case 'none': return <p />; case 'none': return <p />;
@ -169,6 +168,4 @@ class Component extends React.Component<Props, {}> {
} }
}; };
const withRedux: Connect<ReduxProps, OwnProps> = connect(); export const UI: ConnectedComponent<typeof Component, OwnProps> = connect()(Component);
export const UI = compose(withRedux)(Component);

View File

@ -5,7 +5,7 @@ import { defaultTheme, Dispatch, ThemeInterface, ThemeProvider } from '@da/ui-co
import * as LedgerWatcher from '@da/ui-core/lib/ledger-watcher'; import * as LedgerWatcher from '@da/ui-core/lib/ledger-watcher';
import * as Session from '@da/ui-core/lib/session'; import * as Session from '@da/ui-core/lib/session';
import * as React from 'react'; import * as React from 'react';
import { connect } from 'react-redux'; import { connect, ConnectedComponent } from 'react-redux';
import { Action as ReduxAction } from 'redux'; import { Action as ReduxAction } from 'redux';
import Frame from '../../components/Frame'; import Frame from '../../components/Frame';
import { import {
@ -17,7 +17,6 @@ import {
} from '../../config'; } from '../../config';
import * as Either from '../../config/either'; import * as Either from '../../config/either';
import logoUrl from '../../images/logo-large.png'; import logoUrl from '../../images/logo-large.png';
import { Connect } from '../../types';
import * as ConfigSource from '../configsource'; import * as ConfigSource from '../configsource';
import * as Page from '../page'; import * as Page from '../page';
@ -243,11 +242,5 @@ class Component extends React.Component<Props, ComponentState> {
} }
}; };
const withRedux: Connect<ReduxProps, OwnProps> = export const UI: ConnectedComponent<typeof Component, OwnProps> =
connect( connect((state) => ({state}), (dispatch) => ({dispatch}))(Component);
(state) => ({ state }),
(dispatch) => ({ dispatch }),
);
export const UI = withRedux(Component);

View File

@ -1,13 +1,12 @@
// Copyright (c) 2020 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. // Copyright (c) 2020 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
import { Button, Dispatch, styled, ThunkAction } from '@da/ui-core'; import { Button, styled } from '@da/ui-core';
import * as Session from '@da/ui-core/lib/session'; import * as Session from '@da/ui-core/lib/session';
import * as React from 'react'; import * as React from 'react';
import { connect } from 'react-redux'; import { connect, ConnectedComponent } from 'react-redux';
import { compose } from 'redux'; import { ThunkAction, ThunkDispatch } from 'redux-thunk';
import { configFileAPI, ConfigType, prettyPrintConfig } from '../../config'; import { configFileAPI, ConfigType, prettyPrintConfig } from '../../config';
import { Connect } from '../../types';
import * as App from '../app'; import * as App from '../app';
export type Action export type Action
@ -37,7 +36,7 @@ export interface State {
result: StateResult; result: StateResult;
} }
export type ToSelf = (action: Action | ThunkAction<void>) => App.Action; export type ToSelf = (action: Action | ThunkAction<void, undefined, undefined, Action>) => App.Action;
export function init(): State { export function init(): State {
return { return {
@ -46,7 +45,7 @@ export function init(): State {
}; };
} }
export function reload(toSelf: ToSelf): ThunkAction<void> { export function reload(toSelf: ToSelf): ThunkAction<void, App.State, undefined, App.Action> {
return (dispatch) => { return (dispatch) => {
dispatch(toSelf(setLoading())); dispatch(toSelf(setLoading()));
@ -71,13 +70,13 @@ export function reload(toSelf: ToSelf): ThunkAction<void> {
}; };
} }
function handleResponse(to: ToSelf, dispatch: Dispatch<Action>) { function handleResponse(to: ToSelf, dispatch: ThunkDispatch<App.State, undefined, App.Action>) {
return (source: string): void => { return (source: string): void => {
dispatch(to(setSource(source))); dispatch(to(setSource(source)));
}; };
} }
function handleFetchError(to: ToSelf, dispatch: Dispatch<Action>) { function handleFetchError(to: ToSelf, dispatch: ThunkDispatch<App.State, undefined, App.Action>) {
// tslint:disable-next-line no-any // tslint:disable-next-line no-any
return (reason: any) => { return (reason: any) => {
if (reason instanceof Error) { if (reason instanceof Error) {
@ -130,7 +129,7 @@ interface OwnProps {
toSelf: ToSelf; toSelf: ToSelf;
} }
interface ReduxProps { interface ReduxProps {
dispatch: Dispatch<App.Action>; dispatch: ThunkDispatch<App.State, undefined, App.Action>;
} }
type Props = OwnProps & ReduxProps; type Props = OwnProps & ReduxProps;
@ -185,6 +184,4 @@ class Component extends React.Component<Props, {}> {
} }
}; };
const withRedux: Connect<ReduxProps, OwnProps> = connect(); export const UI: ConnectedComponent<typeof Component, OwnProps> = connect()(Component);
export const UI = compose(withRedux)(Component);

View File

@ -8,14 +8,12 @@ import { DamlLfValue } from '@da/ui-core/lib/api/DamlLfValue';
import * as LedgerWatcher from '@da/ui-core/lib/ledger-watcher'; import * as LedgerWatcher from '@da/ui-core/lib/ledger-watcher';
import * as React from 'react'; import * as React from 'react';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { compose } from 'redux';
import { import {
ContractDetailsById, ContractDetailsById,
ContractDetailsById_node_Contract, ContractDetailsById_node_Contract,
ContractDetailsByIdVariables, ContractDetailsByIdVariables,
ContractExercise, ContractExercise,
} from '../../api/Queries'; } from '../../api/Queries';
import { Connect } from '../../types';
import * as App from '../app'; import * as App from '../app';
import ContractComponent from './ContractComponent'; import ContractComponent from './ContractComponent';
@ -187,7 +185,7 @@ const mutation = gql`
// generally confusing to say the least, but works out with a bit of care and // generally confusing to say the least, but works out with a bit of care and
// thinking about the ordering and what each connect function adds. // thinking about the ordering and what each connect function adds.
const _withMutation: Connect<MutationProps, OwnProps> = const _withMutation =
withMutation<OwnProps, ContractExercise, {}, MutationProps>(mutation, withMutation<OwnProps, ContractExercise, {}, MutationProps>(mutation,
{ {
props: ({mutate}): MutationProps => ({ props: ({mutate}): MutationProps => ({
@ -197,8 +195,8 @@ const _withMutation: Connect<MutationProps, OwnProps> =
}, },
); );
const _withQuery: Connect<QueryProps, OwnProps & MutationProps> = const _withQuery =
withQuery<OwnProps, ContractDetailsById, ContractDetailsByIdVariables, QueryProps>(query, { withQuery<OwnProps & MutationProps, ContractDetailsById, ContractDetailsByIdVariables, QueryProps>(query, {
props: ({ data }) => { props: ({ data }) => {
const node = data?.node; const node = data?.node;
const contract = (node && node.__typename === 'Contract') ? node : null; const contract = (node && node.__typename === 'Contract') ? node : null;
@ -210,11 +208,5 @@ const _withQuery: Connect<QueryProps, OwnProps & MutationProps> =
options: ({ state: { id } }: OwnProps) => ({ variables: { id } as ContractDetailsByIdVariables}), options: ({ state: { id } }: OwnProps) => ({ variables: { id } as ContractDetailsByIdVariables}),
}); });
const withRedux: Connect<ReduxProps, OwnProps & QueryProps & MutationProps> = export const UI: React.ComponentClass<OwnProps> =
connect(); _withMutation(_withQuery(connect()(Component)));
export const UI = compose(
_withMutation,
_withQuery,
withRedux,
)(Component);

View File

@ -12,10 +12,8 @@ import {
import { User } from '@da/ui-core/lib/session'; import { User } from '@da/ui-core/lib/session';
import * as React from 'react'; import * as React from 'react';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { compose } from 'redux';
import { contract as contractRoute } from '../../routes'; import { contract as contractRoute } from '../../routes';
import { pathToAction } from '../../routes'; import { pathToAction } from '../../routes';
import { Connect } from '../../types';
import * as App from '../app'; import * as App from '../app';
import columns from './columns'; import columns from './columns';
import { Contract, dataToRows, makeQueryVariables, query } from './data'; import { Contract, dataToRows, makeQueryVariables, query } from './data';
@ -111,9 +109,4 @@ class Component extends React.Component<Props, {}> {
} }
} }
const withRedux: Connect<ReduxProps, OwnProps & ApolloProps> = connect(); export const UI: React.ComponentClass<OwnProps> = withApollo<OwnProps>(connect()(Component));
export const UI: React.ComponentClass<OwnProps> = compose(
(x) => withApollo<OwnProps>(x),
withRedux,
)(Component);

View File

@ -1,16 +1,13 @@
// Copyright (c) 2020 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. // Copyright (c) 2020 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
import { import { ChoicesButton } from '@da/ui-core';
ChoicesButton,
Dispatch,
WithRedux,
} from '@da/ui-core';
import * as LedgerWatcher from '@da/ui-core/lib/ledger-watcher'; import * as LedgerWatcher from '@da/ui-core/lib/ledger-watcher';
import * as Session from '@da/ui-core/lib/session'; import * as Session from '@da/ui-core/lib/session';
import { CellRenderParams, ColumnConfig } from '@da/ui-core/lib/Table'; import { CellRenderParams, ColumnConfig } from '@da/ui-core/lib/Table';
import * as React from 'react'; import * as React from 'react';
import { connect } from 'react-redux'; import { connect, ConnectedComponent } from 'react-redux';
import { ThunkDispatch } from 'redux-thunk';
import Link from '../../components/Link'; import Link from '../../components/Link';
import { ConfigInterface, ConfigType } from '../../config'; import { ConfigInterface, ConfigType } from '../../config';
import * as Routes from '../../routes'; import * as Routes from '../../routes';
@ -139,7 +136,7 @@ interface OwnProps {
} }
interface DispatchProps { interface DispatchProps {
dispatch: Dispatch<Action>; dispatch: ThunkDispatch<App.State, undefined, App.Action>;
} }
type Props = DispatchProps & OwnProps; type Props = DispatchProps & OwnProps;
@ -311,6 +308,4 @@ class Component extends React.Component<Props, ComponentState> {
} }
} }
const withRedux: WithRedux<Props> = connect(); export const UI: ConnectedComponent<typeof Component, OwnProps> = connect()(Component);
export const UI = withRedux(Component);

View File

@ -4,11 +4,11 @@
// Copyright (c) 2020, Digital Asset (Switzerland) GmbH and/or its affiliates. // Copyright (c) 2020, Digital Asset (Switzerland) GmbH and/or its affiliates.
// All rights reserved. // All rights reserved.
import { Dispatch, styled, ThunkAction } from '@da/ui-core'; import { Dispatch, styled } from '@da/ui-core';
import * as React from 'react'; import * as React from 'react';
import { connect } from 'react-redux'; import { connect, ConnectedComponent } from 'react-redux';
import { compose } from 'redux'; import { AnyAction } from 'redux';
import { Connect } from '../../types'; import { ThunkAction, ThunkDispatch } from 'redux-thunk';
import * as App from '../app'; import * as App from '../app';
// The backend returns an opaque JSON object // The backend returns an opaque JSON object
@ -38,7 +38,7 @@ export interface State {
backendInfo: BackendInfoResult; backendInfo: BackendInfoResult;
} }
export type ToSelf = (action: Action | ThunkAction<void>) => App.Action; export type ToSelf = (action: Action | ThunkAction<void, App.State, undefined, Action>) => App.Action;
export function init(): State { export function init(): State {
return { return {
@ -46,7 +46,7 @@ export function init(): State {
}; };
} }
export function reloadBackendInfo(toSelf: ToSelf): ThunkAction<void> { export function reloadBackendInfo(toSelf: ToSelf): ThunkAction<void, App.State, undefined, AnyAction> {
return (dispatch) => { return (dispatch) => {
dispatch(toSelf(setBackendInfoLoading())); dispatch(toSelf(setBackendInfoLoading()));
@ -65,13 +65,13 @@ export function reloadBackendInfo(toSelf: ToSelf): ThunkAction<void> {
}; };
} }
function handleBackendInfoResponse(to: ToSelf, dispatch: Dispatch<Action>) { function handleBackendInfoResponse(to: ToSelf, dispatch: ThunkDispatch<App.State, undefined, App.Action>) {
return (source: Object): void => { return (source: Object): void => {
dispatch(to(setBackendInfoResult(source))); dispatch(to(setBackendInfoResult(source)));
}; };
} }
function handleBackendInfoFetchError(to: ToSelf, dispatch: Dispatch<Action>) { function handleBackendInfoFetchError(to: ToSelf, dispatch: ThunkDispatch<App.State, undefined, App.Action>) {
// tslint:disable-next-line no-any // tslint:disable-next-line no-any
return (reason: any) => { return (reason: any) => {
if (reason instanceof Error) { if (reason instanceof Error) {
@ -154,6 +154,4 @@ class Component extends React.Component<Props, {}> {
} }
}; };
const withRedux: Connect<ReduxProps, OwnProps> = connect(); export const UI: ConnectedComponent<typeof Component, OwnProps> = connect()(Component);
export const UI = compose(withRedux)(Component);

View File

@ -8,7 +8,6 @@ import { DamlLfValue } from '@da/ui-core/lib/api/DamlLfValue';
import * as LedgerWatcher from '@da/ui-core/lib/ledger-watcher'; import * as LedgerWatcher from '@da/ui-core/lib/ledger-watcher';
import * as React from 'react'; import * as React from 'react';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { compose } from 'redux';
import { import {
CreateContract, CreateContract,
CreateContractVariables, CreateContractVariables,
@ -18,7 +17,6 @@ import {
} from '../../api/Queries'; } from '../../api/Queries';
import { pathToAction } from '../../routes'; import { pathToAction } from '../../routes';
import { contracts as dashboardRoute } from '../../routes'; import { contracts as dashboardRoute } from '../../routes';
import { Connect } from '../../types';
import * as App from '../app'; import * as App from '../app';
import TemplateComponent from './TemplateComponent'; import TemplateComponent from './TemplateComponent';
@ -142,7 +140,7 @@ const mutation = gql`
* - the contract data fetched from the GraphQL API * - the contract data fetched from the GraphQL API
*/ */
const _withMutation: Connect<MutationProps, OwnProps> = const _withMutation =
withMutation<OwnProps, CreateContract, CreateContractVariables, MutationProps>(mutation, { withMutation<OwnProps, CreateContract, CreateContractVariables, MutationProps>(mutation, {
props: ({ mutate }) => ({ props: ({ mutate }) => ({
create: mutate && ((templateId: string, argument: DamlLfValue) => create: mutate && ((templateId: string, argument: DamlLfValue) =>
@ -150,17 +148,11 @@ const _withMutation: Connect<MutationProps, OwnProps> =
)}), )}),
}); });
const _withQuery: Connect<QueryProps, OwnProps & MutationProps> = const _withQuery =
withQuery<OwnProps, TemplateInstance, TemplateInstanceVariables, QueryProps>(query, { withQuery<OwnProps & MutationProps, TemplateInstance, TemplateInstanceVariables, QueryProps>(query, {
options: ({ state: { id } }) => options: ({ state: { id } }) =>
({ variables: { templateId: id } }), ({ variables: { templateId: id } }),
}); });
const withRedux: Connect<ReduxProps, OwnProps & QueryProps & MutationProps> = export const UI: React.ComponentClass<OwnProps> =
connect(); _withMutation(_withQuery(connect()(Component)));
export const UI = compose(
_withMutation,
_withQuery,
withRedux,
)(Component);

View File

@ -14,11 +14,9 @@ import {
import { User } from '@da/ui-core/lib/session'; import { User } from '@da/ui-core/lib/session';
import * as React from 'react'; import * as React from 'react';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { compose } from 'redux';
import { ContractsByTemplateParamQuery, ContractsByTemplateParamQueryVariables } from 'src/api/Queries'; import { ContractsByTemplateParamQuery, ContractsByTemplateParamQueryVariables } from 'src/api/Queries';
import { contract as contractRoute } from '../../routes'; import { contract as contractRoute } from '../../routes';
import { pathToAction } from '../../routes'; import { pathToAction } from '../../routes';
import { Connect } from '../../types';
import * as App from '../app'; import * as App from '../app';
import makeColumns from './columns'; import makeColumns from './columns';
import { import {
@ -132,14 +130,18 @@ class Component extends React.Component<Props, {}> {
} }
} }
const withRedux: Connect<ReduxProps, ApolloProps & OwnProps> = connect(); const withGraphQL
const withGraphQL: Connect<GraphQLProps, ReduxProps & ApolloProps & OwnProps>
= =
withQuery<Props, ContractsByTemplateParamQuery, ContractsByTemplateParamQueryVariables, GraphQLProps>( withQuery<
ReduxProps & ApolloProps & OwnProps,
ContractsByTemplateParamQuery,
ContractsByTemplateParamQueryVariables,
GraphQLProps>(
paramQuery, { options: (s) => makeParamQueryVariables(s) }); paramQuery, { options: (s) => makeParamQueryVariables(s) });
export const UI: React.ComponentClass<OwnProps> = compose( export const UI: React.ComponentClass<OwnProps> =
(x) => withApollo<OwnProps>(x), withApollo<OwnProps>(
withRedux, connect()(
withGraphQL, withGraphQL(Component),
)(Component); ),
);

View File

@ -9,15 +9,12 @@ import {
Dispatch, Dispatch,
WithGraphQL, WithGraphQL,
WithRedux,
} from '@da/ui-core'; } from '@da/ui-core';
import { User } from '@da/ui-core/lib/session'; import { User } from '@da/ui-core/lib/session';
import * as React from 'react'; import * as React from 'react';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { compose } from 'redux';
import { template as templateRoute } from '../../routes'; import { template as templateRoute } from '../../routes';
import { pathToAction } from '../../routes'; import { pathToAction } from '../../routes';
import { Connect } from '../../types';
import * as App from '../app'; import * as App from '../app';
import columns from './columns'; import columns from './columns';
import { import {
@ -120,10 +117,4 @@ class Component
} }
} }
const withRedux: WithRedux<Props & ApolloProps> = connect(); export const UI: React.ComponentClass<OwnProps> = withApollo<OwnProps>(connect()(Component));
const _withApollo: Connect<ApolloProps, Omit<Props, keyof ApolloProps>> = (x) => withApollo<Props>(x);
export const UI: React.ComponentClass<OwnProps> = compose(
_withApollo,
withRedux,
)(Component);

View File

@ -4,10 +4,9 @@
import { Dispatch, Route } from '@da/ui-core'; import { Dispatch, Route } from '@da/ui-core';
import UntypedLink, { HrefTarget } from '@da/ui-core/lib/Link'; import UntypedLink, { HrefTarget } from '@da/ui-core/lib/Link';
import * as React from 'react'; import * as React from 'react';
import { connect } from 'react-redux'; import { connect, ConnectedComponent } from 'react-redux';
import * as App from '../applets/app' import * as App from '../applets/app'
import { pathToAction } from '../routes'; import { pathToAction } from '../routes';
import { Connect } from '../types';
// Note: The react-redux typings for connect() try to remove // Note: The react-redux typings for connect() try to remove
// the 'dispatch' property from OwnProps. This makes sense since react-redux // the 'dispatch' property from OwnProps. This makes sense since react-redux
@ -58,6 +57,5 @@ class Link extends React.Component<Props, {}> {
} }
} }
const withRedux: Connect<ReduxProps, OwnProps> = connect(); const C: ConnectedComponent<typeof Link, React.PropsWithChildren<OwnProps>> = connect()(Link);
export default C;
export default withRedux(Link);

View File

@ -1,11 +1,15 @@
// Copyright (c) 2020 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. // Copyright (c) 2020 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
import { AdvanceTime, Button, Dispatch, NavBar, ThunkAction } from '@da/ui-core'; import { ApolloClient } from '@apollo/client';
import { withApollo } from '@apollo/client/react/hoc';
import { AdvanceTime, Button, Dispatch, NavBar } from '@da/ui-core';
import * as LedgerWatcher from '@da/ui-core/lib/ledger-watcher'; import * as LedgerWatcher from '@da/ui-core/lib/ledger-watcher';
import * as Session from '@da/ui-core/lib/session'; import * as Session from '@da/ui-core/lib/session';
import * as React from 'react'; import * as React from 'react';
import { connect } from 'react-redux'; import { connect, ConnectedComponent } from 'react-redux';
import { AnyAction } from 'redux';
import { ThunkAction } from 'redux-thunk'
import styled from 'styled-components'; import styled from 'styled-components';
import * as App from '../applets/app'; import * as App from '../applets/app';
import logoUrl from '../images/logo-large.png'; import logoUrl from '../images/logo-large.png';
@ -13,13 +17,14 @@ import { about } from '../routes';
import { Icon } from './Icon'; import { Icon } from './Icon';
import Link from './Link'; import Link from './Link';
function signOut(toSession: (action: Session.Action) => App.Action) { // tslint:disable-next-line:no-any
return Session.signOut(toSession, ((dispatch) => { function signOut<S>(client: ApolloClient<any>, toSession: (action: Session.Action) => App.Action) {
dispatch({ type: 'APOLLO_STORE_RESET', observableQueryIds: [] }); return Session.signOut<S, App.Action>(toSession, ((dispatch: Dispatch<App.Action>) => {
client.resetStore();
dispatch(App.resetApp()); dispatch(App.resetApp());
// Session.signOut signature can't handle ThunkAction // Session.signOut signature can't handle ThunkAction
// tslint:disable-next-line // tslint:disable-next-line
}) as ThunkAction<void, App.State> as any); }) as ThunkAction<void, App.State, undefined, AnyAction> as any);
} }
interface ReduxProps { interface ReduxProps {
@ -31,7 +36,8 @@ interface OwnProps {
user: Session.User; user: Session.User;
watcher: LedgerWatcher.State; watcher: LedgerWatcher.State;
} }
type Props = ReduxProps & OwnProps; // tslint:disable-next-line:no-any
type Props = ReduxProps & OwnProps & { client: ApolloClient<any> };
const InlineDiv = styled.div` const InlineDiv = styled.div`
display: inline; display: inline;
@ -80,12 +86,13 @@ const Component = ({
user, user,
dispatch, dispatch,
watcher, watcher,
client,
}: Props) => ( }: Props) => (
<NavBar logo={<Logo/>}> <NavBar logo={<Logo/>}>
<InlineDiv> <InlineDiv>
<Button <Button
type="nav-transparent" type="nav-transparent"
onClick={() => { dispatch(signOut(toSession)); }} onClick={() => { dispatch(signOut(client, toSession)); }}
> >
<LeftIcon name="user" /> <LeftIcon name="user" />
{user.id} {user.id}
@ -102,6 +109,6 @@ const Component = ({
</NavBar> </NavBar>
); );
export default connect<void, ReduxProps, OwnProps>( const C: ConnectedComponent<React.ComponentClass<OwnProps & ReduxProps>, OwnProps> =
null, (dispatch) => ({ dispatch }), connect()(withApollo<OwnProps & ReduxProps>(Component));
)(Component); export default C;

View File

@ -15,7 +15,7 @@ import * as React from 'react';
import * as ReactDOM from 'react-dom'; import * as ReactDOM from 'react-dom';
import { Provider } from 'react-redux'; import { Provider } from 'react-redux';
import { applyMiddleware, compose, createStore, Store } from 'redux'; import { applyMiddleware, compose, createStore, Store } from 'redux';
import ReduxThunk from 'redux-thunk'; import ReduxThunk, { ThunkDispatch } from 'redux-thunk';
import * as App from './applets/app'; import * as App from './applets/app';
import { pathToAction, stateToPath } from './routes'; import { pathToAction, stateToPath } from './routes';
@ -40,19 +40,24 @@ const client = new ApolloClient({
// Set up a function to compose Redux enhancers such that Redux DevTools // Set up a function to compose Redux enhancers such that Redux DevTools
// understand them. // understand them.
declare const window: { __REDUX_DEVTOOLS_EXTENSION_COMPOSE__?: Function }; declare global {
interface Window {
__REDUX_DEVTOOLS_EXTENSION_COMPOSE__?: Function
}
}
const composeEnhancers = const composeEnhancers =
typeof window === 'object' && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ typeof window === 'object' && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__
? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({}) ? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({})
: compose; : compose;
// Create Redux store // Create Redux store
const store: Store<App.State> = createStore<App.State>( const store: Store<App.State> & {dispatch: ThunkDispatch<App.State, undefined, App.Action>} =
App.makeReducer(), createStore<App.State, App.Action, undefined, undefined>(
composeEnhancers(applyMiddleware( App.makeReducer(),
Router.middleware({ stateToUrl: stateToPath, urlToAction: pathToAction }), composeEnhancers(applyMiddleware(
ReduxThunk, Router.middleware({ stateToUrl: stateToPath, urlToAction: pathToAction }),
)), ReduxThunk,
)),
); );
@ -68,5 +73,8 @@ ReactDOM.render((
document.getElementById('app'), document.getElementById('app'),
); );
// Dispatch an action for the initial URL so that the reducer can set the
// initial state correctly.
store.dispatch(pathToAction(window.location.pathname));
store.dispatch(App.initSession()); store.dispatch(App.initSession());
store.dispatch(App.initConfig()); store.dispatch(App.initConfig());

View File

@ -28,20 +28,16 @@ export interface RouterOptions<S> {
export type RouterMiddleware<S> = (options: RouterOptions<S>) => Middleware; export type RouterMiddleware<S> = (options: RouterOptions<S>) => Middleware;
export function middleware<S>(options: RouterOptions<S>): Middleware { export function middleware<S>(options: RouterOptions<S>): Middleware<{}, S> {
const { stateToUrl, urlToAction } = options; const { stateToUrl, urlToAction } = options;
return <S2>({ dispatch, getState }: MiddlewareAPI<S2>): (next: Dispatch<S>) => Dispatch<S> => { return ({ dispatch, getState }: MiddlewareAPI<Dispatch, S>): (next: Dispatch) => Dispatch => {
// Dispatch an action for the initial URL so that the reducer can set the
// initial state correctly.
dispatch(urlToAction(window.location.pathname));
// Install URL change listener. This dispatches an action whenever a URL is // Install URL change listener. This dispatches an action whenever a URL is
// popped from the browser history. // popped from the browser history.
window.onpopstate = (_: PopStateEvent) => { window.onpopstate = (_: PopStateEvent) => {
dispatch(urlToAction(window.location.pathname)); dispatch(urlToAction(window.location.pathname));
}; };
return (next: Dispatch<S2>) => ((action: Action) => { return (next: Dispatch) => ((action: Action) => {
// If this is a router action, we capture it and dispatch the action // If this is a router action, we capture it and dispatch the action
// corresponding to the specified URL. We then get the URL for the new // corresponding to the specified URL. We then get the URL for the new
// state and push or replace this onto the browser history. If it's not a // state and push or replace this onto the browser history. If it's not a
@ -55,6 +51,6 @@ export function middleware<S>(options: RouterOptions<S>): Middleware {
window.history.pushState({}, '', url); window.history.pushState({}, '', url);
} }
return returnValue; return returnValue;
}) as Dispatch<S2>; }) as Dispatch;
}; };
} }

View File

@ -2,14 +2,3 @@
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
export type TemplateId = string; export type TemplateId = string;
// The Connect type helps type connect functions that add various props to React
// components from the React context. Redux's `connect` and Apollo's `graphql`
// are example of this. It is parameterised by the props interface of what is
// added and what the result is (that is, the props the resulting component
// still needs).
export type Connect<Add, To> =
(c: React.ComponentClass<To & Add> | React.StatelessComponent<To & Add>) =>
React.ComponentClass<To>;

View File

@ -137,7 +137,7 @@ export default class Autosuggest<R>
); } ); }
} }
renderSuggestionsContainer={ renderSuggestionsContainer={
({containerProps, children}: {containerProps: {}, children: {}[]}) => ({containerProps, children}) =>
( (
<SuggestionsContainer {...containerProps} > <SuggestionsContainer {...containerProps} >
{children} {children}

View File

@ -52,7 +52,7 @@ const Count = styled.span`
min-height: 1.75rem; min-height: 1.75rem;
`; `;
export function makeSidebarLink<P extends {}>(Link: React.ComponentClass<P>) { export function makeSidebarLink<P extends {}>(Link: React.ComponentType<P>) {
// First create the component with the required API. This uses the Link // First create the component with the required API. This uses the Link
// component as the outer wrapper. // component as the outer wrapper.

View File

@ -41,9 +41,7 @@ export {
} from './DataTable'; } from './DataTable';
export { ApolloDataProvider } from './ContractTable/ApolloDataProvider'; export { ApolloDataProvider } from './ContractTable/ApolloDataProvider';
export { export {
ThunkAction,
Dispatch, Dispatch,
WithRedux,
WithGraphQL, WithGraphQL,
} from './types'; } from './types';
export { export {

View File

@ -5,7 +5,7 @@ import { ApolloClient } from '@apollo/client';
import { withApollo } from '@apollo/client/react/hoc'; import { withApollo } from '@apollo/client/react/hoc';
import * as React from 'react'; import * as React from 'react';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { AnyAction, compose } from 'redux'; import { AnyAction } from 'redux';
import { Set } from 'typescript-collections'; import { Set } from 'typescript-collections';
import Watcher, { import Watcher, {
Action, Action,
@ -14,7 +14,7 @@ import Watcher, {
WatchedCommand, WatchedCommand,
} from '.'; } from '.';
import styled from '../theme'; import styled from '../theme';
import { Connect, Dispatch } from '../types'; import { Dispatch } from '../types';
import { createIcon, fadeTime } from './icons'; import { createIcon, fadeTime } from './icons';
// TODO: with ES6, just pass an array to the Set constructor. // TODO: with ES6, just pass an array to the Set constructor.
@ -130,13 +130,5 @@ class Component<A extends Action>
} }
} }
const withRedux: Connect< export const UI: React.ComponentClass<OwnProps<AnyAction>>
ReduxProps<AnyAction>, = withApollo<OwnProps<AnyAction>>(connect()(Component));
OwnProps<AnyAction> & ApolloProps
>
= connect();
export const UI: React.ComponentClass<OwnProps<AnyAction>> = compose(
(x) => withApollo<OwnProps<AnyAction>>(x),
withRedux,
)(Component);

View File

@ -58,7 +58,7 @@ export interface OwnProps<A extends Action> {
logoUrl?: string; logoUrl?: string;
} }
export interface ReduxProps<A> { export interface ReduxProps<A extends Action> {
dispatch: Dispatch<A>; dispatch: Dispatch<A>;
} }

View File

@ -2,7 +2,8 @@
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
import * as Redux from 'redux'; import * as Redux from 'redux';
import { Dispatch, ThunkAction } from '../types'; import { ThunkAction } from 'redux-thunk';
import { Dispatch } from '../types';
import { import {
Action, Action,
AuthFailure, AuthFailure,
@ -48,7 +49,7 @@ function handleSessionResponse<A extends Redux.Action>(
} }
// Async action creators // Async action creators
function init<A extends Redux.Action>(to: To<A>): ThunkAction<void> { function init<A extends Redux.Action>(to: To<A>): ThunkAction<void, void, undefined, A> {
return (dispatch) => { return (dispatch) => {
fetch(sessionUrl, { credentials: 'include' }) fetch(sessionUrl, { credentials: 'include' })
// TODO(NAV-14): Add better error handling here // TODO(NAV-14): Add better error handling here
@ -57,10 +58,10 @@ function init<A extends Redux.Action>(to: To<A>): ThunkAction<void> {
}; };
} }
function signIn<A extends Redux.Action>( function signIn<S, A extends Redux.Action>(
to: To<A>, to: To<A>,
userId: UserId, userId: UserId,
): ThunkAction<void> { ): ThunkAction<void, S, undefined, A> {
return (dispatch) => { return (dispatch) => {
dispatch(to({ type: 'AUTHENTICATING' })); dispatch(to({ type: 'AUTHENTICATING' }));
fetch(sessionUrl, { fetch(sessionUrl, {
@ -74,10 +75,10 @@ function signIn<A extends Redux.Action>(
}; };
} }
function signOut<A extends Redux.Action>( function signOut<S, A extends Redux.Action>(
to: To<A>, to: To<A>,
resetStoreAction: A, resetStoreAction: A,
): ThunkAction<void> { ): ThunkAction<void, S, undefined, A> {
return (dispatch) => { return (dispatch) => {
dispatch(to({ type: 'UNAUTHENTICATING' })); dispatch(to({ type: 'UNAUTHENTICATING' }));
// Empty out store on logout to avoid stale caches. // Empty out store on logout to avoid stale caches.

View File

@ -3,24 +3,15 @@
import * as React from 'react'; import * as React from 'react';
import * as Redux from 'redux'; import * as Redux from 'redux';
import { ThunkDispatch } from 'redux-thunk';
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Redux dispatching // Redux dispatching
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// ThunkAction, as defined in redux-thunk
export type ThunkAction<R, S = {}, E = void> = (
dispatch: Redux.Dispatch<S>,
getState: () => S,
extraArgument: E,
) => R;
// Dispatch, as defined in redux and redux-thunk // Dispatch, as defined in redux and redux-thunk
export interface Dispatch<S> { export type Dispatch<A extends Redux.Action, S = {}, E = void> = ThunkDispatch<S, E, A>;
<A extends Redux.Action>(action: A): A;
<R, E>(thunkAction: ThunkAction<R, S, E>): R;
}
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Types for higher order components // Types for higher order components
@ -55,26 +46,5 @@ export interface GraphQLProps {
mutate?: any; mutate?: any;
}; };
export type WithRedux<P extends ReduxProps>
= ComponentEnhancer<ReduxProps, P>;
export type WithGraphQL<P extends GraphQLProps> export type WithGraphQL<P extends GraphQLProps>
= ComponentEnhancer<GraphQLProps, P>; = ComponentEnhancer<GraphQLProps, P>;
// ----------------------------------------------------------------------------
// Types for higher order components
// ----------------------------------------------------------------------------
/**
* The `Connect` type helps type connect functions that add various props to React
* components from the React context. Redux's `connect` and Apollo's `graphql`
* are example of this. It is parameterised by the props interface of what is
* added and what the result is (that is, the props the resulting component
* still needs).
*/
export type Connect<Add, To> = (c: React.ComponentType<To & Add>) => React.ComponentClass<To>;
/**
* The `HOC` type describes a generic React higher order component. Use this instead of
* the above `Connect` type if your higher order component also adds properties.
*/
export type HOC<From, To> = (c: React.ComponentType<From>) => React.ComponentType<To>;

View File

@ -14,7 +14,6 @@ import Moment from 'moment';
import * as React from 'react'; import * as React from 'react';
import { TimeType } from '../api/OpaqueTypes'; import { TimeType } from '../api/OpaqueTypes';
import { LedgerTimeQuery } from '../api/Queries'; import { LedgerTimeQuery } from '../api/Queries';
import { Connect } from '../types';
import { utcStringToMoment } from '../util'; import { utcStringToMoment } from '../util';
// Not exported by the apollo library // Not exported by the apollo library
@ -125,7 +124,7 @@ export const timeQuery = gql`
* Note: this does not implement any loading or error handling. If the ledger time is not * Note: this does not implement any loading or error handling. If the ledger time is not
* (yet) available for any reason, its value will be undefined. * (yet) available for any reason, its value will be undefined.
*/ */
export default function withLedgerTime<P extends {}>(C: React.ComponentType<InnerProps & P>) export default function withLedgerTime<P>(C: React.ComponentType<InnerProps & P>)
: React.ComponentType<P> { : React.ComponentType<P> {
type Props = P & ApolloProps; type Props = P & ApolloProps;
@ -211,5 +210,5 @@ export default function withLedgerTime<P extends {}>(C: React.ComponentType<Inne
} }
} }
return (withApollo as Connect<ApolloProps, P>)(Component); return withApollo<P>(Component) as React.ComponentClass<P>;
} }

File diff suppressed because it is too large Load Diff