mirror of
https://github.com/wassname/talk.git
synced 2026-09-10 12:43:11 +08:00
[CORL-158] Open/Close stream inside of configure tab (#2223)
* feat: Open or Close stream inside of configure tab * feat: default disable/close commenting message * fix: adjusted tests
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
import { graphql } from "react-relay";
|
||||
import { Environment } from "relay-runtime";
|
||||
|
||||
import {
|
||||
commitMutationPromiseNormalized,
|
||||
createMutationContainer,
|
||||
MutationInput,
|
||||
MutationResponsePromise,
|
||||
} from "talk-framework/lib/relay";
|
||||
|
||||
import { CloseStoryMutation as MutationTypes } from "talk-stream/__generated__/CloseStoryMutation.graphql";
|
||||
|
||||
export type CloseStoryInput = MutationInput<MutationTypes>;
|
||||
|
||||
const mutation = graphql`
|
||||
mutation CloseStoryMutation($input: CloseStoryInput!) {
|
||||
closeStory(input: $input) {
|
||||
story {
|
||||
...ConfigureContainer_story
|
||||
}
|
||||
clientMutationId
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
let clientMutationId = 0;
|
||||
|
||||
function commit(environment: Environment, input: CloseStoryInput) {
|
||||
return commitMutationPromiseNormalized<MutationTypes>(environment, {
|
||||
mutation,
|
||||
variables: {
|
||||
input: {
|
||||
...input,
|
||||
clientMutationId: (clientMutationId++).toString(),
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export const withCloseStoryMutation = createMutationContainer(
|
||||
"closeStory",
|
||||
commit
|
||||
);
|
||||
|
||||
export type CloseStoryMutation = (
|
||||
input: CloseStoryInput
|
||||
) => MutationResponsePromise<MutationTypes, "closeStory">;
|
||||
@@ -0,0 +1,47 @@
|
||||
import { graphql } from "react-relay";
|
||||
import { Environment } from "relay-runtime";
|
||||
|
||||
import {
|
||||
commitMutationPromiseNormalized,
|
||||
createMutationContainer,
|
||||
MutationInput,
|
||||
MutationResponsePromise,
|
||||
} from "talk-framework/lib/relay";
|
||||
|
||||
import { OpenStoryMutation as MutationTypes } from "talk-stream/__generated__/OpenStoryMutation.graphql";
|
||||
|
||||
export type OpenStoryInput = MutationInput<MutationTypes>;
|
||||
|
||||
const mutation = graphql`
|
||||
mutation OpenStoryMutation($input: OpenStoryInput!) {
|
||||
openStory(input: $input) {
|
||||
story {
|
||||
...ConfigureContainer_story
|
||||
}
|
||||
clientMutationId
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
let clientMutationId = 0;
|
||||
|
||||
function commit(environment: Environment, input: OpenStoryInput) {
|
||||
return commitMutationPromiseNormalized<MutationTypes>(environment, {
|
||||
mutation,
|
||||
variables: {
|
||||
input: {
|
||||
...input,
|
||||
clientMutationId: (clientMutationId++).toString(),
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export const withOpenStoryMutation = createMutationContainer(
|
||||
"openStory",
|
||||
commit
|
||||
);
|
||||
|
||||
export type OpenStoryMutation = (
|
||||
input: OpenStoryInput
|
||||
) => MutationResponsePromise<MutationTypes, "openStory">;
|
||||
@@ -60,3 +60,13 @@ export {
|
||||
withUpdateStorySettingsMutation,
|
||||
UpdateStorySettingsMutation,
|
||||
} from "./UpdateStorySettingsMutation";
|
||||
export {
|
||||
OpenStoryInput,
|
||||
withOpenStoryMutation,
|
||||
OpenStoryMutation,
|
||||
} from "./OpenStoryMutation";
|
||||
export {
|
||||
CloseStoryInput,
|
||||
withCloseStoryMutation,
|
||||
CloseStoryMutation,
|
||||
} from "./CloseStoryMutation";
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
.heading {
|
||||
padding-bottom: calc(1.5 * var(--spacing-unit));
|
||||
}
|
||||
|
||||
.button {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
import { Localized } from "fluent-react/compat";
|
||||
import React, { StatelessComponent } from "react";
|
||||
|
||||
import { Button, Flex, Typography } from "talk-ui/components";
|
||||
|
||||
import styles from "./CloseStream.css";
|
||||
|
||||
interface Props {
|
||||
onClick: () => void;
|
||||
disableButton?: boolean;
|
||||
}
|
||||
|
||||
const CloseStream: StatelessComponent<Props> = ({ onClick, disableButton }) => (
|
||||
<div>
|
||||
<Localized id="configure-closeStream-title">
|
||||
<Typography variant="heading2" className={styles.heading}>
|
||||
Close Comment Stream
|
||||
</Typography>
|
||||
</Localized>
|
||||
<Flex alignItems="flex-start" itemGutter>
|
||||
<Localized id="configure-closeStream-description">
|
||||
<Typography>
|
||||
This comment stream is currently open. By closing this comment stream,
|
||||
no new comments may be submitted and all previously submitted comments
|
||||
will still be displayed.
|
||||
</Typography>
|
||||
</Localized>
|
||||
<Localized id="configure-closeStream-closeStream">
|
||||
<Button
|
||||
variant="outlined"
|
||||
color="error"
|
||||
className={styles.button}
|
||||
onClick={onClick}
|
||||
disabled={disableButton}
|
||||
>
|
||||
Close Stream
|
||||
</Button>
|
||||
</Localized>
|
||||
</Flex>
|
||||
</div>
|
||||
);
|
||||
|
||||
export default CloseStream;
|
||||
@@ -4,20 +4,27 @@ import { PropTypesOf } from "talk-framework/types";
|
||||
import UserBoxContainer from "talk-stream/containers/UserBoxContainer";
|
||||
import { HorizontalGutter } from "talk-ui/components";
|
||||
|
||||
import ConfigureCommentStreamContainer from "../containers/ConfigureCommentStreamContainer";
|
||||
import ConfigureStreamContainer from "../containers/ConfigureStreamContainer";
|
||||
import OpenOrCloseStreamContainer from "../containers/OpenOrCloseStreamContainer";
|
||||
import HorizontalRule from "./HorizontalRule";
|
||||
|
||||
export interface Props {
|
||||
me: PropTypesOf<typeof UserBoxContainer>["me"];
|
||||
settings: PropTypesOf<typeof UserBoxContainer>["settings"];
|
||||
story: PropTypesOf<typeof ConfigureCommentStreamContainer>["story"];
|
||||
story: PropTypesOf<typeof ConfigureStreamContainer>["story"] &
|
||||
PropTypesOf<typeof OpenOrCloseStreamContainer>["story"];
|
||||
}
|
||||
|
||||
const Configure: StatelessComponent<Props> = props => {
|
||||
return (
|
||||
<HorizontalGutter size="double">
|
||||
<UserBoxContainer me={props.me} settings={props.settings} />
|
||||
<ConfigureCommentStreamContainer story={props.story} />
|
||||
</HorizontalGutter>
|
||||
<div>
|
||||
<HorizontalGutter size="double">
|
||||
<UserBoxContainer me={props.me} settings={props.settings} />
|
||||
<ConfigureStreamContainer story={props.story} />
|
||||
</HorizontalGutter>
|
||||
<HorizontalRule />
|
||||
<OpenOrCloseStreamContainer story={props.story} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
+5
-5
@@ -17,7 +17,7 @@ import MessageBoxConfigContainer from "../containers/MessageBoxConfigContainer";
|
||||
import PremodConfigContainer from "../containers/PremodConfigContainer";
|
||||
import PremodLinksConfigContainer from "../containers/PremodLinksConfigContainer";
|
||||
|
||||
import styles from "./ConfigureCommentStream.css";
|
||||
import styles from "./ConfigureStream.css";
|
||||
|
||||
interface Props {
|
||||
onSubmit: (settings: any, form: FormApi) => void;
|
||||
@@ -26,7 +26,7 @@ interface Props {
|
||||
PropTypesOf<typeof MessageBoxConfigContainer>["storySettings"];
|
||||
}
|
||||
|
||||
const ConfigureCommentStream: StatelessComponent<Props> = ({
|
||||
const ConfigureStream: StatelessComponent<Props> = ({
|
||||
onSubmit,
|
||||
storySettings,
|
||||
}) => (
|
||||
@@ -40,12 +40,12 @@ const ConfigureCommentStream: StatelessComponent<Props> = ({
|
||||
alignItems="flex-start"
|
||||
itemGutter
|
||||
>
|
||||
<Localized id="configure-commentStream-title">
|
||||
<Localized id="configure-stream-title">
|
||||
<Typography variant="heading2" className={styles.heading}>
|
||||
Configure this Comment Stream
|
||||
</Typography>
|
||||
</Localized>
|
||||
<Localized id="configure-commentStream-apply">
|
||||
<Localized id="configure-stream-apply">
|
||||
<Button
|
||||
color="success"
|
||||
variant="filled"
|
||||
@@ -81,4 +81,4 @@ const ConfigureCommentStream: StatelessComponent<Props> = ({
|
||||
</Form>
|
||||
);
|
||||
|
||||
export default ConfigureCommentStream;
|
||||
export default ConfigureStream;
|
||||
@@ -0,0 +1,7 @@
|
||||
.root {
|
||||
border: 0;
|
||||
border-bottom: 1px solid var(--palette-divider);
|
||||
padding-top: 1px;
|
||||
margin-top: calc(3 * var(--spacing-unit));
|
||||
margin-bottom: calc(2 * var(--spacing-unit));
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export const root: string;
|
||||
@@ -0,0 +1,10 @@
|
||||
import React from "react";
|
||||
import { createRenderer } from "react-test-renderer/shallow";
|
||||
|
||||
import HorizontalRule from "./HorizontalRule";
|
||||
|
||||
it("renders correctly", () => {
|
||||
const renderer = createRenderer();
|
||||
renderer.render(<HorizontalRule />);
|
||||
expect(renderer.getRenderOutput()).toMatchSnapshot();
|
||||
});
|
||||
@@ -0,0 +1,9 @@
|
||||
import React, { StatelessComponent } from "react";
|
||||
|
||||
import styles from "./HorizontalRule.css";
|
||||
|
||||
const HorizontalRule: StatelessComponent = ({ children }) => (
|
||||
<hr className={styles.root} />
|
||||
);
|
||||
|
||||
export default HorizontalRule;
|
||||
@@ -0,0 +1,7 @@
|
||||
.heading {
|
||||
padding-bottom: calc(1.5 * var(--spacing-unit));
|
||||
}
|
||||
|
||||
.button {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
import { Localized } from "fluent-react/compat";
|
||||
import React, { StatelessComponent } from "react";
|
||||
|
||||
import { Button, Flex, Typography } from "talk-ui/components";
|
||||
|
||||
import styles from "./OpenStream.css";
|
||||
|
||||
interface Props {
|
||||
onClick: () => void;
|
||||
disableButton?: boolean;
|
||||
}
|
||||
|
||||
const OpenStream: StatelessComponent<Props> = ({ onClick, disableButton }) => (
|
||||
<div>
|
||||
<Localized id="configure-openStream-title">
|
||||
<Typography variant="heading2" className={styles.heading}>
|
||||
Open Stream
|
||||
</Typography>
|
||||
</Localized>
|
||||
<Flex alignItems="flex-start" itemGutter>
|
||||
<Localized id="configure-openStream-description">
|
||||
<Typography>
|
||||
This comment stream is currently closed. By opening this comment
|
||||
stream new comments may be submitted and displayed
|
||||
</Typography>
|
||||
</Localized>
|
||||
<Localized id="configure-openStream-openStream">
|
||||
<Button
|
||||
variant="outlined"
|
||||
color="error"
|
||||
className={styles.button}
|
||||
onClick={onClick}
|
||||
disabled={disableButton}
|
||||
>
|
||||
Open Stream
|
||||
</Button>
|
||||
</Localized>
|
||||
</Flex>
|
||||
</div>
|
||||
);
|
||||
|
||||
export default OpenStream;
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`renders correctly 1`] = `
|
||||
<hr
|
||||
className="HorizontalRule-root"
|
||||
/>
|
||||
`;
|
||||
@@ -28,7 +28,8 @@ export class StreamContainer extends React.Component<ConfigureContainerProps> {
|
||||
const enhanced = withFragmentContainer<ConfigureContainerProps>({
|
||||
story: graphql`
|
||||
fragment ConfigureContainer_story on Story {
|
||||
...ConfigureCommentStreamContainer_story
|
||||
...ConfigureStreamContainer_story
|
||||
...OpenOrCloseStreamContainer_story
|
||||
}
|
||||
`,
|
||||
me: graphql`
|
||||
|
||||
+6
-6
@@ -3,21 +3,21 @@ import React from "react";
|
||||
|
||||
import { SubmitHookHandler } from "talk-framework/lib/form";
|
||||
import { graphql, withFragmentContainer } from "talk-framework/lib/relay";
|
||||
import { ConfigureCommentStreamContainer_story as StoryData } from "talk-stream/__generated__/ConfigureCommentStreamContainer_story.graphql";
|
||||
import { ConfigureStreamContainer_story as StoryData } from "talk-stream/__generated__/ConfigureStreamContainer_story.graphql";
|
||||
import {
|
||||
UpdateStorySettingsInput,
|
||||
UpdateStorySettingsMutation,
|
||||
withUpdateStorySettingsMutation,
|
||||
} from "talk-stream/mutations";
|
||||
|
||||
import ConfigureCommentStream from "../components/ConfigureCommentStream";
|
||||
import ConfigureStream from "../components/ConfigureStream";
|
||||
|
||||
interface Props {
|
||||
story: StoryData;
|
||||
updateStorySettings: UpdateStorySettingsMutation;
|
||||
}
|
||||
|
||||
class ConfigureCommentStreamContainer extends React.Component<Props> {
|
||||
class ConfigureStreamContainer extends React.Component<Props> {
|
||||
private handleExecute = async (
|
||||
data: UpdateStorySettingsInput["settings"],
|
||||
form: FormApi
|
||||
@@ -33,7 +33,7 @@ class ConfigureCommentStreamContainer extends React.Component<Props> {
|
||||
return (
|
||||
<SubmitHookHandler onExecute={this.handleExecute}>
|
||||
{({ onSubmit }) => (
|
||||
<ConfigureCommentStream
|
||||
<ConfigureStream
|
||||
onSubmit={onSubmit}
|
||||
storySettings={this.props.story.settings}
|
||||
/>
|
||||
@@ -45,7 +45,7 @@ class ConfigureCommentStreamContainer extends React.Component<Props> {
|
||||
|
||||
const enhanced = withFragmentContainer<Props>({
|
||||
story: graphql`
|
||||
fragment ConfigureCommentStreamContainer_story on Story {
|
||||
fragment ConfigureStreamContainer_story on Story {
|
||||
id
|
||||
settings {
|
||||
...PremodConfigContainer_storySettings
|
||||
@@ -54,5 +54,5 @@ const enhanced = withFragmentContainer<Props>({
|
||||
}
|
||||
}
|
||||
`,
|
||||
})(withUpdateStorySettingsMutation(ConfigureCommentStreamContainer));
|
||||
})(withUpdateStorySettingsMutation(ConfigureStreamContainer));
|
||||
export default enhanced;
|
||||
@@ -0,0 +1,65 @@
|
||||
import React from "react";
|
||||
|
||||
import { graphql, withFragmentContainer } from "talk-framework/lib/relay";
|
||||
import { OpenOrCloseStreamContainer_story as StoryData } from "talk-stream/__generated__/OpenOrCloseStreamContainer_story.graphql";
|
||||
import {
|
||||
CloseStoryMutation,
|
||||
OpenStoryMutation,
|
||||
withCloseStoryMutation,
|
||||
withOpenStoryMutation,
|
||||
} from "talk-stream/mutations";
|
||||
|
||||
import CloseStream from "../components/CloseStream";
|
||||
import OpenStream from "../components/OpenStream";
|
||||
|
||||
interface Props {
|
||||
story: StoryData;
|
||||
openStory: OpenStoryMutation;
|
||||
closeStory: CloseStoryMutation;
|
||||
}
|
||||
|
||||
interface State {
|
||||
waitingForResponse: boolean;
|
||||
}
|
||||
|
||||
class OpenOrCloseStreamContainer extends React.Component<Props, State> {
|
||||
public state: State = {
|
||||
waitingForResponse: false,
|
||||
};
|
||||
|
||||
private handleOnClick = async () => {
|
||||
if (!this.state.waitingForResponse) {
|
||||
this.setState({ waitingForResponse: true });
|
||||
if (this.props.story.isClosed) {
|
||||
await this.props.openStory({ id: this.props.story.id });
|
||||
} else {
|
||||
await this.props.closeStory({ id: this.props.story.id });
|
||||
}
|
||||
this.setState({ waitingForResponse: false });
|
||||
}
|
||||
};
|
||||
|
||||
public render() {
|
||||
return this.props.story.isClosed ? (
|
||||
<OpenStream
|
||||
onClick={this.handleOnClick}
|
||||
disableButton={this.state.waitingForResponse}
|
||||
/>
|
||||
) : (
|
||||
<CloseStream
|
||||
onClick={this.handleOnClick}
|
||||
disableButton={this.state.waitingForResponse}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const enhanced = withFragmentContainer<Props>({
|
||||
story: graphql`
|
||||
fragment OpenOrCloseStreamContainer_story on Story {
|
||||
id
|
||||
isClosed
|
||||
}
|
||||
`,
|
||||
})(withOpenStoryMutation(withCloseStoryMutation(OpenOrCloseStreamContainer)));
|
||||
export default enhanced;
|
||||
+209
-173
@@ -8,209 +8,245 @@ exports[`renders configure 1`] = `
|
||||
id="tabPane-CONFIGURE"
|
||||
role="tabpanel"
|
||||
>
|
||||
<div
|
||||
className="HorizontalGutter-root HorizontalGutter-double"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
className="Flex-root"
|
||||
className="HorizontalGutter-root HorizontalGutter-double"
|
||||
>
|
||||
<div
|
||||
className="Flex-flex Flex-halfItemGutter Flex-wrap"
|
||||
className="Flex-root"
|
||||
>
|
||||
<div
|
||||
className="Typography-root Typography-bodyCopy Typography-colorTextPrimary"
|
||||
className="Flex-flex Flex-halfItemGutter Flex-wrap"
|
||||
>
|
||||
Signed in as
|
||||
<span
|
||||
className="Typography-root Typography-bodyCopyBold Typography-colorTextPrimary"
|
||||
<div
|
||||
className="Typography-root Typography-bodyCopy Typography-colorTextPrimary"
|
||||
>
|
||||
Moderator
|
||||
</span>
|
||||
.
|
||||
Signed in as
|
||||
<span
|
||||
className="Typography-root Typography-bodyCopyBold Typography-colorTextPrimary"
|
||||
>
|
||||
Moderator
|
||||
</span>
|
||||
.
|
||||
</div>
|
||||
<div
|
||||
className="Flex-root Typography-root Typography-bodyCopy Typography-colorTextPrimary Flex-flex"
|
||||
>
|
||||
<span>
|
||||
Not you?
|
||||
</span>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeSmall Button-colorPrimary Button-variantUnderlined"
|
||||
onBlur={[Function]}
|
||||
onClick={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
type="button"
|
||||
>
|
||||
Sign Out
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<form
|
||||
autoComplete="off"
|
||||
id="configure-form"
|
||||
onSubmit={[Function]}
|
||||
>
|
||||
<div
|
||||
className="Flex-root Typography-root Typography-bodyCopy Typography-colorTextPrimary Flex-flex"
|
||||
className="Flex-root Flex-flex Flex-itemGutter Flex-justifySpaceBetween Flex-alignFlexStart"
|
||||
>
|
||||
<span>
|
||||
Not you?
|
||||
</span>
|
||||
<h1
|
||||
className="Typography-root Typography-heading2 Typography-colorTextPrimary ConfigureStream-heading"
|
||||
>
|
||||
Configure this Comment Stream
|
||||
</h1>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeSmall Button-colorPrimary Button-variantUnderlined"
|
||||
className="BaseButton-root Button-root Button-sizeRegular Button-colorSuccess Button-variantFilled Button-disabled"
|
||||
disabled={true}
|
||||
onBlur={[Function]}
|
||||
onClick={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
type="button"
|
||||
type="submit"
|
||||
>
|
||||
Sign Out
|
||||
Apply
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<form
|
||||
autoComplete="off"
|
||||
id="configure-form"
|
||||
onSubmit={[Function]}
|
||||
>
|
||||
<div
|
||||
className="Flex-root Flex-flex Flex-itemGutter Flex-justifySpaceBetween Flex-alignFlexStart"
|
||||
>
|
||||
<h1
|
||||
className="Typography-root Typography-heading2 Typography-colorTextPrimary ConfigureCommentStream-heading"
|
||||
<div
|
||||
className="HorizontalGutter-root HorizontalGutter-double"
|
||||
>
|
||||
Configure this Comment Stream
|
||||
</h1>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeRegular Button-colorSuccess Button-variantFilled Button-disabled"
|
||||
disabled={true}
|
||||
onBlur={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
type="submit"
|
||||
>
|
||||
Apply
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
className="HorizontalGutter-root HorizontalGutter-double"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
className="CheckBox-root"
|
||||
>
|
||||
<input
|
||||
checked={false}
|
||||
className="CheckBox-input"
|
||||
disabled={false}
|
||||
id="moderation"
|
||||
name="moderation"
|
||||
onBlur={[Function]}
|
||||
onChange={[Function]}
|
||||
onFocus={[Function]}
|
||||
type="checkbox"
|
||||
/>
|
||||
<label
|
||||
className="CheckBox-label"
|
||||
htmlFor="moderation"
|
||||
>
|
||||
<span
|
||||
className="CheckBox-labelSpan"
|
||||
>
|
||||
<span
|
||||
className="Typography-root Typography-heading3 Typography-colorTextPrimary"
|
||||
>
|
||||
<span>
|
||||
Enable Pre-Moderation
|
||||
</span>
|
||||
</span>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<div
|
||||
className="ToggleConfig-details"
|
||||
>
|
||||
<p
|
||||
className="Typography-root Typography-detail Typography-colorTextSecondary WidthLimitedDescription-root"
|
||||
>
|
||||
Moderators must approve any comment before it is published to this stream.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
className="CheckBox-root"
|
||||
>
|
||||
<input
|
||||
checked={false}
|
||||
className="CheckBox-input"
|
||||
disabled={false}
|
||||
id="premodLinksEnable"
|
||||
name="premodLinksEnable"
|
||||
onBlur={[Function]}
|
||||
onChange={[Function]}
|
||||
onFocus={[Function]}
|
||||
type="checkbox"
|
||||
/>
|
||||
<label
|
||||
className="CheckBox-label"
|
||||
htmlFor="premodLinksEnable"
|
||||
>
|
||||
<span
|
||||
className="CheckBox-labelSpan"
|
||||
>
|
||||
<span
|
||||
className="Typography-root Typography-heading3 Typography-colorTextPrimary"
|
||||
>
|
||||
<span>
|
||||
Pre-Moderate Comments Containing Links
|
||||
</span>
|
||||
</span>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<div
|
||||
className="ToggleConfig-details"
|
||||
>
|
||||
<p
|
||||
className="Typography-root Typography-detail Typography-colorTextSecondary WidthLimitedDescription-root"
|
||||
>
|
||||
Moderators must approve any comment that contains a link before it is published to this stream.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
className="CheckBox-root"
|
||||
>
|
||||
<input
|
||||
checked={false}
|
||||
className="CheckBox-input"
|
||||
disabled={false}
|
||||
id="messageBox.enabled"
|
||||
name="messageBox.enabled"
|
||||
onBlur={[Function]}
|
||||
onChange={[Function]}
|
||||
onFocus={[Function]}
|
||||
type="checkbox"
|
||||
/>
|
||||
<label
|
||||
className="CheckBox-label"
|
||||
htmlFor="messageBox.enabled"
|
||||
>
|
||||
<span
|
||||
className="CheckBox-labelSpan"
|
||||
>
|
||||
<span
|
||||
className="Typography-root Typography-heading3 Typography-colorTextPrimary"
|
||||
>
|
||||
<span>
|
||||
Enable Message Box for this Stream
|
||||
</span>
|
||||
</span>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<div
|
||||
className="ToggleConfig-details"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
className="HorizontalGutter-root HorizontalGutter-oneAndAHalf"
|
||||
className="CheckBox-root"
|
||||
>
|
||||
<input
|
||||
checked={false}
|
||||
className="CheckBox-input"
|
||||
disabled={false}
|
||||
id="moderation"
|
||||
name="moderation"
|
||||
onBlur={[Function]}
|
||||
onChange={[Function]}
|
||||
onFocus={[Function]}
|
||||
type="checkbox"
|
||||
/>
|
||||
<label
|
||||
className="CheckBox-label"
|
||||
htmlFor="moderation"
|
||||
>
|
||||
<span
|
||||
className="CheckBox-labelSpan"
|
||||
>
|
||||
<span
|
||||
className="Typography-root Typography-heading3 Typography-colorTextPrimary"
|
||||
>
|
||||
<span>
|
||||
Enable Pre-Moderation
|
||||
</span>
|
||||
</span>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<div
|
||||
className="ToggleConfig-details"
|
||||
>
|
||||
<p
|
||||
className="Typography-root Typography-detail Typography-colorTextSecondary WidthLimitedDescription-root"
|
||||
>
|
||||
Add a message to the top of the comment box for your readers. Use this to pose a topic,
|
||||
ask a question or make announcements relating to this story.
|
||||
Moderators must approve any comment before it is published to this stream.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
className="CheckBox-root"
|
||||
>
|
||||
<input
|
||||
checked={false}
|
||||
className="CheckBox-input"
|
||||
disabled={false}
|
||||
id="premodLinksEnable"
|
||||
name="premodLinksEnable"
|
||||
onBlur={[Function]}
|
||||
onChange={[Function]}
|
||||
onFocus={[Function]}
|
||||
type="checkbox"
|
||||
/>
|
||||
<label
|
||||
className="CheckBox-label"
|
||||
htmlFor="premodLinksEnable"
|
||||
>
|
||||
<span
|
||||
className="CheckBox-labelSpan"
|
||||
>
|
||||
<span
|
||||
className="Typography-root Typography-heading3 Typography-colorTextPrimary"
|
||||
>
|
||||
<span>
|
||||
Pre-Moderate Comments Containing Links
|
||||
</span>
|
||||
</span>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<div
|
||||
className="ToggleConfig-details"
|
||||
>
|
||||
<p
|
||||
className="Typography-root Typography-detail Typography-colorTextSecondary WidthLimitedDescription-root"
|
||||
>
|
||||
Moderators must approve any comment that contains a link before it is published to this stream.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
className="CheckBox-root"
|
||||
>
|
||||
<input
|
||||
checked={false}
|
||||
className="CheckBox-input"
|
||||
disabled={false}
|
||||
id="messageBox.enabled"
|
||||
name="messageBox.enabled"
|
||||
onBlur={[Function]}
|
||||
onChange={[Function]}
|
||||
onFocus={[Function]}
|
||||
type="checkbox"
|
||||
/>
|
||||
<label
|
||||
className="CheckBox-label"
|
||||
htmlFor="messageBox.enabled"
|
||||
>
|
||||
<span
|
||||
className="CheckBox-labelSpan"
|
||||
>
|
||||
<span
|
||||
className="Typography-root Typography-heading3 Typography-colorTextPrimary"
|
||||
>
|
||||
<span>
|
||||
Enable Message Box for this Stream
|
||||
</span>
|
||||
</span>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<div
|
||||
className="ToggleConfig-details"
|
||||
>
|
||||
<div
|
||||
className="HorizontalGutter-root HorizontalGutter-oneAndAHalf"
|
||||
>
|
||||
<p
|
||||
className="Typography-root Typography-detail Typography-colorTextSecondary WidthLimitedDescription-root"
|
||||
>
|
||||
Add a message to the top of the comment box for your readers. Use this to pose a topic,
|
||||
ask a question or make announcements relating to this story.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<hr
|
||||
className="HorizontalRule-root"
|
||||
/>
|
||||
<div>
|
||||
<h1
|
||||
className="Typography-root Typography-heading2 Typography-colorTextPrimary CloseStream-heading"
|
||||
>
|
||||
Close Comment Stream
|
||||
</h1>
|
||||
<div
|
||||
className="Flex-root Flex-flex Flex-itemGutter Flex-alignFlexStart"
|
||||
>
|
||||
<p
|
||||
className="Typography-root Typography-bodyCopy Typography-colorTextPrimary"
|
||||
>
|
||||
This comment stream is currently open. By closing this comment stream,
|
||||
no new comments may be submitted and all previously submitted comments
|
||||
will still be displayed.
|
||||
</p>
|
||||
<button
|
||||
className="BaseButton-root Button-root CloseStream-button Button-sizeRegular Button-colorError Button-variantOutlined"
|
||||
disabled={false}
|
||||
onBlur={[Function]}
|
||||
onClick={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
type="button"
|
||||
>
|
||||
Close Stream
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
`;
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
import sinon from "sinon";
|
||||
|
||||
import { waitForElement, within } from "talk-framework/testHelpers";
|
||||
|
||||
import { meAsModerator, settings, stories } from "../fixtures";
|
||||
import create from "./create";
|
||||
|
||||
async function createTestRenderer(
|
||||
resolver: any = {},
|
||||
options: { muteNetworkErrors?: boolean; status?: string } = {}
|
||||
) {
|
||||
const resolvers = {
|
||||
...resolver,
|
||||
Query: {
|
||||
settings: sinon.stub().returns(settings),
|
||||
story: sinon.stub().returns(stories[0]),
|
||||
me: sinon.stub().returns(meAsModerator),
|
||||
...resolver.Query,
|
||||
},
|
||||
};
|
||||
|
||||
const { testRenderer } = create({
|
||||
// Set this to true, to see graphql responses.
|
||||
logNetwork: false,
|
||||
muteNetworkErrors: options.muteNetworkErrors,
|
||||
resolvers,
|
||||
initLocalState: localRecord => {
|
||||
localRecord.setValue(stories[0].id, "storyID");
|
||||
},
|
||||
});
|
||||
|
||||
const tabPane = await waitForElement(() =>
|
||||
within(testRenderer.root).getByTestID("current-tab-pane")
|
||||
);
|
||||
|
||||
return { testRenderer, tabPane };
|
||||
}
|
||||
|
||||
it("close stream", async () => {
|
||||
const closeStoryStub = sinon.stub().callsFake((_: any, data: any) => {
|
||||
expectAndFail(data.input.id).toBe(stories[0].id);
|
||||
return {
|
||||
story: { ...stories[0], isClosed: true },
|
||||
clientMutationId: data.input.clientMutationId,
|
||||
};
|
||||
});
|
||||
const { tabPane } = await createTestRenderer({
|
||||
Mutation: {
|
||||
closeStory: closeStoryStub,
|
||||
},
|
||||
});
|
||||
|
||||
const button = within(tabPane).getByText("Close Stream", {
|
||||
selector: "button",
|
||||
});
|
||||
button.props.onClick();
|
||||
|
||||
expect(button.props.disabled).toBe(true);
|
||||
|
||||
// Stream should then appear closed.
|
||||
await waitForElement(() =>
|
||||
within(tabPane).getByText("Open Stream", {
|
||||
selector: "button",
|
||||
})
|
||||
);
|
||||
|
||||
// Should have successfully sent with server.
|
||||
expect(closeStoryStub.called).toBe(true);
|
||||
});
|
||||
|
||||
it("opens stream", async () => {
|
||||
const openStoryStub = sinon.stub().callsFake((_: any, data: any) => {
|
||||
expectAndFail(data.input.id).toBe(stories[0].id);
|
||||
return {
|
||||
story: { ...stories[0], isClosed: false },
|
||||
clientMutationId: data.input.clientMutationId,
|
||||
};
|
||||
});
|
||||
const { tabPane } = await createTestRenderer({
|
||||
Query: {
|
||||
story: sinon.stub().returns({ ...stories[0], isClosed: true }),
|
||||
},
|
||||
Mutation: {
|
||||
openStory: openStoryStub,
|
||||
},
|
||||
});
|
||||
|
||||
const button = within(tabPane).getByText("Open Stream", {
|
||||
selector: "button",
|
||||
});
|
||||
button.props.onClick();
|
||||
|
||||
// Stream should then appear open.
|
||||
await waitForElement(() =>
|
||||
within(tabPane).getByText("Close Stream", {
|
||||
selector: "button",
|
||||
})
|
||||
);
|
||||
|
||||
// Should have successfully sent with server.
|
||||
expect(openStoryStub.called).toBe(true);
|
||||
});
|
||||
Reference in New Issue
Block a user