diff --git a/fusion-plating/fusion_plating/static/src/js/recipe_tree_editor.js b/fusion-plating/fusion_plating/static/src/js/recipe_tree_editor.js index 36f1ddd4..d976e7b8 100644 --- a/fusion-plating/fusion_plating/static/src/js/recipe_tree_editor.js +++ b/fusion-plating/fusion_plating/static/src/js/recipe_tree_editor.js @@ -33,6 +33,63 @@ const NODE_TYPE_OPTIONS = [ { value: "step", label: "Step" }, ]; +// ---- Icon picker options (curated for plating / manufacturing) ----------- +const ICON_OPTIONS = [ + { value: "fa-flask", label: "Flask / Chemistry" }, + { value: "fa-industry", label: "Industry / Line" }, + { value: "fa-sitemap", label: "Sitemap / Process" }, + { value: "fa-wrench", label: "Wrench / Operation" }, + { value: "fa-cog", label: "Gear / General" }, + { value: "fa-cogs", label: "Gears / System" }, + { value: "fa-paint-brush", label: "Paint / Masking" }, + { value: "fa-eraser", label: "Eraser / De-Masking" }, + { value: "fa-th", label: "Grid / Racking" }, + { value: "fa-fire", label: "Fire / Bake" }, + { value: "fa-bolt", label: "Bolt / Electric" }, + { value: "fa-diamond", label: "Diamond / Plating" }, + { value: "fa-tint", label: "Tint / Rinse" }, + { value: "fa-shower", label: "Shower / Clean" }, + { value: "fa-bullseye", label: "Target / Blast" }, + { value: "fa-search", label: "Search / Inspect" }, + { value: "fa-check-circle", label: "Check / Approve" }, + { value: "fa-clock-o", label: "Clock / Wait" }, + { value: "fa-sun-o", label: "Sun / Dry" }, + { value: "fa-thermometer-half", label: "Temp / Heat" }, + { value: "fa-eye", label: "Eye / Visual" }, + { value: "fa-hand-paper-o", label: "Hand / Manual" }, + { value: "fa-cube", label: "Cube / Part" }, + { value: "fa-shield", label: "Shield / Protect" }, +]; + +// ---- Auto-icon: guess the best icon from the node name ------------------ +const ICON_KEYWORDS = [ + { pattern: /mask/i, icon: "fa-paint-brush" }, + { pattern: /de-?mask|unmask/i, icon: "fa-eraser" }, + { pattern: /rack/i, icon: "fa-th" }, + { pattern: /de-?rack|unrack/i, icon: "fa-th" }, + { pattern: /blast/i, icon: "fa-bullseye" }, + { pattern: /bake|oven/i, icon: "fa-fire" }, + { pattern: /clean|soak|wash/i, icon: "fa-shower" }, + { pattern: /rinse/i, icon: "fa-tint" }, + { pattern: /dry/i, icon: "fa-sun-o" }, + { pattern: /nickel|plate|plat/i, icon: "fa-diamond" }, + { pattern: /strike|electro/i, icon: "fa-bolt" }, + { pattern: /acid|dip|etch/i, icon: "fa-flask" }, + { pattern: /inspect|check|test/i, icon: "fa-search" }, + { pattern: /ready|wait|queue/i, icon: "fa-clock-o" }, + { pattern: /line|process/i, icon: "fa-industry" }, + { pattern: /heat|temp/i, icon: "fa-thermometer-half" }, + { pattern: /porosity/i, icon: "fa-tint" }, +]; + +function guessIcon(name) { + if (!name) return "fa-cog"; + for (const rule of ICON_KEYWORDS) { + if (rule.pattern.test(name)) return rule.icon; + } + return "fa-cog"; +} + export class RecipeTreeEditor extends Component { static template = "fusion_plating.RecipeTreeEditor"; static props = ["*"]; @@ -205,6 +262,7 @@ export class RecipeTreeEditor extends Component { parent_id: this.state.addingTo, name: name, node_type: this.state.newNodeType, + vals: { icon: guessIcon(name) }, }); if (result && result.ok) { this.notification.add(`Added "${name}"`, { type: "success" }); @@ -391,6 +449,10 @@ export class RecipeTreeEditor extends Component { return NODE_TYPE_OPTIONS; } + getIconOptions() { + return ICON_OPTIONS; + } + formatDuration(minutes) { if (!minutes) return ""; if (minutes < 60) return `${Math.round(minutes)}m`; diff --git a/fusion-plating/fusion_plating/static/src/scss/recipe_tree_editor.scss b/fusion-plating/fusion_plating/static/src/scss/recipe_tree_editor.scss index 902819f6..cec9e216 100644 --- a/fusion-plating/fusion_plating/static/src/scss/recipe_tree_editor.scss +++ b/fusion-plating/fusion_plating/static/src/scss/recipe_tree_editor.scss @@ -372,6 +372,40 @@ } } +// ---- Icon picker ------------------------------------------------------------ + +.o_fp_recipe_icon_picker { + display: flex; + flex-wrap: wrap; + gap: 4px; +} + +.o_fp_recipe_icon_btn { + width: 34px; + height: 34px; + display: flex; + align-items: center; + justify-content: center; + border: 1px solid $border-color; + border-radius: 6px; + background: transparent; + color: var(--bs-secondary-color); + font-size: 0.9rem; + cursor: pointer; + transition: border-color 0.12s, background-color 0.12s; + + &:hover { + border-color: var(--o-action, var(--bs-primary)); + color: var(--bs-body-color); + } + + &.active { + background: var(--o-action, var(--bs-primary)); + border-color: var(--o-action, var(--bs-primary)); + color: #fff; + } +} + // ---- Responsive ------------------------------------------------------------- @media (max-width: 768px) { diff --git a/fusion-plating/fusion_plating/static/src/xml/recipe_tree_editor.xml b/fusion-plating/fusion_plating/static/src/xml/recipe_tree_editor.xml index 59d159e7..effd3b78 100644 --- a/fusion-plating/fusion_plating/static/src/xml/recipe_tree_editor.xml +++ b/fusion-plating/fusion_plating/static/src/xml/recipe_tree_editor.xml @@ -100,14 +100,15 @@