feat(category): add resets_others option
All checks were successful
Staging Build / build (push) Successful in 2m46s
All checks were successful
Staging Build / build (push) Successful in 2m46s
This commit is contained in:
@@ -48,6 +48,7 @@ const categorySchema = z.object({
|
||||
preselect: z.boolean().default(true),
|
||||
show_in_kauf: z.boolean().default(true),
|
||||
show_in_abo: z.boolean().default(true),
|
||||
resets_others: z.boolean().default(false),
|
||||
})
|
||||
|
||||
type CategoryFormValues = z.infer<typeof categorySchema>
|
||||
@@ -75,6 +76,7 @@ export function CategoryDialog({
|
||||
preselect: category?.preselect ?? true,
|
||||
show_in_kauf: category?.show_in_kauf ?? true,
|
||||
show_in_abo: category?.show_in_abo ?? true,
|
||||
resets_others: category?.resets_others ?? false,
|
||||
},
|
||||
})
|
||||
|
||||
@@ -269,6 +271,29 @@ export function CategoryDialog({
|
||||
/>
|
||||
)}
|
||||
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="resets_others"
|
||||
render={({ field }) => (
|
||||
<FormItem className="flex flex-row items-start space-x-3 space-y-0 rounded-lg border border-slate-200 dark:border-white/10 bg-slate-50 dark:bg-white/5 p-4">
|
||||
<FormControl>
|
||||
<Checkbox
|
||||
checked={field.value}
|
||||
onCheckedChange={field.onChange}
|
||||
/>
|
||||
</FormControl>
|
||||
<div className="space-y-1 leading-none">
|
||||
<FormLabel className="text-slate-900 dark:text-white font-semibold cursor-pointer">
|
||||
Anderen Kategorien bei Auswahl zurücksetzen
|
||||
</FormLabel>
|
||||
<p className="text-xs text-slate-500 dark:text-slate-400">
|
||||
Wenn aktiv, setzt die Auswahl eines Artikels dieser Kategorie alle anderen Kategorien zurück.
|
||||
</p>
|
||||
</div>
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
|
||||
<div className="grid grid-cols-2 gap-4">
|
||||
<FormField
|
||||
control={form.control}
|
||||
|
||||
@@ -379,30 +379,61 @@ export function OrderWizard({
|
||||
nextProductId = productId
|
||||
}
|
||||
|
||||
const isSelectedNow = cat?.allow_multiselect
|
||||
? nextProductIds.includes(productId)
|
||||
: nextProductId === productId
|
||||
|
||||
const shouldReset = isSelectedNow && cat?.resets_others
|
||||
|
||||
const next = {
|
||||
...prev,
|
||||
[catId]: { productId: nextProductId, productIds: nextProductIds, moduleIds: [] },
|
||||
}
|
||||
|
||||
// Automatically deselect now conflicting products in other categories
|
||||
const selectedIds: string[] = []
|
||||
Object.values(next).forEach(s => {
|
||||
if (s.productIds && s.productIds.length > 0) {
|
||||
s.productIds.forEach(id => {
|
||||
if (id) selectedIds.push(id)
|
||||
})
|
||||
} else if (s.productId) {
|
||||
selectedIds.push(s.productId)
|
||||
}
|
||||
})
|
||||
if (shouldReset) {
|
||||
// Reset all other categories
|
||||
categories.forEach(c => {
|
||||
if (c.id !== catId) {
|
||||
next[c.id] = { productId: null, productIds: [], moduleIds: [] }
|
||||
}
|
||||
})
|
||||
} else {
|
||||
// Automatically deselect now conflicting products in other categories
|
||||
const selectedIds: string[] = []
|
||||
Object.values(next).forEach(s => {
|
||||
if (s.productIds && s.productIds.length > 0) {
|
||||
s.productIds.forEach(id => {
|
||||
if (id) selectedIds.push(id)
|
||||
})
|
||||
} else if (s.productId) {
|
||||
selectedIds.push(s.productId)
|
||||
}
|
||||
})
|
||||
|
||||
categories.forEach(c => {
|
||||
if (c.id === catId) return
|
||||
const s = next[c.id]
|
||||
if (c.allow_multiselect && s?.productIds) {
|
||||
const validProductIds = s.productIds.filter(pId => {
|
||||
const prod = products.find(p => p.id === pId)
|
||||
const otherSelectedProductIds = selectedIds.filter(id => id !== pId)
|
||||
categories.forEach(c => {
|
||||
if (c.id === catId) return
|
||||
const s = next[c.id]
|
||||
if (c.allow_multiselect && s?.productIds) {
|
||||
const validProductIds = s.productIds.filter(pId => {
|
||||
const prod = products.find(p => p.id === pId)
|
||||
const otherSelectedProductIds = selectedIds.filter(id => id !== pId)
|
||||
const isExcluded = prod && (
|
||||
otherSelectedProductIds.some(otherId => {
|
||||
const otherProd = products.find(p => p.id === otherId)
|
||||
return otherProd?.exclusions?.includes(prod.id)
|
||||
}) ||
|
||||
prod.exclusions?.some(exId => otherSelectedProductIds.includes(exId))
|
||||
)
|
||||
return !isExcluded
|
||||
})
|
||||
next[c.id] = {
|
||||
productId: validProductIds[0] || null,
|
||||
productIds: validProductIds,
|
||||
moduleIds: []
|
||||
}
|
||||
} else if (s?.productId) {
|
||||
const prod = products.find(p => p.id === s.productId)
|
||||
const otherSelectedProductIds = selectedIds.filter(id => id !== s.productId)
|
||||
const isExcluded = prod && (
|
||||
otherSelectedProductIds.some(otherId => {
|
||||
const otherProd = products.find(p => p.id === otherId)
|
||||
@@ -410,28 +441,12 @@ export function OrderWizard({
|
||||
}) ||
|
||||
prod.exclusions?.some(exId => otherSelectedProductIds.includes(exId))
|
||||
)
|
||||
return !isExcluded
|
||||
})
|
||||
next[c.id] = {
|
||||
productId: validProductIds[0] || null,
|
||||
productIds: validProductIds,
|
||||
moduleIds: []
|
||||
if (isExcluded) {
|
||||
next[c.id] = { productId: null, productIds: [], moduleIds: [] }
|
||||
}
|
||||
}
|
||||
} else if (s?.productId) {
|
||||
const prod = products.find(p => p.id === s.productId)
|
||||
const otherSelectedProductIds = selectedIds.filter(id => id !== s.productId)
|
||||
const isExcluded = prod && (
|
||||
otherSelectedProductIds.some(otherId => {
|
||||
const otherProd = products.find(p => p.id === otherId)
|
||||
return otherProd?.exclusions?.includes(prod.id)
|
||||
}) ||
|
||||
prod.exclusions?.some(exId => otherSelectedProductIds.includes(exId))
|
||||
)
|
||||
if (isExcluded) {
|
||||
next[c.id] = { productId: null, productIds: [], moduleIds: [] }
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
return next
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user