diff --git a/static/js/global.d.ts b/static/js/global.d.ts index c7ca56fe19..200ee0127f 100644 --- a/static/js/global.d.ts +++ b/static/js/global.d.ts @@ -41,4 +41,7 @@ declare interface Window { whitelist_countries: string[]; whitelist_country_keys: string; }; + SNAP_LISTING_DATA: { + DNS_VERIFICATION_TOKEN: string; + }; } diff --git a/static/js/publisher-pages/components/SaveAndPreview/SaveAndPreview.tsx b/static/js/publisher-pages/components/SaveAndPreview/SaveAndPreview.tsx index a6b71a5685..eb2eb093ed 100644 --- a/static/js/publisher-pages/components/SaveAndPreview/SaveAndPreview.tsx +++ b/static/js/publisher-pages/components/SaveAndPreview/SaveAndPreview.tsx @@ -1,4 +1,4 @@ -import { useEffect, useRef } from "react"; +import { useRef } from "react"; import { Row, Col, Button } from "@canonical/react-components"; import debounce from "../../../libs/debounce"; @@ -20,6 +20,8 @@ function SaveAndPreview({ showPreview, }: Props) { const stickyBar = useRef(null); + const mainPanel = document.querySelector(".l-main") as HTMLElement; + const handleScroll = () => { stickyBar?.current?.classList.toggle( "sticky-shadow", @@ -27,13 +29,17 @@ function SaveAndPreview({ ); }; - useEffect(() => { - document.addEventListener("scroll", debounce(handleScroll, 10, false)); - }, []); + if (mainPanel) { + mainPanel.addEventListener("scroll", debounce(handleScroll, 10, false)); + } return ( <> -
+

diff --git a/static/js/publisher-pages/components/SectionNav/SectionNav.tsx b/static/js/publisher-pages/components/SectionNav/SectionNav.tsx index 9100043a12..7fd2bacaa4 100644 --- a/static/js/publisher-pages/components/SectionNav/SectionNav.tsx +++ b/static/js/publisher-pages/components/SectionNav/SectionNav.tsx @@ -9,11 +9,13 @@ type Props = { function SectionNav({ activeTab, snapName }: Props) { return ( { test("Calls useMutatation", () => { jest.spyOn(ReactQuery, "useMutation").mockImplementation(jest.fn()); renderHook(() => useMutateListingData({ - data: mockData, + data: mockListingData, dirtyFields: {}, getDefaultData: jest.fn(), refetch: jest.fn(), diff --git a/static/js/publisher/listing/hooks/__tests__/useVerified.test.ts b/static/js/publisher-pages/hooks/__tests__/useVerified.test.ts similarity index 100% rename from static/js/publisher/listing/hooks/__tests__/useVerified.test.ts rename to static/js/publisher-pages/hooks/__tests__/useVerified.test.ts diff --git a/static/js/publisher-pages/hooks/index.ts b/static/js/publisher-pages/hooks/index.ts index 2867be8665..6bac724388 100644 --- a/static/js/publisher-pages/hooks/index.ts +++ b/static/js/publisher-pages/hooks/index.ts @@ -1,4 +1,11 @@ import useValidationSets from "./useValidationSets"; import useValidationSet from "./useValidationSet"; +import useMutateListingData from "./useMutateListingData"; +import useVerified from "./useVerified"; -export { useValidationSets, useValidationSet }; +export { + useValidationSets, + useValidationSet, + useMutateListingData, + useVerified, +}; diff --git a/static/js/publisher/listing/hooks/useMutateListingData.ts b/static/js/publisher-pages/hooks/useMutateListingData.ts similarity index 86% rename from static/js/publisher/listing/hooks/useMutateListingData.ts rename to static/js/publisher-pages/hooks/useMutateListingData.ts index 441940653c..0a48c56026 100644 --- a/static/js/publisher/listing/hooks/useMutateListingData.ts +++ b/static/js/publisher-pages/hooks/useMutateListingData.ts @@ -1,11 +1,11 @@ import { useMutation } from "react-query"; -import { addDateToFilename, getChanges } from "../utils"; +import { addDateToFilename, getListingChanges } from "../utils"; -import type { Data } from "../types"; +import type { ListingData } from "../types"; type Options = { - data: Data; + data: ListingData; dirtyFields: any; getDefaultData: Function; refetch: Function; @@ -31,7 +31,7 @@ function useMutateListingData({ mutationFn: async (values: any) => { const formData = new FormData(); - const changes = getChanges(dirtyFields, values, data); + const changes = getListingChanges(dirtyFields, values, data); formData.set("csrf_token", window.CSRF_TOKEN); formData.set("snap_id", data.snap_id); @@ -77,9 +77,12 @@ function useMutateListingData({ } }, onSuccess: async () => { - setShowSuccessNotification(true); const response = await refetch(); + setShowSuccessNotification(true); reset(getDefaultData(response.data)); + + const mainPanel = document.querySelector(".l-main") as HTMLElement; + mainPanel.scrollTo({ top: 0, left: 0, behavior: "smooth" }); }, }); } diff --git a/static/js/publisher/listing/hooks/useVerified.ts b/static/js/publisher-pages/hooks/useVerified.ts similarity index 100% rename from static/js/publisher/listing/hooks/useVerified.ts rename to static/js/publisher-pages/hooks/useVerified.ts diff --git a/static/js/publisher-pages/index.tsx b/static/js/publisher-pages/index.tsx index fb21298089..0f58aad902 100644 --- a/static/js/publisher-pages/index.tsx +++ b/static/js/publisher-pages/index.tsx @@ -8,6 +8,7 @@ import Settings from "./pages/Settings"; import ValidationSets from "./pages/ValidationSets"; import ValidationSet from "./pages/ValidationSet"; import Metrics from "./pages/Metrics"; +import Listing from "./pages/Listing"; const router = createBrowserRouter([ { @@ -42,6 +43,10 @@ const router = createBrowserRouter([ path: "/:snapId/metrics", element: , }, + { + path: "/:snapId/listing", + element:

, + }, ], }, ]); diff --git a/static/js/publisher/listing/components/AdditionalInformation/AdditionalInformation.tsx b/static/js/publisher-pages/pages/Listing/AdditionalInformation/AdditionalInformation.tsx similarity index 97% rename from static/js/publisher/listing/components/AdditionalInformation/AdditionalInformation.tsx rename to static/js/publisher-pages/pages/Listing/AdditionalInformation/AdditionalInformation.tsx index 40a3ae3f01..a8a708a276 100644 --- a/static/js/publisher/listing/components/AdditionalInformation/AdditionalInformation.tsx +++ b/static/js/publisher-pages/pages/Listing/AdditionalInformation/AdditionalInformation.tsx @@ -9,10 +9,10 @@ import { Row, Col } from "@canonical/react-components"; import LicenseInputs from "./LicenseInputs"; -import type { Data } from "../../types"; +import type { ListingData } from "../../../types"; type Props = { - data: Data; + data: ListingData; register: UseFormRegister; getValues: UseFormGetValues; setValue: UseFormSetValue; diff --git a/static/js/publisher/listing/components/AdditionalInformation/LicenseInputs.tsx b/static/js/publisher-pages/pages/Listing/AdditionalInformation/LicenseInputs.tsx similarity index 100% rename from static/js/publisher/listing/components/AdditionalInformation/LicenseInputs.tsx rename to static/js/publisher-pages/pages/Listing/AdditionalInformation/LicenseInputs.tsx diff --git a/static/js/publisher/listing/components/AdditionalInformation/LicenseSearch.tsx b/static/js/publisher-pages/pages/Listing/AdditionalInformation/LicenseSearch.tsx similarity index 100% rename from static/js/publisher/listing/components/AdditionalInformation/LicenseSearch.tsx rename to static/js/publisher-pages/pages/Listing/AdditionalInformation/LicenseSearch.tsx diff --git a/static/js/publisher/listing/components/AdditionalInformation/index.ts b/static/js/publisher-pages/pages/Listing/AdditionalInformation/index.ts similarity index 100% rename from static/js/publisher/listing/components/AdditionalInformation/index.ts rename to static/js/publisher-pages/pages/Listing/AdditionalInformation/index.ts diff --git a/static/js/publisher/listing/components/ContactInformation/ContactFields.tsx b/static/js/publisher-pages/pages/Listing/ContactInformation/ContactFields.tsx similarity index 100% rename from static/js/publisher/listing/components/ContactInformation/ContactFields.tsx rename to static/js/publisher-pages/pages/Listing/ContactInformation/ContactFields.tsx diff --git a/static/js/publisher/listing/components/ContactInformation/ContactInformation.tsx b/static/js/publisher-pages/pages/Listing/ContactInformation/ContactInformation.tsx similarity index 95% rename from static/js/publisher/listing/components/ContactInformation/ContactInformation.tsx rename to static/js/publisher-pages/pages/Listing/ContactInformation/ContactInformation.tsx index 99e040663d..0da4c0bc5f 100644 --- a/static/js/publisher/listing/components/ContactInformation/ContactInformation.tsx +++ b/static/js/publisher-pages/pages/Listing/ContactInformation/ContactInformation.tsx @@ -9,10 +9,10 @@ import { import PrimaryDomainInput from "./PrimaryDomainInput"; import ContactFields from "./ContactFields"; -import type { Data } from "../../types"; +import type { ListingData } from "../../../types"; type Props = { - data: Data; + data: ListingData; register: UseFormRegister; control: Control; getFieldState: UseFormGetFieldState; diff --git a/static/js/publisher/listing/components/ContactInformation/PrimaryDomainInput.tsx b/static/js/publisher-pages/pages/Listing/ContactInformation/PrimaryDomainInput.tsx similarity index 97% rename from static/js/publisher/listing/components/ContactInformation/PrimaryDomainInput.tsx rename to static/js/publisher-pages/pages/Listing/ContactInformation/PrimaryDomainInput.tsx index 025c67d9c1..69e36dc70a 100644 --- a/static/js/publisher/listing/components/ContactInformation/PrimaryDomainInput.tsx +++ b/static/js/publisher-pages/pages/Listing/ContactInformation/PrimaryDomainInput.tsx @@ -9,12 +9,12 @@ import { import { nanoid } from "nanoid"; import { Row, Col, Modal } from "@canonical/react-components"; -import { useVerified } from "../../hooks"; +import { useVerified } from "../../../hooks"; -import type { Data } from "../../types"; +import type { ListingData } from "../../../types"; type Props = { - data: Data; + data: ListingData; register: UseFormRegister; getFieldState: UseFormGetFieldState; getValues: UseFormGetValues; @@ -26,14 +26,14 @@ function PrimaryDomainInput({ getFieldState, getValues, }: Props) { - const { snapName } = useParams(); + const { snapId } = useParams(); const id = nanoid(); const fieldState = getFieldState("primary_website"); const [showVerifyModal, setShowVerifyModal] = useState(false); - const { isLoading, status, data: verifiedData } = useVerified(snapName); + const { isLoading, status, data: verifiedData } = useVerified(snapId); const domain = getValues("primary_website"); const defaultDomain = data.primary_website; - const verificationToken = `SNAPCRAFT_IO_VERIFICATION=${window.DNS_VERIFICATION_TOKEN}`; + const verificationToken = `SNAPCRAFT_IO_VERIFICATION=${window.SNAP_LISTING_DATA.DNS_VERIFICATION_TOKEN}`; const noPathDomains = [ "github.com", diff --git a/static/js/publisher/listing/components/ContactInformation/__tests__/PrimaryDomainInput.test.tsx b/static/js/publisher-pages/pages/Listing/ContactInformation/__tests__/PrimaryDomainInput.test.tsx similarity index 87% rename from static/js/publisher/listing/components/ContactInformation/__tests__/PrimaryDomainInput.test.tsx rename to static/js/publisher-pages/pages/Listing/ContactInformation/__tests__/PrimaryDomainInput.test.tsx index 0c350f8929..7118742a2f 100644 --- a/static/js/publisher/listing/components/ContactInformation/__tests__/PrimaryDomainInput.test.tsx +++ b/static/js/publisher-pages/pages/Listing/ContactInformation/__tests__/PrimaryDomainInput.test.tsx @@ -7,11 +7,13 @@ import "@testing-library/jest-dom"; import PrimaryDomainInput from "../PrimaryDomainInput"; -import { mockData } from "../../../test-utils"; +import { mockListingData } from "../../../../test-utils"; -import type { Data } from "../../../types"; +import type { ListingData } from "../../../../types"; -window.DNS_VERIFICATION_TOKEN = "abc123"; +window.SNAP_LISTING_DATA = { + DNS_VERIFICATION_TOKEN: "abc123", +}; jest.mock("react-query", () => ({ ...jest.requireActual("react-query"), @@ -38,7 +40,10 @@ const mockUseFormReturnValue = { getValues: jest.fn().mockReturnValue("https://example.com"), }; -const renderComponent = (data: Data, defaultValues: { [key: string]: any }) => { +const renderComponent = ( + data: ListingData, + defaultValues: { [key: string]: any } +) => { const Component = () => { const { register, getFieldState, getValues } = useForm({ defaultValues, @@ -71,7 +76,9 @@ describe("PrimaryDomainInput", () => { // @ts-ignore useForm.mockImplementation(() => mockUseFormReturnValue); - renderComponent(mockData, { primary_website: "https://example.com" }); + renderComponent(mockListingData, { + primary_website: "https://example.com", + }); expect(screen.getByText("Verified ownership")).toBeInTheDocument(); }); @@ -92,7 +99,9 @@ describe("PrimaryDomainInput", () => { useForm.mockImplementation(() => mockUseFormReturnValue); const user = userEvent.setup(); - renderComponent(mockData, { primary_website: "https://example.com" }); + renderComponent(mockListingData, { + primary_website: "https://example.com", + }); const input = screen.getByRole("textbox", { name: "Primary website:" }); await user.type(input, "https://example.comabc"); expect(input).toHaveValue("https://example.comabc"); @@ -120,7 +129,9 @@ describe("PrimaryDomainInput", () => { useForm.mockImplementation(() => mockUseFormReturnValue); const user = userEvent.setup(); - renderComponent(mockData, { primary_website: "https://example.com" }); + renderComponent(mockListingData, { + primary_website: "https://example.com", + }); const input = screen.getByRole("textbox", { name: "Primary website:" }); await user.clear(input); await user.type(input, "/path"); @@ -141,7 +152,7 @@ describe("PrimaryDomainInput", () => { useForm.mockImplementation(() => mockUseFormReturnValue); const user = userEvent.setup(); renderComponent( - { ...mockData, primary_website: "https://launchpad.net" }, + { ...mockListingData, primary_website: "https://launchpad.net" }, { primary_website: "https://launchpad.net" } ); await user.type( @@ -166,7 +177,9 @@ describe("PrimaryDomainInput", () => { useForm.mockImplementation(() => mockUseFormReturnValue); const user = userEvent.setup(); - renderComponent(mockData, { primary_website: "https://example.com" }); + renderComponent(mockListingData, { + primary_website: "https://example.com", + }); await user.click( screen.getByRole("button", { name: "Verified ownership" }) ); @@ -187,7 +200,9 @@ describe("PrimaryDomainInput", () => { // @ts-ignore useForm.mockImplementation(() => mockUseFormReturnValue); - renderComponent(mockData, { primary_website: "https://example.com" }); + renderComponent(mockListingData, { + primary_website: "https://example.com", + }); expect(screen.queryByText("Verified ownership")).not.toBeInTheDocument(); expect( screen.getByRole("button", { name: "Verify ownership" }) @@ -209,7 +224,9 @@ describe("PrimaryDomainInput", () => { useForm.mockImplementation(() => mockUseFormReturnValue); const user = userEvent.setup(); - renderComponent(mockData, { primary_website: "https://example.com" }); + renderComponent(mockListingData, { + primary_website: "https://example.com", + }); await user.click(screen.getByRole("button", { name: "Verify ownership" })); expect( screen.getByRole("heading", { level: 2, name: "Verify ownership" }) @@ -234,7 +251,9 @@ describe("PrimaryDomainInput", () => { useForm.mockImplementation(() => mockUseFormReturnValue); const user = userEvent.setup(); - renderComponent(mockData, { primary_website: "https://example.com" }); + renderComponent(mockListingData, { + primary_website: "https://example.com", + }); expect( screen.getByRole("button", { name: "Verify ownership" }) ).toBeDisabled(); diff --git a/static/js/publisher/listing/components/ContactInformation/index.ts b/static/js/publisher-pages/pages/Listing/ContactInformation/index.ts similarity index 100% rename from static/js/publisher/listing/components/ContactInformation/index.ts rename to static/js/publisher-pages/pages/Listing/ContactInformation/index.ts diff --git a/static/js/publisher/listing/components/App/App.tsx b/static/js/publisher-pages/pages/Listing/Listing.tsx similarity index 61% rename from static/js/publisher/listing/components/App/App.tsx rename to static/js/publisher-pages/pages/Listing/Listing.tsx index d41960378b..219d51b204 100644 --- a/static/js/publisher/listing/components/App/App.tsx +++ b/static/js/publisher-pages/pages/Listing/Listing.tsx @@ -2,15 +2,15 @@ import { useParams } from "react-router-dom"; import { useQuery } from "react-query"; import { Strip } from "@canonical/react-components"; -import PageHeader from "../../../shared/PageHeader"; -import ListingForm from "../ListingForm"; +import SectionNav from "../../components/SectionNav"; +import ListingForm from "./ListingForm"; -function App(): JSX.Element { - const { snapName } = useParams(); +function Listing(): JSX.Element { + const { snapId } = useParams(); const { data, isLoading, refetch } = useQuery({ queryKey: ["listing"], queryFn: async () => { - const response = await fetch(`/api/${snapName}/listing`); + const response = await fetch(`/api/${snapId}/listing`); if (!response.ok) { throw new Error("There was a problem fetching listing data"); @@ -28,17 +28,18 @@ function App(): JSX.Element { return ( <> - +

+ My snaps / {snapId} / + Listing +

+ + {isLoading && (

 Loading{" "} - {snapName} listing data + {snapId} listing data

)} @@ -48,4 +49,4 @@ function App(): JSX.Element { ); } -export default App; +export default Listing; diff --git a/static/js/publisher/listing/components/ListingDetails/ImageUpload.tsx b/static/js/publisher-pages/pages/Listing/ListingDetails/ImageUpload.tsx similarity index 96% rename from static/js/publisher/listing/components/ListingDetails/ImageUpload.tsx rename to static/js/publisher-pages/pages/Listing/ListingDetails/ImageUpload.tsx index b9b224cc1d..5671be9878 100644 --- a/static/js/publisher/listing/components/ListingDetails/ImageUpload.tsx +++ b/static/js/publisher-pages/pages/Listing/ListingDetails/ImageUpload.tsx @@ -9,7 +9,7 @@ import { Icon, } from "@canonical/react-components"; -import { validateImageDimensions } from "../../utils"; +import { validateImageDimensions } from "../../../utils"; type Props = { imageUrl: string | null; @@ -236,12 +236,8 @@ function ImageUpload({ className="p-button--base snap-remove-icon" onClick={() => { setImageIsValid(true); - setValue(imageUrlFieldKey, "", { - shouldDirty: window?.listingData?.banner_urls[0] !== null, - }); - setValue(imageFieldKey, new File([], ""), { - shouldDirty: window?.listingData?.banner_urls[0] !== null, - }); + setValue(imageUrlFieldKey, ""); + setValue(imageFieldKey, new File([], "")); setPreviewImageUrl(""); }} > diff --git a/static/js/publisher/listing/components/ListingDetails/ListingDetails.tsx b/static/js/publisher-pages/pages/Listing/ListingDetails/ListingDetails.tsx similarity index 99% rename from static/js/publisher/listing/components/ListingDetails/ListingDetails.tsx rename to static/js/publisher-pages/pages/Listing/ListingDetails/ListingDetails.tsx index 96b5f3c39a..22e33bdb38 100644 --- a/static/js/publisher/listing/components/ListingDetails/ListingDetails.tsx +++ b/static/js/publisher-pages/pages/Listing/ListingDetails/ListingDetails.tsx @@ -11,10 +11,10 @@ import { Row, Col, Button, Icon } from "@canonical/react-components"; import ImageUpload from "./ImageUpload"; import Screenshots from "./Screenshots"; -import type { Data } from "../../types"; +import type { ListingData } from "../../../types"; type Props = { - data: Data; + data: ListingData; register: UseFormRegister; getValues: UseFormGetValues; setValue: UseFormSetValue; diff --git a/static/js/publisher/listing/components/ListingDetails/Screenshot.tsx b/static/js/publisher-pages/pages/Listing/ListingDetails/Screenshot.tsx similarity index 100% rename from static/js/publisher/listing/components/ListingDetails/Screenshot.tsx rename to static/js/publisher-pages/pages/Listing/ListingDetails/Screenshot.tsx diff --git a/static/js/publisher/listing/components/ListingDetails/ScreenshotList.tsx b/static/js/publisher-pages/pages/Listing/ListingDetails/ScreenshotList.tsx similarity index 100% rename from static/js/publisher/listing/components/ListingDetails/ScreenshotList.tsx rename to static/js/publisher-pages/pages/Listing/ListingDetails/ScreenshotList.tsx diff --git a/static/js/publisher/listing/components/ListingDetails/Screenshots.tsx b/static/js/publisher-pages/pages/Listing/ListingDetails/Screenshots.tsx similarity index 98% rename from static/js/publisher/listing/components/ListingDetails/Screenshots.tsx rename to static/js/publisher-pages/pages/Listing/ListingDetails/Screenshots.tsx index 1f365ada76..afca1437ba 100644 --- a/static/js/publisher/listing/components/ListingDetails/Screenshots.tsx +++ b/static/js/publisher-pages/pages/Listing/ListingDetails/Screenshots.tsx @@ -3,7 +3,7 @@ import { useFieldArray } from "react-hook-form"; import { nanoid } from "nanoid"; import { Row, Col, Notification } from "@canonical/react-components"; -import { validateImageDimensions } from "../../utils"; +import { validateImageDimensions } from "../../../utils"; import ScreenshotList from "./ScreenshotList"; diff --git a/static/js/publisher/listing/components/ListingDetails/index.ts b/static/js/publisher-pages/pages/Listing/ListingDetails/index.ts similarity index 100% rename from static/js/publisher/listing/components/ListingDetails/index.ts rename to static/js/publisher-pages/pages/Listing/ListingDetails/index.ts diff --git a/static/js/publisher/listing/components/ListingForm/ListingForm.tsx b/static/js/publisher-pages/pages/Listing/ListingForm/ListingForm.tsx similarity index 86% rename from static/js/publisher/listing/components/ListingForm/ListingForm.tsx rename to static/js/publisher-pages/pages/Listing/ListingForm/ListingForm.tsx index 1f2dd2ba53..ba348c76bd 100644 --- a/static/js/publisher/listing/components/ListingForm/ListingForm.tsx +++ b/static/js/publisher-pages/pages/Listing/ListingForm/ListingForm.tsx @@ -3,27 +3,30 @@ import { useParams } from "react-router-dom"; import { useForm, useFormState, FieldValues } from "react-hook-form"; import { Strip, Notification } from "@canonical/react-components"; -import SaveAndPreview from "../../../shared/SaveAndPreview"; +import SaveAndPreview from "../../../components/SaveAndPreview"; import ListingDetails from "../ListingDetails"; import ContactInformation from "../ContactInformation"; import AdditionalInformation from "../AdditionalInformation"; import PreviewForm from "../PreviewForm"; -import UpdateMetadataModal from "../../../shared/UpdateMetadataModal"; +import UpdateMetadataModal from "../../../components/UpdateMetadataModal"; -import { shouldShowUpdateMetadataWarning, getDefaultData } from "../../utils"; -import { initListingTour } from "../../../tour"; +import { + shouldShowUpdateMetadataWarning, + getDefaultListingData, +} from "../../../utils"; +import { initListingTour } from "../../../../publisher/tour"; -import { useMutateListingData } from "../../hooks"; +import { useMutateListingData } from "../../../hooks"; -import type { Data } from "../../types"; +import type { ListingData } from "../../../types"; type Props = { - data: Data; + data: ListingData; refetch: Function; }; function ListingForm({ data, refetch }: Props): JSX.Element { - const { snapName } = useParams(); + const { snapId } = useParams(); const { register, @@ -36,7 +39,7 @@ function ListingForm({ data, refetch }: Props): JSX.Element { handleSubmit, watch, } = useForm({ - defaultValues: getDefaultData(data), + defaultValues: getDefaultListingData(data), }); const { dirtyFields } = useFormState({ control }); @@ -57,13 +60,13 @@ function ListingForm({ data, refetch }: Props): JSX.Element { const { mutate, isLoading } = useMutateListingData({ data, dirtyFields, - getDefaultData, + getDefaultData: getDefaultListingData, refetch, reset, setShowSuccessNotification, setUpdateMetadataOnRelease, shouldShowUpdateMetadataWarning, - snapName, + snapName: snapId, }); useEffect(() => { @@ -71,13 +74,13 @@ function ListingForm({ data, refetch }: Props): JSX.Element { "tour-container" ) as HTMLElement; - if (snapName) { + if (snapId) { initListingTour({ - snapName, + snapName: snapId, container: tourContainer, formFields: { title: data.title, - snap_name: snapName, + snap_name: snapId, categories: [], video_urls: [], images: [], @@ -107,7 +110,7 @@ function ListingForm({ data, refetch }: Props): JSX.Element { })} > - {snapName && } + {snapId && }
); diff --git a/static/js/publisher/listing/components/ListingForm/index.ts b/static/js/publisher-pages/pages/Listing/ListingForm/index.ts similarity index 100% rename from static/js/publisher/listing/components/ListingForm/index.ts rename to static/js/publisher-pages/pages/Listing/ListingForm/index.ts diff --git a/static/js/publisher/listing/components/PreviewForm/PreviewForm.tsx b/static/js/publisher-pages/pages/Listing/PreviewForm/PreviewForm.tsx similarity index 100% rename from static/js/publisher/listing/components/PreviewForm/PreviewForm.tsx rename to static/js/publisher-pages/pages/Listing/PreviewForm/PreviewForm.tsx diff --git a/static/js/publisher/listing/components/PreviewForm/index.ts b/static/js/publisher-pages/pages/Listing/PreviewForm/index.ts similarity index 100% rename from static/js/publisher/listing/components/PreviewForm/index.ts rename to static/js/publisher-pages/pages/Listing/PreviewForm/index.ts diff --git a/static/js/publisher-pages/pages/Listing/index.tsx b/static/js/publisher-pages/pages/Listing/index.tsx new file mode 100644 index 0000000000..f7078049ef --- /dev/null +++ b/static/js/publisher-pages/pages/Listing/index.tsx @@ -0,0 +1,20 @@ +// import { createRoot } from "react-dom/client"; +// import { BrowserRouter as Router, Routes, Route } from "react-router-dom"; +// import { QueryClient, QueryClientProvider } from "react-query"; +// import App from "./components/App"; + +// const queryClient = new QueryClient(); + +// const container = document.getElementById("main-content"); +// const root = createRoot(container as HTMLElement); +// root.render( +// +// +// +// } /> +// +// +// +// ); + +export { default } from "./Listing"; diff --git a/static/js/publisher-pages/pages/Publicise/Publicise.tsx b/static/js/publisher-pages/pages/Publicise/Publicise.tsx index 770f4222c0..71c693dc6a 100644 --- a/static/js/publisher-pages/pages/Publicise/Publicise.tsx +++ b/static/js/publisher-pages/pages/Publicise/Publicise.tsx @@ -1,8 +1,9 @@ -import { useParams, NavLink, Link } from "react-router-dom"; +import { useParams, NavLink } from "react-router-dom"; import { Row, Col, SideNavigation, + Strip, Notification, } from "@canonical/react-components"; @@ -39,49 +40,50 @@ function Publicise({ view }: Props): JSX.Element { - {disableView() && ( - - When your snap is public and has a release, you'll be able to share it - using Store buttons, badges and embeddable cards. Make your snap - public in its settings page. - - )} - - - - - - - {!view && } - {view === "badges" && } - {view === "cards" && } - - + + {disableView() && ( + + When your snap is public and has a release, you'll be able to share + it using Store buttons, badges and embeddable cards. Make your snap + public in its settings page. + + )} + + + + + + {!view && } + {view === "badges" && } + {view === "cards" && } + + + ); } diff --git a/static/js/publisher-pages/pages/Settings/Settings.tsx b/static/js/publisher-pages/pages/Settings/Settings.tsx index fb75796822..07f2907545 100644 --- a/static/js/publisher-pages/pages/Settings/Settings.tsx +++ b/static/js/publisher-pages/pages/Settings/Settings.tsx @@ -18,7 +18,7 @@ import UpdateMetadataModal from "../../components/UpdateMetadataModal"; import SaveStateNotifications from "../../components/SaveStateNotifications"; import { UnregisterSnapModal } from "./UnregisterSnapModal"; -import { getSettingsData, getFormData } from "../../utils"; +import { getSettingsData, getSettingsFormData } from "../../utils"; function Settings() { const { snapId } = useParams(); @@ -92,7 +92,7 @@ function Settings() { const response = await fetch(`/${data.snap_name}/settings.json`, { method: "POST", - body: getFormData(settingsData, dirtyFields, data), + body: getSettingsFormData(settingsData, dirtyFields, data), }); if (response.status !== 200) { diff --git a/static/js/publisher-pages/routes/root.tsx b/static/js/publisher-pages/routes/root.tsx index 77e878463f..6fe58ce9b5 100644 --- a/static/js/publisher-pages/routes/root.tsx +++ b/static/js/publisher-pages/routes/root.tsx @@ -25,7 +25,7 @@ function Root(): JSX.Element { /> } > -
+
diff --git a/static/js/publisher-pages/test-utils/index.ts b/static/js/publisher-pages/test-utils/index.ts new file mode 100644 index 0000000000..dc097f6463 --- /dev/null +++ b/static/js/publisher-pages/test-utils/index.ts @@ -0,0 +1,3 @@ +import { mockListingData } from "./mockListingData"; + +export { mockListingData }; diff --git a/static/js/publisher/listing/test-utils/mockData.ts b/static/js/publisher-pages/test-utils/mockListingData.ts similarity index 97% rename from static/js/publisher/listing/test-utils/mockData.ts rename to static/js/publisher-pages/test-utils/mockListingData.ts index 75ad1d48b5..467bcd7ff9 100644 --- a/static/js/publisher/listing/test-utils/mockData.ts +++ b/static/js/publisher-pages/test-utils/mockListingData.ts @@ -1,4 +1,4 @@ -export const mockData = { +export const mockListingData = { banner_urls: ["https://example.com/screenshot"], categories: [ { name: "Test category 1", slug: "test-category-1" }, diff --git a/static/js/publisher-pages/types/index.d.ts b/static/js/publisher-pages/types/index.d.ts index 922a6c6927..aa2e270670 100644 --- a/static/js/publisher-pages/types/index.d.ts +++ b/static/js/publisher-pages/types/index.d.ts @@ -33,3 +33,40 @@ export type SettingsData = { whitelist_countries: string[]; whitelist_country_keys: string; }; + +export type TourStep = { + id: string; + position?: string; + elements?: HTMLElement[]; + title: string; + content: string; +}; + +export type ListingData = { + snap_id: string; + title: string; + video_urls: string; + summary: string; + description: string; + categories: { name: string; slug: string }[]; + primary_category: string; + secondary_category: string; + websites: { url: string }[]; + contacts: { url: string }[]; + donations: { url: string }[]; + source_code: { url: string }[]; + issues: { url: string }[]; + primary_website: string; + public_metrics_enabled: boolean; + public_metrics_blacklist: string[]; + public_metrics_territories: boolean; + public_metrics_distros: boolean; + license: string; + license_type: string; + licenses: { key: string; name: string }[]; + icon_url: string; + screenshot_urls: string[]; + banner_urls: string[]; + update_metadata_on_release: boolean; + tour_steps: Step[]; +}; diff --git a/static/js/publisher/listing/utils/__tests__/addDateToFilename.test.ts b/static/js/publisher-pages/utils/__tests__/addDateToFilename.test.ts similarity index 100% rename from static/js/publisher/listing/utils/__tests__/addDateToFilename.test.ts rename to static/js/publisher-pages/utils/__tests__/addDateToFilename.test.ts diff --git a/static/js/publisher/listing/utils/__tests__/formatImageChanges.test.ts b/static/js/publisher-pages/utils/__tests__/formatImageChanges.test.ts similarity index 100% rename from static/js/publisher/listing/utils/__tests__/formatImageChanges.test.ts rename to static/js/publisher-pages/utils/__tests__/formatImageChanges.test.ts diff --git a/static/js/publisher/listing/utils/__tests__/getDefaultData.test.ts b/static/js/publisher-pages/utils/__tests__/getDefaultListingData.test.ts similarity index 89% rename from static/js/publisher/listing/utils/__tests__/getDefaultData.test.ts rename to static/js/publisher-pages/utils/__tests__/getDefaultListingData.test.ts index 964cd7222e..058788c9ef 100644 --- a/static/js/publisher/listing/utils/__tests__/getDefaultData.test.ts +++ b/static/js/publisher-pages/utils/__tests__/getDefaultListingData.test.ts @@ -1,10 +1,10 @@ -import getDefaultData from "../getDefaultData"; +import getDefaultListingData from "../getDefaultListingData"; -import { mockData } from "../../test-utils"; +import { mockListingData } from "../../test-utils"; describe("getDefaultData", () => { test("returns default data", () => { - const defaultData = getDefaultData(mockData); + const defaultData = getDefaultListingData(mockListingData); expect(defaultData.contacts).toBeDefined(); expect(defaultData.description).toBeDefined(); diff --git a/static/js/publisher/listing/utils/__tests__/shouldShowUpdateMetadataWarning.test.ts b/static/js/publisher-pages/utils/__tests__/shouldShowUpdateMetadataWarning.test.ts similarity index 100% rename from static/js/publisher/listing/utils/__tests__/shouldShowUpdateMetadataWarning.test.ts rename to static/js/publisher-pages/utils/__tests__/shouldShowUpdateMetadataWarning.test.ts diff --git a/static/js/publisher/listing/utils/__tests__/validateImageDimensions.test.ts b/static/js/publisher-pages/utils/__tests__/validateImageDimensions.test.ts similarity index 100% rename from static/js/publisher/listing/utils/__tests__/validateImageDimensions.test.ts rename to static/js/publisher-pages/utils/__tests__/validateImageDimensions.test.ts diff --git a/static/js/publisher/listing/utils/addDateToFilename.ts b/static/js/publisher-pages/utils/addDateToFilename.ts similarity index 100% rename from static/js/publisher/listing/utils/addDateToFilename.ts rename to static/js/publisher-pages/utils/addDateToFilename.ts diff --git a/static/js/publisher/listing/utils/formatImageChanges.ts b/static/js/publisher-pages/utils/formatImageChanges.ts similarity index 100% rename from static/js/publisher/listing/utils/formatImageChanges.ts rename to static/js/publisher-pages/utils/formatImageChanges.ts diff --git a/static/js/publisher/listing/utils/getDefaultData.ts b/static/js/publisher-pages/utils/getDefaultListingData.ts similarity index 92% rename from static/js/publisher/listing/utils/getDefaultData.ts rename to static/js/publisher-pages/utils/getDefaultListingData.ts index cfeda5a70f..937cf9a180 100644 --- a/static/js/publisher/listing/utils/getDefaultData.ts +++ b/static/js/publisher-pages/utils/getDefaultListingData.ts @@ -1,4 +1,4 @@ -import type { Data } from "../types"; +import type { ListingData } from "../types"; function getPublicMetricsTerritoriesValue( publicMetricsBlacklist: string[] @@ -36,7 +36,9 @@ function getPublicMetricsDistrosValue( return false; } -export default function getDefaultData(data: Data): { [key: string]: any } { +export default function getDefaultListingData(data: ListingData): { + [key: string]: any; +} { return { contacts: data.contacts, description: data.description, diff --git a/static/js/publisher/listing/utils/getChanges.ts b/static/js/publisher-pages/utils/getListingChanges.ts similarity index 96% rename from static/js/publisher/listing/utils/getChanges.ts rename to static/js/publisher-pages/utils/getListingChanges.ts index bde5d68448..7b34725290 100644 --- a/static/js/publisher/listing/utils/getChanges.ts +++ b/static/js/publisher-pages/utils/getListingChanges.ts @@ -1,11 +1,11 @@ import formatImageChanges from "./formatImageChanges"; -import type { Data } from "../types"; +import type { ListingData } from "../types"; -export default function getChanges( +export default function getListingChanges( dirtyFields: any, fieldValues: any, - data: Data + data: ListingData ): { [key: string]: any } { const changes: { [key: string]: any } = {}; diff --git a/static/js/publisher-pages/utils/getChanges.ts b/static/js/publisher-pages/utils/getSettingsChanges.ts similarity index 92% rename from static/js/publisher-pages/utils/getChanges.ts rename to static/js/publisher-pages/utils/getSettingsChanges.ts index 8625ce7e37..26fd5ad7b4 100644 --- a/static/js/publisher-pages/utils/getChanges.ts +++ b/static/js/publisher-pages/utils/getSettingsChanges.ts @@ -1,4 +1,4 @@ -function getChanges(dirtyFields: { [key: string]: any }, data: any) { +function getSettingsChanges(dirtyFields: { [key: string]: any }, data: any) { const changes: { [key: string]: any } = {}; if (dirtyFields?.visibility) { @@ -58,4 +58,4 @@ function getChanges(dirtyFields: { [key: string]: any }, data: any) { return changes; } -export default getChanges; +export default getSettingsChanges; diff --git a/static/js/publisher-pages/utils/getFormData.ts b/static/js/publisher-pages/utils/getSettingsFormData.ts similarity index 90% rename from static/js/publisher-pages/utils/getFormData.ts rename to static/js/publisher-pages/utils/getSettingsFormData.ts index 235b563a79..c2a70dc06a 100644 --- a/static/js/publisher-pages/utils/getFormData.ts +++ b/static/js/publisher-pages/utils/getSettingsFormData.ts @@ -1,13 +1,13 @@ -import getChanges from "./getChanges"; +import getSettingsChanges from "./getSettingsChanges"; import type { SettingsData } from "../types"; -function getFormData( +function getSettingsFormData( settingsData: SettingsData, dirtyFields: { [key: string]: any }, data: any ) { - const changes = getChanges(dirtyFields, data); + const changes = getSettingsChanges(dirtyFields, data); const formData = new FormData(); formData.set("csrf_token", window.CSRF_TOKEN); @@ -51,4 +51,4 @@ function getFormData( return formData; } -export default getFormData; +export default getSettingsFormData; diff --git a/static/js/publisher-pages/utils/index.ts b/static/js/publisher-pages/utils/index.ts index 0deb89bf75..6831b29c2a 100644 --- a/static/js/publisher-pages/utils/index.ts +++ b/static/js/publisher-pages/utils/index.ts @@ -1,5 +1,21 @@ import getSettingsData from "./getSettingsData"; -import getChanges from "./getChanges"; -import getFormData from "./getFormData"; +import getSettingsChanges from "./getSettingsChanges"; +import getSettingsFormData from "./getSettingsFormData"; +import getListingChanges from "./getListingChanges"; +import formatImageChanges from "./formatImageChanges"; +import getDefaultListingData from "./getDefaultListingData"; +import shouldShowUpdateMetadataWarning from "./shouldShowUpdateMetadataWarning"; +import validateImageDimensions from "./validateImageDimensions"; +import addDateToFilename from "./addDateToFilename"; -export { getSettingsData, getChanges, getFormData }; +export { + getSettingsData, + getSettingsChanges, + getSettingsFormData, + getListingChanges, + formatImageChanges, + getDefaultListingData, + shouldShowUpdateMetadataWarning, + validateImageDimensions, + addDateToFilename, +}; diff --git a/static/js/publisher/listing/utils/shouldShowUpdateMetadataWarning.ts b/static/js/publisher-pages/utils/shouldShowUpdateMetadataWarning.ts similarity index 100% rename from static/js/publisher/listing/utils/shouldShowUpdateMetadataWarning.ts rename to static/js/publisher-pages/utils/shouldShowUpdateMetadataWarning.ts diff --git a/static/js/publisher/listing/utils/validateImageDimensions.ts b/static/js/publisher-pages/utils/validateImageDimensions.ts similarity index 100% rename from static/js/publisher/listing/utils/validateImageDimensions.ts rename to static/js/publisher-pages/utils/validateImageDimensions.ts diff --git a/static/js/publisher/listing/components/App/__tests__/App.test.tsx b/static/js/publisher/listing/components/App/__tests__/App.test.tsx deleted file mode 100644 index 34c5d13309..0000000000 --- a/static/js/publisher/listing/components/App/__tests__/App.test.tsx +++ /dev/null @@ -1,150 +0,0 @@ -import { BrowserRouter } from "react-router-dom"; -import { QueryClient, QueryClientProvider, useQuery } from "react-query"; -import { render, screen } from "@testing-library/react"; -import "@testing-library/jest-dom"; - -import App from "../App"; - -import { mockData } from "../../../test-utils"; - -const queryClient = new QueryClient({ - defaultOptions: { - queries: { - refetchOnWindowFocus: false, - refetchOnReconnect: false, - }, - }, -}); - -jest.mock("react-query", () => ({ - ...jest.requireActual("react-query"), - useQuery: jest.fn(), -})); - -jest.mock("react-router-dom", () => ({ - ...jest.requireActual("react-router-dom"), - useParams: () => ({ - snapName: "test-snap", - }), -})); - -const renderComponent = () => { - return render( - - - - - - ); -}; - -describe("App", () => { - test("renders page header", () => { - // @ts-ignore - useQuery.mockReturnValue({ - isLoading: true, - data: undefined, - refetch: jest.fn(), - }); - - renderComponent(); - - expect( - screen.getByRole("heading", { level: 1, name: "test-snap" }) - ).toBeInTheDocument(); - }); - - test("renders loading state", () => { - // @ts-ignore - useQuery.mockReturnValue({ - isLoading: true, - data: undefined, - refetch: jest.fn(), - }); - - renderComponent(); - - expect( - screen.getByText(/Loading test-snap listing data/) - ).toBeInTheDocument(); - }); - - test("renders listing details section", () => { - // @ts-ignore - useQuery.mockReturnValue({ - isLoading: false, - data: mockData, - refetch: jest.fn(), - }); - - renderComponent(); - - expect( - screen.getByRole("heading", { level: 2, name: "Listing details" }) - ).toBeInTheDocument(); - }); - - test("renders contact section", () => { - // @ts-ignore - useQuery.mockReturnValue({ - isLoading: false, - data: mockData, - refetch: jest.fn(), - }); - - renderComponent(); - - expect( - screen.getByRole("heading", { level: 2, name: "Contact information" }) - ).toBeInTheDocument(); - }); - - test("renders additional information section", () => { - // @ts-ignore - useQuery.mockReturnValue({ - isLoading: false, - data: mockData, - refetch: jest.fn(), - }); - - renderComponent(); - - expect( - screen.getByRole("heading", { level: 2, name: "Additional information" }) - ).toBeInTheDocument(); - }); - - test("shows 'Update metadata' notification", () => { - // @ts-ignore - useQuery.mockReturnValue({ - isLoading: false, - data: { ...mockData, update_metadata_on_release: true }, - refetch: jest.fn(), - }); - - renderComponent(); - - expect( - screen.getByText( - /Information here was automatically updated to the latest version of the snapcraft.yaml released to the stable channel/ - ) - ).toBeInTheDocument(); - }); - - test("doesn't show 'Update metadata' nofitication", () => { - // @ts-ignore - useQuery.mockReturnValue({ - isLoading: false, - data: mockData, - refetch: jest.fn(), - }); - - renderComponent(); - - expect( - screen.queryByText( - /Information here was automatically updated to the latest version of the snapcraft.yaml released to the stable channel/ - ) - ).not.toBeInTheDocument(); - }); -}); diff --git a/static/js/publisher/listing/components/App/index.ts b/static/js/publisher/listing/components/App/index.ts deleted file mode 100644 index 8ce017e646..0000000000 --- a/static/js/publisher/listing/components/App/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { default } from "./App"; diff --git a/static/js/publisher/listing/hooks/index.ts b/static/js/publisher/listing/hooks/index.ts deleted file mode 100644 index bd59f1cd25..0000000000 --- a/static/js/publisher/listing/hooks/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -import useVerified from "./useVerified"; -import useMutateListingData from "./useMutateListingData"; - -export { useVerified, useMutateListingData }; diff --git a/static/js/publisher/listing/index.tsx b/static/js/publisher/listing/index.tsx deleted file mode 100644 index f0ebc90826..0000000000 --- a/static/js/publisher/listing/index.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import { createRoot } from "react-dom/client"; -import { BrowserRouter as Router, Routes, Route } from "react-router-dom"; -import { QueryClient, QueryClientProvider } from "react-query"; -import App from "./components/App"; - -const queryClient = new QueryClient(); - -const container = document.getElementById("main-content"); -const root = createRoot(container as HTMLElement); -root.render( - - - - } /> - - - -); diff --git a/static/js/publisher/listing/test-utils/index.ts b/static/js/publisher/listing/test-utils/index.ts deleted file mode 100644 index 5da2429913..0000000000 --- a/static/js/publisher/listing/test-utils/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { mockData } from "./mockData"; - -export { mockData }; diff --git a/static/js/publisher/listing/types/index.d.ts b/static/js/publisher/listing/types/index.d.ts deleted file mode 100644 index 37cd8c4e13..0000000000 --- a/static/js/publisher/listing/types/index.d.ts +++ /dev/null @@ -1,45 +0,0 @@ -declare global { - interface Window { - SENTRY_DSN: string; - CSRF_TOKEN: string; - listingData: any; - tourSteps: any; - } -} - -export type Step = { - id: string; - position?: string; - elements?: HTMLElement[]; - title: string; - content: string; -}; - -export type Data = { - snap_id: string; - title: string; - video_urls: string; - summary: string; - description: string; - categories: { name: string; slug: string }[]; - primary_category: string; - secondary_category: string; - websites: { url: string }[]; - contacts: { url: string }[]; - donations: { url: string }[]; - source_code: { url: string }[]; - issues: { url: string }[]; - primary_website: string; - public_metrics_enabled: boolean; - public_metrics_blacklist: string[]; - public_metrics_territories: boolean; - public_metrics_distros: boolean; - license: string; - license_type: string; - licenses: { key: string; name: string }[]; - icon_url: string; - screenshot_urls: string[]; - banner_urls: string[]; - update_metadata_on_release: boolean; - tour_steps: Step[]; -}; diff --git a/static/js/publisher/listing/utils/index.ts b/static/js/publisher/listing/utils/index.ts deleted file mode 100644 index d7a5f6555d..0000000000 --- a/static/js/publisher/listing/utils/index.ts +++ /dev/null @@ -1,15 +0,0 @@ -import validateImageDimensions from "./validateImageDimensions"; -import shouldShowUpdateMetadataWarning from "./shouldShowUpdateMetadataWarning"; -import addDateToFilename from "./addDateToFilename"; -import formatImageChanges from "./formatImageChanges"; -import getChanges from "./getChanges"; -import getDefaultData from "./getDefaultData"; - -export { - validateImageDimensions, - shouldShowUpdateMetadataWarning, - addDateToFilename, - formatImageChanges, - getChanges, - getDefaultData, -}; diff --git a/static/js/publisher/tour.tsx b/static/js/publisher/tour.tsx index 0cecdd1fae..c25c7eaf8d 100644 --- a/static/js/publisher/tour.tsx +++ b/static/js/publisher/tour.tsx @@ -4,7 +4,7 @@ import Tour from "./tour/tour"; import { toggleShadowWhenSticky } from "./market/stickyListingBar"; -import type { Step } from "./listing/types"; +import type { TourStep } from "../publisher-pages/types"; // returns true if % of truthy values in the array is above the threshold function isCompleted(fields: unknown[], threshold = 0.5): boolean { @@ -21,7 +21,7 @@ export function initTour({ startTour, }: { container: HTMLElement; - steps: Step[]; + steps: TourStep[]; onTourStarted: () => void; onTourClosed: () => void; startTour: boolean; @@ -52,7 +52,7 @@ export function initListingTour({ }: { snapName: string; container: HTMLElement; - steps: Step[]; + steps: TourStep[]; formFields: { title: string; snap_name: string; diff --git a/static/js/publisher/tour/helpers.ts b/static/js/publisher/tour/helpers.ts index 5b9b36a4b8..36a82c5601 100644 --- a/static/js/publisher/tour/helpers.ts +++ b/static/js/publisher/tour/helpers.ts @@ -1,6 +1,6 @@ import { MASK_OFFSET } from "./constants"; -import type { Step } from "../listing/types"; +import type { TourStep } from "../../publisher-pages/types"; // check if element is part of the DOM and is visible export const isVisibleInDocument = (el: HTMLElement): boolean => @@ -8,7 +8,7 @@ export const isVisibleInDocument = (el: HTMLElement): boolean => // find DOM elements for each step, ignore steps with no elements // set default position to "bottom-left" -export function prepareSteps(steps: Step[]): Array<{ +export function prepareSteps(steps: TourStep[]): Array<{ id: string; position: string; elements: HTMLElement[]; diff --git a/static/js/publisher/tour/tour.tsx b/static/js/publisher/tour/tour.tsx index 6978f02aa7..bf7d8fc4b6 100644 --- a/static/js/publisher/tour/tour.tsx +++ b/static/js/publisher/tour/tour.tsx @@ -5,10 +5,10 @@ import TourBar from "./tourBar"; import { tourStartedAutomatically } from "./metricsEvents"; -import type { Step } from "../listing/types"; +import type { TourStep } from "../../publisher-pages/types"; type Props = { - steps: Step[]; + steps: TourStep[]; startTour: boolean; onTourStarted: () => void; onTourClosed: () => void; diff --git a/static/js/publisher/tour/tourBar.tsx b/static/js/publisher/tour/tourBar.tsx index d0b30bca1e..a76cdcf3b7 100644 --- a/static/js/publisher/tour/tourBar.tsx +++ b/static/js/publisher/tour/tourBar.tsx @@ -8,15 +8,13 @@ export default function TourBar({ showTour }: { showTour: () => void }) { return (
-
- -
+
); } diff --git a/static/js/publisher/tour/tourOverlay.tsx b/static/js/publisher/tour/tourOverlay.tsx index c9ddd2b165..2ffebd473a 100644 --- a/static/js/publisher/tour/tourOverlay.tsx +++ b/static/js/publisher/tour/tourOverlay.tsx @@ -14,14 +14,14 @@ import { import { animateScrollTo } from "../../public/scroll-to"; -import type { Step } from "../listing/types"; +import type { TourStep } from "../../publisher-pages/types"; export default function TourOverlay({ steps, hideTour, currentStepIndex = 0, }: { - steps: Step[]; + steps: TourStep[]; hideTour: () => void; currentStepIndex?: number; }) { diff --git a/static/js/publisher/tour/tourStepCard.tsx b/static/js/publisher/tour/tourStepCard.tsx index 2b4865bac2..7c8cb9c188 100644 --- a/static/js/publisher/tour/tourStepCard.tsx +++ b/static/js/publisher/tour/tourStepCard.tsx @@ -1,9 +1,9 @@ import { ReactNode } from "react"; -import type { Step } from "../listing/types"; +import type { TourStep } from "../../publisher-pages/types"; type Props = { - steps: Step[]; + steps: TourStep[]; currentStepIndex: number; mask: { top: number; diff --git a/static/sass/_snapcraft_tour.scss b/static/sass/_snapcraft_tour.scss index 6d7261c463..1b30fd0edc 100644 --- a/static/sass/_snapcraft_tour.scss +++ b/static/sass/_snapcraft_tour.scss @@ -11,7 +11,7 @@ .p-tour-bar { bottom: 0; left: 0; - padding: $spv--medium; + padding: $spv--medium $spv--x-large; pointer-events: none; position: fixed; right: 0; diff --git a/static/sass/styles.scss b/static/sass/styles.scss index e272a87f0a..bcdfcc0c66 100644 --- a/static/sass/styles.scss +++ b/static/sass/styles.scss @@ -562,3 +562,7 @@ dl { flex-grow: 1; } } + +.publisher-app > .p-panel > .p-panel__content { + overflow: visible; +} diff --git a/templates/publisher/listing.html b/templates/publisher/listing.html deleted file mode 100644 index 27a6e41595..0000000000 --- a/templates/publisher/listing.html +++ /dev/null @@ -1,14 +0,0 @@ -{% extends "publisher/_publisher_layout.html" %} - -{% block meta_title %} -Listing details for {{ snap_name }} -{% endblock %} - -{% block content %} -
- - -{% endblock %} diff --git a/templates/store/publisher.html b/templates/store/publisher.html index 95b7c4c29a..40d63e6288 100644 --- a/templates/store/publisher.html +++ b/templates/store/publisher.html @@ -28,6 +28,10 @@ blacklist_countries: {% if blacklist_country_codes %}{{ blacklist_country_codes|tojson }}{% else %}[]{% endif %}, visibility_locked: {% if visibility_locked %}{{ visibility_locked|tojson }}{% else %}false{% endif %}, } + + window.SNAP_LISTING_DATA = { + DNS_VERIFICATION_TOKEN: "{{ dns_verification_token }}", + }; {% endblock %} diff --git a/webapp/publisher/snaps/listing_views.py b/webapp/publisher/snaps/listing_views.py index 38dde97413..1ce3a6bb83 100644 --- a/webapp/publisher/snaps/listing_views.py +++ b/webapp/publisher/snaps/listing_views.py @@ -166,7 +166,7 @@ def get_listing_snap(snap_name): snap_details["snap_name"], snap_details["links"]["website"][0] ) return flask.render_template( - "publisher/listing.html", + "store/publisher.html", snap_name=snap_name, dns_verification_token=token, ) diff --git a/webpack.config.entry.js b/webpack.config.entry.js index 0bdcf04789..edf1d75f05 100644 --- a/webpack.config.entry.js +++ b/webpack.config.entry.js @@ -17,7 +17,6 @@ module.exports = { "distro-install": "./static/js/public/distro-install.ts", "publisher-details": "./static/js/public/publisher-details.ts", "brand-store": "./static/js/brand-store/brand-store.tsx", - "publisher-listing": "./static/js/publisher/listing/index.tsx", "about-listing": "./static/js/public/about/listing.ts", store: "./static/js/store/index.tsx", "publisher-pages": "./static/js/publisher-pages/index.tsx",