mirror of
https://github.com/frappe/erpnext.git
synced 2026-08-15 23:48:38 +00:00
fix: workspace for stock and manufacturing (#56906)
This commit is contained in:
@@ -432,7 +432,7 @@
|
||||
"type": "Link"
|
||||
}
|
||||
],
|
||||
"modified": "2026-07-03 13:44:07.420267",
|
||||
"modified": "2026-07-05 16:32:01.858579",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Manufacturing",
|
||||
"module_onboarding": "Manufacturing Onboarding",
|
||||
@@ -463,6 +463,7 @@
|
||||
{
|
||||
"child": 0,
|
||||
"collapsible": 1,
|
||||
"default_workspace": 0,
|
||||
"icon": "house",
|
||||
"indent": 0,
|
||||
"keep_closed": 0,
|
||||
@@ -476,6 +477,7 @@
|
||||
{
|
||||
"child": 0,
|
||||
"collapsible": 1,
|
||||
"default_workspace": 0,
|
||||
"icon": "chart-column",
|
||||
"indent": 0,
|
||||
"keep_closed": 0,
|
||||
@@ -489,6 +491,7 @@
|
||||
{
|
||||
"child": 0,
|
||||
"collapsible": 1,
|
||||
"default_workspace": 0,
|
||||
"icon": "list-tree",
|
||||
"indent": 0,
|
||||
"keep_closed": 0,
|
||||
@@ -502,6 +505,7 @@
|
||||
{
|
||||
"child": 0,
|
||||
"collapsible": 1,
|
||||
"default_workspace": 0,
|
||||
"icon": "factory",
|
||||
"indent": 0,
|
||||
"keep_closed": 0,
|
||||
@@ -515,6 +519,7 @@
|
||||
{
|
||||
"child": 0,
|
||||
"collapsible": 1,
|
||||
"default_workspace": 0,
|
||||
"icon": "person-standing",
|
||||
"indent": 0,
|
||||
"keep_closed": 0,
|
||||
@@ -528,6 +533,7 @@
|
||||
{
|
||||
"child": 0,
|
||||
"collapsible": 1,
|
||||
"default_workspace": 0,
|
||||
"icon": "package",
|
||||
"indent": 0,
|
||||
"keep_closed": 0,
|
||||
@@ -541,6 +547,20 @@
|
||||
{
|
||||
"child": 0,
|
||||
"collapsible": 1,
|
||||
"default_workspace": 0,
|
||||
"indent": 0,
|
||||
"keep_closed": 0,
|
||||
"label": "Shop Floor",
|
||||
"link_to": "shop-floor",
|
||||
"link_type": "Page",
|
||||
"open_in_new_tab": 1,
|
||||
"show_arrow": 0,
|
||||
"type": "Link"
|
||||
},
|
||||
{
|
||||
"child": 0,
|
||||
"collapsible": 1,
|
||||
"default_workspace": 0,
|
||||
"icon": "rocket",
|
||||
"indent": 1,
|
||||
"keep_closed": 1,
|
||||
@@ -553,6 +573,7 @@
|
||||
{
|
||||
"child": 1,
|
||||
"collapsible": 1,
|
||||
"default_workspace": 0,
|
||||
"icon": "",
|
||||
"indent": 0,
|
||||
"keep_closed": 0,
|
||||
@@ -566,6 +587,7 @@
|
||||
{
|
||||
"child": 1,
|
||||
"collapsible": 1,
|
||||
"default_workspace": 0,
|
||||
"indent": 0,
|
||||
"keep_closed": 0,
|
||||
"label": "Production Plan",
|
||||
@@ -578,6 +600,7 @@
|
||||
{
|
||||
"child": 1,
|
||||
"collapsible": 1,
|
||||
"default_workspace": 0,
|
||||
"icon": "",
|
||||
"indent": 0,
|
||||
"keep_closed": 0,
|
||||
@@ -591,6 +614,7 @@
|
||||
{
|
||||
"child": 1,
|
||||
"collapsible": 1,
|
||||
"default_workspace": 0,
|
||||
"indent": 0,
|
||||
"keep_closed": 0,
|
||||
"label": "Master Production Schedule",
|
||||
@@ -603,6 +627,7 @@
|
||||
{
|
||||
"child": 1,
|
||||
"collapsible": 1,
|
||||
"default_workspace": 0,
|
||||
"indent": 0,
|
||||
"keep_closed": 0,
|
||||
"label": "Sales Forecast",
|
||||
@@ -615,6 +640,7 @@
|
||||
{
|
||||
"child": 1,
|
||||
"collapsible": 1,
|
||||
"default_workspace": 0,
|
||||
"indent": 0,
|
||||
"keep_closed": 0,
|
||||
"label": "Production Planning Report",
|
||||
@@ -627,6 +653,7 @@
|
||||
{
|
||||
"child": 0,
|
||||
"collapsible": 1,
|
||||
"default_workspace": 0,
|
||||
"icon": "wrench",
|
||||
"indent": 1,
|
||||
"keep_closed": 1,
|
||||
@@ -639,6 +666,7 @@
|
||||
{
|
||||
"child": 1,
|
||||
"collapsible": 1,
|
||||
"default_workspace": 0,
|
||||
"indent": 0,
|
||||
"keep_closed": 0,
|
||||
"label": "BOM Creator",
|
||||
@@ -651,6 +679,7 @@
|
||||
{
|
||||
"child": 1,
|
||||
"collapsible": 1,
|
||||
"default_workspace": 0,
|
||||
"indent": 0,
|
||||
"keep_closed": 0,
|
||||
"label": "BOM Update Tool",
|
||||
@@ -663,6 +692,7 @@
|
||||
{
|
||||
"child": 1,
|
||||
"collapsible": 1,
|
||||
"default_workspace": 0,
|
||||
"indent": 0,
|
||||
"keep_closed": 0,
|
||||
"label": "BOM Comparison Tool",
|
||||
@@ -675,6 +705,7 @@
|
||||
{
|
||||
"child": 1,
|
||||
"collapsible": 1,
|
||||
"default_workspace": 0,
|
||||
"indent": 0,
|
||||
"keep_closed": 0,
|
||||
"label": "Downtime Entry",
|
||||
@@ -687,6 +718,7 @@
|
||||
{
|
||||
"child": 0,
|
||||
"collapsible": 1,
|
||||
"default_workspace": 0,
|
||||
"icon": "notepad-text",
|
||||
"indent": 1,
|
||||
"keep_closed": 1,
|
||||
@@ -699,6 +731,7 @@
|
||||
{
|
||||
"child": 1,
|
||||
"collapsible": 1,
|
||||
"default_workspace": 0,
|
||||
"indent": 0,
|
||||
"keep_closed": 0,
|
||||
"label": "Production Planning Report",
|
||||
@@ -711,6 +744,7 @@
|
||||
{
|
||||
"child": 1,
|
||||
"collapsible": 1,
|
||||
"default_workspace": 0,
|
||||
"indent": 0,
|
||||
"keep_closed": 0,
|
||||
"label": "Work Order Summary",
|
||||
@@ -723,6 +757,7 @@
|
||||
{
|
||||
"child": 1,
|
||||
"collapsible": 1,
|
||||
"default_workspace": 0,
|
||||
"indent": 0,
|
||||
"keep_closed": 0,
|
||||
"label": "Quality Inspection Summary",
|
||||
@@ -735,6 +770,7 @@
|
||||
{
|
||||
"child": 1,
|
||||
"collapsible": 1,
|
||||
"default_workspace": 0,
|
||||
"indent": 0,
|
||||
"keep_closed": 0,
|
||||
"label": "Downtime Analysis",
|
||||
@@ -747,6 +783,7 @@
|
||||
{
|
||||
"child": 1,
|
||||
"collapsible": 1,
|
||||
"default_workspace": 0,
|
||||
"indent": 0,
|
||||
"keep_closed": 0,
|
||||
"label": "Job Card Summary",
|
||||
@@ -759,6 +796,7 @@
|
||||
{
|
||||
"child": 1,
|
||||
"collapsible": 1,
|
||||
"default_workspace": 0,
|
||||
"indent": 0,
|
||||
"keep_closed": 0,
|
||||
"label": "BOM Search",
|
||||
@@ -771,6 +809,7 @@
|
||||
{
|
||||
"child": 1,
|
||||
"collapsible": 1,
|
||||
"default_workspace": 0,
|
||||
"indent": 0,
|
||||
"keep_closed": 0,
|
||||
"label": "Production Analytics",
|
||||
@@ -783,6 +822,7 @@
|
||||
{
|
||||
"child": 1,
|
||||
"collapsible": 1,
|
||||
"default_workspace": 0,
|
||||
"indent": 0,
|
||||
"keep_closed": 0,
|
||||
"label": "BOM Operations Time",
|
||||
@@ -795,6 +835,7 @@
|
||||
{
|
||||
"child": 1,
|
||||
"collapsible": 1,
|
||||
"default_workspace": 0,
|
||||
"indent": 0,
|
||||
"keep_closed": 0,
|
||||
"label": "Work Order Consumed Materials",
|
||||
@@ -807,6 +848,7 @@
|
||||
{
|
||||
"child": 0,
|
||||
"collapsible": 1,
|
||||
"default_workspace": 0,
|
||||
"icon": "database",
|
||||
"indent": 1,
|
||||
"keep_closed": 1,
|
||||
@@ -819,6 +861,7 @@
|
||||
{
|
||||
"child": 1,
|
||||
"collapsible": 1,
|
||||
"default_workspace": 0,
|
||||
"icon": "",
|
||||
"indent": 0,
|
||||
"keep_closed": 0,
|
||||
@@ -832,6 +875,7 @@
|
||||
{
|
||||
"child": 1,
|
||||
"collapsible": 1,
|
||||
"default_workspace": 0,
|
||||
"icon": "",
|
||||
"indent": 0,
|
||||
"keep_closed": 0,
|
||||
@@ -845,6 +889,7 @@
|
||||
{
|
||||
"child": 1,
|
||||
"collapsible": 1,
|
||||
"default_workspace": 0,
|
||||
"indent": 0,
|
||||
"keep_closed": 0,
|
||||
"label": "Operation",
|
||||
@@ -857,6 +902,7 @@
|
||||
{
|
||||
"child": 1,
|
||||
"collapsible": 1,
|
||||
"default_workspace": 0,
|
||||
"icon": "",
|
||||
"indent": 0,
|
||||
"keep_closed": 0,
|
||||
@@ -870,6 +916,7 @@
|
||||
{
|
||||
"child": 1,
|
||||
"collapsible": 1,
|
||||
"default_workspace": 0,
|
||||
"indent": 0,
|
||||
"keep_closed": 0,
|
||||
"label": "Workstation Type",
|
||||
@@ -882,6 +929,7 @@
|
||||
{
|
||||
"child": 1,
|
||||
"collapsible": 1,
|
||||
"default_workspace": 0,
|
||||
"indent": 0,
|
||||
"keep_closed": 0,
|
||||
"label": "Plant Floor",
|
||||
@@ -894,6 +942,7 @@
|
||||
{
|
||||
"child": 1,
|
||||
"collapsible": 1,
|
||||
"default_workspace": 0,
|
||||
"indent": 0,
|
||||
"keep_closed": 0,
|
||||
"label": "Routing",
|
||||
@@ -906,6 +955,7 @@
|
||||
{
|
||||
"child": 0,
|
||||
"collapsible": 1,
|
||||
"default_workspace": 0,
|
||||
"icon": "settings",
|
||||
"indent": 0,
|
||||
"keep_closed": 0,
|
||||
|
||||
@@ -80,10 +80,10 @@ class ShopFloor {
|
||||
<div class="sf-topbar-right">
|
||||
<button class="btn btn-default btn-sm sf-btn-theme"></button>
|
||||
<button class="btn btn-default btn-sm sf-btn-home" title="${__("Home")}">
|
||||
${frappe.utils.icon("home", "sm")}
|
||||
${frappe.utils.icon("house", "sm")}
|
||||
</button>
|
||||
<button class="btn btn-default btn-sm sf-btn-refresh" title="${__("Refresh")} (r)">
|
||||
${frappe.utils.icon("refresh", "sm")}
|
||||
${frappe.utils.icon("refresh-cw", "sm")}
|
||||
</button>
|
||||
<button class="btn btn-default btn-sm sf-btn-scan" title="${__("Scan Job Card")} (b)">
|
||||
${frappe.utils.icon("scan", "sm")}
|
||||
@@ -100,6 +100,9 @@ class ShopFloor {
|
||||
`);
|
||||
|
||||
this.app = this.wrapper.find(".sf-app");
|
||||
this.brand_icon = `<img class="sf-brand-icon" src="/assets/erpnext/images/erpnext-logo.svg" alt="${__(
|
||||
"ERPNext"
|
||||
)}">`;
|
||||
this.topbar_left = this.wrapper.find(".sf-topbar-left");
|
||||
this.topbar_center = this.wrapper.find(".sf-topbar-center");
|
||||
this.body = this.wrapper.find(".sf-body");
|
||||
@@ -154,7 +157,7 @@ class ShopFloor {
|
||||
|
||||
if (this.view === "manager") {
|
||||
this.topbar_left.html(`
|
||||
<span class="sf-title">${__("Shop Floor")}</span>
|
||||
<span class="sf-title">${this.brand_icon}${__("Shop Floor")}</span>
|
||||
${toggle}
|
||||
<div class="sf-tabs">
|
||||
${MANAGER_BUCKETS.map(
|
||||
@@ -191,7 +194,9 @@ class ShopFloor {
|
||||
this.toggle_job_cards_only(e.target.checked);
|
||||
});
|
||||
} else {
|
||||
this.topbar_left.html(`<span class="sf-title">${__("Shop Floor")}</span>${toggle}`);
|
||||
this.topbar_left.html(
|
||||
`<span class="sf-title">${this.brand_icon}${__("Shop Floor")}</span>${toggle}`
|
||||
);
|
||||
this.build_operator_filters();
|
||||
}
|
||||
|
||||
@@ -466,11 +471,19 @@ class ShopFloor {
|
||||
this.workstation = workstation;
|
||||
this.work_order = work_order;
|
||||
this.compute_state();
|
||||
this.dedupe_today_sessions();
|
||||
this.render_operator($container);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
// A job card already shown under Completed Operations shouldn't repeat in
|
||||
// Today's Sessions — keep it in Completed Operations only.
|
||||
dedupe_today_sessions() {
|
||||
const shown = new Set((this.completed || []).map((jc) => jc.name));
|
||||
this.today_sessions = (this.today_sessions || []).filter((s) => !shown.has(s.name));
|
||||
}
|
||||
|
||||
// Re-fetch whichever operator content is currently on screen (used after every action).
|
||||
reload() {
|
||||
if (this.view === "manager" && this.selected_wo) {
|
||||
@@ -1570,7 +1583,8 @@ class ShopFloor {
|
||||
.sf-toggle input { cursor: pointer; width: 15px; height: 15px; margin: 0; }
|
||||
.sf-topbar-right { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }
|
||||
.sf-btn-theme { font-size: 15px; line-height: 1; min-width: 30px; }
|
||||
.sf-title { font-size: 18px; font-weight: 700; color: var(--text-color); }
|
||||
.sf-title { font-size: 18px; font-weight: 700; color: var(--text-color); display: inline-flex; align-items: center; gap: 8px; }
|
||||
.sf-title .sf-brand-icon { flex-shrink: 0; width: 22px; height: 22px; border-radius: 5px; }
|
||||
|
||||
.sf-view-toggle { display: inline-flex; border: 1px solid var(--border-color); border-radius: var(--border-radius); overflow: hidden; }
|
||||
.sf-view-btn { border: none; background: var(--fg-color); padding: 5px 12px; font-size: 13px; color: var(--text-muted); cursor: pointer; }
|
||||
@@ -1584,6 +1598,7 @@ class ShopFloor {
|
||||
font-size: 14px; color: var(--text-muted); cursor: pointer;
|
||||
}
|
||||
.sf-tab:hover { background: var(--bg-color); }
|
||||
.sf-tab:focus, .sf-tab:focus-visible { outline: none; box-shadow: none; }
|
||||
.sf-tab.active { background: var(--control-bg); color: var(--text-color); font-weight: 600; }
|
||||
.sf-tab-count { font-variant-numeric: tabular-nums; color: var(--text-muted); }
|
||||
.sf-dot { width: 8px; height: 8px; border-radius: 50%; display: inline-block; }
|
||||
@@ -1637,10 +1652,10 @@ class ShopFloor {
|
||||
drawn with it disappears on dark cards. Light theme keeps the dark ring; dark theme
|
||||
needs an accent colour — a light-gray ring on gray cards is still too subtle. */
|
||||
.sf-wo-card.sf-selected { border-color: var(--primary-color, var(--primary)); }
|
||||
.sf-wo-card.sf-focused { box-shadow: 0 0 0 2px var(--primary-color, var(--primary)); }
|
||||
.sf-wo-card.sf-focused { box-shadow: 0 0 0 1px var(--primary-color, var(--primary)); }
|
||||
[data-theme="dark"] .sf-wo-card.sf-selected { border-color: var(--blue-500, #2490ef); }
|
||||
[data-theme="dark"] .sf-wo-card.sf-focused {
|
||||
box-shadow: 0 0 0 3px var(--blue-500, #2490ef);
|
||||
box-shadow: 0 0 0 1px var(--blue-500, #2490ef);
|
||||
border-color: transparent;
|
||||
}
|
||||
.sf-wo-top { display: flex; align-items: center; gap: 12px; margin-bottom: 12px; }
|
||||
@@ -1666,7 +1681,7 @@ class ShopFloor {
|
||||
.sf-wo-progress-block { margin-bottom: 12px; }
|
||||
.sf-wo-progress-label { display: flex; align-items: center; justify-content: space-between; font-size: 13px; color: var(--text-muted); margin-bottom: 6px; }
|
||||
.sf-wo-progress-count { font-weight: 600; color: var(--text-color); font-variant-numeric: tabular-nums; }
|
||||
.sf-progress { display: flex; height: 10px; border-radius: 6px; background: var(--gray-300, #d1d5db); overflow: hidden; }
|
||||
.sf-progress { display: flex; height: 10px; border-radius: 6px; background: var(--gray-200, #d1d5db); overflow: hidden; }
|
||||
[data-theme="dark"] .sf-progress { background: var(--gray-700, #374151); }
|
||||
.sf-progress-seg { height: 100%; transition: width 0.3s ease; }
|
||||
.sf-seg-done { background: var(--green-400, #9ae6b4); }
|
||||
|
||||
@@ -83,7 +83,11 @@
|
||||
|
||||
/* Active job card — denser than before */
|
||||
/* Keyboard focus highlight for arrow-key navigation in the operator view. */
|
||||
[data-sf-focusable].sf-focused { box-shadow: 0 0 0 2px var(--primary); border-radius: var(--border-radius); outline: none; }
|
||||
[data-sf-focusable].sf-focused {
|
||||
box-shadow: 0 0 0 1px var(--primary-color, var(--primary)); border-radius: var(--border-radius); outline: none;
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: 12px;
|
||||
}
|
||||
.mes-job {
|
||||
border: 1px solid var(--border-color);
|
||||
background: var(--fg-color);
|
||||
|
||||
@@ -33,5 +33,6 @@ def get_data():
|
||||
{"label": _("Traceability"), "items": ["Serial No", "Batch"]},
|
||||
{"label": _("Stock Movement"), "items": ["Stock Entry", "Stock Reconciliation"]},
|
||||
{"label": _("Lead Time"), "items": ["Item Lead Time"]},
|
||||
{"label": _("Standard Cost"), "items": ["Item Standard Cost"]},
|
||||
],
|
||||
}
|
||||
|
||||
@@ -1,78 +1,4 @@
|
||||
{
|
||||
"allowed_users": [
|
||||
{
|
||||
"user": "Administrator"
|
||||
},
|
||||
{
|
||||
"user": "Guest"
|
||||
},
|
||||
{
|
||||
"user": "accounts@test.com"
|
||||
},
|
||||
{
|
||||
"user": "ankush@erpnext.com"
|
||||
},
|
||||
{
|
||||
"user": "faris@erpnext.com"
|
||||
},
|
||||
{
|
||||
"user": "mention_test_user@example.com"
|
||||
},
|
||||
{
|
||||
"user": "project@frappe.io"
|
||||
},
|
||||
{
|
||||
"user": "rushabh@erpnext.com"
|
||||
},
|
||||
{
|
||||
"user": "saqib@erpnext.com"
|
||||
},
|
||||
{
|
||||
"user": "soham@frappe.io"
|
||||
},
|
||||
{
|
||||
"user": "sohamengineer123@gmail.com"
|
||||
},
|
||||
{
|
||||
"user": "sohamkulkarns9@gmail.com"
|
||||
},
|
||||
{
|
||||
"user": "stock@xyz.com"
|
||||
},
|
||||
{
|
||||
"user": "sydel@frappe.io"
|
||||
},
|
||||
{
|
||||
"user": "test'5@example.com"
|
||||
},
|
||||
{
|
||||
"user": "test1@example.com"
|
||||
},
|
||||
{
|
||||
"user": "test2@example.com"
|
||||
},
|
||||
{
|
||||
"user": "test3@example.com"
|
||||
},
|
||||
{
|
||||
"user": "test4@example.com"
|
||||
},
|
||||
{
|
||||
"user": "test@example.com"
|
||||
},
|
||||
{
|
||||
"user": "test@portal.com"
|
||||
},
|
||||
{
|
||||
"user": "testpassword@example.com"
|
||||
},
|
||||
{
|
||||
"user": "testperm@example.com"
|
||||
},
|
||||
{
|
||||
"user": "web@web.com"
|
||||
}
|
||||
],
|
||||
"app": "erpnext",
|
||||
"charts": [
|
||||
{
|
||||
@@ -169,6 +95,16 @@
|
||||
"onboard": 0,
|
||||
"type": "Link"
|
||||
},
|
||||
{
|
||||
"hidden": 0,
|
||||
"is_query_report": 0,
|
||||
"label": "Item Standard Cost",
|
||||
"link_count": 0,
|
||||
"link_to": "Item Standard Cost",
|
||||
"link_type": "DocType",
|
||||
"onboard": 0,
|
||||
"type": "Link"
|
||||
},
|
||||
{
|
||||
"dependencies": "",
|
||||
"hidden": 0,
|
||||
@@ -863,7 +799,7 @@
|
||||
"type": "Link"
|
||||
}
|
||||
],
|
||||
"modified": "2026-07-03 12:11:34.739020",
|
||||
"modified": "2026-07-05 12:08:07.187999",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Stock",
|
||||
"module_onboarding": "Stock Onboarding",
|
||||
@@ -1215,6 +1151,19 @@
|
||||
"show_arrow": 0,
|
||||
"type": "Link"
|
||||
},
|
||||
{
|
||||
"child": 1,
|
||||
"collapsible": 1,
|
||||
"default_workspace": 0,
|
||||
"indent": 0,
|
||||
"keep_closed": 0,
|
||||
"label": "Item Standard Cost",
|
||||
"link_to": "Item Standard Cost",
|
||||
"link_type": "DocType",
|
||||
"open_in_new_tab": 1,
|
||||
"show_arrow": 0,
|
||||
"type": "Link"
|
||||
},
|
||||
{
|
||||
"child": 1,
|
||||
"collapsible": 1,
|
||||
|
||||
Reference in New Issue
Block a user