|
- /* kanban-modal.js — card create/edit modal */
- (function () {
- 'use strict';
-
- var modal = document.getElementById('cardModal');
- var bsModal = new bootstrap.Modal(modal);
- var titleEl = document.getElementById('cardModalLabel');
- var cardIdEl = document.getElementById('card-id');
- var colIdEl = document.getElementById('card-column-id');
- var laneIdEl = document.getElementById('card-lane-id');
- var jobNumEl = document.getElementById('card-job-number');
- var jobNameEl = document.getElementById('card-job-name');
- var errEl = document.getElementById('card-modal-error');
- var btnSave = document.getElementById('btn-save-card');
- var btnDelete = document.getElementById('btn-delete-card');
-
- var custNameEl = document.getElementById('card-customer-name');
- var delivDateEl = document.getElementById('card-delivery-date');
- var qtyEl = document.getElementById('card-quantity');
- var notesEl = document.getElementById('card-notes');
- var fullNoteEl = document.getElementById('card-full-note');
-
- var boardId = KANBAN.boardId;
-
- /* ── Helpers ─────────────────────────────────────────────── */
- function post(url, data, cb) {
- var params = new URLSearchParams();
- Object.keys(data).forEach(function (k) { params.append(k, data[k]); });
- fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: params.toString() })
- .then(function (r) { return r.json(); })
- .then(cb)
- .catch(function (e) { showError('Network error: ' + e); });
- }
-
- function showError(msg) {
- errEl.textContent = msg;
- errEl.classList.remove('d-none');
- }
-
- function clearError() {
- errEl.textContent = '';
- errEl.classList.add('d-none');
- }
-
- /* ── Open for create ──────────────────────────────────────── */
- function openCreate(bId, colId, laneId) {
- titleEl.textContent = 'Add Card';
- cardIdEl.value = '';
- colIdEl.value = colId || '';
- laneIdEl.value = laneId || '';
- jobNumEl.value = '';
- jobNameEl.value = '';
- custNameEl.value = '';
- delivDateEl.value = '';
- qtyEl.value = '';
- notesEl.value = '';
- fullNoteEl.value = '';
- btnDelete.classList.add('d-none');
- clearError();
- bsModal.show();
- jobNumEl.focus();
- }
-
- /* ── Open for edit ───────────────────────────────────────── */
- function openEdit(id, colId, laneId, jobNum, jobName, custName, delivDate, qty, notes, fullNote) {
- titleEl.textContent = 'Edit Card';
- cardIdEl.value = id;
- colIdEl.value = colId;
- laneIdEl.value = laneId;
- jobNumEl.value = jobNum || '';
- jobNameEl.value = jobName || '';
- custNameEl.value = custName || '';
- delivDateEl.value = delivDate || '';
- qtyEl.value = qty || '';
- notesEl.value = notes || '';
- fullNoteEl.value = fullNote || '';
- btnDelete.classList.remove('d-none');
- clearError();
- bsModal.show();
- jobNumEl.focus();
- }
-
- /* ── Save ─────────────────────────────────────────────────── */
- btnSave.addEventListener('click', function () {
- clearError();
- var id = cardIdEl.value;
- var colId = colIdEl.value;
- var laneId = laneIdEl.value;
- var jNum = jobNumEl.value.trim();
- var jName = jobNameEl.value.trim();
- var cust = custNameEl.value.trim();
- var dDate = delivDateEl.value;
- var qty = qtyEl.value.trim();
- var notes = notesEl.value.trim();
- var fullNote = fullNoteEl.value;
-
- if (!jNum && !jName) {
- showError('Enter at least a job number or job name.');
- return;
- }
-
- if (id) {
- // Update existing
- post('/cards/' + id, { job_number: jNum, job_name: jName, customer_name: cust, delivery_date: dDate, quantity: qty, notes: notes, full_note: fullNote }, function (res) {
- if (res.ok) {
- bsModal.hide();
- window.KanbanBoard.onCardUpdated(id, res);
- } else {
- showError(res.error || 'Save failed.');
- }
- });
- } else {
- // Create new — if no col/lane selected show column/lane picker
- if (!colId || !laneId) {
- showError('Please choose a column and swim lane first.');
- return;
- }
- post('/cards', {
- board_id: boardId,
- column_id: colId,
- swim_lane_id: laneId,
- job_number: jNum,
- job_name: jName,
- customer_name: cust,
- delivery_date: dDate,
- quantity: qty,
- notes: notes,
- full_note: fullNote
- }, function (res) {
- if (res.ok) {
- bsModal.hide();
- window.KanbanBoard.onCardCreated(res);
- } else {
- showError(res.error || 'Save failed.');
- }
- });
- }
- });
-
- /* ── Delete ──────────────────────────────────────────────── */
- btnDelete.addEventListener('click', function () {
- if (!confirm('Delete this card?')) return;
- var id = cardIdEl.value;
- post('/cards/' + id + '/delete', {}, function (res) {
- if (res.ok) {
- bsModal.hide();
- window.KanbanBoard.onCardDeleted(id);
- } else {
- showError(res.error || 'Delete failed.');
- }
- });
- });
-
- /* ── Column/Lane picker when Add Card clicked with no cell ── */
- // Populated lazily from board data
- modal.addEventListener('shown.bs.modal', function () {
- if (!cardIdEl.value && (!colIdEl.value || !laneIdEl.value)) {
- injectPicker();
- }
- });
-
- function injectPicker() {
- if (document.getElementById('card-picker')) return;
-
- var picker = document.createElement('div');
- picker.id = 'card-picker';
- picker.className = 'row g-2 mb-3';
-
- var colSel = '<select class="form-select form-select-sm" id="pick-col"><option value="">-- Column --</option>';
- var laneSel = '<select class="form-select form-select-sm" id="pick-lane"><option value="">-- Swim Lane --</option>';
-
- document.querySelectorAll('.kanban-col-header').forEach(function (el) {
- colSel += '<option value="' + el.dataset.colId + '">' + el.querySelector('.col-label').textContent + '</option>';
- });
- document.querySelectorAll('.kanban-lane-header').forEach(function (el) {
- laneSel += '<option value="' + el.dataset.laneId + '">' + el.querySelector('.lane-label').textContent + '</option>';
- });
-
- colSel += '</select>';
- laneSel += '</select>';
-
- picker.innerHTML =
- '<div class="col"><label class="form-label small">Column</label>' + colSel + '</div>' +
- '<div class="col"><label class="form-label small">Swim Lane</label>' + laneSel + '</div>';
-
- var first = document.getElementById('card-job-number').closest('.mb-3');
- modal.querySelector('.modal-body').insertBefore(picker, first);
-
- document.getElementById('pick-col').addEventListener('change', function () {
- colIdEl.value = this.value;
- });
- document.getElementById('pick-lane').addEventListener('change', function () {
- laneIdEl.value = this.value;
- });
- }
-
- /* ── Public API ──────────────────────────────────────────── */
- window.KanbanModal = { openCreate: openCreate, openEdit: openEdit };
-
- })();
|