docs: add supplier modal wizard implementation plan
This commit is contained in:
parent
099f1efde3
commit
dd924904c5
423
docs/superpowers/plans/2026-05-25-supplier-modal-wizard.md
Normal file
423
docs/superpowers/plans/2026-05-25-supplier-modal-wizard.md
Normal file
@ -0,0 +1,423 @@
|
|||||||
|
# Supplier Select Modal — Two-Step Wizard Implementation Plan
|
||||||
|
|
||||||
|
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||||||
|
|
||||||
|
**Goal:** Replace the mutually-exclusive tab bar in the supplier select modal with a two-step wizard: Step 1 picks the supply method (Full Order / By Item), Step 2 shows the appropriate supplier selection UI with a "← Change method" back link that clears all selections.
|
||||||
|
|
||||||
|
**Architecture:** Single Blade component file change only — no controller, route, or migration work. The HTML is restructured into `#sup-step1` (method cards) and `#sup-step2` (existing form), both children of the modal shell. Two new JS functions (`showStep` / `goBack`) drive transitions; the existing form, panes, and submission logic are untouched.
|
||||||
|
|
||||||
|
**Tech Stack:** Laravel Blade, vanilla JS, inline CSS (Tailwind JIT not used — inline styles only per project convention)
|
||||||
|
|
||||||
|
**Spec:** `docs/superpowers/specs/2026-05-25-supplier-modal-wizard-design.md`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Task 1: Replace the header tab bar with the mode badge row
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Modify: `resources/views/components/purchase/supplier-select-modal.blade.php`
|
||||||
|
|
||||||
|
The current header has a tab bar (`stab-global`, `stab-item`). Remove it. Replace with a hidden `#sup-mode-badge-row` div (shown only in Step 2). Also add `id="sup-modal-subtitle"` to the subtitle element so JS can update it dynamically. Change the initial title to "Request for Quotation" and subtitle to "How do you want to assign suppliers?". Change `padding:20px 24px 0` → `padding:20px 24px 16px` (the `0` bottom padding was a tab-flush hack no longer needed).
|
||||||
|
|
||||||
|
- [ ] **Step 1: Replace the header block**
|
||||||
|
|
||||||
|
In `resources/views/components/purchase/supplier-select-modal.blade.php`, find and replace this exact block:
|
||||||
|
|
||||||
|
```blade
|
||||||
|
{{-- Header --}}
|
||||||
|
<div style="padding:20px 24px 0;border-bottom:1px solid #f1f5f9;flex-shrink:0;">
|
||||||
|
<div style="display:flex;align-items:flex-start;justify-content:space-between;gap:12px;margin-bottom:16px;">
|
||||||
|
<div>
|
||||||
|
<div id="sup-modal-title" style="font-size:17px;font-weight:700;color:#0f172a;">Select Suppliers</div>
|
||||||
|
<div style="font-size:12px;color:#64748b;margin-top:3px;">Choose who receives the quote request</div>
|
||||||
|
</div>
|
||||||
|
<button onclick="closeSupplierModal()" aria-label="Close"
|
||||||
|
style="width:32px;height:32px;border-radius:8px;border:none;background:#f1f5f9;cursor:pointer;font-size:18px;color:#64748b;display:flex;align-items:center;justify-content:center;flex-shrink:0;">×</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{-- Tab bar --}}
|
||||||
|
<div style="display:flex;gap:0;">
|
||||||
|
<button id="stab-global" type="button" onclick="switchSupTab('global')"
|
||||||
|
style="padding:10px 20px;font-size:13px;font-weight:700;border:none;background:none;cursor:pointer;color:#2563eb;border-bottom:2px solid #2563eb;margin-bottom:-1px;">
|
||||||
|
Full Order
|
||||||
|
</button>
|
||||||
|
<button id="stab-item" type="button" onclick="switchSupTab('item')"
|
||||||
|
style="padding:10px 20px;font-size:13px;font-weight:700;border:none;background:none;cursor:pointer;color:#94a3b8;border-bottom:2px solid transparent;margin-bottom:-1px;">
|
||||||
|
By Item
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
```
|
||||||
|
|
||||||
|
Replace with:
|
||||||
|
|
||||||
|
```blade
|
||||||
|
{{-- Header --}}
|
||||||
|
<div style="padding:20px 24px 16px;border-bottom:1px solid #f1f5f9;flex-shrink:0;">
|
||||||
|
<div style="display:flex;align-items:flex-start;justify-content:space-between;gap:12px;margin-bottom:4px;">
|
||||||
|
<div>
|
||||||
|
<div id="sup-modal-title" style="font-size:17px;font-weight:700;color:#0f172a;">Request for Quotation</div>
|
||||||
|
<div id="sup-modal-subtitle" style="font-size:12px;color:#64748b;margin-top:3px;">How do you want to assign suppliers?</div>
|
||||||
|
</div>
|
||||||
|
<button onclick="closeSupplierModal()" aria-label="Close"
|
||||||
|
style="width:32px;height:32px;border-radius:8px;border:none;background:#f1f5f9;cursor:pointer;font-size:18px;color:#64748b;display:flex;align-items:center;justify-content:center;flex-shrink:0;">×</button>
|
||||||
|
</div>
|
||||||
|
{{-- Mode badge row: hidden in Step 1, shown in Step 2 --}}
|
||||||
|
<div id="sup-mode-badge-row" style="display:none;align-items:center;gap:8px;margin-top:10px;">
|
||||||
|
<button type="button" onclick="goBack()"
|
||||||
|
style="display:flex;align-items:center;gap:4px;font-size:12px;color:#2563eb;background:none;border:none;cursor:pointer;padding:0;font-weight:600;">
|
||||||
|
<svg width="13" height="13" fill="none" stroke="currentColor" stroke-width="2.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M15 18l-6-6 6-6"/></svg>
|
||||||
|
Change method
|
||||||
|
</button>
|
||||||
|
<span style="color:#cbd5e1;">·</span>
|
||||||
|
<span id="sup-mode-badge" style="font-size:11px;padding:2px 9px;border-radius:10px;font-weight:700;"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 2: Verify the file saved correctly**
|
||||||
|
|
||||||
|
Open `resources/views/components/purchase/supplier-select-modal.blade.php` and confirm:
|
||||||
|
- No `stab-global` or `stab-item` buttons exist
|
||||||
|
- `sup-mode-badge-row` div is present with `display:none`
|
||||||
|
- Title reads "Request for Quotation"
|
||||||
|
- Subtitle element has `id="sup-modal-subtitle"`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Task 2: Add Step 1 method-selection cards and wrap Step 2
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Modify: `resources/views/components/purchase/supplier-select-modal.blade.php`
|
||||||
|
|
||||||
|
Insert `#sup-step1` (method cards + Step 1 Cancel footer) immediately after the header closing `</div>`. Then wrap the existing `<form>` and the existing footer `<div>` inside a new `#sup-step2` div. Step 1 is `display:flex` on load; Step 2 is `display:none`.
|
||||||
|
|
||||||
|
- [ ] **Step 1: Insert Step 1 cards immediately after the header**
|
||||||
|
|
||||||
|
Find this exact line (the comment that opens the form section):
|
||||||
|
|
||||||
|
```blade
|
||||||
|
{{-- Single form wrapping both panes --}}
|
||||||
|
<form id="sup-form" action="{{ route('purchase.requests.rfq.select', $pr) }}" method="POST"
|
||||||
|
style="flex:1;overflow:hidden;display:flex;flex-direction:column;min-height:0;">
|
||||||
|
```
|
||||||
|
|
||||||
|
Replace with:
|
||||||
|
|
||||||
|
```blade
|
||||||
|
{{-- Step 1: Method selection --}}
|
||||||
|
<div id="sup-step1" style="flex:1;display:flex;flex-direction:column;">
|
||||||
|
<div style="padding:24px;display:flex;flex-direction:column;gap:12px;flex:1;">
|
||||||
|
|
||||||
|
<button type="button" onclick="showStep('global')"
|
||||||
|
style="width:100%;text-align:left;border:2px solid #e2e8f0;border-radius:12px;padding:18px 20px;cursor:pointer;display:flex;align-items:center;gap:16px;background:#fff;transition:border-color .15s,background .15s;"
|
||||||
|
onmouseover="this.style.borderColor='#2563eb';this.style.background='#f8fbff'"
|
||||||
|
onmouseout="this.style.borderColor='#e2e8f0';this.style.background='#fff'">
|
||||||
|
<div style="width:44px;height:44px;background:#eff6ff;border-radius:10px;display:flex;align-items:center;justify-content:center;font-size:22px;flex-shrink:0;">📦</div>
|
||||||
|
<div style="flex:1;">
|
||||||
|
<div style="font-size:14px;font-weight:700;color:#0f172a;">Full Order</div>
|
||||||
|
<div style="font-size:12px;color:#64748b;margin-top:3px;">One set of suppliers handles the entire purchase request</div>
|
||||||
|
</div>
|
||||||
|
<svg width="16" height="16" fill="none" stroke="#cbd5e1" stroke-width="2.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M9 18l6-6-6-6"/></svg>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button type="button" onclick="showStep('item')"
|
||||||
|
style="width:100%;text-align:left;border:2px solid #e2e8f0;border-radius:12px;padding:18px 20px;cursor:pointer;display:flex;align-items:center;gap:16px;background:#fff;transition:border-color .15s,background .15s;"
|
||||||
|
onmouseover="this.style.borderColor='#2563eb';this.style.background='#f8fbff'"
|
||||||
|
onmouseout="this.style.borderColor='#e2e8f0';this.style.background='#fff'">
|
||||||
|
<div style="width:44px;height:44px;background:#f0fdf4;border-radius:10px;display:flex;align-items:center;justify-content:center;font-size:22px;flex-shrink:0;">🔀</div>
|
||||||
|
<div style="flex:1;">
|
||||||
|
<div style="font-size:14px;font-weight:700;color:#0f172a;">By Item</div>
|
||||||
|
<div style="font-size:12px;color:#64748b;margin-top:3px;">Assign different suppliers to specific items in this request</div>
|
||||||
|
</div>
|
||||||
|
<svg width="16" height="16" fill="none" stroke="#cbd5e1" stroke-width="2.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M9 18l6-6-6-6"/></svg>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div style="padding:14px 24px;border-top:1px solid #f1f5f9;display:flex;justify-content:flex-end;flex-shrink:0;background:#fafafa;">
|
||||||
|
<button type="button" onclick="closeSupplierModal()"
|
||||||
|
style="padding:8px 18px;border:1px solid #e2e8f0;border-radius:8px;font-size:13px;font-weight:600;color:#64748b;background:#fff;cursor:pointer;">
|
||||||
|
Cancel
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{-- Step 2: Supplier selection --}}
|
||||||
|
<div id="sup-step2" style="flex:1;display:none;flex-direction:column;min-height:0;">
|
||||||
|
|
||||||
|
{{-- Single form wrapping both panes --}}
|
||||||
|
<form id="sup-form" action="{{ route('purchase.requests.rfq.select', $pr) }}" method="POST"
|
||||||
|
style="flex:1;overflow:hidden;display:flex;flex-direction:column;min-height:0;">
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 2: Change `sup-mode` initial value and close Step 2 wrapper**
|
||||||
|
|
||||||
|
Find this exact line inside the form (just after `@csrf`):
|
||||||
|
|
||||||
|
```blade
|
||||||
|
<input type="hidden" name="mode" id="sup-mode" value="global">
|
||||||
|
```
|
||||||
|
|
||||||
|
Replace with:
|
||||||
|
|
||||||
|
```blade
|
||||||
|
<input type="hidden" name="mode" id="sup-mode" value="">
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 3: Close the Step 2 wrapper after the existing footer**
|
||||||
|
|
||||||
|
Find this exact block at the end of the modal shell (the original footer + closing divs):
|
||||||
|
|
||||||
|
```blade
|
||||||
|
{{-- Footer --}}
|
||||||
|
<div style="padding:14px 24px;border-top:1px solid #f1f5f9;display:flex;align-items:center;justify-content:space-between;flex-shrink:0;background:#fafafa;">
|
||||||
|
<div style="font-size:12px;color:#64748b;" id="sup-footer-msg">0 selected</div>
|
||||||
|
<div style="display:flex;gap:10px;">
|
||||||
|
<button type="button" onclick="closeSupplierModal()"
|
||||||
|
style="padding:8px 18px;border:1px solid #e2e8f0;border-radius:8px;font-size:13px;font-weight:600;color:#64748b;background:#fff;cursor:pointer;">
|
||||||
|
Cancel
|
||||||
|
</button>
|
||||||
|
<button type="button" onclick="submitSuppliers()"
|
||||||
|
style="padding:8px 22px;background:#2563eb;color:#fff;border:none;border-radius:8px;font-size:13px;font-weight:700;cursor:pointer;">
|
||||||
|
Save & Continue →
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
```
|
||||||
|
|
||||||
|
Replace with:
|
||||||
|
|
||||||
|
```blade
|
||||||
|
{{-- Footer --}}
|
||||||
|
<div style="padding:14px 24px;border-top:1px solid #f1f5f9;display:flex;align-items:center;justify-content:space-between;flex-shrink:0;background:#fafafa;">
|
||||||
|
<div style="font-size:12px;color:#64748b;" id="sup-footer-msg">0 selected</div>
|
||||||
|
<div style="display:flex;gap:10px;">
|
||||||
|
<button type="button" onclick="closeSupplierModal()"
|
||||||
|
style="padding:8px 18px;border:1px solid #e2e8f0;border-radius:8px;font-size:13px;font-weight:600;color:#64748b;background:#fff;cursor:pointer;">
|
||||||
|
Cancel
|
||||||
|
</button>
|
||||||
|
<button type="button" onclick="submitSuppliers()"
|
||||||
|
style="padding:8px 22px;background:#2563eb;color:#fff;border:none;border-radius:8px;font-size:13px;font-weight:700;cursor:pointer;">
|
||||||
|
Save & Continue →
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>{{-- /sup-step2 --}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 4: Verify structure**
|
||||||
|
|
||||||
|
Confirm the file now has this nesting order:
|
||||||
|
1. `#supplier-modal` → modal shell
|
||||||
|
2. Header (`#sup-mode-badge-row` inside)
|
||||||
|
3. `#sup-step1` with two card buttons + Cancel footer
|
||||||
|
4. `#sup-step2` containing `#sup-form` + the Step 2 footer
|
||||||
|
5. `#sup-step2` closing tag
|
||||||
|
6. Modal shell closing tags
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Task 3: Update JavaScript — add showStep/goBack, update openSupplierModal, remove switchSupTab
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Modify: `resources/views/components/purchase/supplier-select-modal.blade.php` (script block)
|
||||||
|
|
||||||
|
- [ ] **Step 1: Replace `openSupplierModal` and remove `switchSupTab`**
|
||||||
|
|
||||||
|
Find this exact block:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
function openSupplierModal() {
|
||||||
|
document.getElementById('supplier-modal').classList.add('open');
|
||||||
|
switchSupTab('global');
|
||||||
|
document.getElementById('sup-search').focus();
|
||||||
|
}
|
||||||
|
function closeSupplierModal() {
|
||||||
|
closeAllItemDd();
|
||||||
|
document.getElementById('supplier-modal').classList.remove('open');
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Replace with:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
function openSupplierModal() {
|
||||||
|
document.getElementById('supplier-modal').classList.add('open');
|
||||||
|
goBack();
|
||||||
|
}
|
||||||
|
function closeSupplierModal() {
|
||||||
|
closeAllItemDd();
|
||||||
|
document.getElementById('supplier-modal').classList.remove('open');
|
||||||
|
}
|
||||||
|
function showStep(method) {
|
||||||
|
_supTab = method;
|
||||||
|
document.getElementById('sup-mode').value = method === 'item' ? 'by_item' : 'global';
|
||||||
|
|
||||||
|
var badge = document.getElementById('sup-mode-badge');
|
||||||
|
if (method === 'global') {
|
||||||
|
badge.textContent = '📦 Full Order';
|
||||||
|
badge.style.background = '#eff6ff';
|
||||||
|
badge.style.color = '#2563eb';
|
||||||
|
} else {
|
||||||
|
badge.textContent = '🔀 By Item';
|
||||||
|
badge.style.background = '#f0fdf4';
|
||||||
|
badge.style.color = '#15803d';
|
||||||
|
}
|
||||||
|
|
||||||
|
document.getElementById('sup-modal-title').textContent = 'Select Suppliers';
|
||||||
|
document.getElementById('sup-modal-subtitle').textContent = 'Choose who receives the quote request';
|
||||||
|
document.getElementById('sup-mode-badge-row').style.display = 'flex';
|
||||||
|
document.getElementById('sup-step1').style.display = 'none';
|
||||||
|
document.getElementById('sup-step2').style.display = 'flex';
|
||||||
|
|
||||||
|
if (method === 'global') {
|
||||||
|
setTimeout(function(){ document.getElementById('sup-search').focus(); }, 50);
|
||||||
|
}
|
||||||
|
updateFooter();
|
||||||
|
}
|
||||||
|
function goBack() {
|
||||||
|
document.querySelectorAll('#sup-form input[type="checkbox"]:not([disabled])').forEach(function(cb) {
|
||||||
|
cb.checked = false;
|
||||||
|
});
|
||||||
|
document.querySelectorAll('[id^="gchan-"]').forEach(function(el) { el.style.display = 'none'; });
|
||||||
|
var searchEl = document.getElementById('sup-search');
|
||||||
|
if (searchEl) { searchEl.value = ''; filterGlobalSups(''); }
|
||||||
|
document.querySelectorAll('[id^="idd-label-"]').forEach(function(el) {
|
||||||
|
el.textContent = 'Select suppliers…';
|
||||||
|
el.style.color = '#94a3b8';
|
||||||
|
});
|
||||||
|
var ics = document.getElementById('item-chan-section');
|
||||||
|
if (ics) ics.style.display = 'none';
|
||||||
|
document.querySelectorAll('[id^="ic-"]').forEach(function(el) { el.style.display = 'none'; });
|
||||||
|
|
||||||
|
document.getElementById('sup-mode').value = '';
|
||||||
|
document.getElementById('sup-modal-title').textContent = 'Request for Quotation';
|
||||||
|
document.getElementById('sup-modal-subtitle').textContent = 'How do you want to assign suppliers?';
|
||||||
|
document.getElementById('sup-mode-badge-row').style.display = 'none';
|
||||||
|
document.getElementById('sup-step1').style.display = 'flex';
|
||||||
|
document.getElementById('sup-step2').style.display = 'none';
|
||||||
|
closeAllItemDd();
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 2: Delete the now-dead `switchSupTab` function**
|
||||||
|
|
||||||
|
Find and delete this entire block:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
function switchSupTab(tab) {
|
||||||
|
_supTab = tab;
|
||||||
|
document.getElementById('sup-mode').value = tab === 'item' ? 'by_item' : 'global';
|
||||||
|
|
||||||
|
document.getElementById('sup-global-pane').style.display = tab === 'global' ? 'flex' : 'none';
|
||||||
|
document.getElementById('sup-item-pane').style.display = tab === 'item' ? 'flex' : 'none';
|
||||||
|
|
||||||
|
var gBtn = document.getElementById('stab-global');
|
||||||
|
var iBtn = document.getElementById('stab-item');
|
||||||
|
if (tab === 'global') {
|
||||||
|
gBtn.style.color = '#2563eb'; gBtn.style.borderBottomColor = '#2563eb';
|
||||||
|
iBtn.style.color = '#94a3b8'; iBtn.style.borderBottomColor = 'transparent';
|
||||||
|
} else {
|
||||||
|
iBtn.style.color = '#2563eb'; iBtn.style.borderBottomColor = '#2563eb';
|
||||||
|
gBtn.style.color = '#94a3b8'; gBtn.style.borderBottomColor = 'transparent';
|
||||||
|
}
|
||||||
|
updateFooter();
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
(Replace with nothing — delete the block entirely.)
|
||||||
|
|
||||||
|
- [ ] **Step 3: Verify the script block**
|
||||||
|
|
||||||
|
Confirm:
|
||||||
|
- `openSupplierModal` calls `goBack()` only
|
||||||
|
- `showStep` and `goBack` are both defined
|
||||||
|
- `switchSupTab` does not appear anywhere in the file
|
||||||
|
- `stab-global` and `stab-item` do not appear anywhere in the file
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Task 4: Manual verification
|
||||||
|
|
||||||
|
**Prerequisites:** Laravel dev server running (`php artisan serve`) and Vite running (`npm run dev`).
|
||||||
|
|
||||||
|
- [ ] **Step 1: Open a purchase request that has the supplier modal**
|
||||||
|
|
||||||
|
Navigate to `http://localhost:8000/purchase/requests`, open any request that has an "Assign Suppliers" or "Send RFQ" button, and click it.
|
||||||
|
|
||||||
|
**Expected:** Modal opens showing Step 1 — two cards ("Full Order", "By Item") and a Cancel button. No tabs visible.
|
||||||
|
|
||||||
|
- [ ] **Step 2: Test Full Order flow**
|
||||||
|
|
||||||
|
Click the "Full Order" card.
|
||||||
|
|
||||||
|
**Expected:**
|
||||||
|
- Modal transitions to Step 2
|
||||||
|
- Header shows "← Change method · 📦 Full Order" badge row
|
||||||
|
- Title changes to "Select Suppliers", subtitle to "Choose who receives the quote request"
|
||||||
|
- Global supplier list is visible with search input
|
||||||
|
- Search input is auto-focused
|
||||||
|
|
||||||
|
Select one or more suppliers via checkboxes. Confirm channel toggles appear per supplier selected.
|
||||||
|
|
||||||
|
- [ ] **Step 3: Test back navigation clears state**
|
||||||
|
|
||||||
|
Click "← Change method".
|
||||||
|
|
||||||
|
**Expected:**
|
||||||
|
- Returns to Step 1 (method cards)
|
||||||
|
- Title resets to "Request for Quotation"
|
||||||
|
- Mode badge row hidden
|
||||||
|
|
||||||
|
Click "Full Order" again.
|
||||||
|
|
||||||
|
**Expected:** All checkboxes unchecked, search cleared — fresh state.
|
||||||
|
|
||||||
|
- [ ] **Step 4: Test By Item flow**
|
||||||
|
|
||||||
|
Click "By Item" card.
|
||||||
|
|
||||||
|
**Expected:**
|
||||||
|
- Step 2 shows the per-item dropdown UI
|
||||||
|
- Mode badge shows "🔀 By Item" in green
|
||||||
|
|
||||||
|
Assign a supplier to one item. Click "← Change method". Click "By Item" again.
|
||||||
|
|
||||||
|
**Expected:** Item dropdown labels reset to "Select suppliers…", channel section hidden.
|
||||||
|
|
||||||
|
- [ ] **Step 5: Test submission still works**
|
||||||
|
|
||||||
|
Go to Full Order, select one supplier, click "Save & Continue →".
|
||||||
|
|
||||||
|
**Expected:** Form submits to `purchase.requests.rfq.select` with `mode=global` and the selected `supplier_ids[]`. No JS errors in the browser console.
|
||||||
|
|
||||||
|
- [ ] **Step 6: Test Escape key and backdrop click**
|
||||||
|
|
||||||
|
Open modal, press Escape.
|
||||||
|
|
||||||
|
**Expected:** Modal closes regardless of which step is active.
|
||||||
|
|
||||||
|
Open modal, click outside the modal card.
|
||||||
|
|
||||||
|
**Expected:** Modal closes.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Task 5: Commit
|
||||||
|
|
||||||
|
- [ ] **Step 1: Stage the file**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git add resources/views/components/purchase/supplier-select-modal.blade.php
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 2: Commit**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git commit -m "feat: replace supplier modal tabs with two-step wizard"
|
||||||
|
```
|
||||||
Loading…
x
Reference in New Issue
Block a user