From 9b1fd128a287667c7007e2acb534f5969e0d5711 Mon Sep 17 00:00:00 2001 From: Simonas Karuzas Date: Thu, 14 May 2020 18:38:07 +0300 Subject: [PATCH] feat: GraphQL client settings: apiUrl, apiKey --- .../components/ActivityItem/ActivityItem.tsx | 2 +- .../client/src/components/Request/Request.tsx | 2 +- .../client/src/context/AppProvider.tsx | 62 ++++++++++++++++-- .../client/src/context/GraphQLProvider.tsx | 29 +++++++++ examples/react-graphql/client/src/index.tsx | 22 +------ .../client/src/layout/Layout.tsx | 4 ++ .../client/src/layout/NavigationLeft.tsx | 3 + .../client/src/layout/SidePanel.tsx | 2 +- .../client/src/layout/Sidebar.tsx | 2 +- .../client/src/views/Activity/Activity.tsx | 2 +- .../src/views/Identity/IdentitiyManager.tsx | 2 +- .../src/views/Identity/IdentityDetail.tsx | 4 +- .../client/src/views/Issue/Issue.tsx | 2 +- .../client/src/views/Request/Request.tsx | 2 +- .../client/src/views/Settings/Settings.tsx | 65 +++++++++++++++++++ 15 files changed, 170 insertions(+), 35 deletions(-) create mode 100644 examples/react-graphql/client/src/context/GraphQLProvider.tsx create mode 100644 examples/react-graphql/client/src/views/Settings/Settings.tsx diff --git a/examples/react-graphql/client/src/components/ActivityItem/ActivityItem.tsx b/examples/react-graphql/client/src/components/ActivityItem/ActivityItem.tsx index 97082b56a..78c1dfe10 100644 --- a/examples/react-graphql/client/src/components/ActivityItem/ActivityItem.tsx +++ b/examples/react-graphql/client/src/components/ActivityItem/ActivityItem.tsx @@ -28,7 +28,7 @@ interface Props { /** * The viewer's did */ - viewerDid: Types.Identity + viewerDid: string /** * The issuer of this message item diff --git a/examples/react-graphql/client/src/components/Request/Request.tsx b/examples/react-graphql/client/src/components/Request/Request.tsx index 8f5f8c181..94bdbe97e 100644 --- a/examples/react-graphql/client/src/components/Request/Request.tsx +++ b/examples/react-graphql/client/src/components/Request/Request.tsx @@ -30,7 +30,7 @@ const Component: React.FC = ({ sdr, from, to, threadId, close }) => { const [sending, updateSending] = useState(false) const [selected, updateSelected] = useState({}) const [formValid, setValid] = useState(true) - const [appState] = useContext(AppContext) + const { appState } = useContext(AppContext) const checkValidity = () => { let valid = true diff --git a/examples/react-graphql/client/src/context/AppProvider.tsx b/examples/react-graphql/client/src/context/AppProvider.tsx index d1cb12c74..c0d019a91 100644 --- a/examples/react-graphql/client/src/context/AppProvider.tsx +++ b/examples/react-graphql/client/src/context/AppProvider.tsx @@ -1,28 +1,78 @@ import React, { useState, createContext } from 'react' -export const AppContext = createContext({}) +export interface IAppContext { + appState: AppState + setDefaultDid: (defaultDid: string) => void + setApiKey: (apiKey: string) => void + setApiUrl: (apiUrl: string) => void +} + +export const AppContext = createContext({ + appState: { + defaultDid: '', + apiUrl: '', + apiKey: '' + }, + setDefaultDid: (defaultDid: string) => {}, + setApiKey: (apiKey: string) => {}, + setApiUrl: (apiUrl: string) => {} +}) interface AppState { defaultDid: string + apiUrl: string + apiKey: string } export const AppProvider = (props: any) => { const defaultDid = localStorage.getItem('defaultId') || '' + const apiUrl = localStorage.getItem('apiUrl') || 'http://localhost:4000/' + const apiKey = localStorage.getItem('apiKey') || 'hardcoded-example-token' const [appState, setGlobalState] = useState({ - defaultDid: defaultDid, + defaultDid, + apiKey, + apiUrl }) - const setDefaultDid = (did: string) => { - localStorage.setItem('defaultId', did) + const setDefaultDid = (defaultDid: string) => { + localStorage.setItem('defaultId', defaultDid) + + const newState = { + ...appState, + defaultDid, + } + + setGlobalState(newState) + } + + const setApiUrl = (apiUrl: string) => { + localStorage.setItem('apiUrl', apiUrl) const newState = { ...appState, - defaultDid: did, + apiUrl, } setGlobalState(newState) } - return {props.children} + const setApiKey = (apiKey: string) => { + localStorage.setItem('apiKey', apiKey) + + const newState = { + ...appState, + apiKey, + } + + setGlobalState(newState) + } + + + return {props.children} } diff --git a/examples/react-graphql/client/src/context/GraphQLProvider.tsx b/examples/react-graphql/client/src/context/GraphQLProvider.tsx new file mode 100644 index 000000000..a6c692070 --- /dev/null +++ b/examples/react-graphql/client/src/context/GraphQLProvider.tsx @@ -0,0 +1,29 @@ +import React, { useContext } from 'react' +import { ApolloProvider } from 'react-apollo' +import ApolloClient from 'apollo-boost' +import { AppContext } from './AppProvider' + + +export const GraphQLProvider = (props: any) => { + + const { appState } = useContext(AppContext) + + const client = new ApolloClient({ + uri: appState.apiUrl, + + // Authorization is out of scope for this example, + // but this is where you could add your auth logic + request: operation => { + const token = appState.apiKey + operation.setContext({ + headers: { + Authorization: token ? `Bearer ${token}` : '', + }, + }) + }, + }) + + + + return {props.children} +} diff --git a/examples/react-graphql/client/src/index.tsx b/examples/react-graphql/client/src/index.tsx index 799f3730c..899dd023d 100644 --- a/examples/react-graphql/client/src/index.tsx +++ b/examples/react-graphql/client/src/index.tsx @@ -1,33 +1,17 @@ import React from 'react' import ReactDOM from 'react-dom' import Layout from './layout/Layout' -import ApolloClient from 'apollo-boost' -import { ApolloProvider } from 'react-apollo' import * as serviceWorker from './serviceWorker' import { BaseStyles, theme, ToastMessage } from 'rimble-ui' import { ThemeProvider } from 'styled-components' import { AppProvider } from './context/AppProvider' +import { GraphQLProvider } from './context/GraphQLProvider' import '../src/styles/base.css' -const client = new ApolloClient({ - uri: 'http://localhost:4000/', - - // Authorization is out of scope for this example, - // but this is where you could add your auth logic - request: operation => { - const token = 'hardcoded-example-token' - operation.setContext({ - headers: { - authorization: token ? `Bearer ${token}` : '', - }, - }) - }, -}) - ReactDOM.render( - + - + , document.getElementById('root'), ) diff --git a/examples/react-graphql/client/src/layout/Layout.tsx b/examples/react-graphql/client/src/layout/Layout.tsx index c1ca8007c..af9b1f842 100644 --- a/examples/react-graphql/client/src/layout/Layout.tsx +++ b/examples/react-graphql/client/src/layout/Layout.tsx @@ -16,6 +16,7 @@ import NavigationLeft from './NavigationLeft' import Credential from '../components/Credential/Credential' import RequestDetail from '../components/Request/Request' +import Settings from '../views/Settings/Settings' import * as queries from '../gql/queries' @@ -58,6 +59,9 @@ const Dashboard: React.FC = () => { + + + diff --git a/examples/react-graphql/client/src/layout/NavigationLeft.tsx b/examples/react-graphql/client/src/layout/NavigationLeft.tsx index 0480b0c36..104d29913 100644 --- a/examples/react-graphql/client/src/layout/NavigationLeft.tsx +++ b/examples/react-graphql/client/src/layout/NavigationLeft.tsx @@ -28,6 +28,9 @@ const Component = () => {
  • Connections
  • +
  • + Settings +
  • ) diff --git a/examples/react-graphql/client/src/layout/SidePanel.tsx b/examples/react-graphql/client/src/layout/SidePanel.tsx index e9c6931ef..580dc42be 100644 --- a/examples/react-graphql/client/src/layout/SidePanel.tsx +++ b/examples/react-graphql/client/src/layout/SidePanel.tsx @@ -12,7 +12,7 @@ interface Props { } const Component: React.FC = ({ title, closeUrl, query, children, renderQuery }) => { - const [appState] = useContext(AppContext) + const { appState } = useContext(AppContext) const history = useHistory() const { id } = useParams() diff --git a/examples/react-graphql/client/src/layout/Sidebar.tsx b/examples/react-graphql/client/src/layout/Sidebar.tsx index a2aa32a2d..f610eb086 100644 --- a/examples/react-graphql/client/src/layout/Sidebar.tsx +++ b/examples/react-graphql/client/src/layout/Sidebar.tsx @@ -6,7 +6,7 @@ import * as queries from '../gql/queries' import { useQuery } from 'react-apollo' const Component = () => { - const [appState] = useContext(AppContext) + const { appState } = useContext(AppContext) const { data } = useQuery(queries.identity, { variables: { did: appState.defaultDid } }) return ( diff --git a/examples/react-graphql/client/src/views/Activity/Activity.tsx b/examples/react-graphql/client/src/views/Activity/Activity.tsx index 892b39c13..fbe4b301f 100644 --- a/examples/react-graphql/client/src/views/Activity/Activity.tsx +++ b/examples/react-graphql/client/src/views/Activity/Activity.tsx @@ -11,7 +11,7 @@ import { useHistory, useRouteMatch } from 'react-router-dom' interface Activity {} const Activity: React.FC = () => { - const [appState] = useContext(AppContext) + const { appState } = useContext(AppContext) const history = useHistory() const { url } = useRouteMatch() diff --git a/examples/react-graphql/client/src/views/Identity/IdentitiyManager.tsx b/examples/react-graphql/client/src/views/Identity/IdentitiyManager.tsx index 090584e14..4eb38cadf 100644 --- a/examples/react-graphql/client/src/views/Identity/IdentitiyManager.tsx +++ b/examples/react-graphql/client/src/views/Identity/IdentitiyManager.tsx @@ -13,7 +13,7 @@ const Component = () => { const history = useHistory() const { url } = useRouteMatch() const [highlightedIdentity, highlightIdentity] = useState() - const [appState, setDefaultDid] = useContext(AppContext) + const { appState, setDefaultDid } = useContext(AppContext) const { defaultDid } = appState const { data: managedIdentitiesData } = useQuery(queries.managedIdentities) const [createIdentity] = useMutation(mutations.createIdentity, { diff --git a/examples/react-graphql/client/src/views/Identity/IdentityDetail.tsx b/examples/react-graphql/client/src/views/Identity/IdentityDetail.tsx index 315b74374..71a888693 100644 --- a/examples/react-graphql/client/src/views/Identity/IdentityDetail.tsx +++ b/examples/react-graphql/client/src/views/Identity/IdentityDetail.tsx @@ -11,7 +11,7 @@ interface IdentityDetail {} const Component: React.FC = () => { let { id } = useParams() let history = useHistory() - const [appState, setDefaultDid] = useContext(AppContext) + const { appState, setDefaultDid } = useContext(AppContext) const { defaultDid } = appState const [deleteIdentity] = useMutation(mutations.deleteIdentity, { refetchQueries: [{ query: queries.managedIdentities }], @@ -46,7 +46,7 @@ const Component: React.FC = () => { ? 'This is your current default identity' : 'Set this DID as the default identity'} - diff --git a/examples/react-graphql/client/src/views/Issue/Issue.tsx b/examples/react-graphql/client/src/views/Issue/Issue.tsx index c5a13d511..c4cb53dc6 100644 --- a/examples/react-graphql/client/src/views/Issue/Issue.tsx +++ b/examples/react-graphql/client/src/views/Issue/Issue.tsx @@ -14,7 +14,7 @@ declare global { } const Component = () => { - const [appState] = useContext(AppContext) + const { appState } = useContext(AppContext) const [isSending, setIsSending] = useState(false) const [receiver, setReceiver] = useState('did:web:uport.me') const [claimType, setClaimType] = useState('name') diff --git a/examples/react-graphql/client/src/views/Request/Request.tsx b/examples/react-graphql/client/src/views/Request/Request.tsx index 2bda94b55..6ef2c327f 100644 --- a/examples/react-graphql/client/src/views/Request/Request.tsx +++ b/examples/react-graphql/client/src/views/Request/Request.tsx @@ -14,7 +14,7 @@ declare global { } const Component = () => { - const [appState] = useContext(AppContext) + const { appState } = useContext(AppContext) const [isSending, setIsSending] = useState(false) const [receiver, setReceiver] = useState('did:web:uport.me') const [claims, updateClaims] = useState([]) diff --git a/examples/react-graphql/client/src/views/Settings/Settings.tsx b/examples/react-graphql/client/src/views/Settings/Settings.tsx new file mode 100644 index 000000000..09e2b1031 --- /dev/null +++ b/examples/react-graphql/client/src/views/Settings/Settings.tsx @@ -0,0 +1,65 @@ +import React, { useContext, useState } from 'react' +import { Box, Heading, Input, Field, Button, Flex, Form } from 'rimble-ui' +import Page from '../../layout/Page' +import Avatar from '../../components/Avatar/Avatar' +import * as Types from '../../types' +import Panel from '../../components/Panel/Panel' +import { AppContext } from '../../context/AppProvider' + +const Component = () => { + const { appState, setApiKey, setApiUrl } = useContext(AppContext) + const [ newApiKey, setNewApiKey ] = useState(appState.apiKey) + const [ newApiUrl, setNewApiUrl ] = useState(appState.apiUrl) + + const handleSave = () => { + setApiKey(newApiKey) + setApiUrl(newApiUrl) + } + + return ( + + + + + + + + + + + setNewApiUrl(e.target.value)} + /> + + + + + + + + + setNewApiKey(e.target.value)} + /> + + + + + + + + + ) +} + +export default Component