1863 - Support reference attribute reordering (#946)
* Support reference attribute reordering * Update attribute handlers tests
This commit is contained in:
parent
4b8c2ea5e7
commit
b07bb08ade
19 changed files with 615 additions and 297 deletions
|
@ -1,9 +1,8 @@
|
||||||
|
import { createAttributeMultiChangeHandler } from "@saleor/attributes/utils/handlers";
|
||||||
import { AttributeInputData } from "@saleor/components/Attributes";
|
import { AttributeInputData } from "@saleor/components/Attributes";
|
||||||
import { FormsetData } from "@saleor/hooks/useFormset";
|
import { FormsetData } from "@saleor/hooks/useFormset";
|
||||||
import { AttributeInputTypeEnum } from "@saleor/types/globalTypes";
|
import { AttributeInputTypeEnum } from "@saleor/types/globalTypes";
|
||||||
|
|
||||||
import { createAttributeMultiChangeHandler } from "./handlers";
|
|
||||||
|
|
||||||
const attributes: FormsetData<AttributeInputData, string[]> = [
|
const attributes: FormsetData<AttributeInputData, string[]> = [
|
||||||
{
|
{
|
||||||
data: {
|
data: {
|
|
@ -1,14 +1,23 @@
|
||||||
import { AttributeInput } from "@saleor/components/Attributes";
|
import {
|
||||||
|
AttributeInput,
|
||||||
|
AttributeInputData
|
||||||
|
} from "@saleor/components/Attributes";
|
||||||
import {
|
import {
|
||||||
FileUpload,
|
FileUpload,
|
||||||
FileUploadVariables
|
FileUploadVariables
|
||||||
} from "@saleor/files/types/FileUpload";
|
} from "@saleor/files/types/FileUpload";
|
||||||
import { FormsetData } from "@saleor/hooks/useFormset";
|
import {
|
||||||
|
FormsetAtomicData,
|
||||||
|
FormsetChange,
|
||||||
|
FormsetData
|
||||||
|
} from "@saleor/hooks/useFormset";
|
||||||
import { PageDetails_page_attributes } from "@saleor/pages/types/PageDetails";
|
import { PageDetails_page_attributes } from "@saleor/pages/types/PageDetails";
|
||||||
|
import { ReorderEvent } from "@saleor/types";
|
||||||
import {
|
import {
|
||||||
AttributeInputTypeEnum,
|
AttributeInputTypeEnum,
|
||||||
AttributeValueInput
|
AttributeValueInput
|
||||||
} from "@saleor/types/globalTypes";
|
} from "@saleor/types/globalTypes";
|
||||||
|
import { move, toggle } from "@saleor/utils/lists";
|
||||||
import { MutationFetchResult } from "react-apollo";
|
import { MutationFetchResult } from "react-apollo";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
@ -17,6 +26,99 @@ import {
|
||||||
} from "../types/AttributeValueDelete";
|
} from "../types/AttributeValueDelete";
|
||||||
import { getFileValuesToUploadFromAttributes, isFileValueUnused } from "./data";
|
import { getFileValuesToUploadFromAttributes, isFileValueUnused } from "./data";
|
||||||
|
|
||||||
|
export function createAttributeChangeHandler(
|
||||||
|
changeAttributeData: FormsetChange<string[]>,
|
||||||
|
triggerChange: () => void
|
||||||
|
): FormsetChange<string> {
|
||||||
|
return (attributeId: string, value: string) => {
|
||||||
|
triggerChange();
|
||||||
|
changeAttributeData(attributeId, value === "" ? [] : [value]);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createAttributeMultiChangeHandler(
|
||||||
|
changeAttributeData: FormsetChange<string[]>,
|
||||||
|
attributes: FormsetData<AttributeInputData, string[]>,
|
||||||
|
triggerChange: () => void
|
||||||
|
): FormsetChange<string> {
|
||||||
|
return (attributeId: string, value: string) => {
|
||||||
|
const attribute = attributes.find(
|
||||||
|
attribute => attribute.id === attributeId
|
||||||
|
);
|
||||||
|
|
||||||
|
const newAttributeValues = toggle(
|
||||||
|
value,
|
||||||
|
attribute.value,
|
||||||
|
(a, b) => a === b
|
||||||
|
);
|
||||||
|
|
||||||
|
triggerChange();
|
||||||
|
changeAttributeData(attributeId, newAttributeValues);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createAttributeReferenceChangeHandler(
|
||||||
|
changeAttributeData: FormsetChange<string[]>,
|
||||||
|
triggerChange: () => void
|
||||||
|
): FormsetChange<string[]> {
|
||||||
|
return (attributeId: string, values: string[]) => {
|
||||||
|
changeAttributeData(attributeId, values);
|
||||||
|
triggerChange();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createAttributeFileChangeHandler(
|
||||||
|
changeAttributeData: FormsetChange<string[]>,
|
||||||
|
attributesWithNewFileValue: FormsetData<FormsetData<null, File>>,
|
||||||
|
addAttributeNewFileValue: (data: FormsetAtomicData<null, File>) => void,
|
||||||
|
changeAttributeNewFileValue: FormsetChange<File>,
|
||||||
|
triggerChange: () => void
|
||||||
|
): FormsetChange<File> {
|
||||||
|
return (attributeId: string, value: File) => {
|
||||||
|
triggerChange();
|
||||||
|
|
||||||
|
const newFileValueAssigned = attributesWithNewFileValue.find(
|
||||||
|
attribute => attribute.id === attributeId
|
||||||
|
);
|
||||||
|
|
||||||
|
if (newFileValueAssigned) {
|
||||||
|
changeAttributeNewFileValue(attributeId, value);
|
||||||
|
} else {
|
||||||
|
addAttributeNewFileValue({
|
||||||
|
data: null,
|
||||||
|
id: attributeId,
|
||||||
|
label: null,
|
||||||
|
value
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
changeAttributeData(attributeId, value ? [value.name] : []);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createAttributeValueReorderHandler(
|
||||||
|
changeAttributeData: FormsetChange<string[]>,
|
||||||
|
attributes: FormsetData<AttributeInputData, string[]>,
|
||||||
|
triggerChange: () => void
|
||||||
|
): FormsetChange<ReorderEvent> {
|
||||||
|
return (attributeId: string, reorder: ReorderEvent) => {
|
||||||
|
triggerChange();
|
||||||
|
|
||||||
|
const attribute = attributes.find(
|
||||||
|
attribute => attribute.id === attributeId
|
||||||
|
);
|
||||||
|
|
||||||
|
const reorderedValues = move(
|
||||||
|
attribute.value[reorder.oldIndex],
|
||||||
|
attribute.value,
|
||||||
|
(a, b) => a === b,
|
||||||
|
reorder.newIndex
|
||||||
|
);
|
||||||
|
|
||||||
|
changeAttributeData(attributeId, reorderedValues);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
interface AttributesArgs {
|
interface AttributesArgs {
|
||||||
attributes: AttributeInput[];
|
attributes: AttributeInput[];
|
||||||
updatedFileAttributes: AttributeValueInput[];
|
updatedFileAttributes: AttributeValueInput[];
|
||||||
|
|
|
@ -17,7 +17,7 @@ import { PageErrorWithAttributesFragment } from "@saleor/fragments/types/PageErr
|
||||||
import { ProductErrorWithAttributesFragment } from "@saleor/fragments/types/ProductErrorWithAttributesFragment";
|
import { ProductErrorWithAttributesFragment } from "@saleor/fragments/types/ProductErrorWithAttributesFragment";
|
||||||
import { FormsetAtomicData, FormsetChange } from "@saleor/hooks/useFormset";
|
import { FormsetAtomicData, FormsetChange } from "@saleor/hooks/useFormset";
|
||||||
import { SearchPages_search_edges_node } from "@saleor/searches/types/SearchPages";
|
import { SearchPages_search_edges_node } from "@saleor/searches/types/SearchPages";
|
||||||
import { ReorderAction } from "@saleor/types";
|
import { ReorderEvent } from "@saleor/types";
|
||||||
import { AttributeInputTypeEnum } from "@saleor/types/globalTypes";
|
import { AttributeInputTypeEnum } from "@saleor/types/globalTypes";
|
||||||
import { getProductErrorMessage } from "@saleor/utils/errors";
|
import { getProductErrorMessage } from "@saleor/utils/errors";
|
||||||
import getPageErrorMessage from "@saleor/utils/errors/page";
|
import getPageErrorMessage from "@saleor/utils/errors/page";
|
||||||
|
@ -56,12 +56,12 @@ export interface AttributesProps {
|
||||||
ProductErrorWithAttributesFragment | PageErrorWithAttributesFragment
|
ProductErrorWithAttributesFragment | PageErrorWithAttributesFragment
|
||||||
>;
|
>;
|
||||||
title?: React.ReactNode;
|
title?: React.ReactNode;
|
||||||
onChange: FormsetChange;
|
onChange: FormsetChange<string>;
|
||||||
onMultiChange: FormsetChange;
|
onMultiChange: FormsetChange<string>;
|
||||||
onFileChange: FormsetChange;
|
onFileChange: FormsetChange<File>;
|
||||||
onReferencesRemove?: FormsetChange; // TODO: temporairy optional, should be changed to required, after all pages implement it
|
onReferencesRemove: FormsetChange<string[]>;
|
||||||
onReferencesAddClick?: (attribute: AttributeInput) => void; // TODO: temporairy optional, should be changed to required, after all pages implement it
|
onReferencesAddClick: (attribute: AttributeInput) => void;
|
||||||
onReferencesReorder?: ReorderAction; // TODO: temporairy optional, should be changed to required, after all pages implement it
|
onReferencesReorder: FormsetChange<ReorderEvent>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const useStyles = makeStyles(
|
const useStyles = makeStyles(
|
||||||
|
@ -328,8 +328,12 @@ const Attributes: React.FC<AttributesProps> = ({
|
||||||
attribute.value?.filter(id => id !== value)
|
attribute.value?.filter(id => id !== value)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
onValueReorder={onReferencesReorder}
|
onValueReorder={event =>
|
||||||
|
onReferencesReorder(attribute.id, event)
|
||||||
|
}
|
||||||
loading={loading}
|
loading={loading}
|
||||||
|
error={!!error}
|
||||||
|
helperText={getErrorMessage(error, intl)}
|
||||||
/>
|
/>
|
||||||
</ExtendedAttributeRow>
|
</ExtendedAttributeRow>
|
||||||
) : attribute.data.inputType ===
|
) : attribute.data.inputType ===
|
||||||
|
|
|
@ -24,4 +24,11 @@ storiesOf("Generics / Sortable chips field", module)
|
||||||
.addDecorator(CardDecorator)
|
.addDecorator(CardDecorator)
|
||||||
.addDecorator(Decorator)
|
.addDecorator(Decorator)
|
||||||
.add("default", () => <SortableChipsField {...props} />)
|
.add("default", () => <SortableChipsField {...props} />)
|
||||||
.add("loading", () => <SortableChipsField {...props} loading={true} />);
|
.add("loading", () => <SortableChipsField {...props} loading={true} />)
|
||||||
|
.add("with error", () => (
|
||||||
|
<SortableChipsField
|
||||||
|
{...props}
|
||||||
|
error={true}
|
||||||
|
helperText="Something went wrong"
|
||||||
|
/>
|
||||||
|
));
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { makeStyles } from "@material-ui/core/styles";
|
import { makeStyles } from "@material-ui/core/styles";
|
||||||
|
import Typography from "@material-ui/core/Typography";
|
||||||
import { ReorderAction } from "@saleor/types";
|
import { ReorderAction } from "@saleor/types";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { SortableContainerProps } from "react-sortable-hoc";
|
import { SortableContainerProps } from "react-sortable-hoc";
|
||||||
|
@ -13,6 +14,9 @@ const useStyles = makeStyles(
|
||||||
background: "#fff",
|
background: "#fff",
|
||||||
color: theme.palette.primary.dark,
|
color: theme.palette.primary.dark,
|
||||||
marginBottom: theme.spacing(1)
|
marginBottom: theme.spacing(1)
|
||||||
|
},
|
||||||
|
errorText: {
|
||||||
|
color: theme.palette.error.light
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
|
@ -28,12 +32,21 @@ export interface SortableChipsFieldValueType {
|
||||||
export interface SortableChipsFieldProps extends SortableContainerProps {
|
export interface SortableChipsFieldProps extends SortableContainerProps {
|
||||||
loading?: boolean;
|
loading?: boolean;
|
||||||
values: SortableChipsFieldValueType[];
|
values: SortableChipsFieldValueType[];
|
||||||
|
error?: boolean;
|
||||||
|
helperText?: string;
|
||||||
onValueDelete: (id: string) => void;
|
onValueDelete: (id: string) => void;
|
||||||
onValueReorder: ReorderAction;
|
onValueReorder: ReorderAction;
|
||||||
}
|
}
|
||||||
|
|
||||||
const SortableChipsField: React.FC<SortableChipsFieldProps> = props => {
|
const SortableChipsField: React.FC<SortableChipsFieldProps> = props => {
|
||||||
const { loading, values, onValueDelete, onValueReorder } = props;
|
const {
|
||||||
|
loading,
|
||||||
|
values,
|
||||||
|
error,
|
||||||
|
helperText,
|
||||||
|
onValueDelete,
|
||||||
|
onValueReorder
|
||||||
|
} = props;
|
||||||
const classes = useStyles(props);
|
const classes = useStyles(props);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -57,6 +70,11 @@ const SortableChipsField: React.FC<SortableChipsFieldProps> = props => {
|
||||||
/>
|
/>
|
||||||
))
|
))
|
||||||
)}
|
)}
|
||||||
|
{error && (
|
||||||
|
<Typography variant="caption" className={classes.errorText}>
|
||||||
|
{helperText}
|
||||||
|
</Typography>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</SortableContainer>
|
</SortableContainer>
|
||||||
);
|
);
|
||||||
|
|
|
@ -148,6 +148,7 @@ const PageDetailsPage: React.FC<PageDetailsPageProps> = ({
|
||||||
onFileChange={handlers.selectAttributeFile}
|
onFileChange={handlers.selectAttributeFile}
|
||||||
onReferencesRemove={handlers.selectAttributeReference}
|
onReferencesRemove={handlers.selectAttributeReference}
|
||||||
onReferencesAddClick={onAssignReferencesClick}
|
onReferencesAddClick={onAssignReferencesClick}
|
||||||
|
onReferencesReorder={handlers.reorderAttributeValue}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<CardSpacer />
|
<CardSpacer />
|
||||||
|
|
|
@ -1,5 +1,12 @@
|
||||||
import { OutputData } from "@editorjs/editorjs";
|
import { OutputData } from "@editorjs/editorjs";
|
||||||
import { getAttributesDisplayData } from "@saleor/attributes/utils/data";
|
import { getAttributesDisplayData } from "@saleor/attributes/utils/data";
|
||||||
|
import {
|
||||||
|
createAttributeChangeHandler,
|
||||||
|
createAttributeFileChangeHandler,
|
||||||
|
createAttributeMultiChangeHandler,
|
||||||
|
createAttributeReferenceChangeHandler,
|
||||||
|
createAttributeValueReorderHandler
|
||||||
|
} from "@saleor/attributes/utils/handlers";
|
||||||
import { AttributeInput } from "@saleor/components/Attributes";
|
import { AttributeInput } from "@saleor/components/Attributes";
|
||||||
import { MetadataFormData } from "@saleor/components/Metadata";
|
import { MetadataFormData } from "@saleor/components/Metadata";
|
||||||
import { RichTextEditorChange } from "@saleor/components/RichTextEditor";
|
import { RichTextEditorChange } from "@saleor/components/RichTextEditor";
|
||||||
|
@ -16,13 +23,8 @@ import {
|
||||||
} from "@saleor/pages/types/PageDetails";
|
} from "@saleor/pages/types/PageDetails";
|
||||||
import { getAttributeInputFromPage } from "@saleor/pages/utils/data";
|
import { getAttributeInputFromPage } from "@saleor/pages/utils/data";
|
||||||
import { createPageTypeSelectHandler } from "@saleor/pages/utils/handlers";
|
import { createPageTypeSelectHandler } from "@saleor/pages/utils/handlers";
|
||||||
import {
|
|
||||||
createAttributeChangeHandler,
|
|
||||||
createAttributeFileChangeHandler,
|
|
||||||
createAttributeMultiChangeHandler,
|
|
||||||
createAttributeReferenceChangeHandler
|
|
||||||
} from "@saleor/products/utils/handlers";
|
|
||||||
import { SearchPages_search_edges_node } from "@saleor/searches/types/SearchPages";
|
import { SearchPages_search_edges_node } from "@saleor/searches/types/SearchPages";
|
||||||
|
import { ReorderEvent } from "@saleor/types";
|
||||||
import getPublicationData from "@saleor/utils/data/getPublicationData";
|
import getPublicationData from "@saleor/utils/data/getPublicationData";
|
||||||
import handleFormSubmit from "@saleor/utils/handlers/handleFormSubmit";
|
import handleFormSubmit from "@saleor/utils/handlers/handleFormSubmit";
|
||||||
import { mapMetadataItemToInput } from "@saleor/utils/maps";
|
import { mapMetadataItemToInput } from "@saleor/utils/maps";
|
||||||
|
@ -59,6 +61,7 @@ export interface PageUpdateHandlers {
|
||||||
selectAttributeMulti: FormsetChange<string>;
|
selectAttributeMulti: FormsetChange<string>;
|
||||||
selectAttributeReference: FormsetChange<string[]>;
|
selectAttributeReference: FormsetChange<string[]>;
|
||||||
selectAttributeFile: FormsetChange<File>;
|
selectAttributeFile: FormsetChange<File>;
|
||||||
|
reorderAttributeValue: FormsetChange<ReorderEvent>;
|
||||||
}
|
}
|
||||||
export interface UsePageUpdateFormResult {
|
export interface UsePageUpdateFormResult {
|
||||||
change: FormChange;
|
change: FormChange;
|
||||||
|
@ -150,6 +153,11 @@ function usePageForm(
|
||||||
attributesWithNewFileValue.change,
|
attributesWithNewFileValue.change,
|
||||||
triggerChange
|
triggerChange
|
||||||
);
|
);
|
||||||
|
const handleAttributeValueReorder = createAttributeValueReorderHandler(
|
||||||
|
attributes.change,
|
||||||
|
attributes.data,
|
||||||
|
triggerChange
|
||||||
|
);
|
||||||
|
|
||||||
// Need to make it function to always have content.current up to date
|
// Need to make it function to always have content.current up to date
|
||||||
const getData = (): PageData => ({
|
const getData = (): PageData => ({
|
||||||
|
@ -190,6 +198,7 @@ function usePageForm(
|
||||||
handlers: {
|
handlers: {
|
||||||
changeContent,
|
changeContent,
|
||||||
changeMetadata,
|
changeMetadata,
|
||||||
|
reorderAttributeValue: handleAttributeValueReorder,
|
||||||
selectAttribute: handleAttributeChange,
|
selectAttribute: handleAttributeChange,
|
||||||
selectAttributeFile: handleAttributeFileChange,
|
selectAttributeFile: handleAttributeFileChange,
|
||||||
selectAttributeMulti: handleAttributeMultiChange,
|
selectAttributeMulti: handleAttributeMultiChange,
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import { AttributeInputData } from "@saleor/components/Attributes";
|
import { AttributeInputData } from "@saleor/components/Attributes";
|
||||||
import { FormChange } from "@saleor/hooks/useForm";
|
import { FormChange } from "@saleor/hooks/useForm";
|
||||||
import { FormsetChange, FormsetData } from "@saleor/hooks/useFormset";
|
import { FormsetData } from "@saleor/hooks/useFormset";
|
||||||
import { toggle } from "@saleor/utils/lists";
|
|
||||||
|
|
||||||
import { PageDetails_page_pageType } from "../types/PageDetails";
|
import { PageDetails_page_pageType } from "../types/PageDetails";
|
||||||
import { getAttributeInputFromPageType } from "./data";
|
import { getAttributeInputFromPageType } from "./data";
|
||||||
|
@ -23,34 +22,3 @@ export function createPageTypeSelectHandler(
|
||||||
setAttributes(getAttributeInputFromPageType(selectedPageType));
|
setAttributes(getAttributeInputFromPageType(selectedPageType));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createAttributeChangeHandler(
|
|
||||||
changeAttributeData: FormsetChange<string[]>,
|
|
||||||
triggerChange: () => void
|
|
||||||
): FormsetChange {
|
|
||||||
return (attributeId: string, value: string) => {
|
|
||||||
triggerChange();
|
|
||||||
changeAttributeData(attributeId, value === "" ? [] : [value]);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function createAttributeMultiChangeHandler(
|
|
||||||
changeAttributeData: FormsetChange<string[]>,
|
|
||||||
attributes: FormsetData<AttributeInputData, string[]>,
|
|
||||||
triggerChange: () => void
|
|
||||||
): FormsetChange {
|
|
||||||
return (attributeId: string, value: string) => {
|
|
||||||
const attribute = attributes.find(
|
|
||||||
attribute => attribute.id === attributeId
|
|
||||||
);
|
|
||||||
|
|
||||||
const newAttributeValues = toggle(
|
|
||||||
value,
|
|
||||||
attribute.value,
|
|
||||||
(a, b) => a === b
|
|
||||||
);
|
|
||||||
|
|
||||||
triggerChange();
|
|
||||||
changeAttributeData(attributeId, newAttributeValues);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
|
@ -206,6 +206,7 @@ export const ProductCreatePage: React.FC<ProductCreatePageProps> = ({
|
||||||
onFileChange={handlers.selectAttributeFile}
|
onFileChange={handlers.selectAttributeFile}
|
||||||
onReferencesRemove={handlers.selectAttributeReference}
|
onReferencesRemove={handlers.selectAttributeReference}
|
||||||
onReferencesAddClick={onAssignReferencesClick}
|
onReferencesAddClick={onAssignReferencesClick}
|
||||||
|
onReferencesReorder={handlers.reorderAttributeValue}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<CardSpacer />
|
<CardSpacer />
|
||||||
|
|
|
@ -1,5 +1,12 @@
|
||||||
import { OutputData } from "@editorjs/editorjs";
|
import { OutputData } from "@editorjs/editorjs";
|
||||||
import { getAttributesDisplayData } from "@saleor/attributes/utils/data";
|
import { getAttributesDisplayData } from "@saleor/attributes/utils/data";
|
||||||
|
import {
|
||||||
|
createAttributeChangeHandler,
|
||||||
|
createAttributeFileChangeHandler,
|
||||||
|
createAttributeMultiChangeHandler,
|
||||||
|
createAttributeReferenceChangeHandler,
|
||||||
|
createAttributeValueReorderHandler
|
||||||
|
} from "@saleor/attributes/utils/handlers";
|
||||||
import { ChannelData, ChannelPriceArgs } from "@saleor/channels/utils";
|
import { ChannelData, ChannelPriceArgs } from "@saleor/channels/utils";
|
||||||
import {
|
import {
|
||||||
AttributeInput,
|
AttributeInput,
|
||||||
|
@ -20,10 +27,6 @@ import {
|
||||||
ProductType
|
ProductType
|
||||||
} from "@saleor/products/utils/data";
|
} from "@saleor/products/utils/data";
|
||||||
import {
|
import {
|
||||||
createAttributeChangeHandler,
|
|
||||||
createAttributeFileChangeHandler,
|
|
||||||
createAttributeMultiChangeHandler,
|
|
||||||
createAttributeReferenceChangeHandler,
|
|
||||||
createChannelsChangeHandler,
|
createChannelsChangeHandler,
|
||||||
createChannelsPriceChangeHandler,
|
createChannelsPriceChangeHandler,
|
||||||
createProductTypeSelectHandler
|
createProductTypeSelectHandler
|
||||||
|
@ -35,6 +38,7 @@ import {
|
||||||
import { SearchPages_search_edges_node } from "@saleor/searches/types/SearchPages";
|
import { SearchPages_search_edges_node } from "@saleor/searches/types/SearchPages";
|
||||||
import { SearchProductTypes_search_edges_node } from "@saleor/searches/types/SearchProductTypes";
|
import { SearchProductTypes_search_edges_node } from "@saleor/searches/types/SearchProductTypes";
|
||||||
import { SearchWarehouses_search_edges_node } from "@saleor/searches/types/SearchWarehouses";
|
import { SearchWarehouses_search_edges_node } from "@saleor/searches/types/SearchWarehouses";
|
||||||
|
import { ReorderEvent } from "@saleor/types";
|
||||||
import createMultiAutocompleteSelectHandler from "@saleor/utils/handlers/multiAutocompleteSelectChangeHandler";
|
import createMultiAutocompleteSelectHandler from "@saleor/utils/handlers/multiAutocompleteSelectChangeHandler";
|
||||||
import createSingleAutocompleteSelectHandler from "@saleor/utils/handlers/singleAutocompleteSelectChangeHandler";
|
import createSingleAutocompleteSelectHandler from "@saleor/utils/handlers/singleAutocompleteSelectChangeHandler";
|
||||||
import useMetadataChangeTrigger from "@saleor/utils/metadata/useMetadataChangeTrigger";
|
import useMetadataChangeTrigger from "@saleor/utils/metadata/useMetadataChangeTrigger";
|
||||||
|
@ -92,6 +96,7 @@ export interface ProductCreateHandlers
|
||||||
>,
|
>,
|
||||||
Record<"selectAttributeReference", FormsetChange<string[]>>,
|
Record<"selectAttributeReference", FormsetChange<string[]>>,
|
||||||
Record<"selectAttributeFile", FormsetChange<File>>,
|
Record<"selectAttributeFile", FormsetChange<File>>,
|
||||||
|
Record<"reorderAttributeValue", FormsetChange<ReorderEvent>>,
|
||||||
Record<"addStock" | "deleteStock", (id: string) => void> {
|
Record<"addStock" | "deleteStock", (id: string) => void> {
|
||||||
changeDescription: RichTextEditorChange;
|
changeDescription: RichTextEditorChange;
|
||||||
}
|
}
|
||||||
|
@ -224,6 +229,11 @@ function useProductCreateForm(
|
||||||
attributesWithNewFileValue.change,
|
attributesWithNewFileValue.change,
|
||||||
triggerChange
|
triggerChange
|
||||||
);
|
);
|
||||||
|
const handleAttributeValueReorder = createAttributeValueReorderHandler(
|
||||||
|
attributes.change,
|
||||||
|
attributes.data,
|
||||||
|
triggerChange
|
||||||
|
);
|
||||||
const handleProductTypeSelect = createProductTypeSelectHandler(
|
const handleProductTypeSelect = createProductTypeSelectHandler(
|
||||||
attributes.set,
|
attributes.set,
|
||||||
setProductType,
|
setProductType,
|
||||||
|
@ -305,6 +315,7 @@ function useProductCreateForm(
|
||||||
changeMetadata,
|
changeMetadata,
|
||||||
changeStock: handleStockChange,
|
changeStock: handleStockChange,
|
||||||
deleteStock: handleStockDelete,
|
deleteStock: handleStockDelete,
|
||||||
|
reorderAttributeValue: handleAttributeValueReorder,
|
||||||
selectAttribute: handleAttributeChange,
|
selectAttribute: handleAttributeChange,
|
||||||
selectAttributeFile: handleAttributeFileChange,
|
selectAttributeFile: handleAttributeFileChange,
|
||||||
selectAttributeMultiple: handleAttributeMultiChange,
|
selectAttributeMultiple: handleAttributeMultiChange,
|
||||||
|
|
|
@ -267,6 +267,7 @@ export const ProductUpdatePage: React.FC<ProductUpdatePageProps> = ({
|
||||||
onFileChange={handlers.selectAttributeFile}
|
onFileChange={handlers.selectAttributeFile}
|
||||||
onReferencesRemove={handlers.selectAttributeReference}
|
onReferencesRemove={handlers.selectAttributeReference}
|
||||||
onReferencesAddClick={onAssignReferencesClick}
|
onReferencesAddClick={onAssignReferencesClick}
|
||||||
|
onReferencesReorder={handlers.reorderAttributeValue}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<CardSpacer />
|
<CardSpacer />
|
||||||
|
|
|
@ -1,5 +1,12 @@
|
||||||
import { OutputData } from "@editorjs/editorjs";
|
import { OutputData } from "@editorjs/editorjs";
|
||||||
import { getAttributesDisplayData } from "@saleor/attributes/utils/data";
|
import { getAttributesDisplayData } from "@saleor/attributes/utils/data";
|
||||||
|
import {
|
||||||
|
createAttributeChangeHandler,
|
||||||
|
createAttributeFileChangeHandler,
|
||||||
|
createAttributeMultiChangeHandler,
|
||||||
|
createAttributeReferenceChangeHandler,
|
||||||
|
createAttributeValueReorderHandler
|
||||||
|
} from "@saleor/attributes/utils/handlers";
|
||||||
import { ChannelData, ChannelPriceArgs } from "@saleor/channels/utils";
|
import { ChannelData, ChannelPriceArgs } from "@saleor/channels/utils";
|
||||||
import { AttributeInput } from "@saleor/components/Attributes";
|
import { AttributeInput } from "@saleor/components/Attributes";
|
||||||
import { MetadataFormData } from "@saleor/components/Metadata";
|
import { MetadataFormData } from "@saleor/components/Metadata";
|
||||||
|
@ -19,10 +26,6 @@ import {
|
||||||
getStockInputFromProduct
|
getStockInputFromProduct
|
||||||
} from "@saleor/products/utils/data";
|
} from "@saleor/products/utils/data";
|
||||||
import {
|
import {
|
||||||
createAttributeChangeHandler,
|
|
||||||
createAttributeFileChangeHandler,
|
|
||||||
createAttributeMultiChangeHandler,
|
|
||||||
createAttributeReferenceChangeHandler,
|
|
||||||
createChannelsChangeHandler,
|
createChannelsChangeHandler,
|
||||||
createChannelsPriceChangeHandler
|
createChannelsPriceChangeHandler
|
||||||
} from "@saleor/products/utils/handlers";
|
} from "@saleor/products/utils/handlers";
|
||||||
|
@ -32,6 +35,7 @@ import {
|
||||||
} from "@saleor/products/utils/validation";
|
} from "@saleor/products/utils/validation";
|
||||||
import { SearchPages_search_edges_node } from "@saleor/searches/types/SearchPages";
|
import { SearchPages_search_edges_node } from "@saleor/searches/types/SearchPages";
|
||||||
import { SearchWarehouses_search_edges_node } from "@saleor/searches/types/SearchWarehouses";
|
import { SearchWarehouses_search_edges_node } from "@saleor/searches/types/SearchWarehouses";
|
||||||
|
import { ReorderEvent } from "@saleor/types";
|
||||||
import handleFormSubmit from "@saleor/utils/handlers/handleFormSubmit";
|
import handleFormSubmit from "@saleor/utils/handlers/handleFormSubmit";
|
||||||
import createMultiAutocompleteSelectHandler from "@saleor/utils/handlers/multiAutocompleteSelectChangeHandler";
|
import createMultiAutocompleteSelectHandler from "@saleor/utils/handlers/multiAutocompleteSelectChangeHandler";
|
||||||
import createSingleAutocompleteSelectHandler from "@saleor/utils/handlers/singleAutocompleteSelectChangeHandler";
|
import createSingleAutocompleteSelectHandler from "@saleor/utils/handlers/singleAutocompleteSelectChangeHandler";
|
||||||
|
@ -109,6 +113,7 @@ export interface ProductUpdateHandlers
|
||||||
>,
|
>,
|
||||||
Record<"selectAttributeReference", FormsetChange<string[]>>,
|
Record<"selectAttributeReference", FormsetChange<string[]>>,
|
||||||
Record<"selectAttributeFile", FormsetChange<File>>,
|
Record<"selectAttributeFile", FormsetChange<File>>,
|
||||||
|
Record<"reorderAttributeValue", FormsetChange<ReorderEvent>>,
|
||||||
Record<"addStock" | "deleteStock", (id: string) => void> {
|
Record<"addStock" | "deleteStock", (id: string) => void> {
|
||||||
changeDescription: RichTextEditorChange;
|
changeDescription: RichTextEditorChange;
|
||||||
}
|
}
|
||||||
|
@ -234,6 +239,11 @@ function useProductUpdateForm(
|
||||||
attributesWithNewFileValue.change,
|
attributesWithNewFileValue.change,
|
||||||
triggerChange
|
triggerChange
|
||||||
);
|
);
|
||||||
|
const handleAttributeValueReorder = createAttributeValueReorderHandler(
|
||||||
|
attributes.change,
|
||||||
|
attributes.data,
|
||||||
|
triggerChange
|
||||||
|
);
|
||||||
const handleStockChange: FormsetChange<string> = (id, value) => {
|
const handleStockChange: FormsetChange<string> = (id, value) => {
|
||||||
triggerChange();
|
triggerChange();
|
||||||
stocks.change(id, value);
|
stocks.change(id, value);
|
||||||
|
@ -322,6 +332,7 @@ function useProductUpdateForm(
|
||||||
changeMetadata,
|
changeMetadata,
|
||||||
changeStock: handleStockChange,
|
changeStock: handleStockChange,
|
||||||
deleteStock: handleStockDelete,
|
deleteStock: handleStockDelete,
|
||||||
|
reorderAttributeValue: handleAttributeValueReorder,
|
||||||
selectAttribute: handleAttributeChange,
|
selectAttribute: handleAttributeChange,
|
||||||
selectAttributeFile: handleAttributeFileChange,
|
selectAttributeFile: handleAttributeFileChange,
|
||||||
selectAttributeMultiple: handleAttributeMultiChange,
|
selectAttributeMultiple: handleAttributeMultiChange,
|
||||||
|
|
|
@ -162,6 +162,9 @@ const ProductVariantCreatePage: React.FC<ProductVariantCreatePageProps> = ({
|
||||||
onChange={handlers.selectAttribute}
|
onChange={handlers.selectAttribute}
|
||||||
onMultiChange={handlers.selectAttributeMultiple}
|
onMultiChange={handlers.selectAttributeMultiple}
|
||||||
onFileChange={handlers.selectAttributeFile}
|
onFileChange={handlers.selectAttributeFile}
|
||||||
|
onReferencesRemove={handlers.selectAttributeReference}
|
||||||
|
onReferencesAddClick={onAssignReferencesClick}
|
||||||
|
onReferencesReorder={handlers.reorderAttributeValue}
|
||||||
/>
|
/>
|
||||||
<CardSpacer />
|
<CardSpacer />
|
||||||
<Attributes
|
<Attributes
|
||||||
|
@ -179,6 +182,7 @@ const ProductVariantCreatePage: React.FC<ProductVariantCreatePageProps> = ({
|
||||||
onFileChange={handlers.selectAttributeFile}
|
onFileChange={handlers.selectAttributeFile}
|
||||||
onReferencesRemove={handlers.selectAttributeReference}
|
onReferencesRemove={handlers.selectAttributeReference}
|
||||||
onReferencesAddClick={onAssignReferencesClick}
|
onReferencesAddClick={onAssignReferencesClick}
|
||||||
|
onReferencesReorder={handlers.reorderAttributeValue}
|
||||||
/>
|
/>
|
||||||
<CardSpacer />
|
<CardSpacer />
|
||||||
<ProductShipping
|
<ProductShipping
|
||||||
|
|
|
@ -1,4 +1,11 @@
|
||||||
import { getAttributesDisplayData } from "@saleor/attributes/utils/data";
|
import { getAttributesDisplayData } from "@saleor/attributes/utils/data";
|
||||||
|
import {
|
||||||
|
createAttributeChangeHandler,
|
||||||
|
createAttributeFileChangeHandler,
|
||||||
|
createAttributeMultiChangeHandler,
|
||||||
|
createAttributeReferenceChangeHandler,
|
||||||
|
createAttributeValueReorderHandler
|
||||||
|
} from "@saleor/attributes/utils/handlers";
|
||||||
import { ChannelPriceData, IChannelPriceArgs } from "@saleor/channels/utils";
|
import { ChannelPriceData, IChannelPriceArgs } from "@saleor/channels/utils";
|
||||||
import { AttributeInput } from "@saleor/components/Attributes";
|
import { AttributeInput } from "@saleor/components/Attributes";
|
||||||
import { MetadataFormData } from "@saleor/components/Metadata";
|
import { MetadataFormData } from "@saleor/components/Metadata";
|
||||||
|
@ -9,21 +16,14 @@ import useFormset, {
|
||||||
} from "@saleor/hooks/useFormset";
|
} from "@saleor/hooks/useFormset";
|
||||||
import { ProductVariantCreateData_product } from "@saleor/products/types/ProductVariantCreateData";
|
import { ProductVariantCreateData_product } from "@saleor/products/types/ProductVariantCreateData";
|
||||||
import { getVariantAttributeInputFromProduct } from "@saleor/products/utils/data";
|
import { getVariantAttributeInputFromProduct } from "@saleor/products/utils/data";
|
||||||
import {
|
import { getChannelsInput } from "@saleor/products/utils/handlers";
|
||||||
createAttributeFileChangeHandler,
|
|
||||||
createAttributeReferenceChangeHandler,
|
|
||||||
getChannelsInput
|
|
||||||
} from "@saleor/products/utils/handlers";
|
|
||||||
import {
|
|
||||||
createAttributeChangeHandler,
|
|
||||||
createAttributeMultiChangeHandler
|
|
||||||
} from "@saleor/products/utils/handlers";
|
|
||||||
import {
|
import {
|
||||||
validateCostPrice,
|
validateCostPrice,
|
||||||
validatePrice
|
validatePrice
|
||||||
} from "@saleor/products/utils/validation";
|
} from "@saleor/products/utils/validation";
|
||||||
import { SearchPages_search_edges_node } from "@saleor/searches/types/SearchPages";
|
import { SearchPages_search_edges_node } from "@saleor/searches/types/SearchPages";
|
||||||
import { SearchWarehouses_search_edges_node } from "@saleor/searches/types/SearchWarehouses";
|
import { SearchWarehouses_search_edges_node } from "@saleor/searches/types/SearchWarehouses";
|
||||||
|
import { ReorderEvent } from "@saleor/types";
|
||||||
import useMetadataChangeTrigger from "@saleor/utils/metadata/useMetadataChangeTrigger";
|
import useMetadataChangeTrigger from "@saleor/utils/metadata/useMetadataChangeTrigger";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
|
@ -57,6 +57,7 @@ export interface ProductVariantCreateHandlers
|
||||||
>,
|
>,
|
||||||
Record<"selectAttributeReference", FormsetChange<string[]>>,
|
Record<"selectAttributeReference", FormsetChange<string[]>>,
|
||||||
Record<"selectAttributeFile", FormsetChange<File>>,
|
Record<"selectAttributeFile", FormsetChange<File>>,
|
||||||
|
Record<"reorderAttributeValue", FormsetChange<ReorderEvent>>,
|
||||||
Record<"addStock" | "deleteStock", (id: string) => void> {
|
Record<"addStock" | "deleteStock", (id: string) => void> {
|
||||||
changeMetadata: FormChange;
|
changeMetadata: FormChange;
|
||||||
}
|
}
|
||||||
|
@ -131,6 +132,11 @@ function useProductVariantCreateForm(
|
||||||
attributesWithNewFileValue.change,
|
attributesWithNewFileValue.change,
|
||||||
triggerChange
|
triggerChange
|
||||||
);
|
);
|
||||||
|
const handleAttributeValueReorder = createAttributeValueReorderHandler(
|
||||||
|
attributes.change,
|
||||||
|
attributes.data,
|
||||||
|
triggerChange
|
||||||
|
);
|
||||||
const handleStockAdd = (id: string) => {
|
const handleStockAdd = (id: string) => {
|
||||||
triggerChange();
|
triggerChange();
|
||||||
stocks.add({
|
stocks.add({
|
||||||
|
@ -183,6 +189,7 @@ function useProductVariantCreateForm(
|
||||||
changeMetadata,
|
changeMetadata,
|
||||||
changeStock: handleStockChange,
|
changeStock: handleStockChange,
|
||||||
deleteStock: handleStockDelete,
|
deleteStock: handleStockDelete,
|
||||||
|
reorderAttributeValue: handleAttributeValueReorder,
|
||||||
selectAttribute: handleAttributeChange,
|
selectAttribute: handleAttributeChange,
|
||||||
selectAttributeFile: handleAttributeFileChange,
|
selectAttributeFile: handleAttributeFileChange,
|
||||||
selectAttributeMultiple: handleAttributeMultiChange,
|
selectAttributeMultiple: handleAttributeMultiChange,
|
||||||
|
|
|
@ -217,6 +217,7 @@ const ProductVariantPage: React.FC<ProductVariantPageProps> = ({
|
||||||
onFileChange={handlers.selectAttributeFile}
|
onFileChange={handlers.selectAttributeFile}
|
||||||
onReferencesRemove={handlers.selectAttributeReference}
|
onReferencesRemove={handlers.selectAttributeReference}
|
||||||
onReferencesAddClick={onAssignReferencesClick}
|
onReferencesAddClick={onAssignReferencesClick}
|
||||||
|
onReferencesReorder={handlers.reorderAttributeValue}
|
||||||
/>
|
/>
|
||||||
<CardSpacer />
|
<CardSpacer />
|
||||||
<Attributes
|
<Attributes
|
||||||
|
@ -236,6 +237,7 @@ const ProductVariantPage: React.FC<ProductVariantPageProps> = ({
|
||||||
onFileChange={handlers.selectAttributeFile}
|
onFileChange={handlers.selectAttributeFile}
|
||||||
onReferencesRemove={handlers.selectAttributeReference}
|
onReferencesRemove={handlers.selectAttributeReference}
|
||||||
onReferencesAddClick={onAssignReferencesClick}
|
onReferencesAddClick={onAssignReferencesClick}
|
||||||
|
onReferencesReorder={handlers.reorderAttributeValue}
|
||||||
/>
|
/>
|
||||||
<CardSpacer />
|
<CardSpacer />
|
||||||
<ProductVariantImages
|
<ProductVariantImages
|
||||||
|
|
|
@ -1,4 +1,11 @@
|
||||||
import { getAttributesDisplayData } from "@saleor/attributes/utils/data";
|
import { getAttributesDisplayData } from "@saleor/attributes/utils/data";
|
||||||
|
import {
|
||||||
|
createAttributeChangeHandler,
|
||||||
|
createAttributeFileChangeHandler,
|
||||||
|
createAttributeMultiChangeHandler,
|
||||||
|
createAttributeReferenceChangeHandler,
|
||||||
|
createAttributeValueReorderHandler
|
||||||
|
} from "@saleor/attributes/utils/handlers";
|
||||||
import { ChannelPriceData, IChannelPriceArgs } from "@saleor/channels/utils";
|
import { ChannelPriceData, IChannelPriceArgs } from "@saleor/channels/utils";
|
||||||
import { AttributeInput } from "@saleor/components/Attributes";
|
import { AttributeInput } from "@saleor/components/Attributes";
|
||||||
import { MetadataFormData } from "@saleor/components/Metadata";
|
import { MetadataFormData } from "@saleor/components/Metadata";
|
||||||
|
@ -12,21 +19,14 @@ import {
|
||||||
getAttributeInputFromVariant,
|
getAttributeInputFromVariant,
|
||||||
getStockInputFromVariant
|
getStockInputFromVariant
|
||||||
} from "@saleor/products/utils/data";
|
} from "@saleor/products/utils/data";
|
||||||
import {
|
import { getChannelsInput } from "@saleor/products/utils/handlers";
|
||||||
createAttributeFileChangeHandler,
|
|
||||||
createAttributeReferenceChangeHandler,
|
|
||||||
getChannelsInput
|
|
||||||
} from "@saleor/products/utils/handlers";
|
|
||||||
import {
|
|
||||||
createAttributeChangeHandler,
|
|
||||||
createAttributeMultiChangeHandler
|
|
||||||
} from "@saleor/products/utils/handlers";
|
|
||||||
import {
|
import {
|
||||||
validateCostPrice,
|
validateCostPrice,
|
||||||
validatePrice
|
validatePrice
|
||||||
} from "@saleor/products/utils/validation";
|
} from "@saleor/products/utils/validation";
|
||||||
import { SearchPages_search_edges_node } from "@saleor/searches/types/SearchPages";
|
import { SearchPages_search_edges_node } from "@saleor/searches/types/SearchPages";
|
||||||
import { SearchWarehouses_search_edges_node } from "@saleor/searches/types/SearchWarehouses";
|
import { SearchWarehouses_search_edges_node } from "@saleor/searches/types/SearchWarehouses";
|
||||||
|
import { ReorderEvent } from "@saleor/types";
|
||||||
import { mapMetadataItemToInput } from "@saleor/utils/maps";
|
import { mapMetadataItemToInput } from "@saleor/utils/maps";
|
||||||
import getMetadata from "@saleor/utils/metadata/getMetadata";
|
import getMetadata from "@saleor/utils/metadata/getMetadata";
|
||||||
import useMetadataChangeTrigger from "@saleor/utils/metadata/useMetadataChangeTrigger";
|
import useMetadataChangeTrigger from "@saleor/utils/metadata/useMetadataChangeTrigger";
|
||||||
|
@ -72,6 +72,7 @@ export interface ProductVariantUpdateHandlers
|
||||||
>,
|
>,
|
||||||
Record<"selectAttributeReference", FormsetChange<string[]>>,
|
Record<"selectAttributeReference", FormsetChange<string[]>>,
|
||||||
Record<"selectAttributeFile", FormsetChange<File>>,
|
Record<"selectAttributeFile", FormsetChange<File>>,
|
||||||
|
Record<"reorderAttributeValue", FormsetChange<ReorderEvent>>,
|
||||||
Record<"addStock" | "deleteStock", (id: string) => void> {
|
Record<"addStock" | "deleteStock", (id: string) => void> {
|
||||||
changeMetadata: FormChange;
|
changeMetadata: FormChange;
|
||||||
}
|
}
|
||||||
|
@ -148,6 +149,11 @@ function useProductVariantUpdateForm(
|
||||||
attributesWithNewFileValue.change,
|
attributesWithNewFileValue.change,
|
||||||
triggerChange
|
triggerChange
|
||||||
);
|
);
|
||||||
|
const handleAttributeValueReorder = createAttributeValueReorderHandler(
|
||||||
|
attributes.change,
|
||||||
|
attributes.data,
|
||||||
|
triggerChange
|
||||||
|
);
|
||||||
const handleStockAdd = (id: string) => {
|
const handleStockAdd = (id: string) => {
|
||||||
triggerChange();
|
triggerChange();
|
||||||
stocks.add({
|
stocks.add({
|
||||||
|
@ -233,6 +239,7 @@ function useProductVariantUpdateForm(
|
||||||
changeMetadata,
|
changeMetadata,
|
||||||
changeStock: handleStockChange,
|
changeStock: handleStockChange,
|
||||||
deleteStock: handleStockDelete,
|
deleteStock: handleStockDelete,
|
||||||
|
reorderAttributeValue: handleAttributeValueReorder,
|
||||||
selectAttribute: handleAttributeChange,
|
selectAttribute: handleAttributeChange,
|
||||||
selectAttributeFile: handleAttributeFileChange,
|
selectAttributeFile: handleAttributeFileChange,
|
||||||
selectAttributeMultiple: handleAttributeMultiChange,
|
selectAttributeMultiple: handleAttributeMultiChange,
|
||||||
|
|
|
@ -1,142 +0,0 @@
|
||||||
import { AttributeInputData } from "@saleor/components/Attributes";
|
|
||||||
import { FormsetData } from "@saleor/hooks/useFormset";
|
|
||||||
import { AttributeInputTypeEnum } from "@saleor/types/globalTypes";
|
|
||||||
|
|
||||||
import { createAttributeMultiChangeHandler } from "./handlers";
|
|
||||||
|
|
||||||
const attributes: FormsetData<AttributeInputData, string[]> = [
|
|
||||||
{
|
|
||||||
data: {
|
|
||||||
inputType: AttributeInputTypeEnum.DROPDOWN,
|
|
||||||
isRequired: false,
|
|
||||||
values: [
|
|
||||||
{
|
|
||||||
__typename: "AttributeValue",
|
|
||||||
file: null,
|
|
||||||
id: "attrv-1",
|
|
||||||
name: "Attribute 1 Value 1",
|
|
||||||
reference: null,
|
|
||||||
slug: "attr-1-v-1"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
id: "attr-1",
|
|
||||||
label: "Attribute 1",
|
|
||||||
value: []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
data: {
|
|
||||||
inputType: AttributeInputTypeEnum.MULTISELECT,
|
|
||||||
isRequired: false,
|
|
||||||
values: [
|
|
||||||
{
|
|
||||||
__typename: "AttributeValue",
|
|
||||||
file: null,
|
|
||||||
id: "attrv-2",
|
|
||||||
name: "Attribute 2 Value 1",
|
|
||||||
reference: null,
|
|
||||||
slug: "attr-2-v-1"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
__typename: "AttributeValue",
|
|
||||||
file: null,
|
|
||||||
id: "attrv-3",
|
|
||||||
name: "Attribute 2 Value 2",
|
|
||||||
reference: null,
|
|
||||||
slug: "attr-2-v-2"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
__typename: "AttributeValue",
|
|
||||||
file: null,
|
|
||||||
id: "attrv-4",
|
|
||||||
name: "Attribute 2 Value 3",
|
|
||||||
reference: null,
|
|
||||||
slug: "attr-2-v-3"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
id: "attr-2",
|
|
||||||
label: "Attribute 2",
|
|
||||||
value: ["attr-2-v-3"]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
data: {
|
|
||||||
inputType: AttributeInputTypeEnum.FILE,
|
|
||||||
isRequired: false,
|
|
||||||
values: [
|
|
||||||
{
|
|
||||||
__typename: "AttributeValue",
|
|
||||||
file: {
|
|
||||||
__typename: "File",
|
|
||||||
contentType: "image/png",
|
|
||||||
url: "some-non-existing-url"
|
|
||||||
},
|
|
||||||
id: "attrv-5",
|
|
||||||
name: "File First Value",
|
|
||||||
reference: null,
|
|
||||||
slug: "file-first-value"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
id: "attr-3",
|
|
||||||
label: "File Attribute",
|
|
||||||
value: []
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
describe("Multiple select", () => {
|
|
||||||
it("is able to select value", () => {
|
|
||||||
const change = jest.fn();
|
|
||||||
const trigger = jest.fn();
|
|
||||||
const handler = createAttributeMultiChangeHandler(
|
|
||||||
change,
|
|
||||||
attributes,
|
|
||||||
trigger
|
|
||||||
);
|
|
||||||
|
|
||||||
handler("attr-2", "attr-2-v-1");
|
|
||||||
|
|
||||||
expect(change).toHaveBeenCalledTimes(1);
|
|
||||||
expect(change.mock.calls[0][0]).toBe("attr-2");
|
|
||||||
expect(change.mock.calls[0][1]).toHaveLength(2);
|
|
||||||
expect(change.mock.calls[0][1][0]).toBe("attr-2-v-3");
|
|
||||||
expect(change.mock.calls[0][1][1]).toBe("attr-2-v-1");
|
|
||||||
expect(trigger).toHaveBeenCalledTimes(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("is able to deselect value", () => {
|
|
||||||
const change = jest.fn();
|
|
||||||
const trigger = jest.fn();
|
|
||||||
const handler = createAttributeMultiChangeHandler(
|
|
||||||
change,
|
|
||||||
attributes,
|
|
||||||
trigger
|
|
||||||
);
|
|
||||||
|
|
||||||
handler("attr-2", "attr-2-v-3");
|
|
||||||
|
|
||||||
expect(change).toHaveBeenCalledTimes(1);
|
|
||||||
expect(change.mock.calls[0][0]).toBe("attr-2");
|
|
||||||
expect(change.mock.calls[0][1]).toHaveLength(0);
|
|
||||||
expect(trigger).toHaveBeenCalledTimes(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("is able to add custom value", () => {
|
|
||||||
const change = jest.fn();
|
|
||||||
const trigger = jest.fn();
|
|
||||||
const handler = createAttributeMultiChangeHandler(
|
|
||||||
change,
|
|
||||||
attributes,
|
|
||||||
trigger
|
|
||||||
);
|
|
||||||
|
|
||||||
handler("attr-2", "A Value");
|
|
||||||
|
|
||||||
expect(change).toHaveBeenCalledTimes(1);
|
|
||||||
expect(change.mock.calls[0][0]).toBe("attr-2");
|
|
||||||
expect(change.mock.calls[0][1]).toHaveLength(2);
|
|
||||||
expect(change.mock.calls[0][1][0]).toBe("attr-2-v-3");
|
|
||||||
expect(change.mock.calls[0][1][1]).toBe("A Value");
|
|
||||||
expect(trigger).toHaveBeenCalledTimes(1);
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -5,25 +5,10 @@ import {
|
||||||
} from "@saleor/channels/utils";
|
} from "@saleor/channels/utils";
|
||||||
import { AttributeInputData } from "@saleor/components/Attributes";
|
import { AttributeInputData } from "@saleor/components/Attributes";
|
||||||
import { FormChange } from "@saleor/hooks/useForm";
|
import { FormChange } from "@saleor/hooks/useForm";
|
||||||
import {
|
import { FormsetData } from "@saleor/hooks/useFormset";
|
||||||
FormsetAtomicData,
|
|
||||||
FormsetChange,
|
|
||||||
FormsetData
|
|
||||||
} from "@saleor/hooks/useFormset";
|
|
||||||
import { toggle } from "@saleor/utils/lists";
|
|
||||||
|
|
||||||
import { getAttributeInputFromProductType, ProductType } from "./data";
|
import { getAttributeInputFromProductType, ProductType } from "./data";
|
||||||
|
|
||||||
export function createAttributeChangeHandler(
|
|
||||||
changeAttributeData: FormsetChange<string[]>,
|
|
||||||
triggerChange: () => void
|
|
||||||
): FormsetChange<string> {
|
|
||||||
return (attributeId: string, value: string) => {
|
|
||||||
triggerChange();
|
|
||||||
changeAttributeData(attributeId, value === "" ? [] : [value]);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function createChannelsPriceChangeHandler(
|
export function createChannelsPriceChangeHandler(
|
||||||
channelListings: ChannelPriceData[],
|
channelListings: ChannelPriceData[],
|
||||||
updateChannels: (data: ChannelPriceData[]) => void,
|
updateChannels: (data: ChannelPriceData[]) => void,
|
||||||
|
@ -103,66 +88,6 @@ export function createVariantChannelsChangeHandler(
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createAttributeMultiChangeHandler(
|
|
||||||
changeAttributeData: FormsetChange<string[]>,
|
|
||||||
attributes: FormsetData<AttributeInputData, string[]>,
|
|
||||||
triggerChange: () => void
|
|
||||||
): FormsetChange<string> {
|
|
||||||
return (attributeId: string, value: string) => {
|
|
||||||
const attribute = attributes.find(
|
|
||||||
attribute => attribute.id === attributeId
|
|
||||||
);
|
|
||||||
|
|
||||||
const newAttributeValues = toggle(
|
|
||||||
value,
|
|
||||||
attribute.value,
|
|
||||||
(a, b) => a === b
|
|
||||||
);
|
|
||||||
|
|
||||||
triggerChange();
|
|
||||||
changeAttributeData(attributeId, newAttributeValues);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function createAttributeReferenceChangeHandler(
|
|
||||||
changeAttributeData: FormsetChange<string[]>,
|
|
||||||
triggerChange: () => void
|
|
||||||
): FormsetChange<string[]> {
|
|
||||||
return (attributeId: string, values: string[]) => {
|
|
||||||
changeAttributeData(attributeId, values);
|
|
||||||
triggerChange();
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function createAttributeFileChangeHandler(
|
|
||||||
changeAttributeData: FormsetChange<string[]>,
|
|
||||||
attributesWithNewFileValue: FormsetData<FormsetData<null, File>>,
|
|
||||||
addAttributeNewFileValue: (data: FormsetAtomicData<null, File>) => void,
|
|
||||||
changeAttributeNewFileValue: FormsetChange<File>,
|
|
||||||
triggerChange: () => void
|
|
||||||
): FormsetChange<File> {
|
|
||||||
return (attributeId: string, value: File) => {
|
|
||||||
triggerChange();
|
|
||||||
|
|
||||||
const newFileValueAssigned = attributesWithNewFileValue.find(
|
|
||||||
attribute => attribute.id === attributeId
|
|
||||||
);
|
|
||||||
|
|
||||||
if (newFileValueAssigned) {
|
|
||||||
changeAttributeNewFileValue(attributeId, value);
|
|
||||||
} else {
|
|
||||||
addAttributeNewFileValue({
|
|
||||||
data: null,
|
|
||||||
id: attributeId,
|
|
||||||
label: null,
|
|
||||||
value
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
changeAttributeData(attributeId, value ? [value.name] : []);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function createProductTypeSelectHandler(
|
export function createProductTypeSelectHandler(
|
||||||
setAttributes: (data: FormsetData<AttributeInputData>) => void,
|
setAttributes: (data: FormsetData<AttributeInputData>) => void,
|
||||||
setProductType: (productType: ProductType) => void,
|
setProductType: (productType: ProductType) => void,
|
||||||
|
|
|
@ -11234,6 +11234,389 @@ exports[`Storyshots Generics / Sortable chips field loading 1`] = `
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
exports[`Storyshots Generics / Sortable chips field with error 1`] = `
|
||||||
|
<div
|
||||||
|
style="padding:24px"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="MuiPaper-root-id MuiPaper-elevation0-id MuiCard-root-id MuiPaper-rounded-id"
|
||||||
|
style="margin:auto;overflow:visible;position:relative;width:400px"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="MuiCardContent-root-id"
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<div
|
||||||
|
class="SortableChip-root-id SortableChipsField-chip-id"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="SortableChip-content-id"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
aria-hidden="true"
|
||||||
|
class="MuiSvgIcon-root-id SortableHandle-drag-id SortableChip-sortableHandle-id"
|
||||||
|
data-test="button-drag-handle"
|
||||||
|
focusable="false"
|
||||||
|
role="presentation"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
clip-rule="evenodd"
|
||||||
|
d="M3.5 2C3.5 2.82843 2.82843 3.5 2 3.5C1.17157 3.5 0.5 2.82843 0.5 2C0.5 1.17157 1.17157 0.5 2 0.5C2.82843 0.5 3.5 1.17157 3.5 2ZM4 2C4 3.10457 3.10457 4 2 4C0.895431 4 0 3.10457 0 2C0 0.895431 0.895431 0 2 0C3.10457 0 4 0.895431 4 2ZM9.5 2C9.5 2.82843 8.82843 3.5 8 3.5C7.17157 3.5 6.5 2.82843 6.5 2C6.5 1.17157 7.17157 0.5 8 0.5C8.82843 0.5 9.5 1.17157 9.5 2ZM10 2C10 3.10457 9.10457 4 8 4C6.89543 4 6 3.10457 6 2C6 0.895431 6.89543 0 8 0C9.10457 0 10 0.895431 10 2ZM8 9.5C8.82843 9.5 9.5 8.82843 9.5 8C9.5 7.17157 8.82843 6.5 8 6.5C7.17157 6.5 6.5 7.17157 6.5 8C6.5 8.82843 7.17157 9.5 8 9.5ZM8 10C9.10457 10 10 9.10457 10 8C10 6.89543 9.10457 6 8 6C6.89543 6 6 6.89543 6 8C6 9.10457 6.89543 10 8 10ZM3.5 8C3.5 8.82843 2.82843 9.5 2 9.5C1.17157 9.5 0.5 8.82843 0.5 8C0.5 7.17157 1.17157 6.5 2 6.5C2.82843 6.5 3.5 7.17157 3.5 8ZM4 8C4 9.10457 3.10457 10 2 10C0.895431 10 0 9.10457 0 8C0 6.89543 0.895431 6 2 6C3.10457 6 4 6.89543 4 8ZM2 15.5C2.82843 15.5 3.5 14.8284 3.5 14C3.5 13.1716 2.82843 12.5 2 12.5C1.17157 12.5 0.5 13.1716 0.5 14C0.5 14.8284 1.17157 15.5 2 15.5ZM2 16C3.10457 16 4 15.1046 4 14C4 12.8954 3.10457 12 2 12C0.895431 12 0 12.8954 0 14C0 15.1046 0.895431 16 2 16ZM9.5 14C9.5 14.8284 8.82843 15.5 8 15.5C7.17157 15.5 6.5 14.8284 6.5 14C6.5 13.1716 7.17157 12.5 8 12.5C8.82843 12.5 9.5 13.1716 9.5 14ZM10 14C10 15.1046 9.10457 16 8 16C6.89543 16 6 15.1046 6 14C6 12.8954 6.89543 12 8 12C9.10457 12 10 12.8954 10 14Z"
|
||||||
|
fill="url(#paint0_linear)"
|
||||||
|
fill-rule="evenodd"
|
||||||
|
style="transform:translate(7px, 4px)"
|
||||||
|
/>
|
||||||
|
<defs>
|
||||||
|
<linearGradient
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
id="paint0_linear"
|
||||||
|
x1="0"
|
||||||
|
x2="16.0896"
|
||||||
|
y1="0"
|
||||||
|
y2="10.4478"
|
||||||
|
>
|
||||||
|
<stop
|
||||||
|
stop-color="#06847B"
|
||||||
|
/>
|
||||||
|
<stop
|
||||||
|
offset="1"
|
||||||
|
stop-color="#3EE7CD"
|
||||||
|
/>
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
<div
|
||||||
|
class="MuiTypography-root-id MuiTypography-body1-id"
|
||||||
|
data-test="chip-label"
|
||||||
|
>
|
||||||
|
Item 1
|
||||||
|
</div>
|
||||||
|
<svg
|
||||||
|
aria-hidden="true"
|
||||||
|
class="MuiSvgIcon-root-id SortableChip-closeIcon-id"
|
||||||
|
data-test="button-close"
|
||||||
|
focusable="false"
|
||||||
|
role="presentation"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="SortableChip-root-id SortableChipsField-chip-id"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="SortableChip-content-id"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
aria-hidden="true"
|
||||||
|
class="MuiSvgIcon-root-id SortableHandle-drag-id SortableChip-sortableHandle-id"
|
||||||
|
data-test="button-drag-handle"
|
||||||
|
focusable="false"
|
||||||
|
role="presentation"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
clip-rule="evenodd"
|
||||||
|
d="M3.5 2C3.5 2.82843 2.82843 3.5 2 3.5C1.17157 3.5 0.5 2.82843 0.5 2C0.5 1.17157 1.17157 0.5 2 0.5C2.82843 0.5 3.5 1.17157 3.5 2ZM4 2C4 3.10457 3.10457 4 2 4C0.895431 4 0 3.10457 0 2C0 0.895431 0.895431 0 2 0C3.10457 0 4 0.895431 4 2ZM9.5 2C9.5 2.82843 8.82843 3.5 8 3.5C7.17157 3.5 6.5 2.82843 6.5 2C6.5 1.17157 7.17157 0.5 8 0.5C8.82843 0.5 9.5 1.17157 9.5 2ZM10 2C10 3.10457 9.10457 4 8 4C6.89543 4 6 3.10457 6 2C6 0.895431 6.89543 0 8 0C9.10457 0 10 0.895431 10 2ZM8 9.5C8.82843 9.5 9.5 8.82843 9.5 8C9.5 7.17157 8.82843 6.5 8 6.5C7.17157 6.5 6.5 7.17157 6.5 8C6.5 8.82843 7.17157 9.5 8 9.5ZM8 10C9.10457 10 10 9.10457 10 8C10 6.89543 9.10457 6 8 6C6.89543 6 6 6.89543 6 8C6 9.10457 6.89543 10 8 10ZM3.5 8C3.5 8.82843 2.82843 9.5 2 9.5C1.17157 9.5 0.5 8.82843 0.5 8C0.5 7.17157 1.17157 6.5 2 6.5C2.82843 6.5 3.5 7.17157 3.5 8ZM4 8C4 9.10457 3.10457 10 2 10C0.895431 10 0 9.10457 0 8C0 6.89543 0.895431 6 2 6C3.10457 6 4 6.89543 4 8ZM2 15.5C2.82843 15.5 3.5 14.8284 3.5 14C3.5 13.1716 2.82843 12.5 2 12.5C1.17157 12.5 0.5 13.1716 0.5 14C0.5 14.8284 1.17157 15.5 2 15.5ZM2 16C3.10457 16 4 15.1046 4 14C4 12.8954 3.10457 12 2 12C0.895431 12 0 12.8954 0 14C0 15.1046 0.895431 16 2 16ZM9.5 14C9.5 14.8284 8.82843 15.5 8 15.5C7.17157 15.5 6.5 14.8284 6.5 14C6.5 13.1716 7.17157 12.5 8 12.5C8.82843 12.5 9.5 13.1716 9.5 14ZM10 14C10 15.1046 9.10457 16 8 16C6.89543 16 6 15.1046 6 14C6 12.8954 6.89543 12 8 12C9.10457 12 10 12.8954 10 14Z"
|
||||||
|
fill="url(#paint0_linear)"
|
||||||
|
fill-rule="evenodd"
|
||||||
|
style="transform:translate(7px, 4px)"
|
||||||
|
/>
|
||||||
|
<defs>
|
||||||
|
<linearGradient
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
id="paint0_linear"
|
||||||
|
x1="0"
|
||||||
|
x2="16.0896"
|
||||||
|
y1="0"
|
||||||
|
y2="10.4478"
|
||||||
|
>
|
||||||
|
<stop
|
||||||
|
stop-color="#06847B"
|
||||||
|
/>
|
||||||
|
<stop
|
||||||
|
offset="1"
|
||||||
|
stop-color="#3EE7CD"
|
||||||
|
/>
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
<div
|
||||||
|
class="MuiTypography-root-id MuiTypography-body1-id"
|
||||||
|
data-test="chip-label"
|
||||||
|
>
|
||||||
|
Item 2
|
||||||
|
</div>
|
||||||
|
<svg
|
||||||
|
aria-hidden="true"
|
||||||
|
class="MuiSvgIcon-root-id SortableChip-closeIcon-id"
|
||||||
|
data-test="button-close"
|
||||||
|
focusable="false"
|
||||||
|
role="presentation"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="SortableChip-root-id SortableChipsField-chip-id"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="SortableChip-content-id"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
aria-hidden="true"
|
||||||
|
class="MuiSvgIcon-root-id SortableHandle-drag-id SortableChip-sortableHandle-id"
|
||||||
|
data-test="button-drag-handle"
|
||||||
|
focusable="false"
|
||||||
|
role="presentation"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
clip-rule="evenodd"
|
||||||
|
d="M3.5 2C3.5 2.82843 2.82843 3.5 2 3.5C1.17157 3.5 0.5 2.82843 0.5 2C0.5 1.17157 1.17157 0.5 2 0.5C2.82843 0.5 3.5 1.17157 3.5 2ZM4 2C4 3.10457 3.10457 4 2 4C0.895431 4 0 3.10457 0 2C0 0.895431 0.895431 0 2 0C3.10457 0 4 0.895431 4 2ZM9.5 2C9.5 2.82843 8.82843 3.5 8 3.5C7.17157 3.5 6.5 2.82843 6.5 2C6.5 1.17157 7.17157 0.5 8 0.5C8.82843 0.5 9.5 1.17157 9.5 2ZM10 2C10 3.10457 9.10457 4 8 4C6.89543 4 6 3.10457 6 2C6 0.895431 6.89543 0 8 0C9.10457 0 10 0.895431 10 2ZM8 9.5C8.82843 9.5 9.5 8.82843 9.5 8C9.5 7.17157 8.82843 6.5 8 6.5C7.17157 6.5 6.5 7.17157 6.5 8C6.5 8.82843 7.17157 9.5 8 9.5ZM8 10C9.10457 10 10 9.10457 10 8C10 6.89543 9.10457 6 8 6C6.89543 6 6 6.89543 6 8C6 9.10457 6.89543 10 8 10ZM3.5 8C3.5 8.82843 2.82843 9.5 2 9.5C1.17157 9.5 0.5 8.82843 0.5 8C0.5 7.17157 1.17157 6.5 2 6.5C2.82843 6.5 3.5 7.17157 3.5 8ZM4 8C4 9.10457 3.10457 10 2 10C0.895431 10 0 9.10457 0 8C0 6.89543 0.895431 6 2 6C3.10457 6 4 6.89543 4 8ZM2 15.5C2.82843 15.5 3.5 14.8284 3.5 14C3.5 13.1716 2.82843 12.5 2 12.5C1.17157 12.5 0.5 13.1716 0.5 14C0.5 14.8284 1.17157 15.5 2 15.5ZM2 16C3.10457 16 4 15.1046 4 14C4 12.8954 3.10457 12 2 12C0.895431 12 0 12.8954 0 14C0 15.1046 0.895431 16 2 16ZM9.5 14C9.5 14.8284 8.82843 15.5 8 15.5C7.17157 15.5 6.5 14.8284 6.5 14C6.5 13.1716 7.17157 12.5 8 12.5C8.82843 12.5 9.5 13.1716 9.5 14ZM10 14C10 15.1046 9.10457 16 8 16C6.89543 16 6 15.1046 6 14C6 12.8954 6.89543 12 8 12C9.10457 12 10 12.8954 10 14Z"
|
||||||
|
fill="url(#paint0_linear)"
|
||||||
|
fill-rule="evenodd"
|
||||||
|
style="transform:translate(7px, 4px)"
|
||||||
|
/>
|
||||||
|
<defs>
|
||||||
|
<linearGradient
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
id="paint0_linear"
|
||||||
|
x1="0"
|
||||||
|
x2="16.0896"
|
||||||
|
y1="0"
|
||||||
|
y2="10.4478"
|
||||||
|
>
|
||||||
|
<stop
|
||||||
|
stop-color="#06847B"
|
||||||
|
/>
|
||||||
|
<stop
|
||||||
|
offset="1"
|
||||||
|
stop-color="#3EE7CD"
|
||||||
|
/>
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
<div
|
||||||
|
class="MuiTypography-root-id MuiTypography-body1-id"
|
||||||
|
data-test="chip-label"
|
||||||
|
>
|
||||||
|
Item 3
|
||||||
|
</div>
|
||||||
|
<svg
|
||||||
|
aria-hidden="true"
|
||||||
|
class="MuiSvgIcon-root-id SortableChip-closeIcon-id"
|
||||||
|
data-test="button-close"
|
||||||
|
focusable="false"
|
||||||
|
role="presentation"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="SortableChip-root-id SortableChipsField-chip-id"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="SortableChip-content-id"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
aria-hidden="true"
|
||||||
|
class="MuiSvgIcon-root-id SortableHandle-drag-id SortableChip-sortableHandle-id"
|
||||||
|
data-test="button-drag-handle"
|
||||||
|
focusable="false"
|
||||||
|
role="presentation"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
clip-rule="evenodd"
|
||||||
|
d="M3.5 2C3.5 2.82843 2.82843 3.5 2 3.5C1.17157 3.5 0.5 2.82843 0.5 2C0.5 1.17157 1.17157 0.5 2 0.5C2.82843 0.5 3.5 1.17157 3.5 2ZM4 2C4 3.10457 3.10457 4 2 4C0.895431 4 0 3.10457 0 2C0 0.895431 0.895431 0 2 0C3.10457 0 4 0.895431 4 2ZM9.5 2C9.5 2.82843 8.82843 3.5 8 3.5C7.17157 3.5 6.5 2.82843 6.5 2C6.5 1.17157 7.17157 0.5 8 0.5C8.82843 0.5 9.5 1.17157 9.5 2ZM10 2C10 3.10457 9.10457 4 8 4C6.89543 4 6 3.10457 6 2C6 0.895431 6.89543 0 8 0C9.10457 0 10 0.895431 10 2ZM8 9.5C8.82843 9.5 9.5 8.82843 9.5 8C9.5 7.17157 8.82843 6.5 8 6.5C7.17157 6.5 6.5 7.17157 6.5 8C6.5 8.82843 7.17157 9.5 8 9.5ZM8 10C9.10457 10 10 9.10457 10 8C10 6.89543 9.10457 6 8 6C6.89543 6 6 6.89543 6 8C6 9.10457 6.89543 10 8 10ZM3.5 8C3.5 8.82843 2.82843 9.5 2 9.5C1.17157 9.5 0.5 8.82843 0.5 8C0.5 7.17157 1.17157 6.5 2 6.5C2.82843 6.5 3.5 7.17157 3.5 8ZM4 8C4 9.10457 3.10457 10 2 10C0.895431 10 0 9.10457 0 8C0 6.89543 0.895431 6 2 6C3.10457 6 4 6.89543 4 8ZM2 15.5C2.82843 15.5 3.5 14.8284 3.5 14C3.5 13.1716 2.82843 12.5 2 12.5C1.17157 12.5 0.5 13.1716 0.5 14C0.5 14.8284 1.17157 15.5 2 15.5ZM2 16C3.10457 16 4 15.1046 4 14C4 12.8954 3.10457 12 2 12C0.895431 12 0 12.8954 0 14C0 15.1046 0.895431 16 2 16ZM9.5 14C9.5 14.8284 8.82843 15.5 8 15.5C7.17157 15.5 6.5 14.8284 6.5 14C6.5 13.1716 7.17157 12.5 8 12.5C8.82843 12.5 9.5 13.1716 9.5 14ZM10 14C10 15.1046 9.10457 16 8 16C6.89543 16 6 15.1046 6 14C6 12.8954 6.89543 12 8 12C9.10457 12 10 12.8954 10 14Z"
|
||||||
|
fill="url(#paint0_linear)"
|
||||||
|
fill-rule="evenodd"
|
||||||
|
style="transform:translate(7px, 4px)"
|
||||||
|
/>
|
||||||
|
<defs>
|
||||||
|
<linearGradient
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
id="paint0_linear"
|
||||||
|
x1="0"
|
||||||
|
x2="16.0896"
|
||||||
|
y1="0"
|
||||||
|
y2="10.4478"
|
||||||
|
>
|
||||||
|
<stop
|
||||||
|
stop-color="#06847B"
|
||||||
|
/>
|
||||||
|
<stop
|
||||||
|
offset="1"
|
||||||
|
stop-color="#3EE7CD"
|
||||||
|
/>
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
<div
|
||||||
|
class="MuiTypography-root-id MuiTypography-body1-id"
|
||||||
|
data-test="chip-label"
|
||||||
|
>
|
||||||
|
Item 4
|
||||||
|
</div>
|
||||||
|
<svg
|
||||||
|
aria-hidden="true"
|
||||||
|
class="MuiSvgIcon-root-id SortableChip-closeIcon-id"
|
||||||
|
data-test="button-close"
|
||||||
|
focusable="false"
|
||||||
|
role="presentation"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="SortableChip-root-id SortableChipsField-chip-id"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="SortableChip-content-id"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
aria-hidden="true"
|
||||||
|
class="MuiSvgIcon-root-id SortableHandle-drag-id SortableChip-sortableHandle-id"
|
||||||
|
data-test="button-drag-handle"
|
||||||
|
focusable="false"
|
||||||
|
role="presentation"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
clip-rule="evenodd"
|
||||||
|
d="M3.5 2C3.5 2.82843 2.82843 3.5 2 3.5C1.17157 3.5 0.5 2.82843 0.5 2C0.5 1.17157 1.17157 0.5 2 0.5C2.82843 0.5 3.5 1.17157 3.5 2ZM4 2C4 3.10457 3.10457 4 2 4C0.895431 4 0 3.10457 0 2C0 0.895431 0.895431 0 2 0C3.10457 0 4 0.895431 4 2ZM9.5 2C9.5 2.82843 8.82843 3.5 8 3.5C7.17157 3.5 6.5 2.82843 6.5 2C6.5 1.17157 7.17157 0.5 8 0.5C8.82843 0.5 9.5 1.17157 9.5 2ZM10 2C10 3.10457 9.10457 4 8 4C6.89543 4 6 3.10457 6 2C6 0.895431 6.89543 0 8 0C9.10457 0 10 0.895431 10 2ZM8 9.5C8.82843 9.5 9.5 8.82843 9.5 8C9.5 7.17157 8.82843 6.5 8 6.5C7.17157 6.5 6.5 7.17157 6.5 8C6.5 8.82843 7.17157 9.5 8 9.5ZM8 10C9.10457 10 10 9.10457 10 8C10 6.89543 9.10457 6 8 6C6.89543 6 6 6.89543 6 8C6 9.10457 6.89543 10 8 10ZM3.5 8C3.5 8.82843 2.82843 9.5 2 9.5C1.17157 9.5 0.5 8.82843 0.5 8C0.5 7.17157 1.17157 6.5 2 6.5C2.82843 6.5 3.5 7.17157 3.5 8ZM4 8C4 9.10457 3.10457 10 2 10C0.895431 10 0 9.10457 0 8C0 6.89543 0.895431 6 2 6C3.10457 6 4 6.89543 4 8ZM2 15.5C2.82843 15.5 3.5 14.8284 3.5 14C3.5 13.1716 2.82843 12.5 2 12.5C1.17157 12.5 0.5 13.1716 0.5 14C0.5 14.8284 1.17157 15.5 2 15.5ZM2 16C3.10457 16 4 15.1046 4 14C4 12.8954 3.10457 12 2 12C0.895431 12 0 12.8954 0 14C0 15.1046 0.895431 16 2 16ZM9.5 14C9.5 14.8284 8.82843 15.5 8 15.5C7.17157 15.5 6.5 14.8284 6.5 14C6.5 13.1716 7.17157 12.5 8 12.5C8.82843 12.5 9.5 13.1716 9.5 14ZM10 14C10 15.1046 9.10457 16 8 16C6.89543 16 6 15.1046 6 14C6 12.8954 6.89543 12 8 12C9.10457 12 10 12.8954 10 14Z"
|
||||||
|
fill="url(#paint0_linear)"
|
||||||
|
fill-rule="evenodd"
|
||||||
|
style="transform:translate(7px, 4px)"
|
||||||
|
/>
|
||||||
|
<defs>
|
||||||
|
<linearGradient
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
id="paint0_linear"
|
||||||
|
x1="0"
|
||||||
|
x2="16.0896"
|
||||||
|
y1="0"
|
||||||
|
y2="10.4478"
|
||||||
|
>
|
||||||
|
<stop
|
||||||
|
stop-color="#06847B"
|
||||||
|
/>
|
||||||
|
<stop
|
||||||
|
offset="1"
|
||||||
|
stop-color="#3EE7CD"
|
||||||
|
/>
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
<div
|
||||||
|
class="MuiTypography-root-id MuiTypography-body1-id"
|
||||||
|
data-test="chip-label"
|
||||||
|
>
|
||||||
|
Item 5
|
||||||
|
</div>
|
||||||
|
<svg
|
||||||
|
aria-hidden="true"
|
||||||
|
class="MuiSvgIcon-root-id SortableChip-closeIcon-id"
|
||||||
|
data-test="button-close"
|
||||||
|
focusable="false"
|
||||||
|
role="presentation"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="SortableChip-root-id SortableChipsField-chip-id"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="SortableChip-content-id"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
aria-hidden="true"
|
||||||
|
class="MuiSvgIcon-root-id SortableHandle-drag-id SortableChip-sortableHandle-id"
|
||||||
|
data-test="button-drag-handle"
|
||||||
|
focusable="false"
|
||||||
|
role="presentation"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
clip-rule="evenodd"
|
||||||
|
d="M3.5 2C3.5 2.82843 2.82843 3.5 2 3.5C1.17157 3.5 0.5 2.82843 0.5 2C0.5 1.17157 1.17157 0.5 2 0.5C2.82843 0.5 3.5 1.17157 3.5 2ZM4 2C4 3.10457 3.10457 4 2 4C0.895431 4 0 3.10457 0 2C0 0.895431 0.895431 0 2 0C3.10457 0 4 0.895431 4 2ZM9.5 2C9.5 2.82843 8.82843 3.5 8 3.5C7.17157 3.5 6.5 2.82843 6.5 2C6.5 1.17157 7.17157 0.5 8 0.5C8.82843 0.5 9.5 1.17157 9.5 2ZM10 2C10 3.10457 9.10457 4 8 4C6.89543 4 6 3.10457 6 2C6 0.895431 6.89543 0 8 0C9.10457 0 10 0.895431 10 2ZM8 9.5C8.82843 9.5 9.5 8.82843 9.5 8C9.5 7.17157 8.82843 6.5 8 6.5C7.17157 6.5 6.5 7.17157 6.5 8C6.5 8.82843 7.17157 9.5 8 9.5ZM8 10C9.10457 10 10 9.10457 10 8C10 6.89543 9.10457 6 8 6C6.89543 6 6 6.89543 6 8C6 9.10457 6.89543 10 8 10ZM3.5 8C3.5 8.82843 2.82843 9.5 2 9.5C1.17157 9.5 0.5 8.82843 0.5 8C0.5 7.17157 1.17157 6.5 2 6.5C2.82843 6.5 3.5 7.17157 3.5 8ZM4 8C4 9.10457 3.10457 10 2 10C0.895431 10 0 9.10457 0 8C0 6.89543 0.895431 6 2 6C3.10457 6 4 6.89543 4 8ZM2 15.5C2.82843 15.5 3.5 14.8284 3.5 14C3.5 13.1716 2.82843 12.5 2 12.5C1.17157 12.5 0.5 13.1716 0.5 14C0.5 14.8284 1.17157 15.5 2 15.5ZM2 16C3.10457 16 4 15.1046 4 14C4 12.8954 3.10457 12 2 12C0.895431 12 0 12.8954 0 14C0 15.1046 0.895431 16 2 16ZM9.5 14C9.5 14.8284 8.82843 15.5 8 15.5C7.17157 15.5 6.5 14.8284 6.5 14C6.5 13.1716 7.17157 12.5 8 12.5C8.82843 12.5 9.5 13.1716 9.5 14ZM10 14C10 15.1046 9.10457 16 8 16C6.89543 16 6 15.1046 6 14C6 12.8954 6.89543 12 8 12C9.10457 12 10 12.8954 10 14Z"
|
||||||
|
fill="url(#paint0_linear)"
|
||||||
|
fill-rule="evenodd"
|
||||||
|
style="transform:translate(7px, 4px)"
|
||||||
|
/>
|
||||||
|
<defs>
|
||||||
|
<linearGradient
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
id="paint0_linear"
|
||||||
|
x1="0"
|
||||||
|
x2="16.0896"
|
||||||
|
y1="0"
|
||||||
|
y2="10.4478"
|
||||||
|
>
|
||||||
|
<stop
|
||||||
|
stop-color="#06847B"
|
||||||
|
/>
|
||||||
|
<stop
|
||||||
|
offset="1"
|
||||||
|
stop-color="#3EE7CD"
|
||||||
|
/>
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
<div
|
||||||
|
class="MuiTypography-root-id MuiTypography-body1-id"
|
||||||
|
data-test="chip-label"
|
||||||
|
>
|
||||||
|
Item 6
|
||||||
|
</div>
|
||||||
|
<svg
|
||||||
|
aria-hidden="true"
|
||||||
|
class="MuiSvgIcon-root-id SortableChip-closeIcon-id"
|
||||||
|
data-test="button-close"
|
||||||
|
focusable="false"
|
||||||
|
role="presentation"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="MuiTypography-root-id SortableChipsField-errorText-id MuiTypography-caption-id"
|
||||||
|
>
|
||||||
|
Something went wrong
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
exports[`Storyshots Generics / Square Button default 1`] = `
|
exports[`Storyshots Generics / Square Button default 1`] = `
|
||||||
<div
|
<div
|
||||||
style="padding:24px"
|
style="padding:24px"
|
||||||
|
|
Loading…
Reference in a new issue