saleor-dashboard/src/attributes/views/AttributeCreate/AttributeCreate.tsx

281 lines
8 KiB
TypeScript
Raw Normal View History

Use graphql-codegen (#1874) * Use generated hooks in apps * Remove unused files * Use proper types in apps * Use generated hooks in attributes * Use generated hooks in auth module * Use generated hooks in categories * Use generated hooks in channels * Use generated types in collections * Remove legacy types from background tasks * Use generated hooks in customers * Use generated hooks in discounts * Use generated hook in file upload * Use generated types in gift cards * Use generated types in home * Use generated hooks in navigation * Use generated hooks in orders * Use generated hooks in pages * Use generated hooks in page types * Use generated hooks in permission groups * Use generated hooks in plugins * Use generated hooks in products * Use fragment to mark product variants * Improve code a bit * Use generated hooks in page types * Use generated types in searches * Use generated hooks in shipping * Use generated hooks in site settings * Use generated hooks in staff members * Use generated hooks in taxes * Place all gql generated files in one directory * Use generated hooks in translations * Use global types from new generated module * Use generated hooks in warehouses * Use generated hooks in webhooks * Use generated fragment types * Unclutter types * Remove hoc components * Split hooks and types * Fetch introspection file * Delete obsolete schema file * Fix rebase artifacts * Fix autoreplace * Fix auth provider tests * Fix urls * Remove leftover types * Fix rebase artifacts
2022-03-09 08:56:55 +00:00
import {
AttributeErrorCode,
AttributeErrorFragment,
useAttributeCreateMutation,
useUpdateMetadataMutation,
useUpdatePrivateMetadataMutation,
} from "@dashboard/graphql";
import useListSettings from "@dashboard/hooks/useListSettings";
import useLocalPageInfo, {
getMaxPage,
} from "@dashboard/hooks/useLocalPageInfo";
import useNavigator from "@dashboard/hooks/useNavigator";
import useNotifier from "@dashboard/hooks/useNotifier";
import { getMutationErrors, getStringOrPlaceholder } from "@dashboard/misc";
import { ListViews, ReorderEvent } from "@dashboard/types";
import createDialogActionHandlers from "@dashboard/utils/handlers/dialogActionHandlers";
import createMetadataCreateHandler from "@dashboard/utils/handlers/metadataCreateHandler";
2019-08-09 10:17:04 +00:00
import {
add,
isSelected,
move,
remove,
updateAtIndex,
} from "@dashboard/utils/lists";
import React from "react";
import { useIntl } from "react-intl";
import slugify from "slugify";
import AttributePage, {
AttributePageFormData,
} from "../../components/AttributePage";
2019-08-09 10:17:04 +00:00
import AttributeValueDeleteDialog from "../../components/AttributeValueDeleteDialog";
import AttributeValueEditDialog from "../../components/AttributeValueEditDialog";
2019-08-09 10:17:04 +00:00
import {
attributeAddUrl,
AttributeAddUrlDialog,
2019-08-09 10:17:04 +00:00
AttributeAddUrlQueryParams,
attributeUrl,
2019-08-09 10:17:04 +00:00
} from "../../urls";
import {
AttributeValueEditDialogFormData,
getAttributeData,
} from "../../utils/data";
2019-08-09 10:17:04 +00:00
interface AttributeDetailsProps {
params: AttributeAddUrlQueryParams;
}
Page types (#807) * Create attribute class selector * Use ProductAttributeType to check if product is simple or with variants * Allow attribute class selection only during its creation * Update attribute type selection translations * Show only product attributes in columns picker on product list view * Cleanups in Attribute Organization component * Create Page Types list page * Create content management section in settings * Implement page types list view * Remove unused imports from page type list * Updatte page type list style * Remove legacy code from page type list component * Update PageTypeListPage component * Create Page Types details page * Fix page type attribute reordering * Implement PageType create view * Implement PageType update view * gUpdate page type details components * Fix page type update component * Update page type components stories * Update page type errors handling * Update page type details view * Create Page Types details page * Implement PageType create view * Update product attribute assignment mutations * Add page types attribute assignment mutations * Add page types attribute assignment handling * Temporarily fix page create mutation * Update page type error messages * Remove legacy storybook page type stories * Update attribute assignment dialogs stories * Update page type details error handling * Update props for page type components * Create attribute class selector * Implement page types list view * Add page type selector on page create and details views * Add attributes list to page details views * Update page types list * Use attribute errors for attributes muatations * Save attribute values on page create and update * Update messages for page view * Update page attributes fragment * Use AttributeError in AttributeBulkDelete * Update page type and its attribute selection * Handle page types deleting * Update page types deleting messages * Handle page types attribute reorder * Fix PageOrganizeContent component types * Update graphqql types * Fix page fixture * Update messages * Update test snapshots * Pass pageTypes to PageForm * Update changelog with page type addition note * Update package-lock * Update test snapshots * Fix malformed generated type * Update messages after rebase
2020-11-19 14:42:14 +00:00
const attributeValueAlreadyExistsError: AttributeErrorFragment = {
__typename: "AttributeError",
code: AttributeErrorCode.ALREADY_EXISTS,
field: "name",
message: "",
2020-03-24 14:05:26 +00:00
};
2019-08-09 10:17:04 +00:00
function areValuesEqual(
a: AttributeValueEditDialogFormData,
b: AttributeValueEditDialogFormData,
2019-08-09 10:17:04 +00:00
) {
return a.name === b.name;
}
const AttributeDetails: React.FC<AttributeDetailsProps> = ({ params }) => {
const navigate = useNavigator();
const notify = useNotifier();
const intl = useIntl();
2019-08-09 10:17:04 +00:00
const [values, setValues] = React.useState<
AttributeValueEditDialogFormData[]
>([]);
Page types (#807) * Create attribute class selector * Use ProductAttributeType to check if product is simple or with variants * Allow attribute class selection only during its creation * Update attribute type selection translations * Show only product attributes in columns picker on product list view * Cleanups in Attribute Organization component * Create Page Types list page * Create content management section in settings * Implement page types list view * Remove unused imports from page type list * Updatte page type list style * Remove legacy code from page type list component * Update PageTypeListPage component * Create Page Types details page * Fix page type attribute reordering * Implement PageType create view * Implement PageType update view * gUpdate page type details components * Fix page type update component * Update page type components stories * Update page type errors handling * Update page type details view * Create Page Types details page * Implement PageType create view * Update product attribute assignment mutations * Add page types attribute assignment mutations * Add page types attribute assignment handling * Temporarily fix page create mutation * Update page type error messages * Remove legacy storybook page type stories * Update attribute assignment dialogs stories * Update page type details error handling * Update props for page type components * Create attribute class selector * Implement page types list view * Add page type selector on page create and details views * Add attributes list to page details views * Update page types list * Use attribute errors for attributes muatations * Save attribute values on page create and update * Update messages for page view * Update page attributes fragment * Use AttributeError in AttributeBulkDelete * Update page type and its attribute selection * Handle page types deleting * Update page types deleting messages * Handle page types attribute reorder * Fix PageOrganizeContent component types * Update graphqql types * Fix page fixture * Update messages * Update test snapshots * Pass pageTypes to PageForm * Update changelog with page type addition note * Update package-lock * Update test snapshots * Fix malformed generated type * Update messages after rebase
2020-11-19 14:42:14 +00:00
const [valueErrors, setValueErrors] = React.useState<
AttributeErrorFragment[]
>([]);
2019-08-09 10:17:04 +00:00
const { updateListSettings, settings } = useListSettings(
ListViews.ATTRIBUTE_VALUE_LIST,
);
const {
pageInfo,
pageValues,
loadNextPage,
loadPreviousPage,
loadPage,
} = useLocalPageInfo(values, settings?.rowNumber);
const [attributeCreate, attributeCreateOpts] = useAttributeCreateMutation({
onCompleted: data => {
if (data.attributeCreate.errors.length === 0) {
notify({
status: "success",
text: intl.formatMessage({
id: "jTifz+",
defaultMessage: "Successfully created attribute",
}),
});
navigate(attributeUrl(data.attributeCreate.attribute.id));
}
},
});
Use graphql-codegen (#1874) * Use generated hooks in apps * Remove unused files * Use proper types in apps * Use generated hooks in attributes * Use generated hooks in auth module * Use generated hooks in categories * Use generated hooks in channels * Use generated types in collections * Remove legacy types from background tasks * Use generated hooks in customers * Use generated hooks in discounts * Use generated hook in file upload * Use generated types in gift cards * Use generated types in home * Use generated hooks in navigation * Use generated hooks in orders * Use generated hooks in pages * Use generated hooks in page types * Use generated hooks in permission groups * Use generated hooks in plugins * Use generated hooks in products * Use fragment to mark product variants * Improve code a bit * Use generated hooks in page types * Use generated types in searches * Use generated hooks in shipping * Use generated hooks in site settings * Use generated hooks in staff members * Use generated hooks in taxes * Place all gql generated files in one directory * Use generated hooks in translations * Use global types from new generated module * Use generated hooks in warehouses * Use generated hooks in webhooks * Use generated fragment types * Unclutter types * Remove hoc components * Split hooks and types * Fetch introspection file * Delete obsolete schema file * Fix rebase artifacts * Fix autoreplace * Fix auth provider tests * Fix urls * Remove leftover types * Fix rebase artifacts
2022-03-09 08:56:55 +00:00
const [updateMetadata] = useUpdateMetadataMutation({});
const [updatePrivateMetadata] = useUpdatePrivateMetadataMutation({});
const id = params.id
? parseInt(params.id, 10) + pageInfo.startCursor
: undefined;
2019-08-09 10:17:04 +00:00
2019-12-06 14:58:28 +00:00
const [openModal, closeModal] = createDialogActionHandlers<
AttributeAddUrlDialog,
AttributeAddUrlQueryParams
>(navigate, attributeAddUrl, params);
2019-08-09 10:17:04 +00:00
2020-03-24 14:05:26 +00:00
React.useEffect(() => setValueErrors([]), [params.action]);
2019-08-09 10:17:04 +00:00
const handleValueDelete = () => {
const newValues = remove(values[id], values, areValuesEqual);
setValues(newValues);
2019-08-09 10:17:04 +00:00
closeModal();
};
2019-08-09 10:17:04 +00:00
const handleValueUpdate = (input: AttributeValueEditDialogFormData) => {
if (isSelected(input, values, areValuesEqual)) {
2020-03-24 14:05:26 +00:00
setValueErrors([attributeValueAlreadyExistsError]);
2019-08-09 10:17:04 +00:00
} else {
setValues(updateAtIndex(input, values, id));
closeModal();
}
};
2019-08-09 10:17:04 +00:00
const handleValueCreate = (input: AttributeValueEditDialogFormData) => {
if (isSelected(input, values, areValuesEqual)) {
2020-03-24 14:05:26 +00:00
setValueErrors([attributeValueAlreadyExistsError]);
2019-08-09 10:17:04 +00:00
} else {
const newValues = add(input, values);
setValues(newValues);
const addedToNotVisibleLastPage =
newValues.length - pageInfo.startCursor > settings.rowNumber;
if (addedToNotVisibleLastPage) {
const maxPage = getMaxPage(newValues.length, settings.rowNumber);
loadPage(maxPage);
}
2019-08-09 10:17:04 +00:00
closeModal();
}
};
2019-08-09 10:17:04 +00:00
const handleValueReorder = ({ newIndex, oldIndex }: ReorderEvent) =>
setValues(
move(
values[pageInfo.startCursor + oldIndex],
values,
areValuesEqual,
pageInfo.startCursor + newIndex,
),
);
2019-08-09 10:17:04 +00:00
const handleCreate = async (data: AttributePageFormData) => {
const result = await attributeCreate({
variables: {
input: getAttributeData(data, values),
},
});
Exit dirty form (#1816) * Add Exit form prompt component and change some minor styles in other components to match * Add Exit form prompt provider * Adjust generic form and useform hook to allow using exit form prompt provider * Add exit form prompt provider to index * wip * Fix types * Fix styling * Fix types * Revert warehouse details refactor * Add handling of edge cases to exit prompt * Refactor, add comments, fix some types * Refactor after exit form dialog name change * fix types * Fixes after review * Add default value for useform prop opts so the app doesn't crash * Add missing category prop to getting initial data for category details form * Add exit dialog to everywhere WIP (#1600) * Add Exit form prompt component and change some minor styles in other components to match * Add Exit form prompt provider * Adjust generic form and useform hook to allow using exit form prompt provider * Add exit form prompt provider to index * wip * Fix types * Fix styling * Fix types * Revert warehouse details refactor * Add handling of edge cases to exit prompt * Refactor, add comments, fix some types * Refactor after exit form dialog name change * fix types * Add CommonUseFormResultWithHandlers type for later use and refactor handleFormSubmit util * Refactor login form not to use custom form since it doesn't need to * Add exit form dialog to order refund page * Add exit form dialog to order return page * Add exit form dialog to order order settings page * Add exit form dialog to product variant page * Add exit form dialog to product create page * Add exit form dialog to product update page * Add exit form dialog to product variant create page * Fix confirm leave prop passing in generic Form * Add util function to handle for submit to extract errors * Add confirmLeave prop to generic forms * Move handleChange for custom forms to useForm * Add exit dialog to more forms * Add extract mutation errors util function * Add extracting errors to submit functions that use metadata create handler * Fix typo * Add missing category prop to getting initial data for category details form * Fix types * wip * wip * wip * wip * Fix types & refactor * Fix types & refactor * Fix typescript * Fix unmatching tag * Fixes * Add handling of multiple forms at once to exit dirty form provider * Change all usages of ExitFormDialogContext to designated hook * wip * wip * wip * Fix types wip * Fix types * Remove console logs * Add isSubmitting prop to exit form dialog in order to avoid enabling exit dialog while submit is still in progresS * Replace handleSubmit global util with a hook to use exit form dialog props inside * Move useHandleSubmit to general hooks dir, update imports * Small fixes * Update snapshots * Fix types * Small fixes due to extensive rebase * Update package lock * Fixes after rebase * Remove exit form from customer address dialog * Fix types and update messages * Fix types * Change imports names * Refactor * Remove unnecessary console.log * Update types, snapshots. etc after rebase
2022-02-01 09:58:06 +00:00
return {
id: result.data.attributeCreate?.attribute?.id || null,
errors: getMutationErrors(result),
Exit dirty form (#1816) * Add Exit form prompt component and change some minor styles in other components to match * Add Exit form prompt provider * Adjust generic form and useform hook to allow using exit form prompt provider * Add exit form prompt provider to index * wip * Fix types * Fix styling * Fix types * Revert warehouse details refactor * Add handling of edge cases to exit prompt * Refactor, add comments, fix some types * Refactor after exit form dialog name change * fix types * Fixes after review * Add default value for useform prop opts so the app doesn't crash * Add missing category prop to getting initial data for category details form * Add exit dialog to everywhere WIP (#1600) * Add Exit form prompt component and change some minor styles in other components to match * Add Exit form prompt provider * Adjust generic form and useform hook to allow using exit form prompt provider * Add exit form prompt provider to index * wip * Fix types * Fix styling * Fix types * Revert warehouse details refactor * Add handling of edge cases to exit prompt * Refactor, add comments, fix some types * Refactor after exit form dialog name change * fix types * Add CommonUseFormResultWithHandlers type for later use and refactor handleFormSubmit util * Refactor login form not to use custom form since it doesn't need to * Add exit form dialog to order refund page * Add exit form dialog to order return page * Add exit form dialog to order order settings page * Add exit form dialog to product variant page * Add exit form dialog to product create page * Add exit form dialog to product update page * Add exit form dialog to product variant create page * Fix confirm leave prop passing in generic Form * Add util function to handle for submit to extract errors * Add confirmLeave prop to generic forms * Move handleChange for custom forms to useForm * Add exit dialog to more forms * Add extract mutation errors util function * Add extracting errors to submit functions that use metadata create handler * Fix typo * Add missing category prop to getting initial data for category details form * Fix types * wip * wip * wip * wip * Fix types & refactor * Fix types & refactor * Fix typescript * Fix unmatching tag * Fixes * Add handling of multiple forms at once to exit dirty form provider * Change all usages of ExitFormDialogContext to designated hook * wip * wip * wip * Fix types wip * Fix types * Remove console logs * Add isSubmitting prop to exit form dialog in order to avoid enabling exit dialog while submit is still in progresS * Replace handleSubmit global util with a hook to use exit form dialog props inside * Move useHandleSubmit to general hooks dir, update imports * Small fixes * Update snapshots * Fix types * Small fixes due to extensive rebase * Update package lock * Fixes after rebase * Remove exit form from customer address dialog * Fix types and update messages * Fix types * Change imports names * Refactor * Remove unnecessary console.log * Update types, snapshots. etc after rebase
2022-02-01 09:58:06 +00:00
};
};
Exit dirty form (#1816) * Add Exit form prompt component and change some minor styles in other components to match * Add Exit form prompt provider * Adjust generic form and useform hook to allow using exit form prompt provider * Add exit form prompt provider to index * wip * Fix types * Fix styling * Fix types * Revert warehouse details refactor * Add handling of edge cases to exit prompt * Refactor, add comments, fix some types * Refactor after exit form dialog name change * fix types * Fixes after review * Add default value for useform prop opts so the app doesn't crash * Add missing category prop to getting initial data for category details form * Add exit dialog to everywhere WIP (#1600) * Add Exit form prompt component and change some minor styles in other components to match * Add Exit form prompt provider * Adjust generic form and useform hook to allow using exit form prompt provider * Add exit form prompt provider to index * wip * Fix types * Fix styling * Fix types * Revert warehouse details refactor * Add handling of edge cases to exit prompt * Refactor, add comments, fix some types * Refactor after exit form dialog name change * fix types * Add CommonUseFormResultWithHandlers type for later use and refactor handleFormSubmit util * Refactor login form not to use custom form since it doesn't need to * Add exit form dialog to order refund page * Add exit form dialog to order return page * Add exit form dialog to order order settings page * Add exit form dialog to product variant page * Add exit form dialog to product create page * Add exit form dialog to product update page * Add exit form dialog to product variant create page * Fix confirm leave prop passing in generic Form * Add util function to handle for submit to extract errors * Add confirmLeave prop to generic forms * Move handleChange for custom forms to useForm * Add exit dialog to more forms * Add extract mutation errors util function * Add extracting errors to submit functions that use metadata create handler * Fix typo * Add missing category prop to getting initial data for category details form * Fix types * wip * wip * wip * wip * Fix types & refactor * Fix types & refactor * Fix typescript * Fix unmatching tag * Fixes * Add handling of multiple forms at once to exit dirty form provider * Change all usages of ExitFormDialogContext to designated hook * wip * wip * wip * Fix types wip * Fix types * Remove console logs * Add isSubmitting prop to exit form dialog in order to avoid enabling exit dialog while submit is still in progresS * Replace handleSubmit global util with a hook to use exit form dialog props inside * Move useHandleSubmit to general hooks dir, update imports * Small fixes * Update snapshots * Fix types * Small fixes due to extensive rebase * Update package lock * Fixes after rebase * Remove exit form from customer address dialog * Fix types and update messages * Fix types * Change imports names * Refactor * Remove unnecessary console.log * Update types, snapshots. etc after rebase
2022-02-01 09:58:06 +00:00
const handleSubmit = createMetadataCreateHandler(
handleCreate,
updateMetadata,
updatePrivateMetadata,
);
2019-08-09 10:17:04 +00:00
return (
<AttributePage
attribute={null}
disabled={attributeCreateOpts.loading}
errors={attributeCreateOpts.data?.attributeCreate.errors || []}
onDelete={undefined}
onSubmit={handleSubmit}
onValueAdd={() => openModal("add-value")}
onValueDelete={id =>
openModal("remove-value", {
id,
})
}
onValueReorder={handleValueReorder}
onValueUpdate={id =>
openModal("edit-value", {
id,
})
}
saveButtonBarState={attributeCreateOpts.status}
values={{
__typename: "AttributeValueCountableConnection" as "AttributeValueCountableConnection",
pageInfo: {
__typename: "PageInfo" as "PageInfo",
endCursor: "",
hasNextPage: false,
hasPreviousPage: false,
startCursor: "",
},
edges: pageValues.map((value, valueIndex) => ({
__typename: "AttributeValueCountableEdge" as "AttributeValueCountableEdge",
cursor: "1",
node: {
__typename: "AttributeValue" as "AttributeValue",
file: value?.fileUrl
? {
url: value.fileUrl,
contentType: value.contentType,
__typename: "File",
}
: null,
id: valueIndex.toString(),
reference: null,
slug: slugify(value.name).toLowerCase(),
sortOrder: valueIndex,
value: null,
2022-07-19 14:16:43 +00:00
plainText: null,
richText: null,
boolean: null,
date: null,
dateTime: null,
...value,
},
})),
}}
settings={settings}
onUpdateListSettings={updateListSettings}
pageInfo={pageInfo}
onNextPage={loadNextPage}
onPreviousPage={loadPreviousPage}
>
{data => (
<>
2019-12-06 17:11:46 +00:00
<AttributeValueEditDialog
attributeValue={null}
2019-12-06 17:11:46 +00:00
confirmButtonState="default"
disabled={false}
errors={valueErrors}
open={params.action === "add-value"}
2019-12-06 17:11:46 +00:00
onClose={closeModal}
onSubmit={handleValueCreate}
inputType={data.inputType}
2019-12-06 17:11:46 +00:00
/>
{values.length > 0 && (
<>
<AttributeValueDeleteDialog
attributeName={undefined}
open={params.action === "remove-value"}
name={getStringOrPlaceholder(values[id]?.name)}
confirmButtonState="default"
onClose={closeModal}
onConfirm={handleValueDelete}
/>
<AttributeValueEditDialog
inputType={data.inputType}
attributeValue={values[id]}
confirmButtonState="default"
disabled={false}
errors={valueErrors}
open={params.action === "edit-value"}
onClose={closeModal}
onSubmit={handleValueUpdate}
/>
</>
)}
2019-12-06 17:11:46 +00:00
</>
)}
</AttributePage>
2019-08-09 10:17:04 +00:00
);
};
AttributeDetails.displayName = "AttributeDetails";
export default AttributeDetails;