feat: implement category flags, drop global tables, fix sidebar sticky layout
All checks were successful
Staging Build / build (push) Successful in 2m48s
All checks were successful
Staging Build / build (push) Successful in 2m48s
This commit is contained in:
@@ -7,6 +7,8 @@ export function validateWizardSelections(
|
||||
): void {
|
||||
for (const cat of dbCategories) {
|
||||
const sel = selections[cat.id]
|
||||
|
||||
// --- is_required: Pflichtauswahl prüfen ---
|
||||
const hasSelection = sel && (
|
||||
(cat.allow_multiselect && sel.productIds && sel.productIds.length > 0) ||
|
||||
(!cat.allow_multiselect && sel.productId)
|
||||
@@ -17,6 +19,13 @@ export function validateWizardSelections(
|
||||
}
|
||||
|
||||
if (sel) {
|
||||
// --- allow_multiselect = false: keine doppelten IDs erlaubt ---
|
||||
if (!cat.allow_multiselect && sel.productIds && sel.productIds.length > 1) {
|
||||
throw new Error(
|
||||
`Die Kategorie "${cat.name}" erlaubt keine Mehrfachauswahl. Bitte nur ein Produkt wählen.`
|
||||
)
|
||||
}
|
||||
|
||||
const selectedProds: Product[] = []
|
||||
if (cat.allow_multiselect && sel.productIds) {
|
||||
sel.productIds.forEach(pId => {
|
||||
@@ -32,8 +41,8 @@ export function validateWizardSelections(
|
||||
// Validate selected modules
|
||||
for (const mId of sel.moduleIds) {
|
||||
const mod = prod.modules?.find(m => m.id === mId)
|
||||
if (!mod) continue // module might belong to another selected product in the same category, so skip error if it's not this one's
|
||||
|
||||
if (!mod) continue
|
||||
|
||||
// Requirements check
|
||||
if (mod.requirements && mod.requirements.length > 0) {
|
||||
const hasMetRequirement = mod.requirements.some(reqId => sel.moduleIds.includes(reqId))
|
||||
@@ -53,7 +62,7 @@ export function validateWizardSelections(
|
||||
}
|
||||
}
|
||||
|
||||
// Product-level constraints validation
|
||||
// --- Product-level constraints validation ---
|
||||
const selectedProductIds: string[] = []
|
||||
Object.values(selections).forEach(s => {
|
||||
if (s.productIds && s.productIds.length > 0) {
|
||||
@@ -92,3 +101,4 @@ export function validateWizardSelections(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,65 +1,5 @@
|
||||
import { Product, ProductModule, Category, WizardSelections } from './types';
|
||||
|
||||
export interface GlobalInclusion {
|
||||
trigger_product_id: string;
|
||||
included_module_id: string;
|
||||
}
|
||||
|
||||
export interface GlobalExclusion {
|
||||
product_id: string;
|
||||
excluded_product_id?: string | null;
|
||||
excluded_module_id?: string | null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle changes to the base product.
|
||||
* Resets selected modules that are excluded by global exclusions for the new product.
|
||||
* Automatically adds globally included modules for the new product.
|
||||
*/
|
||||
export function handleBaseProductChange(
|
||||
newProductId: string,
|
||||
currentSelections: WizardSelections,
|
||||
modules: ProductModule[],
|
||||
inclusions: GlobalInclusion[],
|
||||
exclusions: GlobalExclusion[]
|
||||
): WizardSelections {
|
||||
const updated: WizardSelections = JSON.parse(JSON.stringify(currentSelections));
|
||||
|
||||
// Find all modules that are excluded for the new product
|
||||
const excludedModuleIds = exclusions
|
||||
.filter(ex => ex.product_id === newProductId && ex.excluded_module_id)
|
||||
.map(ex => ex.excluded_module_id as string);
|
||||
|
||||
// Find all modules that are automatically included for the new product
|
||||
const includedModuleIds = inclusions
|
||||
.filter(inc => inc.trigger_product_id === newProductId)
|
||||
.map(inc => inc.included_module_id);
|
||||
|
||||
// Iterate over categories and filter modules
|
||||
for (const categoryId in updated) {
|
||||
const selection = updated[categoryId];
|
||||
|
||||
// Remove excluded modules
|
||||
selection.moduleIds = selection.moduleIds.filter(
|
||||
mid => !excludedModuleIds.includes(mid)
|
||||
);
|
||||
|
||||
// Add automatically included modules if they belong to this category
|
||||
for (const incId of includedModuleIds) {
|
||||
const module = modules.find(m => m.id === incId);
|
||||
if (module && module.product_id === newProductId) {
|
||||
// Find category of module. In our schema, modules might belong to a category.
|
||||
// Assuming we check if module belongs to current category:
|
||||
// We'll append it if the selections is for that category (or we can resolve category from module)
|
||||
// Let's assume we map it by checking module metadata or category_id if available.
|
||||
// For simplicity: if the module is already in the DB and matches, we add it.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return updated;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle toggling of a module selection.
|
||||
* Handles category-specific allow_multiselect rules.
|
||||
|
||||
Reference in New Issue
Block a user