Numeric attributes (#1065)

* Update schema, types

* Add numeric unit control

* Improvements, tests

* Cleanup

* Add messages

* Small fixes

* Add test id's

* Improve useForm, logic

* Use short names

* Review corrections

* Small improvements
This commit is contained in:
Piotr Grundas 2021-04-29 10:58:03 +02:00 committed by GitHub
parent 074c0f7a6c
commit 2a21609eae
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
80 changed files with 1209 additions and 189 deletions

View file

@ -33,6 +33,7 @@ All notable, unreleased changes to this project will be documented in this file.
- Add multiline field plugins - #974 by @dominik-zeglen - Add multiline field plugins - #974 by @dominik-zeglen
- Handle limit reached error - #990 by @dominik-zeglen - Handle limit reached error - #990 by @dominik-zeglen
- Display Cloud limits - #1004 by @dominik-zeglen - Display Cloud limits - #1004 by @dominik-zeglen
- Introducing numeric attributes - #1065 by @piotrgrundas
- Add shipping method description - #1058 by @jwm0 - Add shipping method description - #1058 by @jwm0
- Fix voucher and sales sorting errors - #1063 by @orzechdev - Fix voucher and sales sorting errors - #1063 by @orzechdev
- Fix custom currency formatting - #1067 by @orzechdev - Fix custom currency formatting - #1067 by @orzechdev

View file

@ -869,6 +869,18 @@
"context": "dialog content", "context": "dialog content",
"string": "Are you sure you want to delete {attributeName}?" "string": "Are you sure you want to delete {attributeName}?"
}, },
"src_dot_attributes_dot_components_dot_AttributeDetails_dot_acreFt": {
"context": "acre-ft unit",
"string": "acre-ft"
},
"src_dot_attributes_dot_components_dot_AttributeDetails_dot_acreInch": {
"context": "acre-inch unit",
"string": "acre-inch"
},
"src_dot_attributes_dot_components_dot_AttributeDetails_dot_area": {
"context": "area units type",
"string": "Area"
},
"src_dot_attributes_dot_components_dot_AttributeDetails_dot_attributeLabel": { "src_dot_attributes_dot_components_dot_AttributeDetails_dot_attributeLabel": {
"context": "attribute's label", "context": "attribute's label",
"string": "Default Label" "string": "Default Label"
@ -881,6 +893,10 @@
"context": "attribute slug input field helper text", "context": "attribute slug input field helper text",
"string": "This is used internally. Make sure you dont use spaces" "string": "This is used internally. Make sure you dont use spaces"
}, },
"src_dot_attributes_dot_components_dot_AttributeDetails_dot_distance": {
"context": "distance units type",
"string": "Distance"
},
"src_dot_attributes_dot_components_dot_AttributeDetails_dot_dropdown": { "src_dot_attributes_dot_components_dot_AttributeDetails_dot_dropdown": {
"context": "product attribute type", "context": "product attribute type",
"string": "Dropdown" "string": "Dropdown"
@ -893,18 +909,34 @@
"context": "file attribute type", "context": "file attribute type",
"string": "File" "string": "File"
}, },
"src_dot_attributes_dot_components_dot_AttributeDetails_dot_imperial": {
"context": "imperial unit system",
"string": "Imperial"
},
"src_dot_attributes_dot_components_dot_AttributeDetails_dot_inputType": { "src_dot_attributes_dot_components_dot_AttributeDetails_dot_inputType": {
"context": "attribute's editor component", "context": "attribute's editor component",
"string": "Catalog Input type for Store Owner" "string": "Catalog Input type for Store Owner"
}, },
"src_dot_attributes_dot_components_dot_AttributeDetails_dot_metric": {
"context": "metric unit system",
"string": "Metric"
},
"src_dot_attributes_dot_components_dot_AttributeDetails_dot_multiselect": { "src_dot_attributes_dot_components_dot_AttributeDetails_dot_multiselect": {
"context": "product attribute type", "context": "product attribute type",
"string": "Multiple Select" "string": "Multiple Select"
}, },
"src_dot_attributes_dot_components_dot_AttributeDetails_dot_numeric": {
"context": "numeric attribute type",
"string": "Numeric"
},
"src_dot_attributes_dot_components_dot_AttributeDetails_dot_page": { "src_dot_attributes_dot_components_dot_AttributeDetails_dot_page": {
"context": "page attribute entity type", "context": "page attribute entity type",
"string": "Pages" "string": "Pages"
}, },
"src_dot_attributes_dot_components_dot_AttributeDetails_dot_pint": {
"context": "pint unit",
"string": "pint"
},
"src_dot_attributes_dot_components_dot_AttributeDetails_dot_product": { "src_dot_attributes_dot_components_dot_AttributeDetails_dot_product": {
"context": "product attribute entity type", "context": "product attribute entity type",
"string": "Products" "string": "Products"
@ -913,14 +945,38 @@
"context": "references attribute type", "context": "references attribute type",
"string": "References" "string": "References"
}, },
"src_dot_attributes_dot_components_dot_AttributeDetails_dot_selectUnit": {
"context": "check to require numeric attribute unit",
"string": "Select unit"
},
"src_dot_attributes_dot_components_dot_AttributeDetails_dot_text": { "src_dot_attributes_dot_components_dot_AttributeDetails_dot_text": {
"context": "text attribute type", "context": "text attribute type",
"string": "Text" "string": "Text"
}, },
"src_dot_attributes_dot_components_dot_AttributeDetails_dot_unit": {
"context": "numeric attribute unit",
"string": "Unit"
},
"src_dot_attributes_dot_components_dot_AttributeDetails_dot_unitOf": {
"context": "numeric attribute units of",
"string": "Units of"
},
"src_dot_attributes_dot_components_dot_AttributeDetails_dot_unitSystem": {
"context": "numeric attribute unit system",
"string": "System"
},
"src_dot_attributes_dot_components_dot_AttributeDetails_dot_valueRequired": { "src_dot_attributes_dot_components_dot_AttributeDetails_dot_valueRequired": {
"context": "check to require attribute to have value", "context": "check to require attribute to have value",
"string": "Value Required" "string": "Value Required"
}, },
"src_dot_attributes_dot_components_dot_AttributeDetails_dot_volume": {
"context": "volume units types",
"string": "Volume"
},
"src_dot_attributes_dot_components_dot_AttributeDetails_dot_weight": {
"context": "weight units type",
"string": "Weight"
},
"src_dot_attributes_dot_components_dot_AttributeListPage_dot_2417065806": { "src_dot_attributes_dot_components_dot_AttributeListPage_dot_2417065806": {
"context": "tab name", "context": "tab name",
"string": "All Attributes" "string": "All Attributes"

6
package-lock.json generated
View file

@ -2802,7 +2802,6 @@
"resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
"integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"is-extendable": "^0.1.0" "is-extendable": "^0.1.0"
} }
@ -2848,7 +2847,6 @@
"resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
"integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"kind-of": "^3.0.2" "kind-of": "^3.0.2"
} }
@ -2858,7 +2856,6 @@
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
"integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"is-buffer": "^1.1.5" "is-buffer": "^1.1.5"
} }
@ -27839,7 +27836,6 @@
"resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
"integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"is-extendable": "^0.1.0" "is-extendable": "^0.1.0"
} }
@ -27885,7 +27881,6 @@
"resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
"integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"kind-of": "^3.0.2" "kind-of": "^3.0.2"
} }
@ -27895,7 +27890,6 @@
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
"integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"is-buffer": "^1.1.5" "is-buffer": "^1.1.5"
} }

View file

