Subversion Repositories SmartDukaan

Rev

Rev 37248 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 37248 Rev 37277
Line 964... Line 964...
964
       '<td>'+flagStatusChip(r.status)+(hits>0?' <span class="chev">&#9656;</span>':'')+'</td>'+
964
       '<td>'+flagStatusChip(r.status)+(hits>0?' <span class="chev">&#9656;</span>':'')+'</td>'+
965
       '</tr>';
965
       '</tr>';
966
  });
966
  });
967
  return h+'</tbody></table></div>';
967
  return h+'</tbody></table></div>';
968
}
968
}
-
 
969
// Minutes-of-day from the first HH:MM in a flag detail string (-1 if none) — for sorting.
-
 
970
function flagTimeVal(detail){
-
 
971
  var m=String(detail||'').match(/(\d{1,2}):(\d{2})/);
-
 
972
  return m ? (parseInt(m[1],10)*60+parseInt(m[2],10)) : -1;
-
 
973
}
969
function openFlag(code){
974
function openFlag(code){
970
  var list=window._visitFlags||[], r=null;
975
  var list=window._visitFlags||[], r=null;
971
  for(var i=0;i<list.length;i++){ if(list[i].code===code){ r=list[i]; break; } }
976
  for(var i=0;i<list.length;i++){ if(list[i].code===code){ r=list[i]; break; } }
972
  if(!r) return;
977
  if(!r) return;
973
  var items=r.items||[], date=window._boardDate||'';
978
  var items=r.items||[], date=window._boardDate||'';
-
 
979
  // Time-based rules (first check-in / last checkout) read best with the latest time on top.
-
 
980
  if(code==='r7a' || code==='r7b'){
-
 
981
    items=items.slice().sort(function(a,b){ return flagTimeVal(b.detail)-flagTimeVal(a.detail); });
-
 
982
  }
974
  var h='<button class="x" onclick="closeModal()">&times;</button><h3>'+esc(r.num)+' &middot; '+esc(r.title)+'</h3>'+
983
  var h='<button class="x" onclick="closeModal()">&times;</button><h3>'+esc(r.num)+' &middot; '+esc(r.title)+'</h3>'+
975
        '<p class="desc">'+items.length+' flagged '+(items.length===1?'visit':'visits')+
984
        '<p class="desc">'+items.length+' flagged '+(items.length===1?'visit':'visits')+
976
        (r.denom?' of '+num(r.denom)+' &middot; '+pct(r.count,r.denom)+'%':'')+' &middot; '+flagStatusChip(r.status)+'</p>';
985
        (r.denom?' of '+num(r.denom)+' &middot; '+pct(r.count,r.denom)+'%':'')+' &middot; '+flagStatusChip(r.status)+'</p>';
977
  if(!items.length){ h+='<p class="desc">Nothing flagged today.</p>'; }
986
  if(!items.length){ h+='<p class="desc">Nothing flagged today.</p>'; }
978
  else{
987
  else{
Line 986... Line 995...
986
    h+='</tbody></table>';
995
    h+='</tbody></table>';
987
  }
996
  }
988
  el('bj-modal').innerHTML=h; el('bj-modal-back').classList.add('show');
997
  el('bj-modal').innerHTML=h; el('bj-modal-back').classList.add('show');
989
}
998
}
990
// Small red flag badge for the board's executive cell (count of rules tripped today).
999
// Small red flag badge for the board's executive cell (count of rules tripped today).
-
 
1000
// Clickable: opens a per-executive breakdown of which rules they tripped.
991
function flagBadge(r){
1001
function flagBadge(r){
992
  var f=r.flags||[]; if(!f.length) return '';
1002
  var f=r.flags||[]; if(!f.length) return '';
-
 
1003
  return ' <span onclick="event.stopPropagation();openExecFlags('+r.userId+',\''+js(r.name)+'\')"'
-
 
1004
    +' title="'+f.length+' visit-quality flag'+(f.length>1?'s':'')+' — click for detail"'
993
  return ' <span title="'+f.length+' visit-quality flag'+(f.length>1?'s':'')+'" style="display:inline-block;font-size:10px;font-weight:700;color:#e03131;background:#fff0f0;border:1px solid #ffc9c9;border-radius:999px;padding:0 6px;vertical-align:middle">&#9873; '+f.length+'</span>';
1005
    +' style="cursor:pointer;display:inline-block;font-size:10px;font-weight:700;color:#e03131;background:#fff0f0;border:1px solid #ffc9c9;border-radius:999px;padding:0 6px;vertical-align:middle">&#9873; '+f.length+'</span>';
-
 
1006
}
-
 
1007
// Per-executive flag drill-down: which visit-quality rules this exec tripped today, with the detail.
-
 
1008
function openExecFlags(userId, name){
-
 
1009
  var row=(window._board||[]).find(function(x){ return x.userId===userId; });
-
 
1010
  var codes=(row&&row.flags)||[];
-
 
1011
  var byCode={}; (window._visitFlags||[]).forEach(function(f){ byCode[f.code]=f; });
-
 
1012
  var date=window._boardDate||'';
-
 
1013
  var h='<button class="x" onclick="closeModal()">&times;</button><h3>'+esc(name)+'</h3>'+
-
 
1014
        '<p class="desc">'+codes.length+' visit-quality flag'+(codes.length===1?'':'s')+' today</p>';
-
 
1015
  if(!codes.length){ h+='<p class="desc">No flags.</p>'; }
-
 
1016
  else{
-
 
1017
    h+='<table><tbody>';
-
 
1018
    codes.forEach(function(code){
-
 
1019
      var f=byCode[code]; if(!f) return;
-
 
1020
      var items=f.items||[];
-
 
1021
      var item=items.filter(function(it){ return it.userId===userId; })[0] || items.filter(function(it){ return it.name===name; })[0];
-
 
1022
      h+='<tr><td style="font-weight:600;white-space:nowrap">'+esc(f.num)+' &middot; '+esc(f.title)+'</td>'+
-
 
1023
         '<td style="color:#69748c">'+esc(item?item.detail:'')+'</td></tr>';
-
 
1024
    });
-
 
1025
    h+='</tbody></table>';
-
 
1026
  }
-
 
1027
  if(userId>0){
-
 
1028
    h+='<p class="desc" style="margin-top:10px"><a href="#" onclick="closeModal();openExec('+userId+',\''+js(name)+'\',\''+date+'\');return false;">Open journey detail &rarr;</a></p>';
-
 
1029
  }
-
 
1030
  el('bj-modal').innerHTML=h; el('bj-modal-back').classList.add('show');
994
}
1031
}
995
function attentionList(a){
1032
function attentionList(a){
996
  window._att = a;
1033
  window._att = a;
997
  var order=['notPunchedIn','idleStale','geofence','locationOff','deferredAwaiting'];
1034
  var order=['notPunchedIn','idleStale','geofence','locationOff','deferredAwaiting'];
998
  var h='<div class="attrow">';
1035
  var h='<div class="attrow">';