Skip to content

Commit

Permalink
god fucking dammit
Browse files Browse the repository at this point in the history
bad ugly not good solution to the race condition on page load,
but it works perfectly so w/e

i'm delaying each query until the backend URL to query is specified

the (imo) correct solution here is to correctly invalidate tags
in the presence of a race condition. seems like there's a PR to do
that here: reduxjs/redux-toolkit#3116
but no movement on it for the last few months

related issue: reduxjs/redux-toolkit#3386
  • Loading branch information
ndepaola committed May 18, 2023
1 parent 784ed29 commit fe779f5
Show file tree
Hide file tree
Showing 12 changed files with 74 additions and 23 deletions.
1 change: 1 addition & 0 deletions frontend/jest.config.mjs
Expand Up @@ -13,6 +13,7 @@ const config = {

testEnvironment: "jest-environment-jsdom",
injectGlobals: true,
testTimeout: 20_000,
};

// createJestConfig is exported this way to ensure that next/jest can load the Next.js config which is async
Expand Down
13 changes: 6 additions & 7 deletions frontend/src/features/backend/backend.tsx
Expand Up @@ -21,7 +21,11 @@ import {
setLocalStorageBackendURL,
} from "@/common/cookies";
import { standardiseURL } from "@/common/processing";
import { clearURL, setURL } from "@/features/backend/backendSlice";
import {
clearURL,
selectBackendURL,
setURL,
} from "@/features/backend/backendSlice";
require("bootstrap-icons/font/bootstrap-icons.css");