@ -382,6 +382,15 @@ type AppUpdate {
app: App app: App
} }
enum AreaUnitsEnum {
SQ_CM
SQ_M
SQ_KM
SQ_FT
SQ_YD
SQ_INCH
}
type AssignNavigation { type AssignNavigation {
menu: Menu menu: Menu
menuErrors: [MenuError!]! @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") menuErrors: [MenuError!]! @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.")
@ -399,6 +408,7 @@ type Attribute implements Node & ObjectWithMetadata {
name: String name: String
slug: String slug: String
type: AttributeTypeEnum type: AttributeTypeEnum
unit: MeasurementUnitsEnum
values: [AttributeValue] values: [AttributeValue]
valueRequired: Boolean! valueRequired: Boolean!
visibleInStorefront: Boolean! visibleInStorefront: Boolean!
@ -438,6 +448,7 @@ input AttributeCreateInput {
name: String! name: String!
slug: String slug: String
type: AttributeTypeEnum! type: AttributeTypeEnum!
unit: MeasurementUnitsEnum
values: [AttributeValueCreateInput] values: [AttributeValueCreateInput]
valueRequired: Boolean valueRequired: Boolean
isVariantOnly: Boolean isVariantOnly: Boolean
@ -493,6 +504,7 @@ input AttributeFilterInput {
input AttributeInput { input AttributeInput {
slug: String! slug: String!
values: [String] values: [String]
valuesRange: IntRangeInput
} }
enum AttributeInputTypeEnum { enum AttributeInputTypeEnum {
@ -500,6 +512,7 @@ enum AttributeInputTypeEnum {
MULTISELECT MULTISELECT
FILE FILE
REFERENCE REFERENCE
NUMERIC
RICH_TEXT RICH_TEXT
} }
@ -559,6 +572,7 @@ type AttributeUpdate {
input AttributeUpdateInput { input AttributeUpdateInput {
name: String name: String
slug: String slug: String
unit: MeasurementUnitsEnum
removeValues: [ID] removeValues: [ID]
addValues: [AttributeValueCreateInput] addValues: [AttributeValueCreateInput]
valueRequired: Boolean valueRequired: Boolean
@ -1781,6 +1795,15 @@ enum DiscountValueTypeEnum {
PERCENTAGE PERCENTAGE
} }
enum DistanceUnitsEnum {
CM
M
KM
FT
YD
INCH
}
type Domain { type Domain {
host: String! host: String!
sslEnabled: Boolean! sslEnabled: Boolean!
@ -2367,6 +2390,39 @@ type Margin {
stop: Int stop: Int
} }
enum MeasurementUnitsEnum {
CM
M
KM
FT
YD
INCH
SQ_CM
SQ_M
SQ_KM
SQ_FT
SQ_YD
SQ_INCH
CUBIC_MILLIMETER
CUBIC_CENTIMETER
CUBIC_DECIMETER
CUBIC_METER
LITER
CUBIC_FOOT
CUBIC_INCH
CUBIC_YARD
QT
PINT
FL_OZ
ACRE_IN
ACRE_FT
G
LB
OZ
KG
TONNE
}
type Menu implements Node & ObjectWithMetadata { type Menu implements Node & ObjectWithMetadata {
id: ID! id: ID!
name: String! name: String!
@ -5637,6 +5693,22 @@ type VerifyToken {
errors: [AccountError!]! errors: [AccountError!]!
} }
enum VolumeUnitsEnum {
CUBIC_MILLIMETER
CUBIC_CENTIMETER
CUBIC_DECIMETER
CUBIC_METER
LITER
CUBIC_FOOT
CUBIC_INCH
CUBIC_YARD
QT
PINT
FL_OZ
ACRE_IN
ACRE_FT
}
type Voucher implements Node { type Voucher implements Node {
id: ID! id: ID!
name: String name: String
@ -6043,10 +6115,11 @@ type Weight {
scalar WeightScalar scalar WeightScalar
enum WeightUnitsEnum { enum WeightUnitsEnum {
KG G
LB LB
OZ OZ
G KG
TONNE
} }
scalar _Any scalar _Any

View file

@ -1,11 +1,13 @@
import Card from "@material-ui/core/Card"; import Card from "@material-ui/core/Card";
import CardContent from "@material-ui/core/CardContent"; import CardContent from "@material-ui/core/CardContent";
import TextField from "@material-ui/core/TextField"; import TextField from "@material-ui/core/TextField";
import { NumericUnits } from "@saleor/attributes/components/AttributeDetails/NumericUnits";
import CardTitle from "@saleor/components/CardTitle"; import CardTitle from "@saleor/components/CardTitle";
import ControlledCheckbox from "@saleor/components/ControlledCheckbox"; import ControlledCheckbox from "@saleor/components/ControlledCheckbox";
import FormSpacer from "@saleor/components/FormSpacer"; import FormSpacer from "@saleor/components/FormSpacer";
import SingleSelectField from "@saleor/components/SingleSelectField"; import SingleSelectField from "@saleor/components/SingleSelectField";
import { AttributeErrorFragment } from "@saleor/fragments/types/AttributeErrorFragment"; import { AttributeErrorFragment } from "@saleor/fragments/types/AttributeErrorFragment";
import { UseFormResult } from "@saleor/hooks/useForm";
import { commonMessages } from "@saleor/intl"; import { commonMessages } from "@saleor/intl";
import { makeStyles } from "@saleor/theme"; import { makeStyles } from "@saleor/theme";
import { import {
@ -20,56 +22,7 @@ import slugify from "slugify";
import { getAttributeSlugErrorMessage } from "../../errors"; import { getAttributeSlugErrorMessage } from "../../errors";
import { AttributePageFormData } from "../AttributePage"; import { AttributePageFormData } from "../AttributePage";
import { inputTypeMessages, messages } from "./messages";
const messages = defineMessages({
attributeLabel: {
defaultMessage: "Default Label",
description: "attribute's label"
},
attributeSlug: {
defaultMessage: "Attribute Code",
description: "attribute's slug short code label"
},
attributeSlugHelperText: {
defaultMessage: "This is used internally. Make sure you dont use spaces",
description: "attribute slug input field helper text"
},
entityType: {
defaultMessage: "Entity",
description: "attribute's editor component entity"
},
inputType: {
defaultMessage: "Catalog Input type for Store Owner",
description: "attribute's editor component"
},
valueRequired: {
defaultMessage: "Value Required",
description: "check to require attribute to have value"
}
});
const inputTypeMessages = defineMessages({
dropdown: {
defaultMessage: "Dropdown",
description: "product attribute type"
},
file: {
defaultMessage: "File",
description: "file attribute type"
},
multiselect: {
defaultMessage: "Multiple Select",
description: "product attribute type"
},
references: {
defaultMessage: "References",
description: "references attribute type"
},
text: {
defaultMessage: "Text",
description: "text attribute type"
}
});
const entityTypeMessages = defineMessages({ const entityTypeMessages = defineMessages({
page: { page: {
@ -96,16 +49,29 @@ const useStyles = makeStyles(
{ name: "AttributeDetails" } { name: "AttributeDetails" }
); );
export interface AttributeDetailsProps { export interface AttributeDetailsProps
extends Pick<
UseFormResult<AttributePageFormData>,
"set" | "setError" | "data" | "clearErrors" | "errors"
> {
canChangeType: boolean; canChangeType: boolean;
data: AttributePageFormData;
disabled: boolean; disabled: boolean;
errors: AttributeErrorFragment[]; apiErrors: AttributeErrorFragment[];
onChange: (event: React.ChangeEvent<any>) => void; onChange: (event: React.ChangeEvent<any>) => void;
} }
const AttributeDetails: React.FC<AttributeDetailsProps> = props => { const AttributeDetails: React.FC<AttributeDetailsProps> = props => {
const { canChangeType, data, disabled, errors, onChange } = props; const {
canChangeType,
errors,
clearErrors,
setError,
data,
disabled,
apiErrors,
onChange,
set
} = props;
const classes = useStyles(props); const classes = useStyles(props);
const intl = useIntl(); const intl = useIntl();
const inputTypeChoices = [ const inputTypeChoices = [
@ -128,6 +94,10 @@ const AttributeDetails: React.FC<AttributeDetailsProps> = props => {
{ {
label: intl.formatMessage(inputTypeMessages.text), label: intl.formatMessage(inputTypeMessages.text),
value: AttributeInputTypeEnum.RICH_TEXT value: AttributeInputTypeEnum.RICH_TEXT
},
{
label: intl.formatMessage(inputTypeMessages.numeric),
value: AttributeInputTypeEnum.NUMERIC
} }
]; ];
const entityTypeChoices = [ const entityTypeChoices = [
@ -141,9 +111,9 @@ const AttributeDetails: React.FC<AttributeDetailsProps> = props => {
} }
]; ];
const formErrors = getFormErrors( const formApiErrors = getFormErrors(
["name", "slug", "inputType", "entityType"], ["name", "slug", "inputType", "entityType", "unit"],
errors apiErrors
); );
return ( return (
@ -154,24 +124,24 @@ const AttributeDetails: React.FC<AttributeDetailsProps> = props => {
<CardContent> <CardContent>
<TextField <TextField
disabled={disabled} disabled={disabled}
error={!!formErrors.name} error={!!formApiErrors.name}
label={intl.formatMessage(messages.attributeLabel)} label={intl.formatMessage(messages.attributeLabel)}
name={"name" as keyof AttributePageFormData} name={"name" as keyof AttributePageFormData}
fullWidth fullWidth
helperText={getAttributeErrorMessage(formErrors.name, intl)} helperText={getAttributeErrorMessage(formApiErrors.name, intl)}
value={data.name} value={data.name}
onChange={onChange} onChange={onChange}
/> />
<FormSpacer /> <FormSpacer />
<TextField <TextField
disabled={disabled} disabled={disabled}
error={!!formErrors.slug} error={!!formApiErrors.slug}
label={intl.formatMessage(messages.attributeSlug)} label={intl.formatMessage(messages.attributeSlug)}
name={"slug" as keyof AttributePageFormData} name={"slug" as keyof AttributePageFormData}
placeholder={slugify(data.name).toLowerCase()} placeholder={slugify(data.name).toLowerCase()}
fullWidth fullWidth
helperText={ helperText={
getAttributeSlugErrorMessage(formErrors.slug, intl) || getAttributeSlugErrorMessage(formApiErrors.slug, intl) ||
intl.formatMessage(messages.attributeSlugHelperText) intl.formatMessage(messages.attributeSlugHelperText)
} }
value={data.slug} value={data.slug}
@ -182,8 +152,8 @@ const AttributeDetails: React.FC<AttributeDetailsProps> = props => {
<SingleSelectField <SingleSelectField
choices={inputTypeChoices} choices={inputTypeChoices}
disabled={disabled || !canChangeType} disabled={disabled || !canChangeType}
error={!!formErrors.inputType} error={!!formApiErrors.inputType}
hint={getAttributeErrorMessage(formErrors.inputType, intl)} hint={getAttributeErrorMessage(formApiErrors.inputType, intl)}
label={intl.formatMessage(messages.inputType)} label={intl.formatMessage(messages.inputType)}
name="inputType" name="inputType"
onChange={onChange} onChange={onChange}
@ -193,8 +163,8 @@ const AttributeDetails: React.FC<AttributeDetailsProps> = props => {
<SingleSelectField <SingleSelectField
choices={entityTypeChoices} choices={entityTypeChoices}
disabled={disabled || !canChangeType} disabled={disabled || !canChangeType}
error={!!formErrors.entityType} error={!!formApiErrors.entityType}
hint={getAttributeErrorMessage(formErrors.entityType, intl)} hint={getAttributeErrorMessage(formApiErrors.entityType, intl)}
label={intl.formatMessage(messages.entityType)} label={intl.formatMessage(messages.entityType)}
name="entityType" name="entityType"
onChange={onChange} onChange={onChange}
@ -210,6 +180,16 @@ const AttributeDetails: React.FC<AttributeDetailsProps> = props => {
onChange={onChange} onChange={onChange}
disabled={disabled} disabled={disabled}
/> />
{data.inputType === AttributeInputTypeEnum.NUMERIC && (
<NumericUnits
data={data}
errors={errors}
disabled={disabled}
clearErrors={clearErrors}
setError={setError}
set={set}
/>
)}
</CardContent> </CardContent>
</Card> </Card>
); );

View file

@ -0,0 +1,189 @@
import { AttributePageFormData } from "@saleor/attributes/components/AttributePage";
import ControlledCheckbox from "@saleor/components/ControlledCheckbox";
import SingleSelectField from "@saleor/components/SingleSelectField";
import { UseFormResult } from "@saleor/hooks/useForm";
import { commonMessages } from "@saleor/intl";
import { makeStyles } from "@saleor/theme";
import { MeasurementUnitsEnum } from "@saleor/types/globalTypes";
import React, { useEffect, useMemo, useState } from "react";
import { useIntl } from "react-intl";
import * as M from "./messages";
import {
getUnitChoices,
unitMapping,
UnitSystem,
unitSystemChoices,
UnitType,
unitTypeChoices
} from "./utils";
const useStyles = makeStyles(
theme => ({
unitsRow: {
columnGap: theme.spacing(2),
display: "flex",
[theme.breakpoints.down("sm")]: {
flexFlow: "wrap",
rowGap: theme.spacing(3)
}
},
hr: {
border: "none",
borderTop: `1px solid ${theme.palette.divider}`,
height: 0,
margin: "0.5rem 0",
width: "100%"
}
}),
{ name: "NumericUnits" }
);
interface UnitData {
unit?: MeasurementUnitsEnum;
system?: UnitSystem;
type?: UnitType;
}
interface NumericUnitsProps
extends Pick<
UseFormResult<AttributePageFormData>,
"set" | "setError" | "data" | "errors" | "clearErrors"
> {
disabled: boolean;
}
export const NumericUnits: React.FC<NumericUnitsProps> = ({
data,
disabled,
errors,
set,
setError,
clearErrors
}) => {
const { formatMessage } = useIntl();
const classes = useStyles();
const [unitData, setUnitData] = useState<UnitData>({
unit: data.unit ?? null
});
const { unit, system, type } = unitData;
const errorProps = {
error: !!errors.unit,
hint: formatMessage(commonMessages.requiredField)
};
const [typeChoices, systemChoices, unitChoices] = useMemo(
() => [
unitTypeChoices.map(choice => ({
...choice,
label: formatMessage(choice.label)
})),
unitSystemChoices.map(choice => ({
...choice,
label: formatMessage(choice.label)
})),
getUnitChoices(formatMessage)
],
[]
);
useEffect(() => set({ unit }), [unit]);
useEffect(() => {
if (data.unit) {
const selectInitialUnitData = () => {
const initialData: UnitData = { unit: data.unit };
Object.entries(unitChoices).some(([system, types]) => {
const systemMatch = Object.entries(types).some(([type, units]) => {
const unitMatch = units.some(({ value }) => value === data.unit);
if (unitMatch) {
initialData.type = type as UnitType;
}
return unitMatch;
});
if (systemMatch) {
initialData.system = system as UnitSystem;
}
return systemMatch;
});
return initialData;
};
setUnitData(selectInitialUnitData());
}
}, []);
useEffect(() => {
if (unit === undefined && !errors.unit) {
setError("unit", formatMessage(commonMessages.requiredField));
}
if (errors.unit && (unit || unit === null)) {
clearErrors("unit");
}
}, [unitData, errors]);
return (
<div>
<div className={classes.hr} />
<ControlledCheckbox
data-test="numeric-with-unit"
name="selectUnit"
label={formatMessage(M.messages.selectUnit)}
checked={data.unit !== null}
onChange={({ target }) =>
setUnitData({ unit: target.value ? undefined : null })
}
disabled={disabled}
/>
{data.unit !== null && (
<div className={classes.unitsRow}>
<SingleSelectField
{...(!system && errorProps)}
testId="unit-system"
label={formatMessage(M.messages.unitSystem)}
choices={systemChoices}
onChange={({ target }: React.ChangeEvent<HTMLSelectElement>) =>
setUnitData({ system: target.value as UnitSystem })
}
value={system}
disabled={disabled}
/>
<SingleSelectField
{...(system && !type && errorProps)}
testId="unit-of"
label={formatMessage(M.messages.unitOf)}
choices={typeChoices}
onChange={({ target }: React.ChangeEvent<HTMLSelectElement>) =>
setUnitData(({ system }) => ({
system,
type: target.value as UnitType
}))
}
disabled={!system || disabled}
value={type}
/>
<SingleSelectField
{...(type && !unit && errorProps)}
testId="unit"
label={formatMessage(M.messages.unit)}
choices={type ? unitChoices[system][type] : []}
onChange={({ target }: React.ChangeEvent<HTMLSelectElement>) =>
setUnitData(data => ({
...data,
unit: target.value as MeasurementUnitsEnum
}))
}
disabled={!type || disabled}
value={
type && unitMapping[system][type].includes(unit)
? unit
: undefined
}
/>
</div>
)}
</div>
);
};

View file

@ -0,0 +1,142 @@
import React from "react";
import { defineMessages } from "react-intl";
export const messages = defineMessages({
attributeLabel: {
defaultMessage: "Default Label",
description: "attribute's label"
},
attributeSlug: {
defaultMessage: "Attribute Code",
description: "attribute's slug short code label"
},
attributeSlugHelperText: {
defaultMessage: "This is used internally. Make sure you dont use spaces",
description: "attribute slug input field helper text"
},
entityType: {
defaultMessage: "Entity",
description: "attribute's editor component entity"
},
inputType: {
defaultMessage: "Catalog Input type for Store Owner",
description: "attribute's editor component"
},
valueRequired: {
defaultMessage: "Value Required",
description: "check to require attribute to have value"
},
selectUnit: {
defaultMessage: "Select unit",
description: "check to require numeric attribute unit"
},
unitSystem: {
defaultMessage: "System",
description: "numeric attribute unit system"
},
unitOf: {
defaultMessage: "Units of",
description: "numeric attribute units of"
},
unit: {
defaultMessage: "Unit",
description: "numeric attribute unit"
}
});
export const inputTypeMessages = defineMessages({
dropdown: {
defaultMessage: "Dropdown",
description: "product attribute type"
},
file: {
defaultMessage: "File",
description: "file attribute type"
},
multiselect: {
defaultMessage: "Multiple Select",
description: "product attribute type"
},
references: {
defaultMessage: "References",
description: "references attribute type"
},
text: {
defaultMessage: "Text",
description: "text attribute type"
},
numeric: {
defaultMessage: "Numeric",
description: "numeric attribute type"
}
});
export const unitSystemMessages = defineMessages({
metric: {
defaultMessage: "Metric",
description: "metric unit system"
},
imperial: {
defaultMessage: "Imperial",
description: "imperial unit system"
}
});
export const unitTypeMessages = defineMessages({
volume: {
defaultMessage: "Volume",
description: "volume units types"
},
distance: {
defaultMessage: "Distance",
description: "distance units type"
},
weight: {
defaultMessage: "Weight",
description: "weight units type"
},
area: {
defaultMessage: "Area",
description: "area units type"
}
});
export const unitMessages = defineMessages({
pint: { defaultMessage: "pint", description: "pint unit" },
acreInch: { defaultMessage: "acre-inch", description: "acre-inch unit" },
acreFt: { defaultMessage: "acre-ft", description: "acre-ft unit" }
});
export const units = {
cubicCentimeter: <>cm&sup3;</>,
cubicDecimeter: <>dm&sup3;</>,
cubicMeter: <>m&sup3;</>,
liter: "l",
centimeter: "cm",
meter: "m",
kilometer: "km",
gram: "g",
kilogram: "kg",
tonne: "t",
squareCentimeter: <>cm&sup2;</>,
squareMeter: <>m&sup2;</>,
squareKilometer: <>km&sup2;</>,
cubicFoot: <>ft&sup3;</>,
cubicInch: <>in&sup3;</>,
cubicYard: <>yd&sup3;</>,
qt: "qt",
flOz: "fl. oz",
pint: unitMessages.pint,
acreInch: unitMessages.acreInch,
acreFt: unitMessages.acreFt,
ft: "ft",
yd: "yd",
inch: "in",
oz: "oz",
lbs: "lbs",
squareFt: <>ft&sup2;</>,
squareYd: <>yd&sup2;</>,
squareInch: <>in&sup2;</>
};

View file

@ -0,0 +1,166 @@
import { Choice } from "@saleor/components/SingleSelectField";
import { MeasurementUnitsEnum } from "@saleor/types/globalTypes";
import React from "react";
import { IntlShape, MessageDescriptor } from "react-intl";
import * as M from "./messages";
export type UnitSystem = "imperial" | "metric";
export type UnitType = "volume" | "weight" | "area" | "distance";
const UNIT_MESSAGES_MAPPING = {
[MeasurementUnitsEnum.CUBIC_FOOT]: M.units.cubicFoot,
[MeasurementUnitsEnum.CUBIC_INCH]: M.units.cubicInch,
[MeasurementUnitsEnum.CUBIC_YARD]: M.units.cubicYard,
[MeasurementUnitsEnum.QT]: M.units.qt,
[MeasurementUnitsEnum.FL_OZ]: M.units.flOz,
[MeasurementUnitsEnum.PINT]: M.units.pint,
[MeasurementUnitsEnum.ACRE_IN]: M.units.acreInch,
[MeasurementUnitsEnum.ACRE_FT]: M.units.acreFt,
[MeasurementUnitsEnum.FT]: M.units.ft,
[MeasurementUnitsEnum.YD]: M.units.yd,
[MeasurementUnitsEnum.INCH]: M.units.inch,
[MeasurementUnitsEnum.LB]: M.units.lbs,
[MeasurementUnitsEnum.OZ]: M.units.oz,
[MeasurementUnitsEnum.SQ_FT]: M.units.squareFt,
[MeasurementUnitsEnum.SQ_YD]: M.units.squareYd,
[MeasurementUnitsEnum.SQ_INCH]: M.units.squareInch,
[MeasurementUnitsEnum.CUBIC_CENTIMETER]: M.units.cubicCentimeter,
[MeasurementUnitsEnum.CUBIC_DECIMETER]: M.units.cubicDecimeter,
[MeasurementUnitsEnum.CUBIC_METER]: M.units.cubicMeter,
[MeasurementUnitsEnum.LITER]: M.units.liter,
[MeasurementUnitsEnum.CM]: M.units.centimeter,
[MeasurementUnitsEnum.M]: M.units.meter,
[MeasurementUnitsEnum.KM]: M.units.kilometer,
[MeasurementUnitsEnum.G]: M.units.gram,
[MeasurementUnitsEnum.KG]: M.units.kilogram,
[MeasurementUnitsEnum.TONNE]: M.units.tonne,
[MeasurementUnitsEnum.SQ_CM]: M.units.squareCentimeter,
[MeasurementUnitsEnum.SQ_M]: M.units.squareMeter,
[MeasurementUnitsEnum.SQ_KM]: M.units.squareKilometer
};
export const getMeasurementUnitMessage = (
unit: MeasurementUnitsEnum,
formatMessage: IntlShape["formatMessage"]
): MessageDescriptor | React.ReactNode => {
const message = UNIT_MESSAGES_MAPPING[unit];
return typeof message === "string" || React.isValidElement(message)
? message
: formatMessage(message);
};
export const unitSystemChoices: Array<Choice<UnitSystem, MessageDescriptor>> = [
{
label: M.unitSystemMessages.metric,
value: "metric"
},
{
label: M.unitSystemMessages.imperial,
value: "imperial"
}
];
export const unitTypeChoices: Array<Choice<UnitType, MessageDescriptor>> = [
{
label: M.unitTypeMessages.volume,
value: "volume"
},
{
label: M.unitTypeMessages.distance,
value: "distance"
},
{
label: M.unitTypeMessages.weight,
value: "weight"
},
{
label: M.unitTypeMessages.area,
value: "area"
}
];
export const unitMapping = {
imperial: {
volume: [
MeasurementUnitsEnum.CUBIC_FOOT,
MeasurementUnitsEnum.CUBIC_INCH,
MeasurementUnitsEnum.CUBIC_YARD,
MeasurementUnitsEnum.QT,
MeasurementUnitsEnum.FL_OZ,
MeasurementUnitsEnum.PINT,
MeasurementUnitsEnum.ACRE_IN,
MeasurementUnitsEnum.ACRE_FT
],
distance: [
MeasurementUnitsEnum.FT,
MeasurementUnitsEnum.YD,
MeasurementUnitsEnum.INCH
],
weight: [MeasurementUnitsEnum.LB, MeasurementUnitsEnum.OZ],
area: [
MeasurementUnitsEnum.SQ_FT,
MeasurementUnitsEnum.SQ_YD,
MeasurementUnitsEnum.SQ_INCH
]
},
metric: {
volume: [
MeasurementUnitsEnum.CUBIC_CENTIMETER,
MeasurementUnitsEnum.CUBIC_DECIMETER,
MeasurementUnitsEnum.CUBIC_METER,
MeasurementUnitsEnum.LITER
],
distance: [
MeasurementUnitsEnum.CM,
MeasurementUnitsEnum.M,
MeasurementUnitsEnum.KM
],
weight: [
MeasurementUnitsEnum.G,
MeasurementUnitsEnum.KG,
MeasurementUnitsEnum.TONNE
],
area: [
MeasurementUnitsEnum.SQ_CM,
MeasurementUnitsEnum.SQ_M,
MeasurementUnitsEnum.SQ_KM
]
}
};
const extractTypeChoices = (
typeEnums: {
[key in UnitType]: MeasurementUnitsEnum[];
},
formatMessage: IntlShape["formatMessage"]
) =>
Object.entries(typeEnums).reduce(
(acc, [type, units]) => ({
...acc,
[type]: units.map(unit => ({
value: unit,
label: getMeasurementUnitMessage(unit, formatMessage)
}))
}),
{}
);
export const getUnitChoices = (
formatMessage: IntlShape["formatMessage"]
): {
[key in UnitSystem]: {
[key in UnitType]: Array<Choice<MeasurementUnitsEnum>>;
};
} =>
Object.entries(unitMapping).reduce(
(acc, [system, typeEnums]) => ({
...acc,
[system]: extractTypeChoices(typeEnums, formatMessage)
}),
{}
) as {
[key in UnitSystem]: {
[key in UnitType]: Array<Choice<MeasurementUnitsEnum>>;
};
};

View file

@ -20,7 +20,8 @@ import { ReorderAction } from "@saleor/types";
import { import {
AttributeEntityTypeEnum, AttributeEntityTypeEnum,
AttributeInputTypeEnum, AttributeInputTypeEnum,
AttributeTypeEnum AttributeTypeEnum,
MeasurementUnitsEnum
} from "@saleor/types/globalTypes"; } from "@saleor/types/globalTypes";
import { mapMetadataItemToInput } from "@saleor/utils/maps"; import { mapMetadataItemToInput } from "@saleor/utils/maps";
import useMetadataChangeTrigger from "@saleor/utils/metadata/useMetadataChangeTrigger"; import useMetadataChangeTrigger from "@saleor/utils/metadata/useMetadataChangeTrigger";
@ -59,13 +60,14 @@ export interface AttributePageFormData extends MetadataFormData {
slug: string; slug: string;
storefrontSearchPosition: string; storefrontSearchPosition: string;
valueRequired: boolean; valueRequired: boolean;
unit: MeasurementUnitsEnum | null | undefined;
visibleInStorefront: boolean; visibleInStorefront: boolean;
} }
const AttributePage: React.FC<AttributePageProps> = ({ const AttributePage: React.FC<AttributePageProps> = ({
attribute, attribute,
disabled, disabled,
errors, errors: apiErrors,
saveButtonBarState, saveButtonBarState,
values, values,
onBack, onBack,
@ -98,36 +100,27 @@ const AttributePage: React.FC<AttributePageProps> = ({
storefrontSearchPosition: "", storefrontSearchPosition: "",
type: AttributeTypeEnum.PRODUCT_TYPE, type: AttributeTypeEnum.PRODUCT_TYPE,
valueRequired: true, valueRequired: true,
visibleInStorefront: true visibleInStorefront: true,
unit: undefined
} }
: { : {
availableInGrid: maybe(() => attribute.availableInGrid, true), availableInGrid: attribute?.availableInGrid ?? true,
entityType: attribute?.entityType ?? null, entityType: attribute?.entityType ?? null,
filterableInDashboard: maybe( filterableInDashboard: attribute?.filterableInDashboard ?? true,
() => attribute.filterableInDashboard, filterableInStorefront: attribute?.filterableInStorefront ?? true,
true inputType: attribute?.inputType ?? AttributeInputTypeEnum.DROPDOWN,
),
filterableInStorefront: maybe(
() => attribute.filterableInStorefront,
true
),
inputType: maybe(
() => attribute.inputType,
AttributeInputTypeEnum.DROPDOWN
),
metadata: attribute?.metadata?.map(mapMetadataItemToInput), metadata: attribute?.metadata?.map(mapMetadataItemToInput),
name: maybe(() => attribute.name, ""), name: attribute?.name ?? "",
privateMetadata: attribute?.privateMetadata?.map( privateMetadata: attribute?.privateMetadata?.map(
mapMetadataItemToInput mapMetadataItemToInput
), ),
slug: maybe(() => attribute.slug, ""), slug: attribute?.slug ?? "",
storefrontSearchPosition: maybe( storefrontSearchPosition:
() => attribute.storefrontSearchPosition.toString(), attribute?.storefrontSearchPosition.toString() ?? "",
""
),
type: attribute?.type || AttributeTypeEnum.PRODUCT_TYPE, type: attribute?.type || AttributeTypeEnum.PRODUCT_TYPE,
valueRequired: maybe(() => attribute.valueRequired, true), valueRequired: !!attribute?.valueRequired ?? true,
visibleInStorefront: maybe(() => attribute.visibleInStorefront, true) visibleInStorefront: attribute?.visibleInStorefront ?? true,
unit: attribute?.unit || null
}; };
const handleSubmit = (data: AttributePageFormData) => { const handleSubmit = (data: AttributePageFormData) => {
@ -150,7 +143,16 @@ const AttributePage: React.FC<AttributePageProps> = ({
return ( return (
<Form initial={initialForm} onSubmit={handleSubmit}> <Form initial={initialForm} onSubmit={handleSubmit}>
{({ change, data, hasChanged, submit }) => { {({
change,
set,
data,
hasChanged,
submit,
errors,
setError,
clearErrors
}) => {
const changeMetadata = makeMetadataChangeHandler(change); const changeMetadata = makeMetadataChangeHandler(change);
return ( return (
@ -174,8 +176,12 @@ const AttributePage: React.FC<AttributePageProps> = ({
canChangeType={attribute === null} canChangeType={attribute === null}
data={data} data={data}
disabled={disabled} disabled={disabled}
errors={errors} apiErrors={apiErrors}
onChange={change} onChange={change}
set={set}
errors={errors}
setError={setError}
clearErrors={clearErrors}
/> />
{ATTRIBUTE_TYPES_WITH_DEDICATED_VALUES.includes( {ATTRIBUTE_TYPES_WITH_DEDICATED_VALUES.includes(
data.inputType data.inputType
@ -205,7 +211,7 @@ const AttributePage: React.FC<AttributePageProps> = ({
<CardSpacer /> <CardSpacer />
<AttributeProperties <AttributeProperties
data={data} data={data}
errors={errors} errors={apiErrors}
disabled={disabled} disabled={disabled}
onChange={change} onChange={change}
/> />

View file

@ -28,6 +28,7 @@ export const attribute: AttributeDetailsFragment = {
storefrontSearchPosition: 2, storefrontSearchPosition: 2,
type: AttributeTypeEnum.PRODUCT_TYPE, type: AttributeTypeEnum.PRODUCT_TYPE,
valueRequired: true, valueRequired: true,
unit: null,
values: [ values: [
{ {
__typename: "AttributeValue" as "AttributeValue", __typename: "AttributeValue" as "AttributeValue",
@ -62,6 +63,7 @@ export const attributes: Array<AttributeList_attributes_edges_node &
name: "Author", name: "Author",
slug: "author", slug: "author",
type: AttributeTypeEnum.PRODUCT_TYPE, type: AttributeTypeEnum.PRODUCT_TYPE,
unit: null,
values: [ values: [
{ {
__typename: "AttributeValue" as "AttributeValue", __typename: "AttributeValue" as "AttributeValue",
@ -98,6 +100,7 @@ export const attributes: Array<AttributeList_attributes_edges_node &
name: "Box Size", name: "Box Size",
slug: "box-size", slug: "box-size",
type: AttributeTypeEnum.PRODUCT_TYPE, type: AttributeTypeEnum.PRODUCT_TYPE,
unit: null,
values: [ values: [
{ {
__typename: "AttributeValue" as "AttributeValue", __typename: "AttributeValue" as "AttributeValue",
@ -156,6 +159,7 @@ export const attributes: Array<AttributeList_attributes_edges_node &
name: "Brand", name: "Brand",
slug: "brand", slug: "brand",
type: AttributeTypeEnum.PRODUCT_TYPE, type: AttributeTypeEnum.PRODUCT_TYPE,
unit: null,
values: [ values: [
{ {
__typename: "AttributeValue" as "AttributeValue", __typename: "AttributeValue" as "AttributeValue",
@ -181,6 +185,7 @@ export const attributes: Array<AttributeList_attributes_edges_node &
name: "Candy Box Size", name: "Candy Box Size",
slug: "candy-box-size", slug: "candy-box-size",
type: AttributeTypeEnum.PRODUCT_TYPE, type: AttributeTypeEnum.PRODUCT_TYPE,
unit: null,
values: [ values: [
{ {
__typename: "AttributeValue" as "AttributeValue", __typename: "AttributeValue" as "AttributeValue",
@ -228,6 +233,7 @@ export const attributes: Array<AttributeList_attributes_edges_node &
name: "Coffee Genre", name: "Coffee Genre",
slug: "coffee-genre", slug: "coffee-genre",
type: AttributeTypeEnum.PRODUCT_TYPE, type: AttributeTypeEnum.PRODUCT_TYPE,
unit: null,
values: [ values: [
{ {
__typename: "AttributeValue" as "AttributeValue", __typename: "AttributeValue" as "AttributeValue",
@ -264,6 +270,7 @@ export const attributes: Array<AttributeList_attributes_edges_node &
name: "Collar", name: "Collar",
slug: "collar", slug: "collar",
type: AttributeTypeEnum.PRODUCT_TYPE, type: AttributeTypeEnum.PRODUCT_TYPE,
unit: null,
values: [ values: [
{ {
__typename: "AttributeValue" as "AttributeValue", __typename: "AttributeValue" as "AttributeValue",
@ -311,6 +318,7 @@ export const attributes: Array<AttributeList_attributes_edges_node &
name: "Color", name: "Color",
slug: "color", slug: "color",
type: AttributeTypeEnum.PRODUCT_TYPE, type: AttributeTypeEnum.PRODUCT_TYPE,
unit: null,
values: [ values: [
{ {
__typename: "AttributeValue" as "AttributeValue", __typename: "AttributeValue" as "AttributeValue",
@ -347,6 +355,7 @@ export const attributes: Array<AttributeList_attributes_edges_node &
name: "Cover", name: "Cover",
slug: "cover", slug: "cover",
type: AttributeTypeEnum.PRODUCT_TYPE, type: AttributeTypeEnum.PRODUCT_TYPE,
unit: null,
values: [ values: [
{ {
__typename: "AttributeValue" as "AttributeValue", __typename: "AttributeValue" as "AttributeValue",
@ -427,6 +436,7 @@ export const attributes: Array<AttributeList_attributes_edges_node &
name: "Flavor", name: "Flavor",
slug: "flavor", slug: "flavor",
type: AttributeTypeEnum.PRODUCT_TYPE, type: AttributeTypeEnum.PRODUCT_TYPE,
unit: null,
values: [ values: [
{ {
__typename: "AttributeValue" as "AttributeValue", __typename: "AttributeValue" as "AttributeValue",
@ -463,6 +473,7 @@ export const attributes: Array<AttributeList_attributes_edges_node &
name: "Language", name: "Language",
slug: "language", slug: "language",
type: AttributeTypeEnum.PRODUCT_TYPE, type: AttributeTypeEnum.PRODUCT_TYPE,
unit: null,
values: [ values: [
{ {
__typename: "AttributeValue" as "AttributeValue", __typename: "AttributeValue" as "AttributeValue",
@ -499,6 +510,7 @@ export const attributes: Array<AttributeList_attributes_edges_node &
name: "Publisher", name: "Publisher",
slug: "publisher", slug: "publisher",
type: AttributeTypeEnum.PRODUCT_TYPE, type: AttributeTypeEnum.PRODUCT_TYPE,
unit: null,
values: [ values: [
{ {
__typename: "AttributeValue" as "AttributeValue", __typename: "AttributeValue" as "AttributeValue",
@ -535,6 +547,7 @@ export const attributes: Array<AttributeList_attributes_edges_node &
name: "Size", name: "Size",
slug: "size", slug: "size",
type: AttributeTypeEnum.PRODUCT_TYPE, type: AttributeTypeEnum.PRODUCT_TYPE,
unit: null,
values: [ values: [
{ {
__typename: "AttributeValue" as "AttributeValue", __typename: "AttributeValue" as "AttributeValue",

View file

@ -3,7 +3,7 @@
// @generated // @generated
// This file was automatically generated and should not be edited. // This file was automatically generated and should not be edited.
import { AttributeCreateInput, AttributeTypeEnum, AttributeInputTypeEnum, AttributeEntityTypeEnum, AttributeErrorCode } from "./../../types/globalTypes"; import { AttributeCreateInput, AttributeTypeEnum, MeasurementUnitsEnum, AttributeInputTypeEnum, AttributeEntityTypeEnum, AttributeErrorCode } from "./../../types/globalTypes";
// ==================================================== // ====================================================
// GraphQL mutation operation: AttributeCreate // GraphQL mutation operation: AttributeCreate
@ -46,6 +46,7 @@ export interface AttributeCreate_attributeCreate_attribute {
visibleInStorefront: boolean; visibleInStorefront: boolean;
filterableInDashboard: boolean; filterableInDashboard: boolean;
filterableInStorefront: boolean; filterableInStorefront: boolean;
unit: MeasurementUnitsEnum | null;
metadata: (AttributeCreate_attributeCreate_attribute_metadata | null)[]; metadata: (AttributeCreate_attributeCreate_attribute_metadata | null)[];
privateMetadata: (AttributeCreate_attributeCreate_attribute_privateMetadata | null)[]; privateMetadata: (AttributeCreate_attributeCreate_attribute_privateMetadata | null)[];
availableInGrid: boolean; availableInGrid: boolean;

View file

@ -3,7 +3,7 @@
// @generated // @generated
// This file was automatically generated and should not be edited. // This file was automatically generated and should not be edited.
import { AttributeTypeEnum, AttributeInputTypeEnum, AttributeEntityTypeEnum } from "./../../types/globalTypes"; import { AttributeTypeEnum, MeasurementUnitsEnum, AttributeInputTypeEnum, AttributeEntityTypeEnum } from "./../../types/globalTypes";
// ==================================================== // ====================================================
// GraphQL query operation: AttributeDetails // GraphQL query operation: AttributeDetails
@ -46,6 +46,7 @@ export interface AttributeDetails_attribute {
visibleInStorefront: boolean; visibleInStorefront: boolean;
filterableInDashboard: boolean; filterableInDashboard: boolean;
filterableInStorefront: boolean; filterableInStorefront: boolean;
unit: MeasurementUnitsEnum | null;
metadata: (AttributeDetails_attribute_metadata | null)[]; metadata: (AttributeDetails_attribute_metadata | null)[];
privateMetadata: (AttributeDetails_attribute_privateMetadata | null)[]; privateMetadata: (AttributeDetails_attribute_privateMetadata | null)[];
availableInGrid: boolean; availableInGrid: boolean;

View file

@ -3,7 +3,7 @@
// @generated // @generated
// This file was automatically generated and should not be edited. // This file was automatically generated and should not be edited.
import { AttributeFilterInput, AttributeSortingInput, AttributeTypeEnum } from "./../../types/globalTypes"; import { AttributeFilterInput, AttributeSortingInput, AttributeTypeEnum, MeasurementUnitsEnum } from "./../../types/globalTypes";
// ==================================================== // ====================================================
// GraphQL query operation: AttributeList // GraphQL query operation: AttributeList
@ -25,6 +25,7 @@ export interface AttributeList_attributes_edges_node {
visibleInStorefront: boolean; visibleInStorefront: boolean;
filterableInDashboard: boolean; filterableInDashboard: boolean;
filterableInStorefront: boolean; filterableInStorefront: boolean;
unit: MeasurementUnitsEnum | null;
values: (AttributeList_attributes_edges_node_values | null)[] | null; values: (AttributeList_attributes_edges_node_values | null)[] | null;
} }

View file

@ -3,7 +3,7 @@
// @generated // @generated
// This file was automatically generated and should not be edited. // This file was automatically generated and should not be edited.
import { AttributeUpdateInput, AttributeTypeEnum, AttributeInputTypeEnum, AttributeEntityTypeEnum, AttributeErrorCode } from "./../../types/globalTypes"; import { AttributeUpdateInput, AttributeTypeEnum, MeasurementUnitsEnum, AttributeInputTypeEnum, AttributeEntityTypeEnum, AttributeErrorCode } from "./../../types/globalTypes";
// ==================================================== // ====================================================
// GraphQL mutation operation: AttributeUpdate // GraphQL mutation operation: AttributeUpdate
@ -46,6 +46,7 @@ export interface AttributeUpdate_attributeUpdate_attribute {
visibleInStorefront: boolean; visibleInStorefront: boolean;
filterableInDashboard: boolean; filterableInDashboard: boolean;
filterableInStorefront: boolean; filterableInStorefront: boolean;
unit: MeasurementUnitsEnum | null;
metadata: (AttributeUpdate_attributeUpdate_attribute_metadata | null)[]; metadata: (AttributeUpdate_attributeUpdate_attribute_metadata | null)[];
privateMetadata: (AttributeUpdate_attributeUpdate_attribute_privateMetadata | null)[]; privateMetadata: (AttributeUpdate_attributeUpdate_attribute_privateMetadata | null)[];
availableInGrid: boolean; availableInGrid: boolean;

View file

@ -3,7 +3,7 @@
// @generated // @generated
// This file was automatically generated and should not be edited. // This file was automatically generated and should not be edited.
import { AttributeValueCreateInput, AttributeTypeEnum, AttributeInputTypeEnum, AttributeEntityTypeEnum, AttributeErrorCode } from "./../../types/globalTypes"; import { AttributeValueCreateInput, AttributeTypeEnum, MeasurementUnitsEnum, AttributeInputTypeEnum, AttributeEntityTypeEnum, AttributeErrorCode } from "./../../types/globalTypes";
// ==================================================== // ====================================================
// GraphQL mutation operation: AttributeValueCreate // GraphQL mutation operation: AttributeValueCreate
@ -46,6 +46,7 @@ export interface AttributeValueCreate_attributeValueCreate_attribute {
visibleInStorefront: boolean; visibleInStorefront: boolean;
filterableInDashboard: boolean; filterableInDashboard: boolean;
filterableInStorefront: boolean; filterableInStorefront: boolean;
unit: MeasurementUnitsEnum | null;
metadata: (AttributeValueCreate_attributeValueCreate_attribute_metadata | null)[]; metadata: (AttributeValueCreate_attributeValueCreate_attribute_metadata | null)[];
privateMetadata: (AttributeValueCreate_attributeValueCreate_attribute_privateMetadata | null)[]; privateMetadata: (AttributeValueCreate_attributeValueCreate_attribute_privateMetadata | null)[];
availableInGrid: boolean; availableInGrid: boolean;

View file

@ -3,7 +3,7 @@
// @generated // @generated
// This file was automatically generated and should not be edited. // This file was automatically generated and should not be edited.
import { AttributeTypeEnum, AttributeInputTypeEnum, AttributeEntityTypeEnum, AttributeErrorCode } from "./../../types/globalTypes"; import { AttributeTypeEnum, MeasurementUnitsEnum, AttributeInputTypeEnum, AttributeEntityTypeEnum, AttributeErrorCode } from "./../../types/globalTypes";
// ==================================================== // ====================================================
// GraphQL mutation operation: AttributeValueDelete // GraphQL mutation operation: AttributeValueDelete
@ -46,6 +46,7 @@ export interface AttributeValueDelete_attributeValueDelete_attribute {
visibleInStorefront: boolean; visibleInStorefront: boolean;
filterableInDashboard: boolean; filterableInDashboard: boolean;
filterableInStorefront: boolean; filterableInStorefront: boolean;
unit: MeasurementUnitsEnum | null;
metadata: (AttributeValueDelete_attributeValueDelete_attribute_metadata | null)[]; metadata: (AttributeValueDelete_attributeValueDelete_attribute_metadata | null)[];
privateMetadata: (AttributeValueDelete_attributeValueDelete_attribute_privateMetadata | null)[]; privateMetadata: (AttributeValueDelete_attributeValueDelete_attribute_privateMetadata | null)[];
availableInGrid: boolean; availableInGrid: boolean;

View file

@ -3,7 +3,7 @@
// @generated // @generated
// This file was automatically generated and should not be edited. // This file was automatically generated and should not be edited.
import { AttributeValueCreateInput, AttributeTypeEnum, AttributeInputTypeEnum, AttributeEntityTypeEnum, AttributeErrorCode } from "./../../types/globalTypes"; import { AttributeValueCreateInput, AttributeTypeEnum, MeasurementUnitsEnum, AttributeInputTypeEnum, AttributeEntityTypeEnum, AttributeErrorCode } from "./../../types/globalTypes";
// ==================================================== // ====================================================
// GraphQL mutation operation: AttributeValueUpdate // GraphQL mutation operation: AttributeValueUpdate
@ -46,6 +46,7 @@ export interface AttributeValueUpdate_attributeValueUpdate_attribute {
visibleInStorefront: boolean; visibleInStorefront: boolean;
filterableInDashboard: boolean; filterableInDashboard: boolean;
filterableInStorefront: boolean; filterableInStorefront: boolean;
unit: MeasurementUnitsEnum | null;
metadata: (AttributeValueUpdate_attributeValueUpdate_attribute_metadata | null)[]; metadata: (AttributeValueUpdate_attributeValueUpdate_attribute_metadata | null)[];
privateMetadata: (AttributeValueUpdate_attributeValueUpdate_attribute_privateMetadata | null)[]; privateMetadata: (AttributeValueUpdate_attributeValueUpdate_attribute_privateMetadata | null)[];
availableInGrid: boolean; availableInGrid: boolean;

View file

@ -77,13 +77,19 @@ export function getSelectedAttributeValues(
| ProductDetails_product_attributes | ProductDetails_product_attributes
| SelectedVariantAttributeFragment | SelectedVariantAttributeFragment
) { ) {
if (attribute.attribute.inputType === AttributeInputTypeEnum.REFERENCE) { switch (attribute.attribute.inputType) {
return attribute.values.map(value => value.reference); case AttributeInputTypeEnum.REFERENCE:
return attribute.values.map(value => value.reference);
case AttributeInputTypeEnum.RICH_TEXT:
return [attribute.values[0]?.richText];
case AttributeInputTypeEnum.NUMERIC:
return [attribute.values[0]?.name];
default:
return attribute.values.map(value => value.slug);
} }
if (attribute.attribute.inputType === AttributeInputTypeEnum.RICH_TEXT) {
return [attribute.values[0]?.richText];
}
return attribute.values.map(value => value.slug);
} }
export const isFileValueUnused = ( export const isFileValueUnused = (

View file

@ -1,4 +1,6 @@
import { InputAdornment, TextField } from "@material-ui/core";
import makeStyles from "@material-ui/core/styles/makeStyles"; import makeStyles from "@material-ui/core/styles/makeStyles";
import { getMeasurementUnitMessage } from "@saleor/attributes/components/AttributeDetails/utils";
import { AttributeInput } from "@saleor/components/Attributes/Attributes"; import { AttributeInput } from "@saleor/components/Attributes/Attributes";
import BasicAttributeRow from "@saleor/components/Attributes/BasicAttributeRow"; import BasicAttributeRow from "@saleor/components/Attributes/BasicAttributeRow";
import ExtendedAttributeRow from "@saleor/components/Attributes/ExtendedAttributeRow"; import ExtendedAttributeRow from "@saleor/components/Attributes/ExtendedAttributeRow";
@ -158,6 +160,34 @@ const AttributeRow: React.FC<AttributeRowProps> = ({
/> />
</BasicAttributeRow> </BasicAttributeRow>
); );
case AttributeInputTypeEnum.NUMERIC:
return (
<BasicAttributeRow label={attribute.label}>
<TextField
fullWidth
disabled={disabled}
error={!!error}
helperText={getErrorMessage(error, intl)}
label={intl.formatMessage(messages.valueLabel)}
name={`attribute:${attribute.label}`}
onChange={event => onChange(attribute.id, event.target.value)}
type="number"
value={attribute.value[0]}
InputProps={
attribute.data.unit && {
endAdornment: (
<InputAdornment position="end">
{getMeasurementUnitMessage(
attribute.data.unit,
intl.formatMessage
)}
</InputAdornment>
)
}
}
/>
</BasicAttributeRow>
);
default: default:
return ( return (
<BasicAttributeRow label={attribute.label}> <BasicAttributeRow label={attribute.label}>

View file

@ -13,7 +13,8 @@ import { FormsetAtomicData } from "@saleor/hooks/useFormset";
import { makeStyles } from "@saleor/theme"; import { makeStyles } from "@saleor/theme";
import { import {
AttributeEntityTypeEnum, AttributeEntityTypeEnum,
AttributeInputTypeEnum AttributeInputTypeEnum,
MeasurementUnitsEnum
} from "@saleor/types/globalTypes"; } from "@saleor/types/globalTypes";
import classNames from "classnames"; import classNames from "classnames";
import React from "react"; import React from "react";
@ -25,6 +26,7 @@ import { VariantAttributeScope } from "./types";
export interface AttributeInputData { export interface AttributeInputData {
inputType: AttributeInputTypeEnum; inputType: AttributeInputTypeEnum;
entityType?: AttributeEntityTypeEnum; entityType?: AttributeEntityTypeEnum;
unit?: MeasurementUnitsEnum | null;
variantAttributeScope?: VariantAttributeScope; variantAttributeScope?: VariantAttributeScope;
isRequired: boolean; isRequired: boolean;
values: AttributeValueFragment[]; values: AttributeValueFragment[];

View file

@ -20,7 +20,7 @@ const useStyles = makeStyles(
); );
interface BasicAttributeRowProps { interface BasicAttributeRowProps {
label: string; label: string | React.ReactNode;
} }
const BasicAttributeRow: React.FC<BasicAttributeRowProps> = props => { const BasicAttributeRow: React.FC<BasicAttributeRowProps> = props => {

View file

@ -193,12 +193,34 @@ const RICH_TEXT_ATTRIBUTE: AttributeInput = {
value: [] value: []
}; };
const NUMERIC_ATTRIBUTE: AttributeInput = {
data: {
inputType: AttributeInputTypeEnum.NUMERIC,
isRequired: true,
values: [
{
__typename: "AttributeValue",
file: null,
id: "QXR0cmlidXRlVmFsdWU6MTAx",
name: "12cm",
reference: null,
richText: null,
slug: "319_35"
}
]
},
id: "QXR0cmlidXRlOjM1",
label: "Numeric Attribute",
value: []
};
export const ATTRIBUTES: AttributeInput[] = [ export const ATTRIBUTES: AttributeInput[] = [
DROPDOWN_ATTRIBUTE, DROPDOWN_ATTRIBUTE,
MULTISELECT_ATTRIBUTE, MULTISELECT_ATTRIBUTE,
FILE_ATTRIBUTE, FILE_ATTRIBUTE,
REFERENCE_ATTRIBUTE, REFERENCE_ATTRIBUTE,
RICH_TEXT_ATTRIBUTE RICH_TEXT_ATTRIBUTE,
NUMERIC_ATTRIBUTE
]; ];
export const ATTRIBUTES_SELECTED: AttributeInput[] = [ export const ATTRIBUTES_SELECTED: AttributeInput[] = [
@ -228,5 +250,9 @@ export const ATTRIBUTES_SELECTED: AttributeInput[] = [
{ {
...RICH_TEXT_ATTRIBUTE, ...RICH_TEXT_ATTRIBUTE,
value: [RICH_TEXT_ATTRIBUTE.data.values[0].richText] value: [RICH_TEXT_ATTRIBUTE.data.values[0].richText]
},
{
...NUMERIC_ATTRIBUTE,
value: [NUMERIC_ATTRIBUTE.data.values[0].name]
} }
]; ];

View file

@ -28,9 +28,9 @@ const useStyles = makeStyles(
{ name: "SingleSelectField" } { name: "SingleSelectField" }
); );
export interface Choice { export interface Choice<T = string, L = string | React.ReactNode> {
value: string; value: T;
label: string | React.ReactNode; label: L;
} }
export type Choices = Choice[]; export type Choices = Choice[];
@ -40,8 +40,8 @@ interface SingleSelectFieldProps {
className?: string; className?: string;
disabled?: boolean; disabled?: boolean;
error?: boolean; error?: boolean;
hint?: string; hint?: string | React.ReactNode;
label?: string; label?: string | React.ReactNode;
name?: string; name?: string;
selectProps?: SelectProps; selectProps?: SelectProps;
placeholder?: string; placeholder?: string;

View file

@ -26,6 +26,7 @@ export const attributeFragment = gql`
visibleInStorefront visibleInStorefront
filterableInDashboard filterableInDashboard
filterableInStorefront filterableInStorefront
unit
} }
`; `;
@ -39,6 +40,7 @@ export const attributeDetailsFragment = gql`
availableInGrid availableInGrid
inputType inputType
entityType entityType
unit
storefrontSearchPosition storefrontSearchPosition
valueRequired valueRequired
values { values {

View file

@ -23,6 +23,7 @@ export const pageAttributesFragment = gql`
inputType inputType
entityType entityType
valueRequired valueRequired
unit
values { values {
...AttributeValueFragment ...AttributeValueFragment
} }

View file

@ -127,6 +127,7 @@ export const productVariantAttributesFragment = gql`
inputType inputType
entityType entityType
valueRequired valueRequired
unit
values { values {
...AttributeValueFragment ...AttributeValueFragment
} }
@ -239,6 +240,7 @@ export const variantAttributeFragment = gql`
inputType inputType
entityType entityType
valueRequired valueRequired
unit
values { values {
...AttributeValueFragment ...AttributeValueFragment
} }

View file

@ -3,7 +3,7 @@
// @generated // @generated
// This file was automatically generated and should not be edited. // This file was automatically generated and should not be edited.
import { AttributeTypeEnum, AttributeInputTypeEnum, AttributeEntityTypeEnum } from "./../../types/globalTypes"; import { AttributeTypeEnum, MeasurementUnitsEnum, AttributeInputTypeEnum, AttributeEntityTypeEnum } from "./../../types/globalTypes";
// ==================================================== // ====================================================
// GraphQL fragment: AttributeDetailsFragment // GraphQL fragment: AttributeDetailsFragment
@ -46,6 +46,7 @@ export interface AttributeDetailsFragment {
visibleInStorefront: boolean; visibleInStorefront: boolean;
filterableInDashboard: boolean; filterableInDashboard: boolean;
filterableInStorefront: boolean; filterableInStorefront: boolean;
unit: MeasurementUnitsEnum | null;
metadata: (AttributeDetailsFragment_metadata | null)[]; metadata: (AttributeDetailsFragment_metadata | null)[];
privateMetadata: (AttributeDetailsFragment_privateMetadata | null)[]; privateMetadata: (AttributeDetailsFragment_privateMetadata | null)[];
availableInGrid: boolean; availableInGrid: boolean;

View file

@ -3,7 +3,7 @@
// @generated // @generated
// This file was automatically generated and should not be edited. // This file was automatically generated and should not be edited.
import { AttributeTypeEnum } from "./../../types/globalTypes"; import { AttributeTypeEnum, MeasurementUnitsEnum } from "./../../types/globalTypes";
// ==================================================== // ====================================================
// GraphQL fragment: AttributeFragment // GraphQL fragment: AttributeFragment
@ -18,4 +18,5 @@ export interface AttributeFragment {
visibleInStorefront: boolean; visibleInStorefront: boolean;
filterableInDashboard: boolean; filterableInDashboard: boolean;
filterableInStorefront: boolean; filterableInStorefront: boolean;
unit: MeasurementUnitsEnum | null;
} }

View file

@ -3,7 +3,7 @@
// @generated // @generated
// This file was automatically generated and should not be edited. // This file was automatically generated and should not be edited.
import { AttributeInputTypeEnum, AttributeEntityTypeEnum } from "./../../types/globalTypes"; import { AttributeInputTypeEnum, AttributeEntityTypeEnum, MeasurementUnitsEnum } from "./../../types/globalTypes";
// ==================================================== // ====================================================
// GraphQL fragment: PageAttributesFragment // GraphQL fragment: PageAttributesFragment
@ -33,6 +33,7 @@ export interface PageAttributesFragment_attributes_attribute {
inputType: AttributeInputTypeEnum | null; inputType: AttributeInputTypeEnum | null;
entityType: AttributeEntityTypeEnum | null; entityType: AttributeEntityTypeEnum | null;
valueRequired: boolean; valueRequired: boolean;
unit: MeasurementUnitsEnum | null;
values: (PageAttributesFragment_attributes_attribute_values | null)[] | null; values: (PageAttributesFragment_attributes_attribute_values | null)[] | null;
} }

View file

@ -3,7 +3,7 @@
// @generated // @generated
// This file was automatically generated and should not be edited. // This file was automatically generated and should not be edited.
import { AttributeInputTypeEnum, AttributeEntityTypeEnum } from "./../../types/globalTypes"; import { AttributeInputTypeEnum, AttributeEntityTypeEnum, MeasurementUnitsEnum } from "./../../types/globalTypes";
// ==================================================== // ====================================================
// GraphQL fragment: PageDetailsFragment // GraphQL fragment: PageDetailsFragment
@ -33,6 +33,7 @@ export interface PageDetailsFragment_attributes_attribute {
inputType: AttributeInputTypeEnum | null; inputType: AttributeInputTypeEnum | null;
entityType: AttributeEntityTypeEnum | null; entityType: AttributeEntityTypeEnum | null;
valueRequired: boolean; valueRequired: boolean;
unit: MeasurementUnitsEnum | null;
values: (PageDetailsFragment_attributes_attribute_values | null)[] | null; values: (PageDetailsFragment_attributes_attribute_values | null)[] | null;
} }

View file

@ -3,7 +3,7 @@
// @generated // @generated
// This file was automatically generated and should not be edited. // This file was automatically generated and should not be edited.
import { AttributeTypeEnum } from "./../../types/globalTypes"; import { AttributeTypeEnum, MeasurementUnitsEnum } from "./../../types/globalTypes";
// ==================================================== // ====================================================
// GraphQL fragment: PageTypeDetailsFragment // GraphQL fragment: PageTypeDetailsFragment
@ -30,6 +30,7 @@ export interface PageTypeDetailsFragment_attributes {
visibleInStorefront: boolean; visibleInStorefront: boolean;
filterableInDashboard: boolean; filterableInDashboard: boolean;
filterableInStorefront: boolean; filterableInStorefront: boolean;
unit: MeasurementUnitsEnum | null;
} }
export interface PageTypeDetailsFragment { export interface PageTypeDetailsFragment {

View file

@ -3,7 +3,7 @@
// @generated // @generated
// This file was automatically generated and should not be edited. // This file was automatically generated and should not be edited.
import { AttributeInputTypeEnum, AttributeEntityTypeEnum, ProductMediaType, WeightUnitsEnum } from "./../../types/globalTypes"; import { AttributeInputTypeEnum, AttributeEntityTypeEnum, MeasurementUnitsEnum, ProductMediaType, WeightUnitsEnum } from "./../../types/globalTypes";
// ==================================================== // ====================================================
// GraphQL fragment: Product // GraphQL fragment: Product
@ -33,6 +33,7 @@ export interface Product_attributes_attribute {
inputType: AttributeInputTypeEnum | null; inputType: AttributeInputTypeEnum | null;
entityType: AttributeEntityTypeEnum | null; entityType: AttributeEntityTypeEnum | null;
valueRequired: boolean; valueRequired: boolean;
unit: MeasurementUnitsEnum | null;
values: (Product_attributes_attribute_values | null)[] | null; values: (Product_attributes_attribute_values | null)[] | null;
} }

View file

@ -3,7 +3,7 @@
// @generated // @generated
// This file was automatically generated and should not be edited. // This file was automatically generated and should not be edited.
import { AttributeTypeEnum, WeightUnitsEnum } from "./../../types/globalTypes"; import { AttributeTypeEnum, MeasurementUnitsEnum, WeightUnitsEnum } from "./../../types/globalTypes";
// ==================================================== // ====================================================
// GraphQL fragment: ProductTypeDetailsFragment // GraphQL fragment: ProductTypeDetailsFragment
@ -36,6 +36,7 @@ export interface ProductTypeDetailsFragment_productAttributes {
visibleInStorefront: boolean; visibleInStorefront: boolean;
filterableInDashboard: boolean; filterableInDashboard: boolean;
filterableInStorefront: boolean; filterableInStorefront: boolean;
unit: MeasurementUnitsEnum | null;
} }
export interface ProductTypeDetailsFragment_variantAttributes { export interface ProductTypeDetailsFragment_variantAttributes {
@ -47,6 +48,7 @@ export interface ProductTypeDetailsFragment_variantAttributes {
visibleInStorefront: boolean; visibleInStorefront: boolean;
filterableInDashboard: boolean; filterableInDashboard: boolean;
filterableInStorefront: boolean; filterableInStorefront: boolean;
unit: MeasurementUnitsEnum | null;
} }
export interface ProductTypeDetailsFragment_weight { export interface ProductTypeDetailsFragment_weight {

View file

@ -3,7 +3,7 @@
// @generated // @generated
// This file was automatically generated and should not be edited. // This file was automatically generated and should not be edited.
import { AttributeInputTypeEnum, AttributeEntityTypeEnum, ProductMediaType, WeightUnitsEnum } from "./../../types/globalTypes"; import { AttributeInputTypeEnum, AttributeEntityTypeEnum, MeasurementUnitsEnum, ProductMediaType, WeightUnitsEnum } from "./../../types/globalTypes";
// ==================================================== // ====================================================
// GraphQL fragment: ProductVariant // GraphQL fragment: ProductVariant
@ -45,6 +45,7 @@ export interface ProductVariant_selectionAttributes_attribute {
inputType: AttributeInputTypeEnum | null; inputType: AttributeInputTypeEnum | null;
entityType: AttributeEntityTypeEnum | null; entityType: AttributeEntityTypeEnum | null;
valueRequired: boolean; valueRequired: boolean;
unit: MeasurementUnitsEnum | null;
values: (ProductVariant_selectionAttributes_attribute_values | null)[] | null; values: (ProductVariant_selectionAttributes_attribute_values | null)[] | null;
} }
@ -94,6 +95,7 @@ export interface ProductVariant_nonSelectionAttributes_attribute {
inputType: AttributeInputTypeEnum | null; inputType: AttributeInputTypeEnum | null;
entityType: AttributeEntityTypeEnum | null; entityType: AttributeEntityTypeEnum | null;
valueRequired: boolean; valueRequired: boolean;
unit: MeasurementUnitsEnum | null;
values: (ProductVariant_nonSelectionAttributes_attribute_values | null)[] | null; values: (ProductVariant_nonSelectionAttributes_attribute_values | null)[] | null;
} }

View file

@ -3,7 +3,7 @@
// @generated // @generated
// This file was automatically generated and should not be edited. // This file was automatically generated and should not be edited.
import { AttributeInputTypeEnum, AttributeEntityTypeEnum } from "./../../types/globalTypes"; import { AttributeInputTypeEnum, AttributeEntityTypeEnum, MeasurementUnitsEnum } from "./../../types/globalTypes";
// ==================================================== // ====================================================
// GraphQL fragment: ProductVariantAttributesFragment // GraphQL fragment: ProductVariantAttributesFragment
@ -33,6 +33,7 @@ export interface ProductVariantAttributesFragment_attributes_attribute {
inputType: AttributeInputTypeEnum | null; inputType: AttributeInputTypeEnum | null;
entityType: AttributeEntityTypeEnum | null; entityType: AttributeEntityTypeEnum | null;
valueRequired: boolean; valueRequired: boolean;
unit: MeasurementUnitsEnum | null;
values: (ProductVariantAttributesFragment_attributes_attribute_values | null)[] | null; values: (ProductVariantAttributesFragment_attributes_attribute_values | null)[] | null;
} }

View file

@ -3,7 +3,7 @@
// @generated // @generated
// This file was automatically generated and should not be edited. // This file was automatically generated and should not be edited.
import { AttributeInputTypeEnum, AttributeEntityTypeEnum } from "./../../types/globalTypes"; import { AttributeInputTypeEnum, AttributeEntityTypeEnum, MeasurementUnitsEnum } from "./../../types/globalTypes";
// ==================================================== // ====================================================
// GraphQL fragment: SelectedVariantAttributeFragment // GraphQL fragment: SelectedVariantAttributeFragment
@ -33,6 +33,7 @@ export interface SelectedVariantAttributeFragment_attribute {
inputType: AttributeInputTypeEnum | null; inputType: AttributeInputTypeEnum | null;
entityType: AttributeEntityTypeEnum | null; entityType: AttributeEntityTypeEnum | null;
valueRequired: boolean; valueRequired: boolean;
unit: MeasurementUnitsEnum | null;
values: (SelectedVariantAttributeFragment_attribute_values | null)[] | null; values: (SelectedVariantAttributeFragment_attribute_values | null)[] | null;
} }

View file

@ -3,7 +3,7 @@
// @generated // @generated
// This file was automatically generated and should not be edited. // This file was automatically generated and should not be edited.
import { AttributeInputTypeEnum, AttributeEntityTypeEnum } from "./../../types/globalTypes"; import { AttributeInputTypeEnum, AttributeEntityTypeEnum, MeasurementUnitsEnum } from "./../../types/globalTypes";
// ==================================================== // ====================================================
// GraphQL fragment: VariantAttributeFragment // GraphQL fragment: VariantAttributeFragment
@ -33,5 +33,6 @@ export interface VariantAttributeFragment {
inputType: AttributeInputTypeEnum | null; inputType: AttributeInputTypeEnum | null;
entityType: AttributeEntityTypeEnum | null; entityType: AttributeEntityTypeEnum | null;
valueRequired: boolean; valueRequired: boolean;
unit: MeasurementUnitsEnum | null;
values: (VariantAttributeFragment_values | null)[] | null; values: (VariantAttributeFragment_values | null)[] | null;
} }

View file

@ -1,5 +1,7 @@
import { toggle } from "@saleor/utils/lists"; import { toggle } from "@saleor/utils/lists";
import isEqual from "lodash-es/isEqual"; import isEqual from "lodash-es/isEqual";
import omit from "lodash/omit";
import React from "react";
import { useState } from "react"; import { useState } from "react";
import useStateFromProps from "./useStateFromProps"; import useStateFromProps from "./useStateFromProps";
@ -14,6 +16,10 @@ export type SubmitPromise = Promise<any[]>;
export type FormChange = (event: ChangeEvent, cb?: () => void) => void; export type FormChange = (event: ChangeEvent, cb?: () => void) => void;
export type FormErrors<T> = {
[field in keyof T]?: string | React.ReactNode;
};
export interface UseFormResult<T> { export interface UseFormResult<T> {
change: FormChange; change: FormChange;
data: T; data: T;
@ -23,6 +29,9 @@ export interface UseFormResult<T> {
submit: () => void; submit: () => void;
triggerChange: () => void; triggerChange: () => void;
toggleValue: FormChange; toggleValue: FormChange;
errors: FormErrors<T>;
setError: (name: keyof T, error: string | React.ReactNode) => void;
clearErrors: (name?: keyof T | Array<keyof T>) => void;
} }
type FormData = Record<string, any | any[]>; type FormData = Record<string, any | any[]>;
@ -55,6 +64,7 @@ function useForm<T extends FormData>(
onSubmit?: (data: T) => SubmitPromise | void onSubmit?: (data: T) => SubmitPromise | void
): UseFormResult<T> { ): UseFormResult<T> {
const [hasChanged, setChanged] = useState(false); const [hasChanged, setChanged] = useState(false);
const [errors, setErrors] = useState<FormErrors<T>>({});
const [data, setData] = useStateFromProps(initial, { const [data, setData] = useStateFromProps(initial, {
mergeFunc: merge, mergeFunc: merge,
onRefresh: newData => handleRefresh(data, newData, setChanged) onRefresh: newData => handleRefresh(data, newData, setChanged)
@ -109,7 +119,7 @@ function useForm<T extends FormData>(
} }
async function submit() { async function submit() {
if (typeof onSubmit === "function") { if (typeof onSubmit === "function" && !Object.keys(errors).length) {
const result = onSubmit(data); const result = onSubmit(data);
if (result) { if (result) {
const errors = await result; const errors = await result;
@ -124,8 +134,24 @@ function useForm<T extends FormData>(
setChanged(true); setChanged(true);
} }
const setError = (field: keyof T, error: string | React.ReactNode) =>
setErrors(e => ({ ...e, [field]: error }));
const clearErrors = (field?: keyof T | Array<keyof T>) => {
if (!field) {
setErrors({});
} else {
setErrors(errors =>
omit<FormErrors<T>>(errors, Array.isArray(field) ? field : [field])
);
}
};
return { return {
setError,
errors,
change, change,
clearErrors,
data, data,
hasChanged, hasChanged,
reset, reset,

View file

@ -46,7 +46,8 @@ export const pageType: PageTypeDetails_pageType = {
visibleInStorefront: true, visibleInStorefront: true,
filterableInDashboard: true, filterableInDashboard: true,
filterableInStorefront: true, filterableInStorefront: true,
type: AttributeTypeEnum.PAGE_TYPE type: AttributeTypeEnum.PAGE_TYPE,
unit: null
}, },
{ {
__typename: "Attribute" as "Attribute", __typename: "Attribute" as "Attribute",
@ -56,7 +57,8 @@ export const pageType: PageTypeDetails_pageType = {
visibleInStorefront: true, visibleInStorefront: true,
filterableInDashboard: true, filterableInDashboard: true,
filterableInStorefront: true, filterableInStorefront: true,
type: AttributeTypeEnum.PAGE_TYPE type: AttributeTypeEnum.PAGE_TYPE,
unit: null
}, },
{ {
__typename: "Attribute" as "Attribute", __typename: "Attribute" as "Attribute",
@ -66,7 +68,8 @@ export const pageType: PageTypeDetails_pageType = {
visibleInStorefront: true, visibleInStorefront: true,
filterableInDashboard: true, filterableInDashboard: true,
filterableInStorefront: true, filterableInStorefront: true,
type: AttributeTypeEnum.PAGE_TYPE type: AttributeTypeEnum.PAGE_TYPE,
unit: null
} }
], ],
privateMetadata: [] privateMetadata: []

View file

@ -3,7 +3,7 @@
// @generated // @generated
// This file was automatically generated and should not be edited. // This file was automatically generated and should not be edited.
import { PageErrorCode, AttributeTypeEnum } from "./../../types/globalTypes"; import { PageErrorCode, AttributeTypeEnum, MeasurementUnitsEnum } from "./../../types/globalTypes";
// ==================================================== // ====================================================
// GraphQL mutation operation: AssignPageAttribute // GraphQL mutation operation: AssignPageAttribute
@ -36,6 +36,7 @@ export interface AssignPageAttribute_pageAttributeAssign_pageType_attributes {
visibleInStorefront: boolean; visibleInStorefront: boolean;
filterableInDashboard: boolean; filterableInDashboard: boolean;
filterableInStorefront: boolean; filterableInStorefront: boolean;
unit: MeasurementUnitsEnum | null;
} }
export interface AssignPageAttribute_pageAttributeAssign_pageType { export interface AssignPageAttribute_pageAttributeAssign_pageType {

View file

@ -3,7 +3,7 @@
// @generated // @generated
// This file was automatically generated and should not be edited. // This file was automatically generated and should not be edited.
import { ReorderInput, PageErrorCode, AttributeTypeEnum } from "./../../types/globalTypes"; import { ReorderInput, PageErrorCode, AttributeTypeEnum, MeasurementUnitsEnum } from "./../../types/globalTypes";
// ==================================================== // ====================================================
// GraphQL mutation operation: PageTypeAttributeReorder // GraphQL mutation operation: PageTypeAttributeReorder
@ -36,6 +36,7 @@ export interface PageTypeAttributeReorder_pageTypeReorderAttributes_pageType_att
visibleInStorefront: boolean; visibleInStorefront: boolean;
filterableInDashboard: boolean; filterableInDashboard: boolean;
filterableInStorefront: boolean; filterableInStorefront: boolean;
unit: MeasurementUnitsEnum | null;
} }
export interface PageTypeAttributeReorder_pageTypeReorderAttributes_pageType { export interface PageTypeAttributeReorder_pageTypeReorderAttributes_pageType {

View file

@ -3,7 +3,7 @@
// @generated // @generated
// This file was automatically generated and should not be edited. // This file was automatically generated and should not be edited.
import { PageTypeCreateInput, PageErrorCode, AttributeTypeEnum } from "./../../types/globalTypes"; import { PageTypeCreateInput, PageErrorCode, AttributeTypeEnum, MeasurementUnitsEnum } from "./../../types/globalTypes";
// ==================================================== // ====================================================
// GraphQL mutation operation: PageTypeCreate // GraphQL mutation operation: PageTypeCreate
@ -36,6 +36,7 @@ export interface PageTypeCreate_pageTypeCreate_pageType_attributes {
visibleInStorefront: boolean; visibleInStorefront: boolean;
filterableInDashboard: boolean; filterableInDashboard: boolean;
filterableInStorefront: boolean; filterableInStorefront: boolean;
unit: MeasurementUnitsEnum | null;
} }
export interface PageTypeCreate_pageTypeCreate_pageType { export interface PageTypeCreate_pageTypeCreate_pageType {

View file

@ -3,7 +3,7 @@
// @generated // @generated
// This file was automatically generated and should not be edited. // This file was automatically generated and should not be edited.
import { AttributeTypeEnum } from "./../../types/globalTypes"; import { AttributeTypeEnum, MeasurementUnitsEnum } from "./../../types/globalTypes";
// ==================================================== // ====================================================
// GraphQL query operation: PageTypeDetails // GraphQL query operation: PageTypeDetails
@ -30,6 +30,7 @@ export interface PageTypeDetails_pageType_attributes {
visibleInStorefront: boolean; visibleInStorefront: boolean;
filterableInDashboard: boolean; filterableInDashboard: boolean;
filterableInStorefront: boolean; filterableInStorefront: boolean;
unit: MeasurementUnitsEnum | null;
} }
export interface PageTypeDetails_pageType { export interface PageTypeDetails_pageType {

View file

@ -3,7 +3,7 @@
// @generated // @generated
// This file was automatically generated and should not be edited. // This file was automatically generated and should not be edited.
import { PageTypeUpdateInput, PageErrorCode, AttributeTypeEnum } from "./../../types/globalTypes"; import { PageTypeUpdateInput, PageErrorCode, AttributeTypeEnum, MeasurementUnitsEnum } from "./../../types/globalTypes";
// ==================================================== // ====================================================
// GraphQL mutation operation: PageTypeUpdate // GraphQL mutation operation: PageTypeUpdate
@ -36,6 +36,7 @@ export interface PageTypeUpdate_pageTypeUpdate_pageType_attributes {
visibleInStorefront: boolean; visibleInStorefront: boolean;
filterableInDashboard: boolean; filterableInDashboard: boolean;
filterableInStorefront: boolean; filterableInStorefront: boolean;
unit: MeasurementUnitsEnum | null;
} }
export interface PageTypeUpdate_pageTypeUpdate_pageType { export interface PageTypeUpdate_pageTypeUpdate_pageType {

View file

@ -3,7 +3,7 @@
// @generated // @generated
// This file was automatically generated and should not be edited. // This file was automatically generated and should not be edited.
import { PageErrorCode, AttributeTypeEnum } from "./../../types/globalTypes"; import { PageErrorCode, AttributeTypeEnum, MeasurementUnitsEnum } from "./../../types/globalTypes";
// ==================================================== // ====================================================
// GraphQL mutation operation: UnassignPageAttribute // GraphQL mutation operation: UnassignPageAttribute
@ -36,6 +36,7 @@ export interface UnassignPageAttribute_pageAttributeUnassign_pageType_attributes
visibleInStorefront: boolean; visibleInStorefront: boolean;
filterableInDashboard: boolean; filterableInDashboard: boolean;
filterableInStorefront: boolean; filterableInStorefront: boolean;
unit: MeasurementUnitsEnum | null;
} }
export interface UnassignPageAttribute_pageAttributeUnassign_pageType { export interface UnassignPageAttribute_pageAttributeUnassign_pageType {

View file

@ -48,6 +48,7 @@ export const page: PageDetails_page = {
entityType: null, entityType: null,
inputType: AttributeInputTypeEnum.DROPDOWN, inputType: AttributeInputTypeEnum.DROPDOWN,
valueRequired: false, valueRequired: false,
unit: null,
values: [ values: [
{ {
id: "QXR0cmlidXRlVmFsdWU6ODc=", id: "QXR0cmlidXRlVmFsdWU6ODc=",
@ -100,6 +101,7 @@ export const page: PageDetails_page = {
entityType: null, entityType: null,
inputType: AttributeInputTypeEnum.MULTISELECT, inputType: AttributeInputTypeEnum.MULTISELECT,
valueRequired: false, valueRequired: false,
unit: null,
values: [ values: [
{ {
id: "QXR0cmlidXRlVmFsdWU6OTA=", id: "QXR0cmlidXRlVmFsdWU6OTA=",

View file

@ -3,7 +3,7 @@
// @generated // @generated
// This file was automatically generated and should not be edited. // This file was automatically generated and should not be edited.
import { PageCreateInput, PageErrorCode, AttributeInputTypeEnum, AttributeEntityTypeEnum } from "./../../types/globalTypes"; import { PageCreateInput, PageErrorCode, AttributeInputTypeEnum, AttributeEntityTypeEnum, MeasurementUnitsEnum } from "./../../types/globalTypes";
// ==================================================== // ====================================================
// GraphQL mutation operation: PageCreate // GraphQL mutation operation: PageCreate
@ -41,6 +41,7 @@ export interface PageCreate_pageCreate_page_attributes_attribute {
inputType: AttributeInputTypeEnum | null; inputType: AttributeInputTypeEnum | null;
entityType: AttributeEntityTypeEnum | null; entityType: AttributeEntityTypeEnum | null;
valueRequired: boolean; valueRequired: boolean;
unit: MeasurementUnitsEnum | null;
values: (PageCreate_pageCreate_page_attributes_attribute_values | null)[] | null; values: (PageCreate_pageCreate_page_attributes_attribute_values | null)[] | null;
} }

View file

@ -3,7 +3,7 @@
// @generated // @generated
// This file was automatically generated and should not be edited. // This file was automatically generated and should not be edited.
import { AttributeInputTypeEnum, AttributeEntityTypeEnum } from "./../../types/globalTypes"; import { AttributeInputTypeEnum, AttributeEntityTypeEnum, MeasurementUnitsEnum } from "./../../types/globalTypes";
// ==================================================== // ====================================================
// GraphQL query operation: PageDetails // GraphQL query operation: PageDetails
@ -33,6 +33,7 @@ export interface PageDetails_page_attributes_attribute {
inputType: AttributeInputTypeEnum | null; inputType: AttributeInputTypeEnum | null;
entityType: AttributeEntityTypeEnum | null; entityType: AttributeEntityTypeEnum | null;
valueRequired: boolean; valueRequired: boolean;
unit: MeasurementUnitsEnum | null;
values: (PageDetails_page_attributes_attribute_values | null)[] | null; values: (PageDetails_page_attributes_attribute_values | null)[] | null;
} }

View file

@ -3,7 +3,7 @@
// @generated // @generated
// This file was automatically generated and should not be edited. // This file was automatically generated and should not be edited.
import { PageInput, PageErrorCode, AttributeInputTypeEnum, AttributeEntityTypeEnum } from "./../../types/globalTypes"; import { PageInput, PageErrorCode, AttributeInputTypeEnum, AttributeEntityTypeEnum, MeasurementUnitsEnum } from "./../../types/globalTypes";
// ==================================================== // ====================================================
// GraphQL mutation operation: PageUpdate // GraphQL mutation operation: PageUpdate
@ -40,6 +40,7 @@ export interface PageUpdate_pageUpdate_page_attributes_attribute {
inputType: AttributeInputTypeEnum | null; inputType: AttributeInputTypeEnum | null;
entityType: AttributeEntityTypeEnum | null; entityType: AttributeEntityTypeEnum | null;
valueRequired: boolean; valueRequired: boolean;
unit: MeasurementUnitsEnum | null;
values: (PageUpdate_pageUpdate_page_attributes_attribute_values | null)[] | null; values: (PageUpdate_pageUpdate_page_attributes_attribute_values | null)[] | null;
} }

View file

@ -15,7 +15,8 @@ export function getAttributeInputFromPage(
inputType: attribute.attribute.inputType, inputType: attribute.attribute.inputType,
isRequired: attribute.attribute.valueRequired, isRequired: attribute.attribute.valueRequired,
selectedValues: attribute.values, selectedValues: attribute.values,
values: attribute.attribute.values values: attribute.attribute.values,
unit: attribute.attribute.unit
}, },
id: attribute.attribute.id, id: attribute.attribute.id,
label: attribute.attribute.name, label: attribute.attribute.name,

View file

@ -22,6 +22,7 @@ export const attributes: ProductType_productType_productAttributes[] = [
name: "Author", name: "Author",
slug: "author", slug: "author",
valueRequired: true, valueRequired: true,
unit: null,
values: [ values: [
{ {
__typename: "AttributeValue" as "AttributeValue", __typename: "AttributeValue" as "AttributeValue",
@ -59,6 +60,7 @@ export const attributes: ProductType_productType_productAttributes[] = [
name: "Box Size", name: "Box Size",
slug: "box-size", slug: "box-size",
valueRequired: true, valueRequired: true,
unit: null,
values: [ values: [
{ {
__typename: "AttributeValue" as "AttributeValue", __typename: "AttributeValue" as "AttributeValue",
@ -120,6 +122,7 @@ export const attributes: ProductType_productType_productAttributes[] = [
name: "Brand", name: "Brand",
slug: "brand", slug: "brand",
valueRequired: true, valueRequired: true,
unit: null,
values: [ values: [
{ {
__typename: "AttributeValue" as "AttributeValue", __typename: "AttributeValue" as "AttributeValue",
@ -145,6 +148,7 @@ export const attributes: ProductType_productType_productAttributes[] = [
name: "Candy Box Size", name: "Candy Box Size",
slug: "candy-box-size", slug: "candy-box-size",
valueRequired: true, valueRequired: true,
unit: null,
values: [ values: [
{ {
__typename: "AttributeValue" as "AttributeValue", __typename: "AttributeValue" as "AttributeValue",
@ -194,6 +198,7 @@ export const attributes: ProductType_productType_productAttributes[] = [
name: "Coffee Genre", name: "Coffee Genre",
slug: "coffee-genre", slug: "coffee-genre",
valueRequired: true, valueRequired: true,
unit: null,
values: [ values: [
{ {
__typename: "AttributeValue" as "AttributeValue", __typename: "AttributeValue" as "AttributeValue",
@ -231,6 +236,7 @@ export const attributes: ProductType_productType_productAttributes[] = [
name: "Collar", name: "Collar",
slug: "collar", slug: "collar",
valueRequired: true, valueRequired: true,
unit: null,
values: [ values: [
{ {
__typename: "AttributeValue" as "AttributeValue", __typename: "AttributeValue" as "AttributeValue",
@ -280,6 +286,7 @@ export const attributes: ProductType_productType_productAttributes[] = [
name: "Color", name: "Color",
slug: "color", slug: "color",
valueRequired: true, valueRequired: true,
unit: null,
values: [ values: [
{ {
__typename: "AttributeValue" as "AttributeValue", __typename: "AttributeValue" as "AttributeValue",
@ -317,6 +324,7 @@ export const attributes: ProductType_productType_productAttributes[] = [
name: "Cover", name: "Cover",
slug: "cover", slug: "cover",
valueRequired: true, valueRequired: true,
unit: null,
values: [ values: [
{ {
__typename: "AttributeValue" as "AttributeValue", __typename: "AttributeValue" as "AttributeValue",
@ -402,6 +410,7 @@ export const attributes: ProductType_productType_productAttributes[] = [
name: "Flavor", name: "Flavor",
slug: "flavor", slug: "flavor",
valueRequired: true, valueRequired: true,
unit: null,
values: [ values: [
{ {
__typename: "AttributeValue" as "AttributeValue", __typename: "AttributeValue" as "AttributeValue",
@ -439,6 +448,7 @@ export const attributes: ProductType_productType_productAttributes[] = [
name: "Language", name: "Language",
slug: "language", slug: "language",
valueRequired: true, valueRequired: true,
unit: null,
values: [ values: [
{ {
__typename: "AttributeValue" as "AttributeValue", __typename: "AttributeValue" as "AttributeValue",
@ -476,6 +486,7 @@ export const attributes: ProductType_productType_productAttributes[] = [
name: "Publisher", name: "Publisher",
slug: "publisher", slug: "publisher",
valueRequired: true, valueRequired: true,
unit: null,
values: [ values: [
{ {
__typename: "AttributeValue" as "AttributeValue", __typename: "AttributeValue" as "AttributeValue",
@ -513,6 +524,7 @@ export const attributes: ProductType_productType_productAttributes[] = [
name: "Size", name: "Size",
slug: "size", slug: "size",
valueRequired: true, valueRequired: true,
unit: null,
values: [ values: [
{ {
__typename: "AttributeValue" as "AttributeValue", __typename: "AttributeValue" as "AttributeValue",
@ -680,6 +692,7 @@ export const productTypes: Array<SearchProductTypes_search_edges_node &
__typename: "ProductType" as "ProductType", __typename: "ProductType" as "ProductType",
...productType ...productType
})); }));
export const productType: ProductTypeDetails_productType = { export const productType: ProductTypeDetails_productType = {
__typename: "ProductType" as "ProductType", __typename: "ProductType" as "ProductType",
hasVariants: false, hasVariants: false,
@ -703,7 +716,8 @@ export const productType: ProductTypeDetails_productType = {
name: "Author", name: "Author",
slug: "author", slug: "author",
type: AttributeTypeEnum.PRODUCT_TYPE, type: AttributeTypeEnum.PRODUCT_TYPE,
visibleInStorefront: true visibleInStorefront: true,
unit: null
}, },
{ {
__typename: "Attribute" as "Attribute", __typename: "Attribute" as "Attribute",
@ -713,7 +727,8 @@ export const productType: ProductTypeDetails_productType = {
name: "Language", name: "Language",
slug: "language", slug: "language",
type: AttributeTypeEnum.PRODUCT_TYPE, type: AttributeTypeEnum.PRODUCT_TYPE,
visibleInStorefront: true visibleInStorefront: true,
unit: null
}, },
{ {
__typename: "Attribute" as "Attribute", __typename: "Attribute" as "Attribute",
@ -723,7 +738,8 @@ export const productType: ProductTypeDetails_productType = {
name: "Publisher", name: "Publisher",
slug: "publisher", slug: "publisher",
type: AttributeTypeEnum.PRODUCT_TYPE, type: AttributeTypeEnum.PRODUCT_TYPE,
visibleInStorefront: true visibleInStorefront: true,
unit: null
} }
], ],
taxType: { taxType: {
@ -737,14 +753,16 @@ export const productType: ProductTypeDetails_productType = {
filterableInDashboard: true, filterableInDashboard: true,
filterableInStorefront: false, filterableInStorefront: false,
type: AttributeTypeEnum.PRODUCT_TYPE, type: AttributeTypeEnum.PRODUCT_TYPE,
visibleInStorefront: true visibleInStorefront: true,
unit: null
}, },
{ {
...attributes[6], ...attributes[6],
filterableInDashboard: true, filterableInDashboard: true,
filterableInStorefront: false, filterableInStorefront: false,
type: AttributeTypeEnum.PRODUCT_TYPE, type: AttributeTypeEnum.PRODUCT_TYPE,
visibleInStorefront: true visibleInStorefront: true,
unit: null
} }
], ],
weight: { weight: {

View file

@ -3,7 +3,7 @@
// @generated // @generated
// This file was automatically generated and should not be edited. // This file was automatically generated and should not be edited.
import { ProductAttributeAssignInput, AttributeTypeEnum, WeightUnitsEnum } from "./../../types/globalTypes"; import { ProductAttributeAssignInput, AttributeTypeEnum, MeasurementUnitsEnum, WeightUnitsEnum } from "./../../types/globalTypes";
// ==================================================== // ====================================================
// GraphQL mutation operation: AssignProductAttribute // GraphQL mutation operation: AssignProductAttribute
@ -42,6 +42,7 @@ export interface AssignProductAttribute_productAttributeAssign_productType_produ
visibleInStorefront: boolean; visibleInStorefront: boolean;
filterableInDashboard: boolean; filterableInDashboard: boolean;
filterableInStorefront: boolean; filterableInStorefront: boolean;
unit: MeasurementUnitsEnum | null;
} }
export interface AssignProductAttribute_productAttributeAssign_productType_variantAttributes { export interface AssignProductAttribute_productAttributeAssign_productType_variantAttributes {
@ -53,6 +54,7 @@ export interface AssignProductAttribute_productAttributeAssign_productType_varia
visibleInStorefront: boolean; visibleInStorefront: boolean;
filterableInDashboard: boolean; filterableInDashboard: boolean;
filterableInStorefront: boolean; filterableInStorefront: boolean;
unit: MeasurementUnitsEnum | null;
} }
export interface AssignProductAttribute_productAttributeAssign_productType_weight { export interface AssignProductAttribute_productAttributeAssign_productType_weight {

View file

@ -3,7 +3,7 @@
// @generated // @generated
// This file was automatically generated and should not be edited. // This file was automatically generated and should not be edited.
import { ReorderInput, ProductAttributeType, AttributeTypeEnum, WeightUnitsEnum } from "./../../types/globalTypes"; import { ReorderInput, ProductAttributeType, AttributeTypeEnum, MeasurementUnitsEnum, WeightUnitsEnum } from "./../../types/globalTypes";
// ==================================================== // ====================================================
// GraphQL mutation operation: ProductTypeAttributeReorder // GraphQL mutation operation: ProductTypeAttributeReorder
@ -42,6 +42,7 @@ export interface ProductTypeAttributeReorder_productTypeReorderAttributes_produc
visibleInStorefront: boolean; visibleInStorefront: boolean;
filterableInDashboard: boolean; filterableInDashboard: boolean;
filterableInStorefront: boolean; filterableInStorefront: boolean;
unit: MeasurementUnitsEnum | null;
} }
export interface ProductTypeAttributeReorder_productTypeReorderAttributes_productType_variantAttributes { export interface ProductTypeAttributeReorder_productTypeReorderAttributes_productType_variantAttributes {
@ -53,6 +54,7 @@ export interface ProductTypeAttributeReorder_productTypeReorderAttributes_produc
visibleInStorefront: boolean; visibleInStorefront: boolean;
filterableInDashboard: boolean; filterableInDashboard: boolean;
filterableInStorefront: boolean; filterableInStorefront: boolean;
unit: MeasurementUnitsEnum | null;
} }
export interface ProductTypeAttributeReorder_productTypeReorderAttributes_productType_weight { export interface ProductTypeAttributeReorder_productTypeReorderAttributes_productType_weight {

View file

@ -3,7 +3,7 @@
// @generated // @generated
// This file was automatically generated and should not be edited. // This file was automatically generated and should not be edited.
import { ProductTypeInput, AttributeTypeEnum, WeightUnitsEnum } from "./../../types/globalTypes"; import { ProductTypeInput, AttributeTypeEnum, MeasurementUnitsEnum, WeightUnitsEnum } from "./../../types/globalTypes";
// ==================================================== // ====================================================
// GraphQL mutation operation: ProductTypeCreate // GraphQL mutation operation: ProductTypeCreate
@ -42,6 +42,7 @@ export interface ProductTypeCreate_productTypeCreate_productType_productAttribut
visibleInStorefront: boolean; visibleInStorefront: boolean;
filterableInDashboard: boolean; filterableInDashboard: boolean;
filterableInStorefront: boolean; filterableInStorefront: boolean;
unit: MeasurementUnitsEnum | null;
} }
export interface ProductTypeCreate_productTypeCreate_productType_variantAttributes { export interface ProductTypeCreate_productTypeCreate_productType_variantAttributes {
@ -53,6 +54,7 @@ export interface ProductTypeCreate_productTypeCreate_productType_variantAttribut
visibleInStorefront: boolean; visibleInStorefront: boolean;
filterableInDashboard: boolean; filterableInDashboard: boolean;
filterableInStorefront: boolean; filterableInStorefront: boolean;
unit: MeasurementUnitsEnum | null;
} }
export interface ProductTypeCreate_productTypeCreate_productType_weight { export interface ProductTypeCreate_productTypeCreate_productType_weight {

View file

@ -3,7 +3,7 @@
// @generated // @generated
// This file was automatically generated and should not be edited. // This file was automatically generated and should not be edited.
import { AttributeTypeEnum, WeightUnitsEnum } from "./../../types/globalTypes"; import { AttributeTypeEnum, MeasurementUnitsEnum, WeightUnitsEnum } from "./../../types/globalTypes";
// ==================================================== // ====================================================
// GraphQL query operation: ProductTypeDetails // GraphQL query operation: ProductTypeDetails
@ -36,6 +36,7 @@ export interface ProductTypeDetails_productType_productAttributes {
visibleInStorefront: boolean; visibleInStorefront: boolean;
filterableInDashboard: boolean; filterableInDashboard: boolean;
filterableInStorefront: boolean; filterableInStorefront: boolean;
unit: MeasurementUnitsEnum | null;
} }
export interface ProductTypeDetails_productType_variantAttributes { export interface ProductTypeDetails_productType_variantAttributes {
@ -47,6 +48,7 @@ export interface ProductTypeDetails_productType_variantAttributes {
visibleInStorefront: boolean; visibleInStorefront: boolean;
filterableInDashboard: boolean; filterableInDashboard: boolean;
filterableInStorefront: boolean; filterableInStorefront: boolean;
unit: MeasurementUnitsEnum | null;
} }
export interface ProductTypeDetails_productType_weight { export interface ProductTypeDetails_productType_weight {

View file

@ -3,7 +3,7 @@
// @generated // @generated
// This file was automatically generated and should not be edited. // This file was automatically generated and should not be edited.
import { ProductTypeInput, AttributeTypeEnum, WeightUnitsEnum } from "./../../types/globalTypes"; import { ProductTypeInput, AttributeTypeEnum, MeasurementUnitsEnum, WeightUnitsEnum } from "./../../types/globalTypes";
// ==================================================== // ====================================================
// GraphQL mutation operation: ProductTypeUpdate // GraphQL mutation operation: ProductTypeUpdate
@ -42,6 +42,7 @@ export interface ProductTypeUpdate_productTypeUpdate_productType_productAttribut
visibleInStorefront: boolean; visibleInStorefront: boolean;
filterableInDashboard: boolean; filterableInDashboard: boolean;
filterableInStorefront: boolean; filterableInStorefront: boolean;
unit: MeasurementUnitsEnum | null;
} }
export interface ProductTypeUpdate_productTypeUpdate_productType_variantAttributes { export interface ProductTypeUpdate_productTypeUpdate_productType_variantAttributes {
@ -53,6 +54,7 @@ export interface ProductTypeUpdate_productTypeUpdate_productType_variantAttribut
visibleInStorefront: boolean; visibleInStorefront: boolean;
filterableInDashboard: boolean; filterableInDashboard: boolean;
filterableInStorefront: boolean; filterableInStorefront: boolean;
unit: MeasurementUnitsEnum | null;
} }
export interface ProductTypeUpdate_productTypeUpdate_productType_weight { export interface ProductTypeUpdate_productTypeUpdate_productType_weight {

View file

@ -3,7 +3,7 @@
// @generated // @generated
// This file was automatically generated and should not be edited. // This file was automatically generated and should not be edited.
import { AttributeTypeEnum, WeightUnitsEnum } from "./../../types/globalTypes"; import { AttributeTypeEnum, MeasurementUnitsEnum, WeightUnitsEnum } from "./../../types/globalTypes";
// ==================================================== // ====================================================
// GraphQL mutation operation: UnassignProductAttribute // GraphQL mutation operation: UnassignProductAttribute
@ -42,6 +42,7 @@ export interface UnassignProductAttribute_productAttributeUnassign_productType_p
visibleInStorefront: boolean; visibleInStorefront: boolean;
filterableInDashboard: boolean; filterableInDashboard: boolean;
filterableInStorefront: boolean; filterableInStorefront: boolean;
unit: MeasurementUnitsEnum | null;
} }
export interface UnassignProductAttribute_productAttributeUnassign_productType_variantAttributes { export interface UnassignProductAttribute_productAttributeUnassign_productType_variantAttributes {
@ -53,6 +54,7 @@ export interface UnassignProductAttribute_productAttributeUnassign_productType_v
visibleInStorefront: boolean; visibleInStorefront: boolean;
filterableInDashboard: boolean; filterableInDashboard: boolean;
filterableInStorefront: boolean; filterableInStorefront: boolean;
unit: MeasurementUnitsEnum | null;
} }
export interface UnassignProductAttribute_productAttributeUnassign_productType_weight { export interface UnassignProductAttribute_productAttributeUnassign_productType_weight {

View file

@ -29,6 +29,7 @@ export const product: (
name: "Borders", name: "Borders",
slug: "Borders", slug: "Borders",
valueRequired: false, valueRequired: false,
unit: null,
values: [ values: [
{ {
__typename: "AttributeValue", __typename: "AttributeValue",
@ -72,6 +73,7 @@ export const product: (
name: "Legacy", name: "Legacy",
slug: "Legacy", slug: "Legacy",
valueRequired: true, valueRequired: true,
unit: null,
values: [ values: [
{ {
__typename: "AttributeValue", __typename: "AttributeValue",
@ -289,6 +291,7 @@ export const product: (
name: "Attachment", name: "Attachment",
slug: "attachment", slug: "attachment",
valueRequired: true, valueRequired: true,
unit: null,
values: [ values: [
{ {
__typename: "AttributeValue", __typename: "AttributeValue",
@ -315,6 +318,7 @@ export const product: (
name: "Color", name: "Color",
slug: "color", slug: "color",
valueRequired: true, valueRequired: true,
unit: null,
values: [ values: [
{ {
__typename: "AttributeValue", __typename: "AttributeValue",
@ -2778,6 +2782,7 @@ export const variant = (placeholderImage: string): ProductVariant => ({
name: "Attachment", name: "Attachment",
slug: "attachment", slug: "attachment",
valueRequired: true, valueRequired: true,
unit: null,
values: [ values: [
{ {
__typename: "AttributeValue", __typename: "AttributeValue",
@ -3046,6 +3051,7 @@ export const variant = (placeholderImage: string): ProductVariant => ({
name: "Borders", name: "Borders",
slug: "Borders", slug: "Borders",
valueRequired: true, valueRequired: true,
unit: null,
values: [ values: [
{ {
__typename: "AttributeValue", __typename: "AttributeValue",
@ -3089,6 +3095,7 @@ export const variant = (placeholderImage: string): ProductVariant => ({
name: "Legacy", name: "Legacy",
slug: "Legacy", slug: "Legacy",
valueRequired: true, valueRequired: true,
unit: null,
values: [ values: [
{ {
__typename: "AttributeValue", __typename: "AttributeValue",

View file

@ -219,6 +219,7 @@ const productTypeQuery = gql`
slug slug
name name
valueRequired valueRequired
unit
values { values {
...AttributeValueFragment ...AttributeValueFragment
} }

View file

@ -3,7 +3,7 @@
// @generated // @generated
// This file was automatically generated and should not be edited. // This file was automatically generated and should not be edited.
import { AttributeInputTypeEnum, AttributeEntityTypeEnum } from "./../../types/globalTypes"; import { AttributeInputTypeEnum, AttributeEntityTypeEnum, MeasurementUnitsEnum } from "./../../types/globalTypes";
// ==================================================== // ====================================================
// GraphQL query operation: CreateMultipleVariantsData // GraphQL query operation: CreateMultipleVariantsData
@ -33,6 +33,7 @@ export interface CreateMultipleVariantsData_product_attributes_attribute {
inputType: AttributeInputTypeEnum | null; inputType: AttributeInputTypeEnum | null;
entityType: AttributeEntityTypeEnum | null; entityType: AttributeEntityTypeEnum | null;
valueRequired: boolean; valueRequired: boolean;
unit: MeasurementUnitsEnum | null;
values: (CreateMultipleVariantsData_product_attributes_attribute_values | null)[] | null; values: (CreateMultipleVariantsData_product_attributes_attribute_values | null)[] | null;
} }

View file

@ -3,7 +3,7 @@
// @generated // @generated
// This file was automatically generated and should not be edited. // This file was automatically generated and should not be edited.
import { ProductChannelListingUpdateInput, AttributeInputTypeEnum, AttributeEntityTypeEnum, ProductMediaType, WeightUnitsEnum, ProductErrorCode } from "./../../types/globalTypes"; import { ProductChannelListingUpdateInput, AttributeInputTypeEnum, AttributeEntityTypeEnum, MeasurementUnitsEnum, ProductMediaType, WeightUnitsEnum, ProductErrorCode } from "./../../types/globalTypes";
// ==================================================== // ====================================================
// GraphQL mutation operation: ProductChannelListingUpdate // GraphQL mutation operation: ProductChannelListingUpdate
@ -33,6 +33,7 @@ export interface ProductChannelListingUpdate_productChannelListingUpdate_product
inputType: AttributeInputTypeEnum | null; inputType: AttributeInputTypeEnum | null;
entityType: AttributeEntityTypeEnum | null; entityType: AttributeEntityTypeEnum | null;
valueRequired: boolean; valueRequired: boolean;
unit: MeasurementUnitsEnum | null;
values: (ProductChannelListingUpdate_productChannelListingUpdate_product_attributes_attribute_values | null)[] | null; values: (ProductChannelListingUpdate_productChannelListingUpdate_product_attributes_attribute_values | null)[] | null;
} }

View file

@ -3,7 +3,7 @@
// @generated // @generated
// This file was automatically generated and should not be edited. // This file was automatically generated and should not be edited.
import { ProductCreateInput, ProductErrorCode, AttributeInputTypeEnum, AttributeEntityTypeEnum, ProductMediaType, WeightUnitsEnum } from "./../../types/globalTypes"; import { ProductCreateInput, ProductErrorCode, AttributeInputTypeEnum, AttributeEntityTypeEnum, MeasurementUnitsEnum, ProductMediaType, WeightUnitsEnum } from "./../../types/globalTypes";
// ==================================================== // ====================================================
// GraphQL mutation operation: ProductCreate // GraphQL mutation operation: ProductCreate
@ -40,6 +40,7 @@ export interface ProductCreate_productCreate_product_attributes_attribute {
inputType: AttributeInputTypeEnum | null; inputType: AttributeInputTypeEnum | null;
entityType: AttributeEntityTypeEnum | null; entityType: AttributeEntityTypeEnum | null;
valueRequired: boolean; valueRequired: boolean;
unit: MeasurementUnitsEnum | null;
values: (ProductCreate_productCreate_product_attributes_attribute_values | null)[] | null; values: (ProductCreate_productCreate_product_attributes_attribute_values | null)[] | null;
} }

View file

@ -3,7 +3,7 @@
// @generated // @generated
// This file was automatically generated and should not be edited. // This file was automatically generated and should not be edited.
import { AttributeInputTypeEnum, AttributeEntityTypeEnum, ProductMediaType, WeightUnitsEnum } from "./../../types/globalTypes"; import { AttributeInputTypeEnum, AttributeEntityTypeEnum, MeasurementUnitsEnum, ProductMediaType, WeightUnitsEnum } from "./../../types/globalTypes";
// ==================================================== // ====================================================
// GraphQL query operation: ProductDetails // GraphQL query operation: ProductDetails
@ -33,6 +33,7 @@ export interface ProductDetails_product_attributes_attribute {
inputType: AttributeInputTypeEnum | null; inputType: AttributeInputTypeEnum | null;
entityType: AttributeEntityTypeEnum | null; entityType: AttributeEntityTypeEnum | null;
valueRequired: boolean; valueRequired: boolean;
unit: MeasurementUnitsEnum | null;
values: (ProductDetails_product_attributes_attribute_values | null)[] | null; values: (ProductDetails_product_attributes_attribute_values | null)[] | null;
} }

View file

@ -3,7 +3,7 @@
// @generated // @generated
// This file was automatically generated and should not be edited. // This file was automatically generated and should not be edited.
import { ProductErrorCode, AttributeInputTypeEnum, AttributeEntityTypeEnum, ProductMediaType, WeightUnitsEnum } from "./../../types/globalTypes"; import { ProductErrorCode, AttributeInputTypeEnum, AttributeEntityTypeEnum, MeasurementUnitsEnum, ProductMediaType, WeightUnitsEnum } from "./../../types/globalTypes";
// ==================================================== // ====================================================
// GraphQL mutation operation: ProductMediaCreate // GraphQL mutation operation: ProductMediaCreate
@ -39,6 +39,7 @@ export interface ProductMediaCreate_productMediaCreate_product_attributes_attrib
inputType: AttributeInputTypeEnum | null; inputType: AttributeInputTypeEnum | null;
entityType: AttributeEntityTypeEnum | null; entityType: AttributeEntityTypeEnum | null;
valueRequired: boolean; valueRequired: boolean;
unit: MeasurementUnitsEnum | null;
values: (ProductMediaCreate_productMediaCreate_product_attributes_attribute_values | null)[] | null; values: (ProductMediaCreate_productMediaCreate_product_attributes_attribute_values | null)[] | null;
} }

View file

@ -3,7 +3,7 @@
// @generated // @generated
// This file was automatically generated and should not be edited. // This file was automatically generated and should not be edited.
import { ProductErrorCode, AttributeInputTypeEnum, AttributeEntityTypeEnum, ProductMediaType, WeightUnitsEnum } from "./../../types/globalTypes"; import { ProductErrorCode, AttributeInputTypeEnum, AttributeEntityTypeEnum, MeasurementUnitsEnum, ProductMediaType, WeightUnitsEnum } from "./../../types/globalTypes";
// ==================================================== // ====================================================
// GraphQL mutation operation: ProductMediaUpdate // GraphQL mutation operation: ProductMediaUpdate
@ -39,6 +39,7 @@ export interface ProductMediaUpdate_productMediaUpdate_product_attributes_attrib
inputType: AttributeInputTypeEnum | null; inputType: AttributeInputTypeEnum | null;
entityType: AttributeEntityTypeEnum | null; entityType: AttributeEntityTypeEnum | null;
valueRequired: boolean; valueRequired: boolean;
unit: MeasurementUnitsEnum | null;
values: (ProductMediaUpdate_productMediaUpdate_product_attributes_attribute_values | null)[] | null; values: (ProductMediaUpdate_productMediaUpdate_product_attributes_attribute_values | null)[] | null;
} }

View file

@ -3,7 +3,7 @@
// @generated // @generated
// This file was automatically generated and should not be edited. // This file was automatically generated and should not be edited.
import { AttributeInputTypeEnum, AttributeEntityTypeEnum } from "./../../types/globalTypes"; import { AttributeInputTypeEnum, AttributeEntityTypeEnum, MeasurementUnitsEnum } from "./../../types/globalTypes";
// ==================================================== // ====================================================
// GraphQL query operation: ProductType // GraphQL query operation: ProductType
@ -33,6 +33,7 @@ export interface ProductType_productType_productAttributes {
slug: string | null; slug: string | null;
name: string | null; name: string | null;
valueRequired: boolean; valueRequired: boolean;
unit: MeasurementUnitsEnum | null;
values: (ProductType_productType_productAttributes_values | null)[] | null; values: (ProductType_productType_productAttributes_values | null)[] | null;
} }

View file

@ -3,7 +3,7 @@
// @generated // @generated
// This file was automatically generated and should not be edited. // This file was automatically generated and should not be edited.
import { ProductInput, ProductErrorCode, AttributeInputTypeEnum, AttributeEntityTypeEnum, ProductMediaType, WeightUnitsEnum } from "./../../types/globalTypes"; import { ProductInput, ProductErrorCode, AttributeInputTypeEnum, AttributeEntityTypeEnum, MeasurementUnitsEnum, ProductMediaType, WeightUnitsEnum } from "./../../types/globalTypes";
// ==================================================== // ====================================================
// GraphQL mutation operation: ProductUpdate // GraphQL mutation operation: ProductUpdate
@ -40,6 +40,7 @@ export interface ProductUpdate_productUpdate_product_attributes_attribute {
inputType: AttributeInputTypeEnum | null; inputType: AttributeInputTypeEnum | null;
entityType: AttributeEntityTypeEnum | null; entityType: AttributeEntityTypeEnum | null;
valueRequired: boolean; valueRequired: boolean;
unit: MeasurementUnitsEnum | null;
values: (ProductUpdate_productUpdate_product_attributes_attribute_values | null)[] | null; values: (ProductUpdate_productUpdate_product_attributes_attribute_values | null)[] | null;
} }

View file

@ -3,7 +3,7 @@
// @generated // @generated
// This file was automatically generated and should not be edited. // This file was automatically generated and should not be edited.
import { ProductVariantChannelListingAddInput, AttributeInputTypeEnum, AttributeEntityTypeEnum, ProductMediaType, WeightUnitsEnum, ProductErrorCode } from "./../../types/globalTypes"; import { ProductVariantChannelListingAddInput, AttributeInputTypeEnum, AttributeEntityTypeEnum, MeasurementUnitsEnum, ProductMediaType, WeightUnitsEnum, ProductErrorCode } from "./../../types/globalTypes";
// ==================================================== // ====================================================
// GraphQL mutation operation: ProductVariantChannelListingUpdate // GraphQL mutation operation: ProductVariantChannelListingUpdate
@ -45,6 +45,7 @@ export interface ProductVariantChannelListingUpdate_productVariantChannelListing
inputType: AttributeInputTypeEnum | null; inputType: AttributeInputTypeEnum | null;
entityType: AttributeEntityTypeEnum | null; entityType: AttributeEntityTypeEnum | null;
valueRequired: boolean; valueRequired: boolean;
unit: MeasurementUnitsEnum | null;
values: (ProductVariantChannelListingUpdate_productVariantChannelListingUpdate_variant_selectionAttributes_attribute_values | null)[] | null; values: (ProductVariantChannelListingUpdate_productVariantChannelListingUpdate_variant_selectionAttributes_attribute_values | null)[] | null;
} }
@ -94,6 +95,7 @@ export interface ProductVariantChannelListingUpdate_productVariantChannelListing
inputType: AttributeInputTypeEnum | null; inputType: AttributeInputTypeEnum | null;
entityType: AttributeEntityTypeEnum | null; entityType: AttributeEntityTypeEnum | null;
valueRequired: boolean; valueRequired: boolean;
unit: MeasurementUnitsEnum | null;
values: (ProductVariantChannelListingUpdate_productVariantChannelListingUpdate_variant_nonSelectionAttributes_attribute_values | null)[] | null; values: (ProductVariantChannelListingUpdate_productVariantChannelListingUpdate_variant_nonSelectionAttributes_attribute_values | null)[] | null;
} }

View file

@ -3,7 +3,7 @@
// @generated // @generated
// This file was automatically generated and should not be edited. // This file was automatically generated and should not be edited.
import { AttributeInputTypeEnum, AttributeEntityTypeEnum, ProductMediaType } from "./../../types/globalTypes"; import { AttributeInputTypeEnum, AttributeEntityTypeEnum, MeasurementUnitsEnum, ProductMediaType } from "./../../types/globalTypes";
// ==================================================== // ====================================================
// GraphQL query operation: ProductVariantCreateData // GraphQL query operation: ProductVariantCreateData
@ -52,6 +52,7 @@ export interface ProductVariantCreateData_product_productType_selectionVariantAt
inputType: AttributeInputTypeEnum | null; inputType: AttributeInputTypeEnum | null;
entityType: AttributeEntityTypeEnum | null; entityType: AttributeEntityTypeEnum | null;
valueRequired: boolean; valueRequired: boolean;
unit: MeasurementUnitsEnum | null;
values: (ProductVariantCreateData_product_productType_selectionVariantAttributes_values | null)[] | null; values: (ProductVariantCreateData_product_productType_selectionVariantAttributes_values | null)[] | null;
} }
@ -79,6 +80,7 @@ export interface ProductVariantCreateData_product_productType_nonSelectionVarian
inputType: AttributeInputTypeEnum | null; inputType: AttributeInputTypeEnum | null;
entityType: AttributeEntityTypeEnum | null; entityType: AttributeEntityTypeEnum | null;
valueRequired: boolean; valueRequired: boolean;
unit: MeasurementUnitsEnum | null;
values: (ProductVariantCreateData_product_productType_nonSelectionVariantAttributes_values | null)[] | null; values: (ProductVariantCreateData_product_productType_nonSelectionVariantAttributes_values | null)[] | null;
} }

View file

@ -3,7 +3,7 @@
// @generated // @generated
// This file was automatically generated and should not be edited. // This file was automatically generated and should not be edited.
import { AttributeInputTypeEnum, AttributeEntityTypeEnum, ProductMediaType, WeightUnitsEnum } from "./../../types/globalTypes"; import { AttributeInputTypeEnum, AttributeEntityTypeEnum, MeasurementUnitsEnum, ProductMediaType, WeightUnitsEnum } from "./../../types/globalTypes";
// ==================================================== // ====================================================
// GraphQL query operation: ProductVariantDetails // GraphQL query operation: ProductVariantDetails
@ -45,6 +45,7 @@ export interface ProductVariantDetails_productVariant_selectionAttributes_attrib
inputType: AttributeInputTypeEnum | null; inputType: AttributeInputTypeEnum | null;
entityType: AttributeEntityTypeEnum | null; entityType: AttributeEntityTypeEnum | null;
valueRequired: boolean; valueRequired: boolean;
unit: MeasurementUnitsEnum | null;
values: (ProductVariantDetails_productVariant_selectionAttributes_attribute_values | null)[] | null; values: (ProductVariantDetails_productVariant_selectionAttributes_attribute_values | null)[] | null;
} }
@ -94,6 +95,7 @@ export interface ProductVariantDetails_productVariant_nonSelectionAttributes_att
inputType: AttributeInputTypeEnum | null; inputType: AttributeInputTypeEnum | null;
entityType: AttributeEntityTypeEnum | null; entityType: AttributeEntityTypeEnum | null;
valueRequired: boolean; valueRequired: boolean;
unit: MeasurementUnitsEnum | null;
values: (ProductVariantDetails_productVariant_nonSelectionAttributes_attribute_values | null)[] | null; values: (ProductVariantDetails_productVariant_nonSelectionAttributes_attribute_values | null)[] | null;
} }

View file

@ -3,7 +3,7 @@
// @generated // @generated
// This file was automatically generated and should not be edited. // This file was automatically generated and should not be edited.
import { ReorderInput, ProductErrorCode, AttributeInputTypeEnum, AttributeEntityTypeEnum, ProductMediaType, WeightUnitsEnum } from "./../../types/globalTypes"; import { ReorderInput, ProductErrorCode, AttributeInputTypeEnum, AttributeEntityTypeEnum, MeasurementUnitsEnum, ProductMediaType, WeightUnitsEnum } from "./../../types/globalTypes";
// ==================================================== // ====================================================
// GraphQL mutation operation: ProductVariantReorder // GraphQL mutation operation: ProductVariantReorder
@ -39,6 +39,7 @@ export interface ProductVariantReorder_productVariantReorder_product_attributes_
inputType: AttributeInputTypeEnum | null; inputType: AttributeInputTypeEnum | null;
entityType: AttributeEntityTypeEnum | null; entityType: AttributeEntityTypeEnum | null;
valueRequired: boolean; valueRequired: boolean;
unit: MeasurementUnitsEnum | null;
values: (ProductVariantReorder_productVariantReorder_product_attributes_attribute_values | null)[] | null; values: (ProductVariantReorder_productVariantReorder_product_attributes_attribute_values | null)[] | null;
} }

View file

@ -3,7 +3,7 @@
// @generated // @generated
// This file was automatically generated and should not be edited. // This file was automatically generated and should not be edited.
import { ProductErrorCode, AttributeInputTypeEnum, AttributeEntityTypeEnum, ProductMediaType, WeightUnitsEnum } from "./../../types/globalTypes"; import { ProductErrorCode, AttributeInputTypeEnum, AttributeEntityTypeEnum, MeasurementUnitsEnum, ProductMediaType, WeightUnitsEnum } from "./../../types/globalTypes";
// ==================================================== // ====================================================
// GraphQL mutation operation: ProductVariantSetDefault // GraphQL mutation operation: ProductVariantSetDefault
@ -39,6 +39,7 @@ export interface ProductVariantSetDefault_productVariantSetDefault_product_attri
inputType: AttributeInputTypeEnum | null; inputType: AttributeInputTypeEnum | null;
entityType: AttributeEntityTypeEnum | null; entityType: AttributeEntityTypeEnum | null;
valueRequired: boolean; valueRequired: boolean;
unit: MeasurementUnitsEnum | null;
values: (ProductVariantSetDefault_productVariantSetDefault_product_attributes_attribute_values | null)[] | null; values: (ProductVariantSetDefault_productVariantSetDefault_product_attributes_attribute_values | null)[] | null;
} }

View file

@ -3,7 +3,7 @@
// @generated // @generated
// This file was automatically generated and should not be edited. // This file was automatically generated and should not be edited.
import { ProductInput, ProductVariantInput, StockInput, ProductErrorCode, AttributeInputTypeEnum, AttributeEntityTypeEnum, ProductMediaType, WeightUnitsEnum, StockErrorCode } from "./../../types/globalTypes"; import { ProductInput, ProductVariantInput, StockInput, ProductErrorCode, AttributeInputTypeEnum, AttributeEntityTypeEnum, MeasurementUnitsEnum, ProductMediaType, WeightUnitsEnum, StockErrorCode } from "./../../types/globalTypes";
// ==================================================== // ====================================================
// GraphQL mutation operation: SimpleProductUpdate // GraphQL mutation operation: SimpleProductUpdate
@ -40,6 +40,7 @@ export interface SimpleProductUpdate_productUpdate_product_attributes_attribute
inputType: AttributeInputTypeEnum | null; inputType: AttributeInputTypeEnum | null;
entityType: AttributeEntityTypeEnum | null; entityType: AttributeEntityTypeEnum | null;
valueRequired: boolean; valueRequired: boolean;
unit: MeasurementUnitsEnum | null;
values: (SimpleProductUpdate_productUpdate_product_attributes_attribute_values | null)[] | null; values: (SimpleProductUpdate_productUpdate_product_attributes_attribute_values | null)[] | null;
} }
@ -336,6 +337,7 @@ export interface SimpleProductUpdate_productVariantUpdate_productVariant_selecti
inputType: AttributeInputTypeEnum | null; inputType: AttributeInputTypeEnum | null;
entityType: AttributeEntityTypeEnum | null; entityType: AttributeEntityTypeEnum | null;
valueRequired: boolean; valueRequired: boolean;
unit: MeasurementUnitsEnum | null;
values: (SimpleProductUpdate_productVariantUpdate_productVariant_selectionAttributes_attribute_values | null)[] | null; values: (SimpleProductUpdate_productVariantUpdate_productVariant_selectionAttributes_attribute_values | null)[] | null;
} }
@ -385,6 +387,7 @@ export interface SimpleProductUpdate_productVariantUpdate_productVariant_nonSele
inputType: AttributeInputTypeEnum | null; inputType: AttributeInputTypeEnum | null;
entityType: AttributeEntityTypeEnum | null; entityType: AttributeEntityTypeEnum | null;
valueRequired: boolean; valueRequired: boolean;
unit: MeasurementUnitsEnum | null;
values: (SimpleProductUpdate_productVariantUpdate_productVariant_nonSelectionAttributes_attribute_values | null)[] | null; values: (SimpleProductUpdate_productVariantUpdate_productVariant_nonSelectionAttributes_attribute_values | null)[] | null;
} }
@ -625,6 +628,7 @@ export interface SimpleProductUpdate_productVariantStocksCreate_productVariant_s
inputType: AttributeInputTypeEnum | null; inputType: AttributeInputTypeEnum | null;
entityType: AttributeEntityTypeEnum | null; entityType: AttributeEntityTypeEnum | null;
valueRequired: boolean; valueRequired: boolean;
unit: MeasurementUnitsEnum | null;
values: (SimpleProductUpdate_productVariantStocksCreate_productVariant_selectionAttributes_attribute_values | null)[] | null; values: (SimpleProductUpdate_productVariantStocksCreate_productVariant_selectionAttributes_attribute_values | null)[] | null;
} }
@ -674,6 +678,7 @@ export interface SimpleProductUpdate_productVariantStocksCreate_productVariant_n
inputType: AttributeInputTypeEnum | null; inputType: AttributeInputTypeEnum | null;
entityType: AttributeEntityTypeEnum | null; entityType: AttributeEntityTypeEnum | null;
valueRequired: boolean; valueRequired: boolean;
unit: MeasurementUnitsEnum | null;
values: (SimpleProductUpdate_productVariantStocksCreate_productVariant_nonSelectionAttributes_attribute_values | null)[] | null; values: (SimpleProductUpdate_productVariantStocksCreate_productVariant_nonSelectionAttributes_attribute_values | null)[] | null;
} }
@ -913,6 +918,7 @@ export interface SimpleProductUpdate_productVariantStocksDelete_productVariant_s
inputType: AttributeInputTypeEnum | null; inputType: AttributeInputTypeEnum | null;
entityType: AttributeEntityTypeEnum | null; entityType: AttributeEntityTypeEnum | null;
valueRequired: boolean; valueRequired: boolean;
unit: MeasurementUnitsEnum | null;
values: (SimpleProductUpdate_productVariantStocksDelete_productVariant_selectionAttributes_attribute_values | null)[] | null; values: (SimpleProductUpdate_productVariantStocksDelete_productVariant_selectionAttributes_attribute_values | null)[] | null;
} }
@ -962,6 +968,7 @@ export interface SimpleProductUpdate_productVariantStocksDelete_productVariant_n
inputType: AttributeInputTypeEnum | null; inputType: AttributeInputTypeEnum | null;
entityType: AttributeEntityTypeEnum | null; entityType: AttributeEntityTypeEnum | null;
valueRequired: boolean; valueRequired: boolean;
unit: MeasurementUnitsEnum | null;
values: (SimpleProductUpdate_productVariantStocksDelete_productVariant_nonSelectionAttributes_attribute_values | null)[] | null; values: (SimpleProductUpdate_productVariantStocksDelete_productVariant_nonSelectionAttributes_attribute_values | null)[] | null;
} }
@ -1202,6 +1209,7 @@ export interface SimpleProductUpdate_productVariantStocksUpdate_productVariant_s
inputType: AttributeInputTypeEnum | null; inputType: AttributeInputTypeEnum | null;
entityType: AttributeEntityTypeEnum | null; entityType: AttributeEntityTypeEnum | null;
valueRequired: boolean; valueRequired: boolean;
unit: MeasurementUnitsEnum | null;
values: (SimpleProductUpdate_productVariantStocksUpdate_productVariant_selectionAttributes_attribute_values | null)[] | null; values: (SimpleProductUpdate_productVariantStocksUpdate_productVariant_selectionAttributes_attribute_values | null)[] | null;
} }
@ -1251,6 +1259,7 @@ export interface SimpleProductUpdate_productVariantStocksUpdate_productVariant_n
inputType: AttributeInputTypeEnum | null; inputType: AttributeInputTypeEnum | null;
entityType: AttributeEntityTypeEnum | null; entityType: AttributeEntityTypeEnum | null;
valueRequired: boolean; valueRequired: boolean;
unit: MeasurementUnitsEnum | null;
values: (SimpleProductUpdate_productVariantStocksUpdate_productVariant_nonSelectionAttributes_attribute_values | null)[] | null; values: (SimpleProductUpdate_productVariantStocksUpdate_productVariant_nonSelectionAttributes_attribute_values | null)[] | null;
} }

View file

@ -3,7 +3,7 @@
// @generated // @generated
// This file was automatically generated and should not be edited. // This file was automatically generated and should not be edited.
import { ProductVariantCreateInput, ProductErrorCode, AttributeInputTypeEnum, AttributeEntityTypeEnum, ProductMediaType, WeightUnitsEnum } from "./../../types/globalTypes"; import { ProductVariantCreateInput, ProductErrorCode, AttributeInputTypeEnum, AttributeEntityTypeEnum, MeasurementUnitsEnum, ProductMediaType, WeightUnitsEnum } from "./../../types/globalTypes";
// ==================================================== // ====================================================
// GraphQL mutation operation: VariantCreate // GraphQL mutation operation: VariantCreate
@ -52,6 +52,7 @@ export interface VariantCreate_productVariantCreate_productVariant_selectionAttr
inputType: AttributeInputTypeEnum | null; inputType: AttributeInputTypeEnum | null;
entityType: AttributeEntityTypeEnum | null; entityType: AttributeEntityTypeEnum | null;
valueRequired: boolean; valueRequired: boolean;
unit: MeasurementUnitsEnum | null;
values: (VariantCreate_productVariantCreate_productVariant_selectionAttributes_attribute_values | null)[] | null; values: (VariantCreate_productVariantCreate_productVariant_selectionAttributes_attribute_values | null)[] | null;
} }
@ -101,6 +102,7 @@ export interface VariantCreate_productVariantCreate_productVariant_nonSelectionA
inputType: AttributeInputTypeEnum | null; inputType: AttributeInputTypeEnum | null;
entityType: AttributeEntityTypeEnum | null; entityType: AttributeEntityTypeEnum | null;
valueRequired: boolean; valueRequired: boolean;
unit: MeasurementUnitsEnum | null;
values: (VariantCreate_productVariantCreate_productVariant_nonSelectionAttributes_attribute_values | null)[] | null; values: (VariantCreate_productVariantCreate_productVariant_nonSelectionAttributes_attribute_values | null)[] | null;
} }

View file

@ -3,7 +3,7 @@
// @generated // @generated
// This file was automatically generated and should not be edited. // This file was automatically generated and should not be edited.
import { ProductErrorCode, AttributeInputTypeEnum, AttributeEntityTypeEnum, ProductMediaType, WeightUnitsEnum } from "./../../types/globalTypes"; import { ProductErrorCode, AttributeInputTypeEnum, AttributeEntityTypeEnum, MeasurementUnitsEnum, ProductMediaType, WeightUnitsEnum } from "./../../types/globalTypes";
// ==================================================== // ====================================================
// GraphQL mutation operation: VariantMediaAssign // GraphQL mutation operation: VariantMediaAssign
@ -51,6 +51,7 @@ export interface VariantMediaAssign_variantMediaAssign_productVariant_selectionA
inputType: AttributeInputTypeEnum | null; inputType: AttributeInputTypeEnum | null;
entityType: AttributeEntityTypeEnum | null; entityType: AttributeEntityTypeEnum | null;
valueRequired: boolean; valueRequired: boolean;
unit: MeasurementUnitsEnum | null;
values: (VariantMediaAssign_variantMediaAssign_productVariant_selectionAttributes_attribute_values | null)[] | null; values: (VariantMediaAssign_variantMediaAssign_productVariant_selectionAttributes_attribute_values | null)[] | null;
} }
@ -100,6 +101,7 @@ export interface VariantMediaAssign_variantMediaAssign_productVariant_nonSelecti
inputType: AttributeInputTypeEnum | null; inputType: AttributeInputTypeEnum | null;
entityType: AttributeEntityTypeEnum | null; entityType: AttributeEntityTypeEnum | null;
valueRequired: boolean; valueRequired: boolean;
unit: MeasurementUnitsEnum | null;
values: (VariantMediaAssign_variantMediaAssign_productVariant_nonSelectionAttributes_attribute_values | null)[] | null; values: (VariantMediaAssign_variantMediaAssign_productVariant_nonSelectionAttributes_attribute_values | null)[] | null;
} }

View file

@ -3,7 +3,7 @@
// @generated // @generated
// This file was automatically generated and should not be edited. // This file was automatically generated and should not be edited.
import { ProductErrorCode, AttributeInputTypeEnum, AttributeEntityTypeEnum, ProductMediaType, WeightUnitsEnum } from "./../../types/globalTypes"; import { ProductErrorCode, AttributeInputTypeEnum, AttributeEntityTypeEnum, MeasurementUnitsEnum, ProductMediaType, WeightUnitsEnum } from "./../../types/globalTypes";
// ==================================================== // ====================================================
// GraphQL mutation operation: VariantMediaUnassign // GraphQL mutation operation: VariantMediaUnassign
@ -51,6 +51,7 @@ export interface VariantMediaUnassign_variantMediaUnassign_productVariant_select
inputType: AttributeInputTypeEnum | null; inputType: AttributeInputTypeEnum | null;
entityType: AttributeEntityTypeEnum | null; entityType: AttributeEntityTypeEnum | null;
valueRequired: boolean; valueRequired: boolean;
unit: MeasurementUnitsEnum | null;
values: (VariantMediaUnassign_variantMediaUnassign_productVariant_selectionAttributes_attribute_values | null)[] | null; values: (VariantMediaUnassign_variantMediaUnassign_productVariant_selectionAttributes_attribute_values | null)[] | null;
} }
@ -100,6 +101,7 @@ export interface VariantMediaUnassign_variantMediaUnassign_productVariant_nonSel
inputType: AttributeInputTypeEnum | null; inputType: AttributeInputTypeEnum | null;
entityType: AttributeEntityTypeEnum | null; entityType: AttributeEntityTypeEnum | null;
valueRequired: boolean; valueRequired: boolean;
unit: MeasurementUnitsEnum | null;
values: (VariantMediaUnassign_variantMediaUnassign_productVariant_nonSelectionAttributes_attribute_values | null)[] | null; values: (VariantMediaUnassign_variantMediaUnassign_productVariant_nonSelectionAttributes_attribute_values | null)[] | null;
} }

View file

@ -3,7 +3,7 @@
// @generated // @generated
// This file was automatically generated and should not be edited. // This file was automatically generated and should not be edited.
import { StockInput, AttributeValueInput, ProductErrorCode, AttributeInputTypeEnum, AttributeEntityTypeEnum, ProductMediaType, WeightUnitsEnum, StockErrorCode } from "./../../types/globalTypes"; import { StockInput, AttributeValueInput, ProductErrorCode, AttributeInputTypeEnum, AttributeEntityTypeEnum, MeasurementUnitsEnum, ProductMediaType, WeightUnitsEnum, StockErrorCode } from "./../../types/globalTypes";
// ==================================================== // ====================================================
// GraphQL mutation operation: VariantUpdate // GraphQL mutation operation: VariantUpdate
@ -52,6 +52,7 @@ export interface VariantUpdate_productVariantUpdate_productVariant_selectionAttr
inputType: AttributeInputTypeEnum | null; inputType: AttributeInputTypeEnum | null;
entityType: AttributeEntityTypeEnum | null; entityType: AttributeEntityTypeEnum | null;
valueRequired: boolean; valueRequired: boolean;
unit: MeasurementUnitsEnum | null;
values: (VariantUpdate_productVariantUpdate_productVariant_selectionAttributes_attribute_values | null)[] | null; values: (VariantUpdate_productVariantUpdate_productVariant_selectionAttributes_attribute_values | null)[] | null;
} }
@ -101,6 +102,7 @@ export interface VariantUpdate_productVariantUpdate_productVariant_nonSelectionA
inputType: AttributeInputTypeEnum | null; inputType: AttributeInputTypeEnum | null;
entityType: AttributeEntityTypeEnum | null; entityType: AttributeEntityTypeEnum | null;
valueRequired: boolean; valueRequired: boolean;
unit: MeasurementUnitsEnum | null;
values: (VariantUpdate_productVariantUpdate_productVariant_nonSelectionAttributes_attribute_values | null)[] | null; values: (VariantUpdate_productVariantUpdate_productVariant_nonSelectionAttributes_attribute_values | null)[] | null;
} }
@ -341,6 +343,7 @@ export interface VariantUpdate_productVariantStocksUpdate_productVariant_selecti
inputType: AttributeInputTypeEnum | null; inputType: AttributeInputTypeEnum | null;
entityType: AttributeEntityTypeEnum | null; entityType: AttributeEntityTypeEnum | null;
valueRequired: boolean; valueRequired: boolean;
unit: MeasurementUnitsEnum | null;
values: (VariantUpdate_productVariantStocksUpdate_productVariant_selectionAttributes_attribute_values | null)[] | null; values: (VariantUpdate_productVariantStocksUpdate_productVariant_selectionAttributes_attribute_values | null)[] | null;
} }
@ -390,6 +393,7 @@ export interface VariantUpdate_productVariantStocksUpdate_productVariant_nonSele
inputType: AttributeInputTypeEnum | null; inputType: AttributeInputTypeEnum | null;
entityType: AttributeEntityTypeEnum | null; entityType: AttributeEntityTypeEnum | null;
valueRequired: boolean; valueRequired: boolean;
unit: MeasurementUnitsEnum | null;
values: (VariantUpdate_productVariantStocksUpdate_productVariant_nonSelectionAttributes_attribute_values | null)[] | null; values: (VariantUpdate_productVariantStocksUpdate_productVariant_nonSelectionAttributes_attribute_values | null)[] | null;
} }

View file

@ -52,7 +52,8 @@ export function getAttributeInputFromProduct(
inputType: attribute.attribute.inputType, inputType: attribute.attribute.inputType,
isRequired: attribute.attribute.valueRequired, isRequired: attribute.attribute.valueRequired,
selectedValues: attribute.values, selectedValues: attribute.values,
values: attribute.attribute.values values: attribute.attribute.values,
unit: attribute.attribute.unit
}, },
id: attribute.attribute.id, id: attribute.attribute.id,
label: attribute.attribute.name, label: attribute.attribute.name,
@ -70,7 +71,8 @@ export function getAttributeInputFromProductType(
entityType: attribute.entityType, entityType: attribute.entityType,
inputType: attribute.inputType, inputType: attribute.inputType,
isRequired: attribute.valueRequired, isRequired: attribute.valueRequired,
values: attribute.values values: attribute.values,
unit: attribute.unit
}, },
id: attribute.id, id: attribute.id,
label: attribute.name, label: attribute.name,
@ -88,6 +90,7 @@ export function getAttributeInputFromAttributes(
inputType: attribute.inputType, inputType: attribute.inputType,
isRequired: attribute.valueRequired, isRequired: attribute.valueRequired,
values: attribute.values, values: attribute.values,
unit: attribute.unit,
variantAttributeScope variantAttributeScope
}, },
id: attribute.id, id: attribute.id,
@ -107,6 +110,7 @@ export function getAttributeInputFromSelectedAttributes(
isRequired: attribute.attribute.valueRequired, isRequired: attribute.attribute.valueRequired,
selectedValues: attribute.values, selectedValues: attribute.values,
values: attribute.attribute.values, values: attribute.attribute.values,
unit: attribute.attribute.unit,
variantAttributeScope variantAttributeScope
}, },
id: attribute.attribute.id, id: attribute.attribute.id,

View file

@ -61,7 +61,7 @@ exports[`Storyshots Attributes / Attributes default 1`] = `
<div <div
class="MuiTypography-root-id Attributes-expansionBarLabel-id MuiTypography-caption-id" class="MuiTypography-root-id Attributes-expansionBarLabel-id MuiTypography-caption-id"
> >
5 Attributes 6 Attributes
</div> </div>
</div> </div>
<button <button
@ -366,6 +366,59 @@ exports[`Storyshots Attributes / Attributes default 1`] = `
</div> </div>
</div> </div>
</div> </div>
<hr
class="Hr-root-id"
/>
<div
class="BasicAttributeRow-attributeSection-id Grid-root-id Grid-uniform-id"
>
<div
class="BasicAttributeRow-attributeSectionLabel-id"
data-test="attribute-label"
>
<div
class="MuiTypography-root-id MuiTypography-body1-id"
>
Numeric Attribute
</div>
</div>
<div
data-test="attribute-value"
>
<div
class="MuiFormControl-root-id MuiTextField-root-id MuiFormControl-fullWidth-id"
>
<label
class="MuiFormLabel-root-id MuiInputLabel-root-id MuiInputLabel-formControl-id MuiInputLabel-animated-id MuiInputLabel-outlined-id"
data-shrink="false"
>
Value
</label>
<div
class="MuiInputBase-root-id MuiOutlinedInput-root-id MuiInputBase-fullWidth-id MuiInputBase-formControl-id"
>
<input
aria-invalid="false"
class="MuiInputBase-input-id MuiOutlinedInput-input-id"
name="attribute:Numeric Attribute"
type="number"
/>
<fieldset
aria-hidden="true"
class="PrivateNotchedOutline-root-id MuiOutlinedInput-notchedOutline-id"
>
<legend
class="PrivateNotchedOutline-legendLabelled-id"
>
<span>
Value
</span>
</legend>
</fieldset>
</div>
</div>
</div>
</div>
</div> </div>
</div> </div>
</div> </div>
@ -408,7 +461,7 @@ exports[`Storyshots Attributes / Attributes disabled 1`] = `
<div <div
class="MuiTypography-root-id Attributes-expansionBarLabel-id MuiTypography-caption-id" class="MuiTypography-root-id Attributes-expansionBarLabel-id MuiTypography-caption-id"
> >
5 Attributes 6 Attributes
</div> </div>
</div> </div>
<button <button
@ -717,6 +770,60 @@ exports[`Storyshots Attributes / Attributes disabled 1`] = `
</div> </div>
</div> </div>
</div> </div>
<hr
class="Hr-root-id"
/>
<div
class="BasicAttributeRow-attributeSection-id Grid-root-id Grid-uniform-id"
>
<div
class="BasicAttributeRow-attributeSectionLabel-id"
data-test="attribute-label"
>
<div
class="MuiTypography-root-id MuiTypography-body1-id"
>
Numeric Attribute
</div>
</div>
<div
data-test="attribute-value"
>
<div
class="MuiFormControl-root-id MuiTextField-root-id MuiFormControl-fullWidth-id"
>
<label
class="MuiFormLabel-root-id MuiInputLabel-root-id MuiInputLabel-formControl-id MuiInputLabel-animated-id MuiInputLabel-outlined-id MuiFormLabel-disabled-id MuiInputLabel-disabled-id"
data-shrink="false"
>
Value
</label>
<div
class="MuiInputBase-root-id MuiOutlinedInput-root-id MuiInputBase-disabled-id MuiOutlinedInput-disabled-id MuiInputBase-fullWidth-id MuiInputBase-formControl-id"
>
<input
aria-invalid="false"
class="MuiInputBase-input-id MuiOutlinedInput-input-id MuiInputBase-disabled-id MuiOutlinedInput-disabled-id"
disabled=""
name="attribute:Numeric Attribute"
type="number"
/>
<fieldset
aria-hidden="true"
class="PrivateNotchedOutline-root-id MuiOutlinedInput-notchedOutline-id"
>
<legend
class="PrivateNotchedOutline-legendLabelled-id"
>
<span>
Value
</span>
</legend>
</fieldset>
</div>
</div>
</div>
</div>
</div> </div>
</div> </div>
</div> </div>
@ -759,7 +866,7 @@ exports[`Storyshots Attributes / Attributes selected 1`] = `
<div <div
class="MuiTypography-root-id Attributes-expansionBarLabel-id MuiTypography-caption-id" class="MuiTypography-root-id Attributes-expansionBarLabel-id MuiTypography-caption-id"
> >
5 Attributes 6 Attributes
</div> </div>
</div> </div>
<button <button
@ -1330,6 +1437,60 @@ exports[`Storyshots Attributes / Attributes selected 1`] = `
</div> </div>
</div> </div>
</div> </div>
<hr
class="Hr-root-id"
/>
<div
class="BasicAttributeRow-attributeSection-id Grid-root-id Grid-uniform-id"
>
<div
class="BasicAttributeRow-attributeSectionLabel-id"
data-test="attribute-label"
>
<div
class="MuiTypography-root-id MuiTypography-body1-id"
>
Numeric Attribute
</div>
</div>
<div
data-test="attribute-value"
>
<div
class="MuiFormControl-root-id MuiTextField-root-id MuiFormControl-fullWidth-id"
>
<label
class="MuiFormLabel-root-id MuiInputLabel-root-id MuiInputLabel-formControl-id MuiInputLabel-animated-id MuiInputLabel-shrink-id MuiInputLabel-outlined-id MuiFormLabel-filled-id"
data-shrink="true"
>
Value
</label>
<div
class="MuiInputBase-root-id MuiOutlinedInput-root-id MuiInputBase-fullWidth-id MuiInputBase-formControl-id"
>
<input
aria-invalid="false"
class="MuiInputBase-input-id MuiOutlinedInput-input-id"
name="attribute:Numeric Attribute"
type="number"
value="12cm"
/>
<fieldset
aria-hidden="true"
class="PrivateNotchedOutline-root-id MuiOutlinedInput-notchedOutline-id"
>
<legend
class="PrivateNotchedOutline-legendLabelled-id PrivateNotchedOutline-legendNotched-id"
>
<span>
Value
</span>
</legend>
</fieldset>
</div>
</div>
</div>
</div>
</div> </div>
</div> </div>
</div> </div>
@ -36223,14 +36384,13 @@ exports[`Storyshots Views / Attributes / Attribute details loading 1`] = `
> >
<span <span
aria-disabled="true" aria-disabled="true"
class="MuiButtonBase-root-id MuiIconButton-root-id PrivateSwitchBase-root-id MuiCheckbox-root-id MuiCheckbox-colorPrimary-id PrivateSwitchBase-checked-id MuiCheckbox-checked-id PrivateSwitchBase-disabled-id MuiCheckbox-disabled-id MuiIconButton-colorPrimary-id MuiIconButton-disabled-id MuiButtonBase-disabled-id" class="MuiButtonBase-root-id MuiIconButton-root-id PrivateSwitchBase-root-id MuiCheckbox-root-id MuiCheckbox-colorPrimary-id PrivateSwitchBase-disabled-id MuiCheckbox-disabled-id MuiIconButton-colorPrimary-id MuiIconButton-disabled-id MuiButtonBase-disabled-id"
tabindex="-1" tabindex="-1"
> >
<span <span
class="MuiIconButton-label-id" class="MuiIconButton-label-id"
> >
<input <input
checked=""
class="PrivateSwitchBase-input-id" class="PrivateSwitchBase-input-id"
data-indeterminate="false" data-indeterminate="false"
disabled="" disabled=""
@ -36244,18 +36404,13 @@ exports[`Storyshots Views / Attributes / Attribute details loading 1`] = `
viewBox="0 0 24 24" viewBox="0 0 24 24"
> >
<rect <rect
fill="currentColor" fill="none"
height="14" height="14"
stroke="currentColor"
width="14" width="14"
x="5" x="5"
y="5" y="5"
/> />
<path
clip-rule="evenodd"
d="M 16.7527 9.33783 L 10.86618 15.7595 L 8 12.32006 L 8.76822 11.67988 L 10.90204 14.24046 L 16.0155 8.66211 L 16.7527 9.33783 Z"
fill="white"
fill-rule="evenodd"
/>
</svg> </svg>
</span> </span>
</span> </span>

View file

@ -89,6 +89,7 @@ export enum AttributeInputTypeEnum {
DROPDOWN = "DROPDOWN", DROPDOWN = "DROPDOWN",
FILE = "FILE", FILE = "FILE",
MULTISELECT = "MULTISELECT", MULTISELECT = "MULTISELECT",
NUMERIC = "NUMERIC",
REFERENCE = "REFERENCE", REFERENCE = "REFERENCE",
RICH_TEXT = "RICH_TEXT", RICH_TEXT = "RICH_TEXT",
} }
@ -530,6 +531,39 @@ export enum LanguageCodeEnum {
ZH_HANT = "ZH_HANT", ZH_HANT = "ZH_HANT",
} }
export enum MeasurementUnitsEnum {
ACRE_FT = "ACRE_FT",
ACRE_IN = "ACRE_IN",
CM = "CM",
CUBIC_CENTIMETER = "CUBIC_CENTIMETER",
CUBIC_DECIMETER = "CUBIC_DECIMETER",
CUBIC_FOOT = "CUBIC_FOOT",
CUBIC_INCH = "CUBIC_INCH",
CUBIC_METER = "CUBIC_METER",
CUBIC_MILLIMETER = "CUBIC_MILLIMETER",
CUBIC_YARD = "CUBIC_YARD",
FL_OZ = "FL_OZ",
FT = "FT",
G = "G",
INCH = "INCH",
KG = "KG",
KM = "KM",
LB = "LB",
LITER = "LITER",
M = "M",
OZ = "OZ",
PINT = "PINT",
QT = "QT",
SQ_CM = "SQ_CM",
SQ_FT = "SQ_FT",
SQ_INCH = "SQ_INCH",
SQ_KM = "SQ_KM",
SQ_M = "SQ_M",
SQ_YD = "SQ_YD",
TONNE = "TONNE",
YD = "YD",
}
export enum MenuErrorCode { export enum MenuErrorCode {
CANNOT_ASSIGN_NODE = "CANNOT_ASSIGN_NODE", CANNOT_ASSIGN_NODE = "CANNOT_ASSIGN_NODE",
GRAPHQL_ERROR = "GRAPHQL_ERROR", GRAPHQL_ERROR = "GRAPHQL_ERROR",
@ -1025,6 +1059,7 @@ export enum WeightUnitsEnum {
KG = "KG", KG = "KG",
LB = "LB", LB = "LB",
OZ = "OZ", OZ = "OZ",
TONNE = "TONNE",
} }
export interface AddressInput { export interface AddressInput {
@ -1075,6 +1110,7 @@ export interface AttributeCreateInput {
name: string; name: string;
slug?: string | null; slug?: string | null;
type: AttributeTypeEnum; type: AttributeTypeEnum;
unit?: MeasurementUnitsEnum | null;
values?: (AttributeValueCreateInput | null)[] | null; values?: (AttributeValueCreateInput | null)[] | null;
valueRequired?: boolean | null; valueRequired?: boolean | null;
isVariantOnly?: boolean | null; isVariantOnly?: boolean | null;
@ -1104,6 +1140,7 @@ export interface AttributeFilterInput {
export interface AttributeInput { export interface AttributeInput {
slug: string; slug: string;
values?: (string | null)[] | null; values?: (string | null)[] | null;
valuesRange?: IntRangeInput | null;
} }
export interface AttributeSortingInput { export interface AttributeSortingInput {
@ -1114,6 +1151,7 @@ export interface AttributeSortingInput {
export interface AttributeUpdateInput { export interface AttributeUpdateInput {
name?: string | null; name?: string | null;
slug?: string | null; slug?: string | null;
unit?: MeasurementUnitsEnum | null;
removeValues?: (string | null)[] | null; removeValues?: (string | null)[] | null;
addValues?: (AttributeValueCreateInput | null)[] | null; addValues?: (AttributeValueCreateInput | null)[] | null;
valueRequired?: boolean | null; valueRequired?: boolean | null;