diff --git a/src/categories/components/CategoryCreatePage/CategoryCreatePage.tsx b/src/categories/components/CategoryCreatePage/CategoryCreatePage.tsx index 202abe404..4659a8340 100644 --- a/src/categories/components/CategoryCreatePage/CategoryCreatePage.tsx +++ b/src/categories/components/CategoryCreatePage/CategoryCreatePage.tsx @@ -19,6 +19,7 @@ import CategoryDetailsForm from "../../components/CategoryDetailsForm"; export interface FormData extends MetadataFormData { description: RawDraftContentState; name: string; + slug: string; seoTitle: string; seoDescription: string; } @@ -29,7 +30,8 @@ const initialData: FormData = { name: "", privateMetadata: [], seoDescription: "", - seoTitle: "" + seoTitle: "", + slug: "" }; export interface CategoryCreatePageProps { @@ -81,6 +83,8 @@ export const CategoryCreatePage: React.FC = ({ defaultMessage: "Add search engine title and description to make this category easier to find" })} + slug={data.slug} + slugPlaceholder={data.name} title={data.seoTitle} titlePlaceholder={data.name} description={data.seoDescription} diff --git a/src/categories/components/CategoryUpdatePage/CategoryUpdatePage.tsx b/src/categories/components/CategoryUpdatePage/CategoryUpdatePage.tsx index 7b64d842d..9acb198a8 100644 --- a/src/categories/components/CategoryUpdatePage/CategoryUpdatePage.tsx +++ b/src/categories/components/CategoryUpdatePage/CategoryUpdatePage.tsx @@ -118,7 +118,8 @@ export const CategoryUpdatePage: React.FC = ({ name: category.name || "", privateMetadata: category?.privateMetadata?.map(mapMetadataItemToInput), seoDescription: category.seoDescription || "", - seoTitle: category.seoTitle || "" + seoTitle: category.seoTitle || "", + slug: category?.slug || "" } : { backgroundImageAlt: "", @@ -127,7 +128,8 @@ export const CategoryUpdatePage: React.FC = ({ name: "", privateMetadata: undefined, seoDescription: "", - seoTitle: "" + seoTitle: "", + slug: "" }; const handleSubmit = (data: FormData) => { @@ -179,6 +181,8 @@ export const CategoryUpdatePage: React.FC = ({ titlePlaceholder={data.name} description={data.seoDescription} descriptionPlaceholder={data.name} + slug={data.slug} + slugPlaceholder={data.name} loading={!category} onChange={change} disabled={disabled} diff --git a/src/categories/types/CategoryCreate.ts b/src/categories/types/CategoryCreate.ts index 21991ef8d..a7f5336e7 100644 --- a/src/categories/types/CategoryCreate.ts +++ b/src/categories/types/CategoryCreate.ts @@ -38,6 +38,7 @@ export interface CategoryCreate_categoryCreate_category { privateMetadata: (CategoryCreate_categoryCreate_category_privateMetadata | null)[]; backgroundImage: CategoryCreate_categoryCreate_category_backgroundImage | null; name: string; + slug: string; descriptionJson: any; seoDescription: string | null; seoTitle: string | null; diff --git a/src/categories/types/CategoryDetails.ts b/src/categories/types/CategoryDetails.ts index 5cf7baa08..d6ce553eb 100644 --- a/src/categories/types/CategoryDetails.ts +++ b/src/categories/types/CategoryDetails.ts @@ -147,6 +147,7 @@ export interface CategoryDetails_category { privateMetadata: (CategoryDetails_category_privateMetadata | null)[]; backgroundImage: CategoryDetails_category_backgroundImage | null; name: string; + slug: string; descriptionJson: any; seoDescription: string | null; seoTitle: string | null; diff --git a/src/categories/types/CategoryUpdate.ts b/src/categories/types/CategoryUpdate.ts index 1be777c04..2a7bb4429 100644 --- a/src/categories/types/CategoryUpdate.ts +++ b/src/categories/types/CategoryUpdate.ts @@ -38,6 +38,7 @@ export interface CategoryUpdate_categoryUpdate_category { privateMetadata: (CategoryUpdate_categoryUpdate_category_privateMetadata | null)[]; backgroundImage: CategoryUpdate_categoryUpdate_category_backgroundImage | null; name: string; + slug: string; descriptionJson: any; seoDescription: string | null; seoTitle: string | null; diff --git a/src/collections/components/CollectionCreatePage/CollectionCreatePage.tsx b/src/collections/components/CollectionCreatePage/CollectionCreatePage.tsx index f31998883..6e2e31427 100644 --- a/src/collections/components/CollectionCreatePage/CollectionCreatePage.tsx +++ b/src/collections/components/CollectionCreatePage/CollectionCreatePage.tsx @@ -28,6 +28,7 @@ export interface CollectionCreatePageFormData extends MetadataFormData { backgroundImageAlt: string; description: RawDraftContentState; name: string; + slug: string; publicationDate: string; isPublished: boolean; seoDescription: string; @@ -55,7 +56,8 @@ const initialForm: CollectionCreatePageFormData = { privateMetadata: [], publicationDate: "", seoDescription: "", - seoTitle: "" + seoTitle: "", + slug: "" }; const CollectionCreatePage: React.FC = ({ @@ -140,6 +142,8 @@ const CollectionCreatePage: React.FC = ({ defaultMessage: "Add search engine title and description to make this collection easier to find" })} + slug={data.slug} + slugPlaceholder={data.name} title={data.seoTitle} titlePlaceholder={data.name} onChange={change} diff --git a/src/collections/components/CollectionDetailsPage/CollectionDetailsPage.tsx b/src/collections/components/CollectionDetailsPage/CollectionDetailsPage.tsx index 8fba3282d..a86fb1c05 100644 --- a/src/collections/components/CollectionDetailsPage/CollectionDetailsPage.tsx +++ b/src/collections/components/CollectionDetailsPage/CollectionDetailsPage.tsx @@ -33,6 +33,7 @@ export interface CollectionDetailsPageFormData extends MetadataFormData { backgroundImageAlt: string; description: RawDraftContentState; name: string; + slug: string; publicationDate: string; seoDescription: string; seoTitle: string; @@ -101,7 +102,8 @@ const CollectionDetailsPage: React.FC = ({ ), publicationDate: maybe(() => collection.publicationDate, ""), seoDescription: maybe(() => collection.seoDescription, ""), - seoTitle: maybe(() => collection.seoTitle, "") + seoTitle: maybe(() => collection.seoTitle, ""), + slug: collection.slug || "" }} onSubmit={handleSubmit} confirmLeave @@ -149,6 +151,8 @@ const CollectionDetailsPage: React.FC = ({ defaultMessage: "Add search engine title and description to make this collection easier to find" })} + slug={data.slug} + slugPlaceholder={data.name} title={data.seoTitle} titlePlaceholder={maybe(() => collection.name)} onChange={change} diff --git a/src/collections/types/CollectionDetails.ts b/src/collections/types/CollectionDetails.ts index f46367d6a..1746d93fc 100644 --- a/src/collections/types/CollectionDetails.ts +++ b/src/collections/types/CollectionDetails.ts @@ -71,6 +71,7 @@ export interface CollectionDetails_collection { metadata: (CollectionDetails_collection_metadata | null)[]; privateMetadata: (CollectionDetails_collection_privateMetadata | null)[]; backgroundImage: CollectionDetails_collection_backgroundImage | null; + slug: string; descriptionJson: any; publicationDate: any | null; seoDescription: string | null; diff --git a/src/collections/types/CollectionUpdate.ts b/src/collections/types/CollectionUpdate.ts index a3b85081f..f390dd7be 100644 --- a/src/collections/types/CollectionUpdate.ts +++ b/src/collections/types/CollectionUpdate.ts @@ -34,6 +34,7 @@ export interface CollectionUpdate_collectionUpdate_collection { metadata: (CollectionUpdate_collectionUpdate_collection_metadata | null)[]; privateMetadata: (CollectionUpdate_collectionUpdate_collection_privateMetadata | null)[]; backgroundImage: CollectionUpdate_collectionUpdate_collection_backgroundImage | null; + slug: string; descriptionJson: any; publicationDate: any | null; seoDescription: string | null; diff --git a/src/collections/types/CollectionUpdateWithHomepage.ts b/src/collections/types/CollectionUpdateWithHomepage.ts index d034e7cfe..7c982190f 100644 --- a/src/collections/types/CollectionUpdateWithHomepage.ts +++ b/src/collections/types/CollectionUpdateWithHomepage.ts @@ -56,6 +56,7 @@ export interface CollectionUpdateWithHomepage_collectionUpdate_collection { metadata: (CollectionUpdateWithHomepage_collectionUpdate_collection_metadata | null)[]; privateMetadata: (CollectionUpdateWithHomepage_collectionUpdate_collection_privateMetadata | null)[]; backgroundImage: CollectionUpdateWithHomepage_collectionUpdate_collection_backgroundImage | null; + slug: string; descriptionJson: any; publicationDate: any | null; seoDescription: string | null; diff --git a/src/collections/types/CreateCollection.ts b/src/collections/types/CreateCollection.ts index 7f1646436..efb28ca4b 100644 --- a/src/collections/types/CreateCollection.ts +++ b/src/collections/types/CreateCollection.ts @@ -34,6 +34,7 @@ export interface CreateCollection_collectionCreate_collection { metadata: (CreateCollection_collectionCreate_collection_metadata | null)[]; privateMetadata: (CreateCollection_collectionCreate_collection_privateMetadata | null)[]; backgroundImage: CreateCollection_collectionCreate_collection_backgroundImage | null; + slug: string; descriptionJson: any; publicationDate: any | null; seoDescription: string | null; diff --git a/src/components/SeoForm/SeoForm.tsx b/src/components/SeoForm/SeoForm.tsx index 77e7ffc2e..dfe4bc587 100644 --- a/src/components/SeoForm/SeoForm.tsx +++ b/src/components/SeoForm/SeoForm.tsx @@ -7,6 +7,7 @@ import Typography from "@material-ui/core/Typography"; import classNames from "classnames"; import React from "react"; import { FormattedMessage, useIntl } from "react-intl"; +import slugify from "slugify"; import CardTitle from "../CardTitle"; import FormSpacer from "../FormSpacer"; @@ -68,6 +69,8 @@ interface SeoFormProps { loading?: boolean; helperText?: string; title: string; + slug: string; + slugPlaceholder?: string; titlePlaceholder: string; onChange(event: any); onClick?(); @@ -75,13 +78,14 @@ interface SeoFormProps { const SeoForm: React.FC = props => { const { - description, + description = "", descriptionPlaceholder, disabled, helperText, loading, - title, + title = "", slug, + slugPlaceholder = "", titlePlaceholder, onChange } = props; @@ -90,7 +94,9 @@ const SeoForm: React.FC = props => { const intl = useIntl(); const [expanded, setExpansionStatus] = React.useState(false); const toggleExpansion = () => setExpansionStatus(!expanded); + const shouldDisplayHelperText = () => helperText && !expanded; + console.log({ slug }); return ( = props => { } /> - {helperText && ( + {shouldDisplayHelperText() && ( @@ -123,14 +129,14 @@ const SeoForm: React.FC = props => {
- {title.length > 0 && ( + {slug?.length > 0 && ( @@ -141,9 +147,9 @@ const SeoForm: React.FC = props => { defaultMessage: "If empty, the preview shows what will be autogenerated." })} - value={title.slice(0, 69)} + value={slug.slice(0, 69)} disabled={loading || disabled} - placeholder="Slug" + placeholder={slug || slugify(slugPlaceholder)} onChange={onChange} fullWidth /> diff --git a/src/fragments/categories.ts b/src/fragments/categories.ts index 3eebe58d9..5545d6220 100644 --- a/src/fragments/categories.ts +++ b/src/fragments/categories.ts @@ -24,6 +24,7 @@ export const categoryDetailsFragment = gql` url } name + slug descriptionJson seoDescription seoTitle diff --git a/src/fragments/collections.ts b/src/fragments/collections.ts index a27129ce3..984db729b 100644 --- a/src/fragments/collections.ts +++ b/src/fragments/collections.ts @@ -20,6 +20,7 @@ export const collectionDetailsFragment = gql` alt url } + slug descriptionJson publicationDate seoDescription diff --git a/src/fragments/products.ts b/src/fragments/products.ts index 1b651dfdd..7df94e527 100644 --- a/src/fragments/products.ts +++ b/src/fragments/products.ts @@ -111,6 +111,7 @@ export const productFragmentDetails = gql` ...ProductVariantAttributesFragment ...MetadataFragment name + slug descriptionJson seoTitle seoDescription diff --git a/src/fragments/types/CategoryDetailsFragment.ts b/src/fragments/types/CategoryDetailsFragment.ts index 49e5640ea..e1b2d5fbb 100644 --- a/src/fragments/types/CategoryDetailsFragment.ts +++ b/src/fragments/types/CategoryDetailsFragment.ts @@ -36,6 +36,7 @@ export interface CategoryDetailsFragment { privateMetadata: (CategoryDetailsFragment_privateMetadata | null)[]; backgroundImage: CategoryDetailsFragment_backgroundImage | null; name: string; + slug: string; descriptionJson: any; seoDescription: string | null; seoTitle: string | null; diff --git a/src/fragments/types/CollectionDetailsFragment.ts b/src/fragments/types/CollectionDetailsFragment.ts index d2dc154a8..0464eb6e7 100644 --- a/src/fragments/types/CollectionDetailsFragment.ts +++ b/src/fragments/types/CollectionDetailsFragment.ts @@ -32,6 +32,7 @@ export interface CollectionDetailsFragment { metadata: (CollectionDetailsFragment_metadata | null)[]; privateMetadata: (CollectionDetailsFragment_privateMetadata | null)[]; backgroundImage: CollectionDetailsFragment_backgroundImage | null; + slug: string; descriptionJson: any; publicationDate: any | null; seoDescription: string | null; diff --git a/src/fragments/types/Product.ts b/src/fragments/types/Product.ts index 6921ecc67..0ae50c5df 100644 --- a/src/fragments/types/Product.ts +++ b/src/fragments/types/Product.ts @@ -195,6 +195,7 @@ export interface Product { metadata: (Product_metadata | null)[]; privateMetadata: (Product_privateMetadata | null)[]; name: string; + slug: string; descriptionJson: any; seoTitle: string | null; seoDescription: string | null; diff --git a/src/pages/components/PageDetailsPage/PageDetailsPage.tsx b/src/pages/components/PageDetailsPage/PageDetailsPage.tsx index 6176562fa..95f0bfb43 100644 --- a/src/pages/components/PageDetailsPage/PageDetailsPage.tsx +++ b/src/pages/components/PageDetailsPage/PageDetailsPage.tsx @@ -23,7 +23,6 @@ import { useIntl } from "react-intl"; import { maybe } from "../../../misc"; import { PageDetails_page } from "../../types/PageDetails"; import PageInfo from "../PageInfo"; -import PageSlug from "../PageSlug"; export interface FormData { content: RawDraftContentState; @@ -31,7 +30,6 @@ export interface FormData { publicationDate: string; seoDescription: string; seoTitle: string; - seoSlug: string; slug: string; title: string; } @@ -108,6 +106,8 @@ const PageDetailsPage: React.FC = ({ "" )} onChange={change} + slug={data.slug} + slugPlaceholder={data.title} title={data.seoTitle} titlePlaceholder={data.title} helperText={intl.formatMessage({ diff --git a/src/products/components/ProductCreatePage/ProductCreatePage.tsx b/src/products/components/ProductCreatePage/ProductCreatePage.tsx index d96f30343..03ab907ab 100644 --- a/src/products/components/ProductCreatePage/ProductCreatePage.tsx +++ b/src/products/components/ProductCreatePage/ProductCreatePage.tsx @@ -59,6 +59,7 @@ interface FormData extends MetadataFormData { isAvailableForPurchase: boolean; isPublished: boolean; name: string; + slug: string; productType: string; seoDescription: string; seoTitle: string; @@ -156,6 +157,7 @@ export const ProductCreatePage: React.FC = ({ isPublished: false, metadata: [], name: "", + slug: "", privateMetadata: [], productType: "", publicationDate: "", @@ -309,6 +311,8 @@ export const ProductCreatePage: React.FC = ({ "Add search engine title and description to make this product easier to find" })} title={data.seoTitle} + slug={data.slug} + slugPlaceholder={data.name} titlePlaceholder={data.name} description={data.seoDescription} descriptionPlaceholder={data.seoTitle} diff --git a/src/products/components/ProductUpdatePage/ProductUpdatePage.tsx b/src/products/components/ProductUpdatePage/ProductUpdatePage.tsx index d3be9d79e..3c5cb9ded 100644 --- a/src/products/components/ProductUpdatePage/ProductUpdatePage.tsx +++ b/src/products/components/ProductUpdatePage/ProductUpdatePage.tsx @@ -357,6 +357,8 @@ export const ProductUpdatePage: React.FC = ({ .getPlainText() .slice(0, 300) )} + slug={data.slug} + slugPlaceholder={data.name} loading={disabled} onClick={onSeoClick} onChange={change} diff --git a/src/products/types/ProductCreate.ts b/src/products/types/ProductCreate.ts index 68c154d91..b8dd2ca59 100644 --- a/src/products/types/ProductCreate.ts +++ b/src/products/types/ProductCreate.ts @@ -201,6 +201,7 @@ export interface ProductCreate_productCreate_product { metadata: (ProductCreate_productCreate_product_metadata | null)[]; privateMetadata: (ProductCreate_productCreate_product_privateMetadata | null)[]; name: string; + slug: string; descriptionJson: any; seoTitle: string | null; seoDescription: string | null; diff --git a/src/products/types/ProductDetails.ts b/src/products/types/ProductDetails.ts index 06e579bae..094ac6d5c 100644 --- a/src/products/types/ProductDetails.ts +++ b/src/products/types/ProductDetails.ts @@ -195,6 +195,7 @@ export interface ProductDetails_product { metadata: (ProductDetails_product_metadata | null)[]; privateMetadata: (ProductDetails_product_privateMetadata | null)[]; name: string; + slug: string; descriptionJson: any; seoTitle: string | null; seoDescription: string | null; diff --git a/src/products/types/ProductImageCreate.ts b/src/products/types/ProductImageCreate.ts index 9c472c556..06243ea4e 100644 --- a/src/products/types/ProductImageCreate.ts +++ b/src/products/types/ProductImageCreate.ts @@ -201,6 +201,7 @@ export interface ProductImageCreate_productImageCreate_product { metadata: (ProductImageCreate_productImageCreate_product_metadata | null)[]; privateMetadata: (ProductImageCreate_productImageCreate_product_privateMetadata | null)[]; name: string; + slug: string; descriptionJson: any; seoTitle: string | null; seoDescription: string | null; diff --git a/src/products/types/ProductImageUpdate.ts b/src/products/types/ProductImageUpdate.ts index e85899725..1931b23e7 100644 --- a/src/products/types/ProductImageUpdate.ts +++ b/src/products/types/ProductImageUpdate.ts @@ -201,6 +201,7 @@ export interface ProductImageUpdate_productImageUpdate_product { metadata: (ProductImageUpdate_productImageUpdate_product_metadata | null)[]; privateMetadata: (ProductImageUpdate_productImageUpdate_product_privateMetadata | null)[]; name: string; + slug: string; descriptionJson: any; seoTitle: string | null; seoDescription: string | null; diff --git a/src/products/types/ProductUpdate.ts b/src/products/types/ProductUpdate.ts index f03604480..c94b1772a 100644 --- a/src/products/types/ProductUpdate.ts +++ b/src/products/types/ProductUpdate.ts @@ -201,6 +201,7 @@ export interface ProductUpdate_productUpdate_product { metadata: (ProductUpdate_productUpdate_product_metadata | null)[]; privateMetadata: (ProductUpdate_productUpdate_product_privateMetadata | null)[]; name: string; + slug: string; descriptionJson: any; seoTitle: string | null; seoDescription: string | null; @@ -236,6 +237,7 @@ export interface ProductUpdateVariables { publicationDate?: any | null; category?: string | null; chargeTaxes: boolean; + slug?: string | null; collections?: (string | null)[] | null; descriptionJson?: any | null; isPublished: boolean; diff --git a/src/products/types/SimpleProductUpdate.ts b/src/products/types/SimpleProductUpdate.ts index e023f09b1..c83e36fed 100644 --- a/src/products/types/SimpleProductUpdate.ts +++ b/src/products/types/SimpleProductUpdate.ts @@ -201,6 +201,7 @@ export interface SimpleProductUpdate_productUpdate_product { metadata: (SimpleProductUpdate_productUpdate_product_metadata | null)[]; privateMetadata: (SimpleProductUpdate_productUpdate_product_privateMetadata | null)[]; name: string; + slug: string; descriptionJson: any; seoTitle: string | null; seoDescription: string | null; diff --git a/src/products/utils/data.ts b/src/products/utils/data.ts index 28eab8a18..ec378a288 100644 --- a/src/products/utils/data.ts +++ b/src/products/utils/data.ts @@ -181,6 +181,7 @@ export interface ProductUpdatePageFormData extends MetadataFormData { isAvailable: boolean; isPublished: boolean; name: string; + slug: string; publicationDate: string; seoDescription: string; seoTitle: string; @@ -222,6 +223,7 @@ export function getProductUpdatePageFormData( : undefined, "" ), + slug: product?.slug || "", trackInventory: !!product?.variants[0]?.trackInventory, visibleInListings: !!product?.visibleInListings, weight: product?.weight?.value.toString() || ""