interface BackendConfigProps {
Expand Down Expand Up @@ -90,10 +94,7 @@ export function BackendConfig(props: BackendConfigProps) {
>([]);
const [validating, setValidating] = useState<boolean>(false);

const [triggerFn, getBackendInfoQuery] =
apiSlice.endpoints.getBackendInfo.useLazyQuery();

const backendURL = useSelector((state: RootState) => state.backend.url);
const backendURL = useSelector(selectBackendURL);
const clearBackendURL = () => {
dispatch(clearURL());
clearLocalStorageBackendURL();
Expand Down Expand Up @@ -139,7 +140,6 @@ export function BackendConfig(props: BackendConfigProps) {
setLocalStorageBackendURL(formattedURL);
dispatch(apiSlice.util.invalidateTags([QueryTags.BackendSpecific]));
setLocalBackendURL("");
triggerFn();
}
setValidating(false);
};
Expand All @@ -149,7 +149,6 @@ export function BackendConfig(props: BackendConfigProps) {
if (backendURL != undefined) {
dispatch(setURL(backendURL));
dispatch(apiSlice.util.invalidateTags([QueryTags.BackendSpecific]));
triggerFn();
}
}, []);

Expand Down
2 changes: 2 additions & 0 deletions frontend/src/features/backend/backendSlice.ts
Expand Up @@ -27,3 +27,5 @@ export const backendSlice = createSlice({

export const { setURL, clearURL } = backendSlice.actions;
export default backendSlice.reducer;

export const selectBackendURL = (state: RootState) => state.backend.url;
6 changes: 5 additions & 1 deletion frontend/src/features/import/importCSV.tsx
Expand Up @@ -24,6 +24,7 @@ import {
convertLinesIntoSlotProjectMembers,
processLines,
} from "@/common/processing";
import { selectBackendURL } from "@/features/backend/backendSlice";
import { addMembers, selectProjectSize } from "@/features/project/projectSlice";

const BorderedTable = styled(Table)`
Expand Down Expand Up @@ -138,7 +139,10 @@ function SampleCSV() {

export function ImportCSV() {
const dispatch = useDispatch<AppDispatch>();
const dfcPairsQuery = useGetDFCPairsQuery();
const backendURL = useSelector(selectBackendURL);
const dfcPairsQuery = useGetDFCPairsQuery(undefined, {
skip: backendURL == null,
});
const [showCSVModal, setShowCSVModal] = useState(false);
const handleCloseCSVModal = () => setShowCSVModal(false);
const handleShowCSVModal = () => setShowCSVModal(true);
Expand Down
10 changes: 8 additions & 2 deletions frontend/src/features/import/importText.tsx
Expand Up @@ -27,12 +27,18 @@ import {
stripTextInParentheses,
} from "@/common/processing";
import { CardDocument } from "@/common/types";
import { selectBackendURL } from "@/features/backend/backendSlice";
import { addMembers, selectProjectSize } from "@/features/project/projectSlice";

export function ImportText() {
// TODO: add an accordion here for explaining how to search for each different card type with prefixes
const sampleCardsQuery = useGetSampleCardsQuery();
const dfcPairsQuery = useGetDFCPairsQuery();
const backendURL = useSelector(selectBackendURL);
const sampleCardsQuery = useGetSampleCardsQuery(undefined, {
skip: backendURL == null,
});
const dfcPairsQuery = useGetDFCPairsQuery(undefined, {
skip: backendURL == null,
});

const dispatch = useDispatch<AppDispatch>();
const [showTextModal, setShowTextModal] = useState(false);
Expand Down
14 changes: 11 additions & 3 deletions frontend/src/features/import/importURL.tsx
Expand Up @@ -26,13 +26,21 @@ import {
convertLinesIntoSlotProjectMembers,
processStringAsMultipleLines,
} from "@/common/processing";
import { selectBackendURL } from "@/features/backend/backendSlice";
import { addMembers, selectProjectSize } from "@/features/project/projectSlice";
import { Spinner } from "@/features/ui/spinner";

export function ImportURL() {
const dfcPairsQuery = useGetDFCPairsQuery();
const importSitesQuery = useGetImportSitesQuery();
const backendInfoQuery = useGetBackendInfoQuery();
const backendURL = useSelector(selectBackendURL);
const dfcPairsQuery = useGetDFCPairsQuery(undefined, {
skip: backendURL == null,
});
const importSitesQuery = useGetImportSitesQuery(undefined, {
skip: backendURL == null,
});
const backendInfoQuery = useGetBackendInfoQuery(undefined, {
skip: backendURL == null,
});

const projectSize = useSelector(selectProjectSize);
const dispatch = useDispatch<AppDispatch>();
Expand Down
7 changes: 6 additions & 1 deletion frontend/src/features/support/supportBackend.tsx
@@ -1,8 +1,10 @@
import React from "react";
import Button from "react-bootstrap/Button";
import Modal from "react-bootstrap/Modal";
import { useSelector } from "react-redux";

import { useGetBackendInfoQuery } from "@/app/api";
import { selectBackendURL } from "@/features/backend/backendSlice";
import { Spinner } from "@/features/ui/spinner";

interface SupportBackendModalProps {
Expand All @@ -14,7 +16,10 @@ interface SupportBackendModalProps {
}

export function SupportBackendModal(props: SupportBackendModalProps) {
const backendInfoQuery = useGetBackendInfoQuery();
const backendURL = useSelector(selectBackendURL);
const backendInfoQuery = useGetBackendInfoQuery(undefined, {
skip: backendURL == null,
});

return (
<Modal show={props.show} onHide={props.handleClose}>
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/features/support/supportDeveloper.tsx
Expand Up @@ -31,7 +31,7 @@ export function SupportDeveloperModal(props: SupportDeveloperModalProps) {
</p>
<p>
I&apos;m responsible for this website, the code that image repository
servers run on, and the desktop tool that automates
servers run on, and the desktop tool that automates{" "}
<a href={MakePlayingCardsURL} target="_blank">
{MakePlayingCards}
</a>
Expand Down
7 changes: 6 additions & 1 deletion frontend/src/features/ui/footer.tsx
@@ -1,6 +1,8 @@
import Link from "next/link";
import { useSelector } from "react-redux";

import { useGetBackendInfoQuery } from "@/app/api";
import { selectBackendURL } from "@/features/backend/backendSlice";

function Spacer() {
return (
Expand All @@ -9,7 +11,10 @@ function Spacer() {
}

export default function Footer() {
const backendInfoQuery = useGetBackendInfoQuery();
const backendURL = useSelector(selectBackendURL);
const backendInfoQuery = useGetBackendInfoQuery(undefined, {
skip: backendURL == null,
});
return (
<>
<hr />
Expand Down
7 changes: 5 additions & 2 deletions frontend/src/features/ui/navbar.tsx
Expand Up @@ -13,6 +13,7 @@ import { useGetBackendInfoQuery } from "@/app/api";
import { RootState } from "@/app/store";
import { ProjectName } from "@/common/constants";
import { BackendConfig } from "@/features/backend/backend";
import { selectBackendURL } from "@/features/backend/backendSlice";
import { SupportBackendModal } from "@/features/support/supportBackend";
import { SupportDeveloperModal } from "@/features/support/supportDeveloper";
import DisableSSR from "@/features/ui/disableSSR";
Expand All @@ -30,7 +31,10 @@ const BoldCollapse = styled(BSNavbar.Collapse)`
`;

export default function Navbar() {
const backendInfoQuery = useGetBackendInfoQuery();
const backendURL = useSelector(selectBackendURL);
const backendInfoQuery = useGetBackendInfoQuery(undefined, {
skip: backendURL == null,
});

const [showBackendConfig, setShowBackendConfig] = useState(false);
const [showSupportDeveloperModal, setShowSupportDeveloperModal] =
Expand All @@ -47,7 +51,6 @@ export default function Navbar() {
setShowSupportBackendModal(false);
const handleShowSupportBackendModal = () => setShowSupportBackendModal(true);

const backendURL = useSelector((state: RootState) => state.backend.url);
const name =
(backendInfoQuery.isSuccess ? backendInfoQuery.data?.name : null) ??
ProjectName;
Expand Down
7 changes: 6 additions & 1 deletion frontend/src/pages/about.tsx
@@ -1,9 +1,11 @@
import Head from "next/head";
import { useSelector } from "react-redux";
import styled from "styled-components";

import { useGetBackendInfoQuery } from "@/app/api";
import { ProjectName } from "@/common/constants";
import { MakePlayingCards, MakePlayingCardsURL } from "@/common/constants";
import { selectBackendURL } from "@/features/backend/backendSlice";
import Footer from "@/features/ui/footer";
import Layout from "@/features/ui/layout";

Expand All @@ -12,7 +14,10 @@ const CentreAligned = styled.div`
`;

function BackendDescription() {
const backendInfoQuery = useGetBackendInfoQuery();
const backendURL = useSelector(selectBackendURL);
const backendInfoQuery = useGetBackendInfoQuery(undefined, {
skip: backendURL == null,
});

return (
<>
Expand Down
21 changes: 17 additions & 4 deletions frontend/src/pages/contributions.tsx
Expand Up @@ -3,6 +3,7 @@ import Link from "next/link";
import React from "react";
import Alert from "react-bootstrap/Alert";
import Table from "react-bootstrap/Table";
import { useSelector } from "react-redux";
import styled from "styled-components";

import { useGetBackendInfoQuery, useGetContributionsQuery } from "@/app/api";
Expand All @@ -15,6 +16,7 @@ import {
Token,
} from "@/common/constants";
import { SourceContribution } from "@/common/types";
import { selectBackendURL } from "@/features/backend/backendSlice";
import Footer from "@/features/ui/footer";
import Layout from "@/features/ui/layout";
import { Spinner } from "@/features/ui/spinner";
Expand All @@ -24,8 +26,13 @@ const AutoLayoutTable = styled(Table)`
`;

function ContributionsSummary() {
const contributionsQuery = useGetContributionsQuery();
const backendInfoQuery = useGetBackendInfoQuery();
const backendURL = useSelector(selectBackendURL);
const contributionsQuery = useGetContributionsQuery(undefined, {
skip: backendURL == null,
});
const backendInfoQuery = useGetBackendInfoQuery(undefined, {
skip: backendURL == null,
});

const totalImages =
contributionsQuery.data?.card_count_by_type != null
Expand Down Expand Up @@ -73,7 +80,10 @@ function ContributionsSummary() {
}

function ContributionGuidelines() {
const backendInfoQuery = useGetBackendInfoQuery();
const backendURL = useSelector(selectBackendURL);
const backendInfoQuery = useGetBackendInfoQuery(undefined, {
skip: backendURL == null,
});

const name = backendInfoQuery.data?.name ?? ProjectName;

Expand Down Expand Up @@ -166,7 +176,10 @@ function sourceContributionRow(contribution: SourceContribution) {
}

function ContributionsPerSource() {
const contributionsQuery = useGetContributionsQuery();
const backendURL = useSelector(selectBackendURL);
const contributionsQuery = useGetContributionsQuery(undefined, {
skip: backendURL == null,
});

return contributionsQuery.isSuccess ? (
contributionsQuery.isLoading || contributionsQuery.data?.sources == null ? (
Expand Down

0 comments on commit fe779f5

Please sign in to comment.