Fix UserBox

This commit is contained in:
Chi Vinh Le
2018-08-24 11:17:09 +02:00
parent 5501ee7832
commit 65a212b531
12 changed files with 70 additions and 114 deletions
@@ -1,28 +0,0 @@
import { commitLocalUpdate, Environment } from "relay-runtime";
import { TalkContext } from "talk-framework/lib/bootstrap";
import { createMutationContainer } from "talk-framework/lib/relay";
import { LOCAL_ID } from "talk-framework/lib/relay/withLocalStateContainer";
export type SignOffMutation = () => Promise<void>;
export async function commit(
environment: Environment,
{ localStorage }: TalkContext
) {
return commitLocalUpdate(environment, store => {
const record = store.get(LOCAL_ID)!;
record.setValue("", "authToken");
localStorage.removeItem("authToken");
// Force gc to trigger.
environment
.retain({
dataID: "tmp",
node: { selections: [] },
variables: {},
})
.dispose();
});
}
export const withSignOffMutation = createMutationContainer("signOff", commit);
-1
View File
@@ -1,4 +1,3 @@
export { withSetViewMutation, SetViewMutation } from "./SetViewMutation";
export { withSignInMutation, SignInMutation } from "./SignInMutation";
export { withSignUpMutation, SignUpMutation } from "./SignUpMutation";
export { withSignOffMutation, SignOffMutation } from "./SignOffMutation";
@@ -0,0 +1,14 @@
import { Environment } from "relay-runtime";
import { TalkContext } from "talk-framework/lib/bootstrap";
import { createMutationContainer } from "talk-framework/lib/relay";
import signOut from "../rest/signOut";
import { commit as setAuthToken } from "./SetAuthTokenMutation";
export type SignOutMutation = () => Promise<void>;
export async function commit(environment: Environment, ctx: TalkContext) {
await setAuthToken(environment, { authToken: "" }, ctx);
await signOut(ctx.rest);
}
export const withSignOutMutation = createMutationContainer("signOut", commit);
@@ -3,3 +3,4 @@ export {
SetAuthTokenMutation,
SetAuthTokenInput,
} from "./SetAuthTokenMutation";
export { withSignOutMutation, SignOutMutation } from "./SignOutMutation";
+1 -1
View File
@@ -1,3 +1,3 @@
export { default as signIn, SignInInput } from "./signIn";
export { default as signUp, SignUpInput } from "./signUp";
export { default as signOff } from "./signOff";
export { default as signOut } from "./signOut";
@@ -1,7 +0,0 @@
import { RestClient } from "../lib/rest";
export default function signOff(rest: RestClient) {
return rest.fetch("/tenant/auth/local", {
method: "DELETE",
});
}
@@ -0,0 +1,7 @@
import { RestClient } from "../lib/rest";
export default function signOut(rest: RestClient) {
return rest.fetch("/tenant/auth", {
method: "DELETE",
});
}
@@ -4,12 +4,11 @@ import React, { StatelessComponent } from "react";
import { Button, Flex, Typography } from "talk-ui/components";
import MatchMedia from "talk-ui/components/MatchMedia";
import { User } from "../containers/UserBoxContainer";
import * as styles from "./UserBoxAuthenticated.css";
export interface UserBoxAuthenticatedProps {
onSignOff: () => void;
user: User;
onSignOut: () => void;
username: string;
}
const UserBoxAuthenticated: StatelessComponent<
@@ -25,7 +24,7 @@ const UserBoxAuthenticated: StatelessComponent<
</Typography>
</Localized>
<Typography variant="bodyCopyBold" component="span">
{props.user.username}
{props.username}
</Typography>
</MatchMedia>
</Flex>
@@ -40,7 +39,7 @@ const UserBoxAuthenticated: StatelessComponent<
color="primary"
size="small"
variant="underlined"
onClick={props.onSignOff}
onClick={props.onSignOut}
>
Sign Out
</Button>
@@ -1,16 +0,0 @@
import { shallow } from "enzyme";
import { noop } from "lodash";
import React from "react";
import { PropTypesOf } from "talk-framework/types";
import UserBoxUnauthenticated from "./UserBoxUnauthenticated";
it("renders correctly", () => {
const props: PropTypesOf<typeof UserBoxUnauthenticated> = {
onSignIn: noop,
onRegister: noop,
};
const wrapper = shallow(<UserBoxUnauthenticated {...props} />);
expect(wrapper).toMatchSnapshot();
});
@@ -1,25 +0,0 @@
import React, { Component } from "react";
import UserBoxAuthenticated from "talk-stream/components/UserBoxAuthenticated";
import { SignOffMutation, withSignOffMutation } from "../../auth/mutations";
import { User } from "../containers/UserBoxContainer";
interface UserBoxAuthenticatedProps {
signOff: SignOffMutation;
user: User;
}
class UserBoxAuthenticatedContainer extends Component<
UserBoxAuthenticatedProps
> {
private onSignOff = () => {
this.props.signOff();
};
public render() {
return (
<UserBoxAuthenticated onSignOff={this.onSignOff} user={this.props.user} />
);
}
}
const enhanced = withSignOffMutation(UserBoxAuthenticatedContainer);
export default enhanced;
@@ -14,10 +14,13 @@ it("renders correctly", () => {
view: "SIGN_IN",
},
},
user: null,
// tslint:disable-next-line:no-empty
showAuthPopup: async () => {},
// tslint:disable-next-line:no-empty
setAuthPopupState: async () => {},
// tslint:disable-next-line:no-empty
signOut: async () => {},
};
const wrapper = shallow(<UserBoxContainer {...props} />);
expect(wrapper).toMatchSnapshot();
@@ -1,6 +1,11 @@
import * as React from "react";
import { Component } from "react";
import { graphql, withLocalStateContainer } from "talk-framework/lib/relay";
import {
graphql,
withFragmentContainer,
withLocalStateContainer,
} from "talk-framework/lib/relay";
import { UserBoxContainer_user as UserData } from "talk-stream/__generated__/UserBoxContainer_user.graphql";
import { UserBoxContainerLocal as Local } from "talk-stream/__generated__/UserBoxContainerLocal.graphql";
import {
SetAuthPopupStateMutation,
@@ -8,30 +13,18 @@ import {
withSetAuthPopupStateMutation,
withShowAuthPopupMutation,
} from "talk-stream/mutations";
import { SignOutMutation, withSignOutMutation } from "talk-framework/mutations";
import { Popup } from "talk-ui/components";
import UserBoxUnauthenticated from "talk-stream/components/UserBoxUnauthenticated";
import UserBoxAuthenticatedContainer from "../containers/UserBoxAuthenticatedContainer";
export type USER_ROLE =
| "ADMIN"
| "COMMENTER"
| "MODERATOR"
| "STAFF"
| "%future added value";
export interface User {
id?: string;
username?: string | null;
displayName?: string | null;
role?: USER_ROLE;
}
import UserBoxAuthenticated from "../components/UserBoxAuthenticated";
interface InnerProps {
local: Local;
user: User | null | undefined;
user: UserData | null;
showAuthPopup: ShowAuthPopupMutation;
setAuthPopupState: SetAuthPopupStateMutation;
signOut: SignOutMutation;
}
export class UserBoxContainer extends Component<InnerProps> {
@@ -47,10 +40,17 @@ export class UserBoxContainer extends Component<InnerProps> {
authPopup: { open, focus, view },
},
user,
signOut,
} = this.props;
if (user) {
return <UserBoxAuthenticatedContainer user={user} />;
return (
<UserBoxAuthenticated
onSignOut={signOut}
// TODO: why nullable?
username={user.username!}
/>
);
}
return (
@@ -74,21 +74,30 @@ export class UserBoxContainer extends Component<InnerProps> {
}
}
const enhanced = withSetAuthPopupStateMutation(
withShowAuthPopupMutation(
withLocalStateContainer<Local>(
graphql`
fragment UserBoxContainerLocal on Local {
authPopup {
open
focus
view
const enhanced = withSignOutMutation(
withSetAuthPopupStateMutation(
withShowAuthPopupMutation(
withLocalStateContainer<Local>(
graphql`
fragment UserBoxContainerLocal on Local {
authPopup {
open
focus
view
}
}
}
`
)(UserBoxContainer)
`
)(
withFragmentContainer<{ user: UserData | null }>({
user: graphql`
fragment UserBoxContainer_user on User {
username
}
`,
})(UserBoxContainer)
)
)
)
);
// TODO: (bc) Add fragment here if composing is doable.
export default enhanced;