/*! MIRIX Sheet Cases — production build */ (function($){ 'use strict'; /* ===== 0) 共通ユーティリティ ===== */ 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 を自動付与(bad nonce対策) var MIRIX_NONCE = (window.MSC_RUNTIME && MSC_RUNTIME.nonce) ? MSC_RUNTIME.nonce : ''; $.ajaxPrefilter(function(options, originalOptions){ if ((options.type||'').toUpperCase() === 'POST') { if (typeof originalOptions.data === 'string') { originalOptions.data += (originalOptions.data ? '&' : '') + '_ajax_nonce=' + encodeURIComponent(MIRIX_NONCE); options.data = originalOptions.data; } else { options.data = Object.assign({_ajax_nonce: MIRIX_NONCE}, originalOptions.data || {}); } } }); /* ===== 1) 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); } /* ===== 2) 表示補助 ===== */ 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 rowPlain(html){ if(isEmpty(html)) return ''; return '
'+html+'
'; } // 共通メディア表示(画像 or PDF or 直リンク) 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)+''; } // スケルトン図/造作後図:PDFはリンクのみ(画像を出さない) function mediaFieldPdfOnlyLink(url){ var u = val(url); if (isEmpty(u)) return ''; if (isCf7Proxy(u)) return '
'; if (isPdf(u)) return 'PDFを見る'; return mediaField(u); } // cf7-file の実体を画像/PDFで自動分岐(imgロード試行) 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'); // スケルトン/造作後図はPDFのみ表示 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; } // pdf-only指定時は画像を出さずPDFリンク $h.replaceWith( 'image' + '
拡大画像を見る
' ); } // まず画像として試す。成功→画像 / 失敗→PDF 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)+''; } /* ===== 3) セレクト(状態/対応/担当) ===== */ 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; } function statusSelect(row, statuses, canUpdate){ var cur = val(row['状態']), dis = canUpdate ? '' : ' disabled'; var html = ''; return html; } var PROGRESS_ORDER = ['返信済','返答あり','現調確認','現調済み','見積提出','追い電','着工','納品']; function progressSelect(row){ var current = ''; for (var i=0;i'; html += ''; // valueは空(シートには未選択のまま) for (var j=0;j'+esc(x)+''; } html += ''; return html; } function assigneeSelect(row){ var choices = ['みさと','たくま','けんゆう','しんご','キム姉']; var cur = val(row['担当']); var html = ''; return html; } /* ===== 4) 1カード生成 ===== */ function cardHtml(r, statuses, canUpdate){ // 上部:状態(左 50%)・担当(右 50%) var top = '' + '
' + '
'+ statusSelect(r,statuses,canUpdate) +'
' + '
'+ assigneeSelect(r) +'
' + '
'; // 「対応」(見出し無しセレクトのみ) var progress = '
'+ 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['メール'])) ; // 案件情報(物件種別とEVは別行) 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['問い合わせ内容']))) ; // 情報詳細(PDFルール・cf7-proxy対応) 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(!isEmpty(g1) || !isEmpty(g2) || !isEmpty(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 head = '
'+ top + progress +'
'; // 本文:依頼主情報・案件情報 var body = '' + '

依頼主情報

'+client+'
' + '

案件情報

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

読み込み失敗(設定未完了)

'); 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() } }) .done(function(res){ if(!res || !res.ok){ $list.html('

読み込み失敗

'); 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データがありません

'); // 状態の色付け・cf7ファイル自動判定 $('.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)+'
'); }); } /* ===== 6) イベント ===== */ $(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); }); }); /* ===== 7) 起動 ===== */ try { loadData(); } catch(e){ console.error('[MIRIX] loadData error', e); $('.msc-list').html('

読み込み失敗(JS例外)

'); } })(jQuery);