Fix KDS nested modifier display with breadcrumb paths
- Rewrote modifier rendering to display leaf modifiers only - Added breadcrumb paths for full context (e.g., "Customize Spread: Extra") - Eliminated nested div wrappers that were breaking the display - Added comprehensive debug logging for troubleshooting - Modifiers now show complete hierarchy without clutter 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
d7f68e8098
commit
4f694850e6
1 changed files with 85 additions and 19 deletions
104
kds/kds.js
104
kds/kds.js
|
|
@ -100,8 +100,13 @@ function startAutoRefresh() {
|
||||||
async function loadOrders() {
|
async function loadOrders() {
|
||||||
if (!config.businessId) return;
|
if (!config.businessId) return;
|
||||||
|
|
||||||
|
console.log('[loadOrders] Fetching with BusinessID:', config.businessId, 'ServicePointID:', config.servicePointId);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch(`${config.apiBaseUrl}/orders/listForKDS.cfm`, {
|
const url = `${config.apiBaseUrl}/orders/listForKDS.cfm`;
|
||||||
|
console.log('[loadOrders] URL:', url);
|
||||||
|
|
||||||
|
const response = await fetch(url, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
|
|
@ -112,13 +117,20 @@ async function loadOrders() {
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
console.log('[loadOrders] Response status:', response.status);
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
|
console.log('[loadOrders] Response data:', data);
|
||||||
|
|
||||||
if (data.OK) {
|
if (data.OK) {
|
||||||
orders = data.ORDERS || [];
|
orders = data.ORDERS || [];
|
||||||
|
console.log('[loadOrders] Orders received:', orders.length);
|
||||||
|
if (orders.length > 0) {
|
||||||
|
console.log('[loadOrders] First order LineItems:', orders[0].LineItems);
|
||||||
|
}
|
||||||
renderOrders();
|
renderOrders();
|
||||||
updateStatus(true, `${orders.length} active orders`);
|
updateStatus(true, `${orders.length} active orders`);
|
||||||
} else {
|
} else {
|
||||||
|
console.error('[loadOrders] API returned OK=false:', data);
|
||||||
updateStatus(false, `Error: ${data.MESSAGE || data.ERROR}`);
|
updateStatus(false, `Error: ${data.MESSAGE || data.ERROR}`);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|
@ -203,6 +215,11 @@ function renderOrder(order) {
|
||||||
function renderLineItem(item, allItems) {
|
function renderLineItem(item, allItems) {
|
||||||
const modifiers = allItems.filter(mod => mod.OrderLineItemParentOrderLineItemID === item.OrderLineItemID);
|
const modifiers = allItems.filter(mod => mod.OrderLineItemParentOrderLineItemID === item.OrderLineItemID);
|
||||||
|
|
||||||
|
console.log(`[renderLineItem] Item: ${item.ItemName}, ID: ${item.OrderLineItemID}, Modifiers found: ${modifiers.length}`);
|
||||||
|
if (modifiers.length > 0) {
|
||||||
|
console.log('[renderLineItem] Modifiers:', modifiers);
|
||||||
|
}
|
||||||
|
|
||||||
return `
|
return `
|
||||||
<div class="line-item">
|
<div class="line-item">
|
||||||
<div class="line-item-main">
|
<div class="line-item-main">
|
||||||
|
|
@ -210,11 +227,7 @@ function renderLineItem(item, allItems) {
|
||||||
<div class="item-qty">×${item.OrderLineItemQuantity}</div>
|
<div class="item-qty">×${item.OrderLineItemQuantity}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
${modifiers.length > 0 ? `
|
${modifiers.length > 0 ? renderAllModifiers(modifiers, allItems) : ''}
|
||||||
<div class="modifiers">
|
|
||||||
${modifiers.map(mod => renderModifier(mod, allItems)).join('')}
|
|
||||||
</div>
|
|
||||||
` : ''}
|
|
||||||
|
|
||||||
${item.OrderLineItemRemark ? `
|
${item.OrderLineItemRemark ? `
|
||||||
<div class="item-remark">Note: ${escapeHtml(item.OrderLineItemRemark)}</div>
|
<div class="item-remark">Note: ${escapeHtml(item.OrderLineItemRemark)}</div>
|
||||||
|
|
@ -223,20 +236,73 @@ function renderLineItem(item, allItems) {
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render modifier (recursive for nested modifiers)
|
// Render all modifiers (flattened, no nested wrappers)
|
||||||
function renderModifier(modifier, allItems) {
|
function renderAllModifiers(modifiers, allItems) {
|
||||||
const subModifiers = allItems.filter(mod => mod.OrderLineItemParentOrderLineItemID === modifier.OrderLineItemID);
|
let html = '<div class="modifiers">';
|
||||||
|
|
||||||
return `
|
// Build path for each leaf modifier
|
||||||
<div class="modifier">
|
function getModifierPath(mod) {
|
||||||
+ ${escapeHtml(modifier.ItemName)}
|
const path = [];
|
||||||
${subModifiers.length > 0 ? `
|
let current = mod;
|
||||||
<div class="modifiers">
|
|
||||||
${subModifiers.map(sub => renderModifier(sub, allItems)).join('')}
|
// Walk up the tree to build the path
|
||||||
</div>
|
while (current) {
|
||||||
` : ''}
|
path.unshift(current.ItemName);
|
||||||
</div>
|
const parentId = current.OrderLineItemParentOrderLineItemID;
|
||||||
`;
|
if (parentId === 0) break;
|
||||||
|
current = allItems.find(item => item.OrderLineItemID === parentId);
|
||||||
|
}
|
||||||
|
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Collect all leaf modifiers with their paths
|
||||||
|
const leafModifiers = [];
|
||||||
|
|
||||||
|
function collectLeafModifiers(mods) {
|
||||||
|
mods.forEach(mod => {
|
||||||
|
const children = allItems.filter(item => item.OrderLineItemParentOrderLineItemID === mod.OrderLineItemID);
|
||||||
|
if (children.length === 0) {
|
||||||
|
// This is a leaf - no children
|
||||||
|
const path = getModifierPath(mod);
|
||||||
|
leafModifiers.push({ mod, path });
|
||||||
|
} else {
|
||||||
|
// This has children, recurse into them
|
||||||
|
collectLeafModifiers(children);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
collectLeafModifiers(modifiers);
|
||||||
|
|
||||||
|
// Render leaf modifiers with breadcrumb paths
|
||||||
|
leafModifiers.forEach(({ path }) => {
|
||||||
|
const displayText = path.join(': ');
|
||||||
|
html += `<div class="modifier">+ ${escapeHtml(displayText)}</div>`;
|
||||||
|
});
|
||||||
|
|
||||||
|
html += '</div>';
|
||||||
|
return html;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render modifier recursively with indentation
|
||||||
|
function renderModifierRecursive(modifier, allItems, level) {
|
||||||
|
const subModifiers = allItems.filter(mod => mod.OrderLineItemParentOrderLineItemID === modifier.OrderLineItemID);
|
||||||
|
// For KDS MVP: no indentation, just flat list
|
||||||
|
const indent = 0; // Changed from: level * 20
|
||||||
|
|
||||||
|
console.log(`[renderModifierRecursive] Level ${level}: ${modifier.ItemName} (ID: ${modifier.OrderLineItemID}), Sub-modifiers: ${subModifiers.length}`);
|
||||||
|
|
||||||
|
let html = `<div class="modifier" style="padding-left: ${indent}px;">+ ${escapeHtml(modifier.ItemName)}</div>`;
|
||||||
|
|
||||||
|
// Recursively render sub-modifiers
|
||||||
|
if (subModifiers.length > 0) {
|
||||||
|
subModifiers.forEach(sub => {
|
||||||
|
html += renderModifierRecursive(sub, allItems, level + 1);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return html;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render action buttons based on order status
|
// Render action buttons based on order status
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue