|
|
@@ -1,36 +1,43 @@
|
|
|
import { MoneyInput } from '@/components/data-input/money-input.js';
|
|
|
-import { ContentLanguageSelector } from '@/components/layout/content-language-selector.js';
|
|
|
+import { AssignedFacetValues } from '@/components/shared/assigned-facet-values.js';
|
|
|
import { EntityAssets } from '@/components/shared/entity-assets.js';
|
|
|
import { ErrorPage } from '@/components/shared/error-page.js';
|
|
|
+import { FormFieldWrapper } from '@/components/shared/form-field-wrapper.js';
|
|
|
import { PermissionGuard } from '@/components/shared/permission-guard.js';
|
|
|
import { TaxCategorySelector } from '@/components/shared/tax-category-selector.js';
|
|
|
-import { TranslatableFormField } from '@/components/shared/translatable-form-field.js';
|
|
|
+import {
|
|
|
+ TranslatableFormFieldWrapper
|
|
|
+} from '@/components/shared/translatable-form-field.js';
|
|
|
import { Button } from '@/components/ui/button.js';
|
|
|
import {
|
|
|
- Form,
|
|
|
FormControl,
|
|
|
FormDescription,
|
|
|
FormField,
|
|
|
FormItem,
|
|
|
FormLabel,
|
|
|
- FormMessage,
|
|
|
+ FormMessage
|
|
|
} from '@/components/ui/form.js';
|
|
|
import { Input } from '@/components/ui/input.js';
|
|
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select.js';
|
|
|
import { Switch } from '@/components/ui/switch.js';
|
|
|
import { NEW_ENTITY_PATH } from '@/constants.js';
|
|
|
-import { addCustomFields } from '@/framework/document-introspection/add-custom-fields.js';
|
|
|
import {
|
|
|
CustomFieldsPageBlock,
|
|
|
+ DetailFormGrid,
|
|
|
Page,
|
|
|
PageActionBar,
|
|
|
+ PageActionBarRight,
|
|
|
PageBlock,
|
|
|
+ PageDetailForm,
|
|
|
PageLayout,
|
|
|
PageTitle,
|
|
|
} from '@/framework/layout-engine/page-layout.js';
|
|
|
-import { getDetailQueryOptions, useDetailPage } from '@/framework/page/use-detail-page.js';
|
|
|
+import { detailPageRouteLoader } from '@/framework/page/detail-page-route-loader.js';
|
|
|
+import { useDetailPage } from '@/framework/page/use-detail-page.js';
|
|
|
+import { useChannel } from '@/hooks/use-channel.js';
|
|
|
import { Trans, useLingui } from '@lingui/react/macro';
|
|
|
import { createFileRoute, useNavigate } from '@tanstack/react-router';
|
|
|
+import { Fragment } from 'react/jsx-runtime';
|
|
|
import { toast } from 'sonner';
|
|
|
import { VariantPriceDetail } from './components/variant-price-detail.js';
|
|
|
import {
|
|
|
@@ -38,29 +45,15 @@ import {
|
|
|
productVariantDetailDocument,
|
|
|
updateProductVariantDocument,
|
|
|
} from './product-variants.graphql.js';
|
|
|
-import { Fragment } from 'react/jsx-runtime';
|
|
|
-import { AssignedFacetValues } from '@/components/shared/assigned-facet-values.js';
|
|
|
|
|
|
export const Route = createFileRoute('/_authenticated/_product-variants/product-variants_/$id')({
|
|
|
component: ProductVariantDetailPage,
|
|
|
- loader: async ({ context, params }) => {
|
|
|
- const isNew = params.id === NEW_ENTITY_PATH;
|
|
|
- const result = isNew
|
|
|
- ? null
|
|
|
- : await context.queryClient.ensureQueryData(
|
|
|
- getDetailQueryOptions(addCustomFields(productVariantDetailDocument), { id: params.id }),
|
|
|
- { id: params.id },
|
|
|
- );
|
|
|
- if (!isNew && !result.productVariant) {
|
|
|
- throw new Error(`Product with the ID ${params.id} was not found`);
|
|
|
- }
|
|
|
- return {
|
|
|
- breadcrumb: [
|
|
|
- { path: '/product-variants', label: 'Product variants' },
|
|
|
- isNew ? <Trans>New product variant</Trans> : result.productVariant.name,
|
|
|
- ],
|
|
|
- };
|
|
|
- },
|
|
|
+ loader: detailPageRouteLoader({
|
|
|
+ queryDocument: productVariantDetailDocument,
|
|
|
+ breadcrumb(_isNew, entity) {
|
|
|
+ return [{ path: '/product-variants', label: 'Product variants' }, entity?.name];
|
|
|
+ },
|
|
|
+ }),
|
|
|
errorComponent: ({ error }) => <ErrorPage message={error.message} />,
|
|
|
});
|
|
|
|
|
|
@@ -69,10 +62,10 @@ export function ProductVariantDetailPage() {
|
|
|
const navigate = useNavigate();
|
|
|
const creatingNewEntity = params.id === NEW_ENTITY_PATH;
|
|
|
const { i18n } = useLingui();
|
|
|
+ const { activeChannel } = useChannel();
|
|
|
|
|
|
- const { form, submitHandler, entity, isPending, refreshEntity } = useDetailPage({
|
|
|
- queryDocument: addCustomFields(productVariantDetailDocument),
|
|
|
- entityField: 'productVariant',
|
|
|
+ const { form, submitHandler, entity, isPending, resetForm } = useDetailPage({
|
|
|
+ queryDocument: productVariantDetailDocument,
|
|
|
createDocument: createProductVariantDocument,
|
|
|
updateDocument: updateProductVariantDocument,
|
|
|
setValuesForUpdate: entity => {
|
|
|
@@ -103,17 +96,14 @@ export function ProductVariantDetailPage() {
|
|
|
},
|
|
|
params: { id: params.id },
|
|
|
onSuccess: data => {
|
|
|
- toast(i18n.t('Successfully updated product'), {
|
|
|
- position: 'top-right',
|
|
|
- });
|
|
|
- form.reset(form.getValues());
|
|
|
+ toast.success(i18n.t('Successfully updated product'));
|
|
|
+ resetForm();
|
|
|
if (creatingNewEntity) {
|
|
|
navigate({ to: `../${data?.[0]?.id}`, from: Route.id });
|
|
|
}
|
|
|
},
|
|
|
onError: err => {
|
|
|
- toast(i18n.t('Failed to update product'), {
|
|
|
- position: 'top-right',
|
|
|
+ toast.error(i18n.t('Failed to update product'), {
|
|
|
description: err instanceof Error ? err.message : 'Unknown error',
|
|
|
});
|
|
|
},
|
|
|
@@ -126,10 +116,9 @@ export function ProductVariantDetailPage() {
|
|
|
<PageTitle>
|
|
|
{creatingNewEntity ? <Trans>New product variant</Trans> : (entity?.name ?? '')}
|
|
|
</PageTitle>
|
|
|
- <Form {...form}>
|
|
|
- <form onSubmit={submitHandler} className="space-y-8">
|
|
|
- <PageActionBar>
|
|
|
- <ContentLanguageSelector />
|
|
|
+ <PageDetailForm form={form} submitHandler={submitHandler}>
|
|
|
+ <PageActionBar>
|
|
|
+ <PageActionBarRight>
|
|
|
<PermissionGuard requires={['UpdateProduct', 'UpdateCatalog']}>
|
|
|
<Button
|
|
|
type="submit"
|
|
|
@@ -138,269 +127,210 @@ export function ProductVariantDetailPage() {
|
|
|
<Trans>Update</Trans>
|
|
|
</Button>
|
|
|
</PermissionGuard>
|
|
|
- </PageActionBar>
|
|
|
- <PageLayout>
|
|
|
- <PageBlock column="side">
|
|
|
- <FormField
|
|
|
+ </PageActionBarRight>
|
|
|
+ </PageActionBar>
|
|
|
+ <PageLayout>
|
|
|
+ <PageBlock column="side">
|
|
|
+ <FormFieldWrapper
|
|
|
+ control={form.control}
|
|
|
+ name="enabled"
|
|
|
+ label={<Trans>Enabled</Trans>}
|
|
|
+ description={<Trans>When enabled, a product is available in the shop</Trans>}
|
|
|
+ render={({ field }) => (
|
|
|
+ <Switch checked={field.value} onCheckedChange={field.onChange} />
|
|
|
+ )}
|
|
|
+ />
|
|
|
+ </PageBlock>
|
|
|
+ <PageBlock column="main">
|
|
|
+ <DetailFormGrid>
|
|
|
+ <TranslatableFormFieldWrapper
|
|
|
+ control={form.control}
|
|
|
+ name="name"
|
|
|
+ label={<Trans>Product name</Trans>}
|
|
|
+ render={({ field }) => <Input {...field} />}
|
|
|
+ />
|
|
|
+
|
|
|
+ <FormFieldWrapper
|
|
|
+ control={form.control}
|
|
|
+ name="sku"
|
|
|
+ label={<Trans>SKU</Trans>}
|
|
|
+ render={({ field }) => <Input {...field} />}
|
|
|
+ />
|
|
|
+ </DetailFormGrid>
|
|
|
+ </PageBlock>
|
|
|
+ <CustomFieldsPageBlock column="main" entityType="ProductVariant" control={form.control} />
|
|
|
+
|
|
|
+ <PageBlock column="main" title={<Trans>Price and tax</Trans>}>
|
|
|
+ <div className="grid grid-cols-2 gap-4 items-start">
|
|
|
+ <FormFieldWrapper
|
|
|
control={form.control}
|
|
|
- name="enabled"
|
|
|
+ name="taxCategoryId"
|
|
|
+ label={<Trans>Tax category</Trans>}
|
|
|
render={({ field }) => (
|
|
|
- <FormItem>
|
|
|
- <FormLabel>
|
|
|
- <Trans>Enabled</Trans>
|
|
|
- </FormLabel>
|
|
|
- <FormControl>
|
|
|
- <Switch checked={field.value} onCheckedChange={field.onChange} />
|
|
|
- </FormControl>
|
|
|
- <FormDescription>
|
|
|
- <Trans>When enabled, a product is available in the shop</Trans>
|
|
|
- </FormDescription>
|
|
|
- <FormMessage />
|
|
|
- </FormItem>
|
|
|
+ <TaxCategorySelector value={field.value} onChange={field.onChange} />
|
|
|
)}
|
|
|
/>
|
|
|
- </PageBlock>
|
|
|
- <PageBlock column="main">
|
|
|
- <div className="md:flex w-full gap-4">
|
|
|
- <div className="w-1/2">
|
|
|
- <TranslatableFormField
|
|
|
- control={form.control}
|
|
|
- name="name"
|
|
|
- render={({ field }) => (
|
|
|
- <FormItem>
|
|
|
- <FormLabel>
|
|
|
- <Trans>Product name</Trans>
|
|
|
- </FormLabel>
|
|
|
- <FormControl>
|
|
|
- <Input placeholder="" {...field} />
|
|
|
- </FormControl>
|
|
|
- <FormMessage />
|
|
|
- </FormItem>
|
|
|
- )}
|
|
|
- />
|
|
|
- </div>
|
|
|
- <div className="w-1/2">
|
|
|
- <FormField
|
|
|
- control={form.control}
|
|
|
- name="sku"
|
|
|
- render={({ field }) => (
|
|
|
- <FormItem>
|
|
|
- <FormLabel>
|
|
|
- <Trans>SKU</Trans>
|
|
|
- </FormLabel>
|
|
|
- <FormControl>
|
|
|
- <Input placeholder="" {...field} />
|
|
|
- </FormControl>
|
|
|
- <FormMessage />
|
|
|
- </FormItem>
|
|
|
- )}
|
|
|
- />
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </PageBlock>
|
|
|
- <CustomFieldsPageBlock
|
|
|
- column="main"
|
|
|
- entityType="ProductVariant"
|
|
|
- control={form.control}
|
|
|
- />
|
|
|
|
|
|
- <PageBlock column="main" title={<Trans>Price and tax</Trans>}>
|
|
|
- <div className="grid grid-cols-2 gap-4 items-start">
|
|
|
- <FormField
|
|
|
+ <div>
|
|
|
+ <FormFieldWrapper
|
|
|
control={form.control}
|
|
|
- name="taxCategoryId"
|
|
|
+ name="price"
|
|
|
+ label={<Trans>Price</Trans>}
|
|
|
render={({ field }) => (
|
|
|
- <FormItem>
|
|
|
- <FormLabel>
|
|
|
- <Trans>Tax category</Trans>
|
|
|
- </FormLabel>
|
|
|
- <FormControl>
|
|
|
- <TaxCategorySelector {...field} />
|
|
|
- </FormControl>
|
|
|
- </FormItem>
|
|
|
+ <MoneyInput {...field} currency={entity?.currencyCode} />
|
|
|
)}
|
|
|
/>
|
|
|
-
|
|
|
- <div>
|
|
|
- <FormField
|
|
|
+ <VariantPriceDetail
|
|
|
+ priceIncludesTax={activeChannel?.pricesIncludeTax ?? false}
|
|
|
+ price={price}
|
|
|
+ currencyCode={entity?.currencyCode}
|
|
|
+ taxCategoryId={taxCategoryId}
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </PageBlock>
|
|
|
+ <PageBlock column="main" title={<Trans>Stock</Trans>}>
|
|
|
+ <DetailFormGrid>
|
|
|
+ {entity.stockLevels.map((stockLevel, index) => (
|
|
|
+ <Fragment key={stockLevel.id}>
|
|
|
+ <FormFieldWrapper
|
|
|
control={form.control}
|
|
|
- name="price"
|
|
|
+ name={`stockLevels.${index}.stockOnHand`}
|
|
|
render={({ field }) => (
|
|
|
<FormItem>
|
|
|
<FormLabel>
|
|
|
- <Trans>Price</Trans>
|
|
|
+ <Trans>Stock level</Trans>
|
|
|
</FormLabel>
|
|
|
<FormControl>
|
|
|
- <MoneyInput {...field} currency={entity?.currencyCode} />
|
|
|
+ <Input type="number" {...field} />
|
|
|
</FormControl>
|
|
|
</FormItem>
|
|
|
)}
|
|
|
/>
|
|
|
- <VariantPriceDetail
|
|
|
- priceIncludesTax={entity.priceIncludesTax}
|
|
|
- price={price}
|
|
|
- currencyCode={entity.currencyCode}
|
|
|
- taxCategoryId={taxCategoryId}
|
|
|
- />
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </PageBlock>
|
|
|
- <PageBlock column="main" title={<Trans>Stock</Trans>}>
|
|
|
- <div className="grid grid-cols-2 gap-4 items-start">
|
|
|
- {entity.stockLevels.map((stockLevel, index) => (
|
|
|
- <Fragment key={stockLevel.id}>
|
|
|
- <FormField
|
|
|
- control={form.control}
|
|
|
- name={`stockLevels.${index}.stockOnHand`}
|
|
|
- render={({ field }) => (
|
|
|
- <FormItem>
|
|
|
- <FormLabel>
|
|
|
- <Trans>Stock level</Trans>
|
|
|
- </FormLabel>
|
|
|
- <FormControl>
|
|
|
- <Input type="number" {...field} />
|
|
|
- </FormControl>
|
|
|
- </FormItem>
|
|
|
- )}
|
|
|
- />
|
|
|
- <div>
|
|
|
- <FormItem>
|
|
|
- <FormLabel>
|
|
|
- <Trans>Allocated</Trans>
|
|
|
- </FormLabel>
|
|
|
- <div className="text-sm pt-1.5">{stockLevel.stockAllocated}</div>
|
|
|
- </FormItem>
|
|
|
- </div>
|
|
|
- </Fragment>
|
|
|
- ))}
|
|
|
-
|
|
|
- <FormField
|
|
|
- control={form.control}
|
|
|
- name="trackInventory"
|
|
|
- render={({ field }) => (
|
|
|
- <FormItem>
|
|
|
- <FormLabel>
|
|
|
- <Trans>Track inventory</Trans>
|
|
|
- </FormLabel>
|
|
|
- <Select onValueChange={field.onChange} value={field.value}>
|
|
|
- <FormControl>
|
|
|
- <SelectTrigger className="">
|
|
|
- <SelectValue placeholder="Track inventory" />
|
|
|
- </SelectTrigger>
|
|
|
- </FormControl>
|
|
|
- <SelectContent>
|
|
|
- <SelectItem value="INHERIT">
|
|
|
- <Trans>Inherit from global settings</Trans>
|
|
|
- </SelectItem>
|
|
|
- <SelectItem value="TRUE">
|
|
|
- <Trans>Track</Trans>
|
|
|
- </SelectItem>
|
|
|
- <SelectItem value="FALSE">
|
|
|
- <Trans>Do not track</Trans>
|
|
|
- </SelectItem>
|
|
|
- </SelectContent>
|
|
|
- </Select>
|
|
|
- </FormItem>
|
|
|
- )}
|
|
|
- />
|
|
|
- <FormField
|
|
|
- control={form.control}
|
|
|
- name="outOfStockThreshold"
|
|
|
- render={({ field }) => (
|
|
|
+ <div>
|
|
|
<FormItem>
|
|
|
<FormLabel>
|
|
|
- <Trans>Out-of-stock threshold</Trans>
|
|
|
+ <Trans>Allocated</Trans>
|
|
|
</FormLabel>
|
|
|
- <FormControl>
|
|
|
- <Input type="number" {...field} />
|
|
|
- </FormControl>
|
|
|
- <FormDescription>
|
|
|
- <Trans>
|
|
|
- Sets the stock level at which this variant is considered
|
|
|
- to be out of stock. Using a negative value enables
|
|
|
- backorder support.
|
|
|
- </Trans>
|
|
|
- </FormDescription>
|
|
|
+ <div className="text-sm pt-1.5">{stockLevel.stockAllocated}</div>
|
|
|
</FormItem>
|
|
|
- )}
|
|
|
- />
|
|
|
- <FormField
|
|
|
- control={form.control}
|
|
|
- name="useGlobalOutOfStockThreshold"
|
|
|
- render={({ field }) => (
|
|
|
- <FormItem>
|
|
|
- <FormLabel>
|
|
|
- <Trans>Use global out-of-stock threshold</Trans>
|
|
|
- </FormLabel>
|
|
|
+ </div>
|
|
|
+ </Fragment>
|
|
|
+ ))}
|
|
|
+
|
|
|
+ <FormField
|
|
|
+ control={form.control}
|
|
|
+ name="trackInventory"
|
|
|
+ render={({ field }) => (
|
|
|
+ <FormItem>
|
|
|
+ <FormLabel>
|
|
|
+ <Trans>Track inventory</Trans>
|
|
|
+ </FormLabel>
|
|
|
+ <Select onValueChange={field.onChange} value={field.value}>
|
|
|
<FormControl>
|
|
|
- <Switch
|
|
|
- checked={field.value}
|
|
|
- onCheckedChange={field.onChange}
|
|
|
- />
|
|
|
+ <SelectTrigger className="">
|
|
|
+ <SelectValue placeholder="Track inventory" />
|
|
|
+ </SelectTrigger>
|
|
|
</FormControl>
|
|
|
- <FormDescription>
|
|
|
- <Trans>
|
|
|
- Sets the stock level at which this variant is considered
|
|
|
- to be out of stock. Using a negative value enables
|
|
|
- backorder support.
|
|
|
- </Trans>
|
|
|
- </FormDescription>
|
|
|
- </FormItem>
|
|
|
- )}
|
|
|
- />
|
|
|
- </div>
|
|
|
- </PageBlock>
|
|
|
-
|
|
|
- <PageBlock column="side">
|
|
|
+ <SelectContent>
|
|
|
+ <SelectItem value="INHERIT">
|
|
|
+ <Trans>Inherit from global settings</Trans>
|
|
|
+ </SelectItem>
|
|
|
+ <SelectItem value="TRUE">
|
|
|
+ <Trans>Track</Trans>
|
|
|
+ </SelectItem>
|
|
|
+ <SelectItem value="FALSE">
|
|
|
+ <Trans>Do not track</Trans>
|
|
|
+ </SelectItem>
|
|
|
+ </SelectContent>
|
|
|
+ </Select>
|
|
|
+ </FormItem>
|
|
|
+ )}
|
|
|
+ />
|
|
|
<FormField
|
|
|
control={form.control}
|
|
|
- name="facetValueIds"
|
|
|
+ name="outOfStockThreshold"
|
|
|
render={({ field }) => (
|
|
|
<FormItem>
|
|
|
<FormLabel>
|
|
|
- <Trans>Facet values</Trans>
|
|
|
+ <Trans>Out-of-stock threshold</Trans>
|
|
|
</FormLabel>
|
|
|
<FormControl>
|
|
|
- <AssignedFacetValues
|
|
|
- facetValues={entity?.facetValues ?? []}
|
|
|
- {...field}
|
|
|
- />
|
|
|
+ <Input type="number" {...field} />
|
|
|
</FormControl>
|
|
|
- <FormMessage />
|
|
|
+ <FormDescription>
|
|
|
+ <Trans>
|
|
|
+ Sets the stock level at which this variant is considered to be
|
|
|
+ out of stock. Using a negative value enables backorder
|
|
|
+ support.
|
|
|
+ </Trans>
|
|
|
+ </FormDescription>
|
|
|
</FormItem>
|
|
|
)}
|
|
|
/>
|
|
|
- </PageBlock>
|
|
|
- <PageBlock column="side">
|
|
|
- <FormItem>
|
|
|
- <FormLabel>
|
|
|
- <Trans>Assets</Trans>
|
|
|
- </FormLabel>
|
|
|
- <FormControl>
|
|
|
- <EntityAssets
|
|
|
- assets={entity?.assets}
|
|
|
- featuredAsset={entity?.featuredAsset}
|
|
|
- compact={true}
|
|
|
- value={form.getValues()}
|
|
|
- onChange={value => {
|
|
|
- form.setValue('featuredAssetId', value.featuredAssetId, {
|
|
|
- shouldDirty: true,
|
|
|
- shouldValidate: true,
|
|
|
- });
|
|
|
- form.setValue('assetIds', value.assetIds, {
|
|
|
- shouldDirty: true,
|
|
|
- shouldValidate: true,
|
|
|
- });
|
|
|
- }}
|
|
|
- />
|
|
|
- </FormControl>
|
|
|
- <FormDescription></FormDescription>
|
|
|
- <FormMessage />
|
|
|
- </FormItem>
|
|
|
- </PageBlock>
|
|
|
- </PageLayout>
|
|
|
- </form>
|
|
|
- </Form>
|
|
|
+ <FormField
|
|
|
+ control={form.control}
|
|
|
+ name="useGlobalOutOfStockThreshold"
|
|
|
+ render={({ field }) => (
|
|
|
+ <FormItem>
|
|
|
+ <FormLabel>
|
|
|
+ <Trans>Use global out-of-stock threshold</Trans>
|
|
|
+ </FormLabel>
|
|
|
+ <FormControl>
|
|
|
+ <Switch checked={field.value} onCheckedChange={field.onChange} />
|
|
|
+ </FormControl>
|
|
|
+ <FormDescription>
|
|
|
+ <Trans>
|
|
|
+ Sets the stock level at which this variant is considered to be
|
|
|
+ out of stock. Using a negative value enables backorder
|
|
|
+ support.
|
|
|
+ </Trans>
|
|
|
+ </FormDescription>
|
|
|
+ </FormItem>
|
|
|
+ )}
|
|
|
+ />
|
|
|
+ </DetailFormGrid>
|
|
|
+ </PageBlock>
|
|
|
+
|
|
|
+ <PageBlock column="side">
|
|
|
+ <FormFieldWrapper
|
|
|
+ control={form.control}
|
|
|
+ name="facetValueIds"
|
|
|
+ label={<Trans>Facet values</Trans>}
|
|
|
+ render={({ field }) => (
|
|
|
+ <AssignedFacetValues facetValues={entity?.facetValues ?? []} {...field} />
|
|
|
+ )}
|
|
|
+ />
|
|
|
+ </PageBlock>
|
|
|
+ <PageBlock column="side">
|
|
|
+ <FormItem>
|
|
|
+ <FormLabel>
|
|
|
+ <Trans>Assets</Trans>
|
|
|
+ </FormLabel>
|
|
|
+ <FormControl>
|
|
|
+ <EntityAssets
|
|
|
+ assets={entity?.assets}
|
|
|
+ featuredAsset={entity?.featuredAsset}
|
|
|
+ compact={true}
|
|
|
+ value={form.getValues()}
|
|
|
+ onChange={value => {
|
|
|
+ form.setValue('featuredAssetId', value.featuredAssetId, {
|
|
|
+ shouldDirty: true,
|
|
|
+ shouldValidate: true,
|
|
|
+ });
|
|
|
+ form.setValue('assetIds', value.assetIds, {
|
|
|
+ shouldDirty: true,
|
|
|
+ shouldValidate: true,
|
|
|
+ });
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ </FormControl>
|
|
|
+ <FormDescription></FormDescription>
|
|
|
+ <FormMessage />
|
|
|
+ </FormItem>
|
|
|
+ </PageBlock>
|
|
|
+ </PageLayout>
|
|
|
+ </PageDetailForm>
|
|
|
</Page>
|
|
|
);
|
|
|
}
|