mirror of
https://github.com/wassname/talk.git
synced 2026-07-21 12:51:03 +08:00
[CORL-918] make siteID required in site query (#2851)
* make siteID required in site query * update specs and snaps * remove unnecessary comment
This commit is contained in:
@@ -13,7 +13,7 @@ it("renders correctly", () => {
|
||||
allStories: true,
|
||||
moderationQueues: {},
|
||||
story: {},
|
||||
site: null,
|
||||
siteID: null,
|
||||
query: "",
|
||||
routeParams: {},
|
||||
queueName: "",
|
||||
|
||||
@@ -26,15 +26,12 @@ interface RouteParams {
|
||||
interface Props {
|
||||
story: PropTypesOf<typeof ModerateNavigationContainer>["story"] &
|
||||
PropTypesOf<typeof ModerateSearchBarContainer>["story"];
|
||||
site:
|
||||
| { id: string } & PropTypesOf<typeof ModerateNavigationContainer>["site"] &
|
||||
PropTypesOf<typeof SiteSelectorContainer>["site"]
|
||||
| null;
|
||||
query: PropTypesOf<typeof SiteSelectorContainer>["query"];
|
||||
moderationQueues: PropTypesOf<
|
||||
typeof ModerateNavigationContainer
|
||||
>["moderationQueues"];
|
||||
allStories: boolean;
|
||||
siteID: string | null;
|
||||
settings: PropTypesOf<typeof ModerateSearchBarContainer>["settings"] | null;
|
||||
children?: React.ReactNode;
|
||||
queueName: string;
|
||||
@@ -44,13 +41,13 @@ interface Props {
|
||||
const Moderate: FunctionComponent<Props> = ({
|
||||
moderationQueues,
|
||||
story,
|
||||
site,
|
||||
query,
|
||||
allStories,
|
||||
children,
|
||||
queueName,
|
||||
routeParams,
|
||||
settings,
|
||||
siteID,
|
||||
}) => {
|
||||
const [showHotkeysModal, setShowHotkeysModal] = useState(false);
|
||||
const closeModal = useCallback(() => {
|
||||
@@ -79,8 +76,8 @@ const Moderate: FunctionComponent<Props> = ({
|
||||
siteSelector={
|
||||
<SiteSelectorContainer
|
||||
queueName={queueName}
|
||||
site={site}
|
||||
query={query}
|
||||
siteID={routeParams.siteID || siteID || null}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
@@ -88,7 +85,7 @@ const Moderate: FunctionComponent<Props> = ({
|
||||
<ModerateNavigationContainer
|
||||
moderationQueues={moderationQueues}
|
||||
story={story}
|
||||
site={story ? null : site}
|
||||
siteID={routeParams.siteID || siteID || null}
|
||||
/>
|
||||
</SubBar>
|
||||
<div className={styles.background} />
|
||||
|
||||
@@ -31,6 +31,7 @@ class ModerateContainer extends React.Component<Props> {
|
||||
"reported",
|
||||
"pending",
|
||||
"unmoderated",
|
||||
"approved",
|
||||
"rejected",
|
||||
].find(name => {
|
||||
return this.props.match.location.pathname.includes(name);
|
||||
@@ -40,8 +41,8 @@ class ModerateContainer extends React.Component<Props> {
|
||||
<Moderate
|
||||
moderationQueues={null}
|
||||
story={null}
|
||||
site={null}
|
||||
settings={null}
|
||||
siteID={null}
|
||||
query={this.props.data}
|
||||
routeParams={this.props.match.params}
|
||||
queueName={queueName || "default"}
|
||||
@@ -56,10 +57,7 @@ class ModerateContainer extends React.Component<Props> {
|
||||
<Moderate
|
||||
moderationQueues={this.props.data.moderationQueues}
|
||||
story={this.props.data.story || null}
|
||||
site={
|
||||
this.props.data.site ||
|
||||
(this.props.data.story ? this.props.data.story.site : null)
|
||||
}
|
||||
siteID={this.props.data.story ? this.props.data.story.site.id : null}
|
||||
routeParams={this.props.match.params}
|
||||
query={this.props.data}
|
||||
allStories={allStories}
|
||||
@@ -78,7 +76,6 @@ const enhanced = withRouteConfig<Props>({
|
||||
$storyID: ID
|
||||
$includeStory: Boolean!
|
||||
$siteID: ID
|
||||
$includeSite: Boolean!
|
||||
) {
|
||||
settings {
|
||||
...ModerateSearchBarContainer_settings
|
||||
@@ -88,15 +85,8 @@ const enhanced = withRouteConfig<Props>({
|
||||
...ModerateSearchBarContainer_story
|
||||
site {
|
||||
id
|
||||
...ModerateNavigationContainer_site
|
||||
...SiteSelectorSelected_site
|
||||
}
|
||||
}
|
||||
site(id: $siteID) @include(if: $includeSite) {
|
||||
id
|
||||
...ModerateNavigationContainer_site
|
||||
...SiteSelectorSelected_site
|
||||
}
|
||||
moderationQueues(storyID: $storyID, siteID: $siteID) {
|
||||
...ModerateNavigationContainer_moderationQueues
|
||||
}
|
||||
|
||||
+4
-10
@@ -8,7 +8,6 @@ import {
|
||||
} from "coral-framework/lib/relay";
|
||||
|
||||
import { ModerateNavigationContainer_moderationQueues as ModerationQueuesData } from "coral-admin/__generated__/ModerateNavigationContainer_moderationQueues.graphql";
|
||||
import { ModerateNavigationContainer_site as SiteData } from "coral-admin/__generated__/ModerateNavigationContainer_site.graphql";
|
||||
import { ModerateNavigationContainer_story as StoryData } from "coral-admin/__generated__/ModerateNavigationContainer_story.graphql";
|
||||
|
||||
import ModerateCountsCommentEnteredSubscription from "./ModerateCountsCommentEnteredSubscription";
|
||||
@@ -18,7 +17,7 @@ import Navigation from "./Navigation";
|
||||
interface Props {
|
||||
moderationQueues: ModerationQueuesData | null;
|
||||
story: StoryData | null;
|
||||
site: SiteData | null;
|
||||
siteID: string | null;
|
||||
}
|
||||
|
||||
const ModerateNavigationContainer: React.FunctionComponent<Props> = props => {
|
||||
@@ -35,7 +34,7 @@ const ModerateNavigationContainer: React.FunctionComponent<Props> = props => {
|
||||
}
|
||||
const vars = {
|
||||
storyID: props.story && props.story.id,
|
||||
siteID: props.site && props.site.id,
|
||||
siteID: props.siteID,
|
||||
};
|
||||
const disposable = combineDisposables(
|
||||
subscribeToCommentEntered(vars),
|
||||
@@ -44,7 +43,7 @@ const ModerateNavigationContainer: React.FunctionComponent<Props> = props => {
|
||||
return () => {
|
||||
disposable.dispose();
|
||||
};
|
||||
}, [Boolean(props.moderationQueues), props.story, props.site]);
|
||||
}, [Boolean(props.moderationQueues), props.story, props.siteID]);
|
||||
|
||||
if (!props.moderationQueues) {
|
||||
return <Navigation />;
|
||||
@@ -55,7 +54,7 @@ const ModerateNavigationContainer: React.FunctionComponent<Props> = props => {
|
||||
reportedCount={props.moderationQueues.reported.count}
|
||||
pendingCount={props.moderationQueues.pending.count}
|
||||
storyID={props.story && props.story.id}
|
||||
siteID={props.site && props.site.id}
|
||||
siteID={props.siteID}
|
||||
/>
|
||||
);
|
||||
};
|
||||
@@ -66,11 +65,6 @@ const enhanced = withFragmentContainer<Props>({
|
||||
id
|
||||
}
|
||||
`,
|
||||
site: graphql`
|
||||
fragment ModerateNavigationContainer_site on Site {
|
||||
id
|
||||
}
|
||||
`,
|
||||
moderationQueues: graphql`
|
||||
fragment ModerateNavigationContainer_moderationQueues on ModerationQueues {
|
||||
unmoderated {
|
||||
|
||||
@@ -5,31 +5,29 @@ import PaginatedSelect from "coral-admin/components/PaginatedSelect";
|
||||
import { getModerationLink, QUEUE_NAME } from "coral-framework/helpers";
|
||||
import { PropTypesOf } from "coral-framework/types";
|
||||
|
||||
import SiteSelectorSelected from "./SiteSelectorSelected";
|
||||
import SiteSelectorCurrentSiteQuery from "./SiteSelectorCurrentSiteQuery";
|
||||
import SiteSelectorSite from "./SiteSelectorSite";
|
||||
|
||||
import styles from "./SiteSelector.css";
|
||||
|
||||
interface Props {
|
||||
sites: Array<{ id: string } & PropTypesOf<typeof SiteSelectorSite>["site"]>;
|
||||
site:
|
||||
| { id: string } & PropTypesOf<typeof SiteSelectorSelected>["site"]
|
||||
| null;
|
||||
queueName: string;
|
||||
onLoadMore: () => void;
|
||||
hasMore: boolean;
|
||||
disableLoadMore: boolean;
|
||||
loading: boolean;
|
||||
siteID: string | null;
|
||||
}
|
||||
|
||||
const SiteSelector: FunctionComponent<Props> = ({
|
||||
sites,
|
||||
site,
|
||||
queueName,
|
||||
loading,
|
||||
onLoadMore,
|
||||
disableLoadMore,
|
||||
hasMore,
|
||||
siteID,
|
||||
}) => {
|
||||
return (
|
||||
<PaginatedSelect
|
||||
@@ -41,9 +39,9 @@ const SiteSelector: FunctionComponent<Props> = ({
|
||||
className={styles.button}
|
||||
selected={
|
||||
<>
|
||||
{site && <SiteSelectorSelected site={site} />}
|
||||
{siteID && <SiteSelectorCurrentSiteQuery siteID={siteID} />}
|
||||
|
||||
{!site && (
|
||||
{!siteID && (
|
||||
<Localized id="site-selector-all-sites">
|
||||
<span className={styles.buttonText}>All sites</span>
|
||||
</Localized>
|
||||
@@ -55,7 +53,7 @@ const SiteSelector: FunctionComponent<Props> = ({
|
||||
<SiteSelectorSite
|
||||
link={getModerationLink({ queue: queueName as QUEUE_NAME })}
|
||||
site={null}
|
||||
active={!site}
|
||||
active={!siteID}
|
||||
/>
|
||||
{sites.map(s => (
|
||||
<SiteSelectorSite
|
||||
@@ -65,7 +63,7 @@ const SiteSelector: FunctionComponent<Props> = ({
|
||||
})}
|
||||
key={s.id}
|
||||
site={s}
|
||||
active={(site && site.id === s.id) || false}
|
||||
active={(siteID && siteID === s.id) || false}
|
||||
/>
|
||||
))}
|
||||
</>
|
||||
|
||||
@@ -6,7 +6,6 @@ import {
|
||||
useRefetch,
|
||||
withPaginationContainer,
|
||||
} from "coral-framework/lib/relay";
|
||||
import { PropTypesOf } from "coral-ui/types";
|
||||
|
||||
import { SiteSelectorContainer_query as QueryData } from "coral-admin/__generated__/SiteSelectorContainer_query.graphql";
|
||||
import { SiteSelectorContainerPaginationQueryVariables } from "coral-admin/__generated__/SiteSelectorContainerPaginationQuery.graphql";
|
||||
@@ -15,9 +14,9 @@ import SiteSelector from "./SiteSelector";
|
||||
|
||||
interface Props {
|
||||
query: QueryData | null;
|
||||
site: PropTypesOf<typeof SiteSelector>["site"] | null;
|
||||
relay: RelayPaginationProp;
|
||||
queueName: string;
|
||||
siteID: string | null;
|
||||
}
|
||||
|
||||
const SiteSelectorContainer: React.FunctionComponent<Props> = props => {
|
||||
@@ -32,11 +31,11 @@ const SiteSelectorContainer: React.FunctionComponent<Props> = props => {
|
||||
<SiteSelector
|
||||
loading={!props.query || isRefetching}
|
||||
sites={sites}
|
||||
site={props.site}
|
||||
onLoadMore={loadMore}
|
||||
hasMore={!isRefetching && props.relay.hasMore()}
|
||||
disableLoadMore={isLoadingMore}
|
||||
queueName={props.queueName}
|
||||
siteID={props.siteID}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
import React, { FunctionComponent } from "react";
|
||||
|
||||
import {
|
||||
graphql,
|
||||
QueryRenderData,
|
||||
QueryRenderer,
|
||||
} from "coral-framework/lib/relay";
|
||||
import Spinner from "coral-stream/common/Spinner";
|
||||
import { Delay } from "coral-ui/components";
|
||||
|
||||
import { SiteSelectorCurrentSiteQuery as QueryTypes } from "coral-admin/__generated__/SiteSelectorCurrentSiteQuery.graphql";
|
||||
|
||||
interface Props {
|
||||
siteID: string;
|
||||
}
|
||||
|
||||
export const render = ({ error, props }: QueryRenderData<QueryTypes>) => {
|
||||
if (error) {
|
||||
return <div>{error.message}</div>;
|
||||
}
|
||||
if (props) {
|
||||
return <div>{props.site && props.site.name}</div>;
|
||||
}
|
||||
return (
|
||||
<Delay>
|
||||
<Spinner />
|
||||
</Delay>
|
||||
);
|
||||
};
|
||||
|
||||
const enhanced: FunctionComponent<Props> = ({ siteID }) => {
|
||||
return (
|
||||
<QueryRenderer<QueryTypes>
|
||||
query={graphql`
|
||||
query SiteSelectorCurrentSiteQuery($siteID: ID!) {
|
||||
site(id: $siteID) {
|
||||
id
|
||||
name
|
||||
}
|
||||
}
|
||||
`}
|
||||
variables={{
|
||||
siteID,
|
||||
}}
|
||||
render={render}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default enhanced;
|
||||
@@ -1,4 +0,0 @@
|
||||
.root {
|
||||
overflow-x: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
import React, { FunctionComponent } from "react";
|
||||
|
||||
import { graphql, withFragmentContainer } from "coral-framework/lib/relay";
|
||||
|
||||
import { SiteSelectorSelected_site } from "coral-admin/__generated__/SiteSelectorSelected_site.graphql";
|
||||
|
||||
import styles from "./SiteSelectorSelected.css";
|
||||
|
||||
interface Props {
|
||||
site: SiteSelectorSelected_site;
|
||||
}
|
||||
|
||||
const SiteSelectorSelected: FunctionComponent<Props> = ({ site }) => {
|
||||
return <span className={styles.root}>{site.name}</span>;
|
||||
};
|
||||
|
||||
const enhanced = withFragmentContainer<Props>({
|
||||
site: graphql`
|
||||
fragment SiteSelectorSelected_site on Site {
|
||||
name
|
||||
id
|
||||
}
|
||||
`,
|
||||
})(SiteSelectorSelected);
|
||||
|
||||
export default enhanced;
|
||||
@@ -16,7 +16,7 @@ exports[`renders correctly 1`] = `
|
||||
<Relay(SiteSelectorContainer)
|
||||
query=""
|
||||
queueName=""
|
||||
site={null}
|
||||
siteID={null}
|
||||
/>
|
||||
}
|
||||
story={Object {}}
|
||||
@@ -26,7 +26,7 @@ exports[`renders correctly 1`] = `
|
||||
>
|
||||
<Relay(ModerateNavigationContainer)
|
||||
moderationQueues={Object {}}
|
||||
site={null}
|
||||
siteID={null}
|
||||
story={Object {}}
|
||||
/>
|
||||
</withPropsOnChange(SubBar)>
|
||||
|
||||
@@ -2929,7 +2929,7 @@ type Query {
|
||||
status: USER_STATUS
|
||||
): UsersConnection! @auth(roles: [ADMIN, MODERATOR])
|
||||
|
||||
site(id: ID): Site @auth(roles: [ADMIN, MODERATOR])
|
||||
site(id: ID!): Site @auth(roles: [ADMIN, MODERATOR])
|
||||
|
||||
sites(first: Int = 10 @constraint(max: 50), after: Cursor): SitesConnection!
|
||||
@auth(roles: [ADMIN, MODERATOR])
|
||||
|
||||
Reference in New Issue
Block a user