/*! MIRIX Sheet Cases — diagnostic build (2025-09-19) */ (function bootstrap(factory){ // 全面エラーハンドラ(ページに可視化) window.addEventListener('error', function(ev){ try { var $box = document.querySelector('.msc-list') || document.body; var msg = '[JS Global Error]\n' + 'message: ' + (ev.message||'') + '\n' + 'file: ' + (ev.filename||'') + '\n' + 'lineno: ' + (ev.lineno||'') + ', colno: ' + (ev.colno||'') + '\n' + 'stack: ' + (ev.error && ev.error.stack ? ev.error.stack : '(no stack)') + '\n' + 'MSC_RUNTIME? ' + (typeof window.MSC_RUNTIME) + '\n' + 'jQuery? ' + (typeof window.jQuery); var pre = document.createElement('pre'); pre.style.whiteSpace='pre-wrap'; pre.style.color='#c00'; pre.style.fontSize='.9rem'; pre.textContent = msg; $box && $box.appendChild(pre); } catch(_) {} }); // jQuery 安全ブート function start(){ try { factory(window.jQuery); } catch(e){ var $box = document.querySelector('.msc-list') || document.body; var pre = document.createElement('pre'); pre.style.whiteSpace='pre-wrap'; pre.style.color='#c00'; pre.style.fontSize='.9rem'; pre.textContent = '[MIRIX] 読み込み失敗(JS例外:factory)\n' + 'error: ' + e.message + '\nstack:\n' + (e.stack||'(no stack)') + '\n' + 'MSC_RUNTIME: ' + JSON.stringify(window.MSC_RUNTIME||{}) + '\n' + 'jQuery?: ' + (typeof window.jQuery); $box && $box.appendChild(pre); } } function tryInit(){ if (typeof window.jQuery !== 'undefined') { start(); return true; } return false; } if (document.readyState === 'complete' || document.readyState === 'interactive') { if (!tryInit()) { setTimeout(tryInit, 50); setTimeout(tryInit, 200); setTimeout(tryInit, 500); } } else { document.addEventListener('DOMContentLoaded', function(){ if (!tryInit()) { setTimeout(tryInit, 50); setTimeout(tryInit, 200); setTimeout(tryInit, 500); } }); } })(function($){ 'use strict'; /* ===== 診断ユーティリティ ===== */ function diag(msg, obj){ var box = document.querySelector('.msc-list') || document.body; var pre = document.createElement('pre'); pre.style.whiteSpace='pre-wrap'; pre.style.color='#555'; pre.style.fontSize='.85rem'; pre.textContent = '[MIRIX-DIAG] ' + msg + (obj ? '\n' + JSON.stringify(obj,null,2) : ''); box && box.appendChild(pre); } // 起動時情報 try { diag('bootstrap ok', { userAgent: navigator.userAgent, MSC_RUNTIME: window.MSC_RUNTIME || null, jQueryVersion: $.fn && $.fn.jquery }); } catch(_){} /* ===== 共通 ===== */ function val(x){ return (x==null)?'':String(x).trim(); } function isEmpty(x){ return val(x)===''; } function esc(s){ return String(s).replace(/&/g,'&').replace(//g,'>'); } function escAttr(s){ return esc(s).replace(/"/g,'"'); } // すべての jQuery POST に WP nonce を自動付与 var MIRIX_NONCE = (window.MSC_RUNTIME && window.MSC_RUNTIME.nonce) ? window.MSC_RUNTIME.nonce : ''; $.ajaxPrefilter(function(options, original){ try{ if ((options.type||'').toUpperCase() === 'POST') { if (typeof original.data === 'string') { original.data += (original.data ? '&' : '') + '_ajax_nonce=' + encodeURIComponent(MIRIX_NONCE); options.data = original.data; } else { options.data = Object.assign({_ajax_nonce: MIRIX_NONCE}, original.data || {}); } } }catch(e){ diag('ajaxPrefilter error', {e:e.message}); } }); /* ===== URL/ファイル判定 ===== */ function isCf7Proxy(u){ var s=val(u); return /^https?:\/\/mirix\.co\.jp\/cf7-file\?/i.test(s); } function isPdf(u){ var s = val(u); if(!s) return false; try{ var url = new URL(s); var path = decodeURIComponent((url.pathname||'').toLowerCase()); return path.endsWith('.pdf'); }catch(_){ return /\.pdf(\?.*)?$/i.test(s); } } function isImg(u){ var s = val(u); if(!s) return false; if (isPdf(s)) return false; return /\.(png|jpe?g|gif|webp|svg)(\?.*)?$/i.test(s); } /* ===== 表示補助 ===== */ function toJPDateOnly(raw){ var s = val(raw); if (isEmpty(s)) return ''; var d; if (/^\d{4}-\d{2}-\d{2}T/.test(s) || /^\d{4}\/\d{2}\/\d{2}/.test(s)) { d = new Date(s.replace(' ', 'T')); if (isNaN(d)) d = new Date(s); } else if (/^\d{4}[\/-]\d{1,2}[\/-]\d{1,2}$/.test(s)) { d = new Date(s); } else { var m = s.match(/(\d{4})[\/\-](\d{1,2})[\/\-](\d{1,2})/); if (!m) return esc(s); d = new Date(m[1], Number(m[2])-1, Number(m[3])); } if (isNaN(d)) return esc(s); var y=d.getFullYear(), mm=('0'+(d.getMonth()+1)).slice(-2), dd=('0'+d.getDate()).slice(-2); return y+'年'+mm+'月'+dd+'日'; } function row(label, html){ if(isEmpty(html)) return ''; return '
'+esc(label)+''+html+'
'; } function mediaField(url){ var u = val(url); if(isEmpty(u)) return ''; if (isCf7Proxy(u)) return '
'; if (isPdf(u)) return 'PDFを見る'; if (isImg(u)) { return 'image' + '
拡大画像を見る
'; } return ''+esc(u)+''; } function mediaFieldPdfOnlyLink(url){ var u = val(url); if (isEmpty(u)) return ''; if (isCf7Proxy(u)) return '
'; if (isPdf(u)) return 'PDFを見る'; return mediaField(u); } function processCf7Auto(){ $('.msc-cf7-auto').each(function(){ var $h=$(this); if ($h.data('done')) return; $h.data('done',1); var url=$h.attr('data-url')||''; var pdfOnly = $h.hasClass('pdf-only'); var decided=false, timer=null; function toPdf(){ if(decided) return; decided=true; $h.replaceWith('PDFを見る'); } function toImg(){ if(decided) return; decided=true; if (pdfOnly) { toPdf(); return; } $h.replaceWith( 'image' + '
拡大画像を見る
' ); } var img=new Image(); img.onload = function(){ clearTimeout(timer); toImg(); }; img.onerror= function(){ clearTimeout(timer); toPdf(); }; timer = setTimeout(function(){ toPdf(); }, 15000); img.src = url; }); } function telLink(t){ t=val(t); return isEmpty(t)?'':''+esc(t)+''; } function mailLink(m){ m=val(m); return isEmpty(m)?'':''+esc(m)+''; } function anchor(u){ u=val(u); return isEmpty(u)?'':''+esc(u)+''; } function applyStatusStyle($sel){ var v = ($sel.val()||'').trim(); $sel.removeClass('st-default st-working st-contract st-done st-black'); if (v==='対応中') $sel.addClass('st-working'); else if (v==='契約') $sel.addClass('st-contract'); else if (v==='完了') $sel.addClass('st-done'); else if (v==='ボツ') $sel.addClass('st-black'); else $sel.addClass('st-default'); } function displayStatusLabel(v){ return (v==='未対応') ? '契約状態を選択' : v; } var PROGRESS_ORDER = ['返信済','返答あり','現調確認','現調済み','見積提出','追い電','着工','納品']; function statusSelect(row, statuses, canUpdate){ var cur = val(row['状態']), dis = canUpdate ? '' : ' disabled'; var html = ''; return html; } function progressSelect(row){ var current = ''; for (var i=0;i'; html += ''; for (var j=0;j'+esc(x)+''; } html += ''; return html; } function assigneeSelect(row){ var choices = ['みさと','たくま','けんゆう','しんご','キム姉']; var cur = val(row['担当']); var html = ''; return html; } function rowPlain(html){ if(isEmpty(html)) return ''; return '
'+html+'
'; } /* ===== カード生成 ===== */ function cardHtml(r, statuses, canUpdate){ var top = '' + '
' + '
'+ statusSelect(r,statuses,canUpdate) +'
' + '
'+ assigneeSelect(r) +'
' + '
' + '
'+ progressSelect(r) +'
'; var client = '' + row('受付日時', esc(toJPDateOnly(r['受付日時']))) + row('会社名', esc(val(r['会社名']))) + row('お名前', esc(val(r['お名前']))) + row('物件住所', esc(val(r['物件住所']))) + row('電話番号', telLink(r['電話'])) + row('メルアド', mailLink(r['メール'])) ; var info = '' + row('セクション', esc(val(r['セクション']))) + row('物件種別', esc(val(r['物件種別']))) + row('EV', esc(val(r['エレベーター'] || r['EV']))) + row('希望工期', esc(toJPDateOnly(r['希望工期']))) + row('依頼内容', esc(val(r['問い合わせ内容']))) ; var detail = '' + row('図面', esc(val(r['図面(有無)']))) + row('スケルトン図', mediaFieldPdfOnlyLink(r['スケルトン図面(URL)'])) + row('造作後図', mediaFieldPdfOnlyLink(r['造作後図面(URL)'])) + row('仕様・規約書', esc(val(r['仕様書・規約書']))) + row('仕様規約書', anchor(r['仕様書・規約書ファイル'])) + row('デザイン', esc(val(r['デザイン(相談/決定)']))) + row('デザイン案', esc(val(r['デザイン案/パース(有無)']))) + row('ファイル1', mediaField(r['デザインファイル1(URL)'])) + row('ファイル2', mediaField(r['デザインファイル2(URL)'])) + row('ファイル3', mediaField(r['デザインファイル3(URL)'])) + row('ストレージ', anchor(r['ストレージリンク'])) + row('作業種別', esc(val(r['作業種別']))) + row('欲しい型番', esc(val(r['欲しい型番']))) + row('現在の写真', esc(val(r['現在の写真(有無)']))) + row('写真1', mediaField(r['写真1(URL)'])) + row('写真2', mediaField(r['写真2(URL)'])) + row('写真3', mediaField(r['写真3(URL)'])) ; var g1 = esc(val(r['業者情報1'])), g2 = esc(val(r['業者情報2'])), g3 = esc(val(r['業者情報3'])); var sub = ''; if(g1 || g2 || g3){ sub = '

下請け情報

' + row('業者情報1', g1) + row('業者情報2', g2) + row('業者情報3', g3) + '
'; } var hasDetail = (function(){ var keys = [ '図面(有無)','スケルトン図面(URL)','造作後図面(URL)','仕様書・規約書','仕様書・規約書ファイル', 'デザイン(相談/決定)','デザイン案/パース(有無)','デザインファイル1(URL)','デザインファイル2(URL)','デザインファイル3(URL)', 'ストレージリンク','作業種別','欲しい型番','現在の写真(有無)','写真1(URL)','写真2(URL)','写真3(URL)', '業者情報1','業者情報2','業者情報3' ]; for (var i=0;i' + '') : ''; var body = '' + '

依頼主情報

'+client+'
' + '

案件情報

'+info+'
' + acc; return '
'+ top + body +'
'; } /* ===== 読み込み ===== */ function loadData(){ var $wrap = $('.msc-wrap'); if(!$wrap.length){ diag('no .msc-wrap'); return; } var $list = $wrap.find('.msc-list'); if(!window.MSC_RUNTIME){ $list.html('

読み込み失敗:MSC_RUNTIMEが未定義(PHPの wp_localize_script が走っていない可能性)

'); return; } if(!MSC_RUNTIME.ajax_url){ $list.html('

読み込み失敗:ajax_url 未設定

'); return; } $list.html('

読み込み中...

'); var defSort = MSC_RUNTIME.default_sort || '受付新しい順'; var statuses = (MSC_RUNTIME.statuses || []); var canUpdate= !!MSC_RUNTIME.update_allowed; $.ajax({ url: MSC_RUNTIME.ajax_url, method: 'POST', dataType: 'json', data: { action:'mirix_fetch_list', _ts: Date.now(), _ajax_nonce: (MSC_RUNTIME.nonce||'') } }) .done(function(res){ diag('ajax list done', {http:200, ok:res && res.ok, count: res && res.data ? res.data.length : 0}); if(!res || !res.ok){ $list.html('

読み込み失敗(list ng)

'); return; } var arr = res.data || []; arr.sort(function(a,b){ var A = val(a['受付日時']), B = val(b['受付日時']); if(defSort==='受付古い順') return (A>B?1:(AB?-1:0)); }); var html = ''; for (var i=0;iデータがありません

'); $('.msc-status-sel').each(function(){ applyStatusStyle($(this)); }); processCf7Auto(); }) .fail(function(jqXHR, textStatus, errorThrown){ var ct = jqXHR.getResponseHeader && jqXHR.getResponseHeader('content-type') || ''; var body = (jqXHR.responseText||'').slice(0,600); var msg = '読み込みエラー / HTTP '+jqXHR.status+' / '+textStatus+' / '+errorThrown+'\ncontent-type: '+ct+'\n---\n'+body; $list.html('
'+esc(msg)+'
'); diag('ajax list fail', {status: jqXHR.status, textStatus:textStatus, error:errorThrown, ct:ct}); }); } /* ===== イベント ===== */ $(document).on('click','.msc-acc-btn',function(){ var p = $(this).closest('.msc-accordion').find('.msc-acc-panel'); p.slideToggle(160); var opened = $(this).toggleClass('open').hasClass('open'); $(this).text(opened ? '情報詳細を閉じる' : '情報詳細を表示'); }); $(document).on('change','.msc-status-sel',function(){ var sel = $(this); applyStatusStyle(sel); var rowNo = sel.data('row'), status = sel.val(); sel.prop('disabled', true); $.post(MSC_RUNTIME.ajax_url, { action:'mirix_update_status', rowNo:rowNo, status:status }) .always(function(){ sel.prop('disabled', false); }); }); $(document).on('change','.msc-progress-sel',function(){ var sel = $(this), rowNo = sel.data('row'), stage = sel.val(); sel.prop('disabled', true); $.post(MSC_RUNTIME.ajax_url, { action:'mirix_update_progress', rowNo:rowNo, stage:stage }) .always(function(){ sel.prop('disabled', false); }); }); $(document).on('change','.msc-assignee-sel',function(){ var sel = $(this), rowNo = sel.data('row'), assignee = sel.val(); sel.prop('disabled', true); $.post(MSC_RUNTIME.ajax_url, { action:'mirix_update_assignee', rowNo:rowNo, assignee:assignee }) .always(function(){ sel.prop('disabled', false); }); }); /* ===== 起動 ===== */ try { loadData(); } catch(e){ var $list = document.querySelector('.msc-list'); if ($list) { $list.innerHTML = '
読み込み失敗(JS例外:loadData)\n'+(e.stack||e.message)+'
'; } diag('loadData exception', {error:e.message, stack:e.stack}); } });