Просмотр исходного кода

new job listing support up to 2000 with fast loading

master
patrick 6 лет назад
Родитель
Сommit
6eeb0583f5
5 измененных файлов: 126 добавлений и 99 удалений
  1. +1
    -1
      Apiv1.php
  2. +15
    -10
      css/bts_office.css
  3. +13
    -14
      html/jobv1.html
  4. +96
    -73
      js/bts_office.js
  5. +1
    -1
      ts.php

+ 1
- 1
Apiv1.php Просмотреть файл

); );
$sql = "SELECT * FROM $this->job_table WHERE start>='%s' and start <='%s' order by start ASC ,staff ASC"; $sql = "SELECT * FROM $this->job_table WHERE start>='%s' and start <='%s' order by start ASC ,staff ASC";
//$sql = "SELECT * FROM $this->job_table order by start ASC ,staff ASC";
$sql = "SELECT * FROM $this->job_table order by start ASC ,staff ASC";
$query = $wpdb->prepare ($sql, array($start, $finish)); $query = $wpdb->prepare ($sql, array($start, $finish));
$response['sql'] = $query; $response['sql'] = $query;
$jobs = $wpdb->get_results($query); $jobs = $wpdb->get_results($query);

+ 15
- 10
css/bts_office.css Просмотреть файл



.divTable.blueTable .divTableBody .divTableCell { .divTable.blueTable .divTableBody .divTableCell {
font-size: 15px; font-size: 15px;
border-bottom: 1px lightgrey solid;
border-right: 1px lightgrey dotted;
vertical-align: middle;
} }


.divTable.blueTable .divTableRow:nth-child(even) { .divTable.blueTable .divTableRow:nth-child(even) {
} }


.divTable.highlight { .divTable.highlight {
box-shadow: 1px 1px 10px green;
box-shadow: 0px 0px 10px green;
}
.divTable.highlight div {
background-color: lightyellow;
} }


.divTable.invalidjob.highlight { .divTable.invalidjob.highlight {
} }


div.bsave span.ticon-copy { div.bsave span.ticon-copy {
display: none;
display: none;
}
div.bsave.saved span.ticon-copy {
display: inline-block;
border: 3px solid orange;
padding: 5px;
border-radius: 20px;
color: orange;
} }


div.bsave span.ticon-save { div.bsave span.ticon-save {
display: none; display: none;
} }


div.bsave.saved span.ticon-copy {
display: inline-block;
border: 3px solid orange;
padding: 5px;
border-radius: 20px;
color: orange;
}

div.bdelete span.ticon-trash { div.bdelete span.ticon-trash {
display: inline-block; display: inline-block;
border: 3px solid lightgrey; border: 3px solid lightgrey;

+ 13
- 14
html/jobv1.html Просмотреть файл

{{#jobs}} {{#jobs}}
<div class="divTable blueTable " id="job_{{id}}"
<div class="divTable jobTable blueTable " id="job_{{id}}"
data-id="{{id}}" data-tos="{{tos}}" data-rate="{{rate}}" data-staff="{{staff}}" data-client="{{client}}"> data-id="{{id}}" data-tos="{{tos}}" data-rate="{{rate}}" data-staff="{{staff}}" data-client="{{client}}">
<div class="divTableBody"> <div class="divTableBody">
<div class="divTableRow"> <div class="divTableRow">
<div class="divTableCell btos"> <div class="divTableCell btos">
{{tos_name}}
{{tos_name}}
</div> </div>
<div class="divTableCell bstart">{{start}}</div> <div class="divTableCell bstart">{{start}}</div>
<div class="divTableCell bfinish">{{finish}}</div> <div class="divTableCell bfinish">{{finish}}</div>
<div class="divTableCell bdelete"> <div class="divTableCell bdelete">
<span class="ticon ticon-trash"></span> <span class="ticon ticon-trash"></span>
</div> </div>
<div class="divTableCell bsave ">
<div class="divTableCell bsave {{#saved}} saved {{/saved}}">
<span class="ticon ticon-save"></span> <span class="ticon ticon-save"></span>
<span class="ticon ticon-copy"></span> <span class="ticon ticon-copy"></span>
</div> </div>
</div> </div>
<div class="divTableRow errmsg"> <div class="divTableRow errmsg">
<div class="divTableCell btos_err"> e tos
</div>
<div class="divTableCell bstart_err">es</div>
<div class="divTableCell bfinish_err">ef</div>
<div class="divTableCell brate_err">er</div>
<div class="divTableCell bstaff_err">estaf</div>
<div class="divTableCell bclient_err">ecli</div>
<div class="divTableCell bconfirmed_err">econfirm</div>
<div class="divTableCell brating_err">e rat</div>
<div class="divTableCell bdelete_err">edel</div>
<div class="divTableCell bsave_err">eeave</div>
<div class="divTableCell btos_err"></div>
<div class="divTableCell bstart_err"></div>
<div class="divTableCell bfinish_err"></div>
<div class="divTableCell brate_err"></div>
<div class="divTableCell bstaff_err"></div>
<div class="divTableCell bclient_err"></div>
<div class="divTableCell bconfirmed_err"></div>
<div class="divTableCell brating_err"></div>
<div class="divTableCell bdelete_err"></div>
<div class="divTableCell bsave_err"></div>
</div> </div>
</div> </div>

+ 96
- 73
js/bts_office.js Просмотреть файл

}); });
$(document).on('click', 'div.divTableCell.bdelete', function(){ $(document).on('click', 'div.divTableCell.bdelete', function(){
var job = $(this).closest('.divTable').data().job;
var el = $(this).closest('div.divTable');
if ( job.get_job_id() == '')
var el = $(this).closest('div.jobTable');
var data = el.data();
if (typeof data.id =='undefined' || data.id == '')
el.remove(); el.remove();
else{ else{
var id = data.id;
if (confirm('delete this job?')){ if (confirm('delete this job?')){
$.post(bts().ajax_url, { // POST request $.post(bts().ajax_url, { // POST request
_ajax_nonce: bts().nonce, // nonce _ajax_nonce: bts().nonce, // nonce
action: "delete_job", // action action: "delete_job", // action
jobid: job.data.id,
jobid: id,
}, function(response, status, xhr){ }, function(response, status, xhr){
if (response.status=='success'){ if (response.status=='success'){
el.addClass('blink_me'); el.addClass('blink_me');
}); });
class Job{ //save data for the record, and display it as GUI class Job{ //save data for the record, and display it as GUI
constructor(data){
var html = jQuery("#jobv1_item").html();
this.el = $(html);
//jQuery('div.workspace').append(this.el);
this.load_data(data);
this.init_start_rating();
constructor(selector, data){
this.el = $(selector);
//this.load_data(data);
//this.init_start_rating();
} }
init_start_rating(){ init_start_rating(){
return this.el.find('input[name="id"]').attr('value'); return this.el.find('input[name="id"]').attr('value');
} }
set_job_id(val){ set_job_id(val){
return this.el.find('input[name="id"]').attr('value', val);
if (typeof val == 'undefined' || val == '')
{//remove data-id and id
this.el.removeAttr('data-id');
this.el.removeAttr('id');
}else{
this.el.attr('data-id', val);
this.el.attr('id', 'job_' + val);
}
} }
get_tos() get_tos()
{ {
return this.el.find('div.btos select').children("option:selected").val();
this.el.find('div.btos select').children("option:selected").val();
} }
set_tos(val) set_tos(val)
{ {
if (typeof(val) =="undefined") if (typeof(val) =="undefined")
return; return;
this.el.find('div.btos select option[value="'+val+'"]').prop('selected',true);
this.el.find('input.tos_name').attr('value', bts().tos[val].tos_full_str);
} }
get_start(){ get_start(){
return this.el.find('div.bstart input').attr('value');
return this.el.find('div.bstart').html();
} }
set_start(val) set_start(val)
{ {
if (typeof(val) =="undefined")
return;
this.el.find('div.bstart input').attr('value', val);
this.el.find('div.bstart').html(val);
} }
get_finish() get_finish()
{ {
return this.el.find('div.bfinish input').attr('value');
return this.el.find('div.bfinish').html();
} }
set_finish(val) set_finish(val)
{ {
if (typeof(val) == "undefined") if (typeof(val) == "undefined")
return; return;
this.el.find('div.bfinish input').attr('value', val);
this.el.find('div.bfinish').html(val);
} }
get_rate() get_rate()
{ {
return this.el.find('div.brate select').children("option:selected").val();
return this.el.find('div.brate').children("option:selected").val();
} }
set_rate(val) set_rate(val)
{ {
var b = bts(); var b = bts();
if ((typeof b.staff_map != "undefined" && Object.keys(b.staff_map).length > 0) && if ((typeof b.staff_map != "undefined" && Object.keys(b.staff_map).length > 0) &&
(typeof b.client_map != "undefined" && Object.keys(b.client_map).length > 0) && (typeof b.client_map != "undefined" && Object.keys(b.client_map).length > 0) &&
(typeof b.tos != "undefined" && Object.keys(b.tos).length > 0 ))
(typeof b.tos != "undefined" && Object.keys(b.tos).length > 0 ) &&
(typeof b.earnings_rate != "undefined" && Object.keys(b.earnings_rate).length > 0 ))
{ {
//we do works, load timesheets
var template = $("#jobv1_item").html();
var html = Mustache.render(template, response);
$('div.workspace').append(html);
hide_loading_jobs();
//filter it if reqired
//debounced_filter_workspace();
return;
//map data for each jobTable
response.jobs.forEach(function(e){
e.tos_name = bts().tos[e.tos].tos_full_str;
e.staff_name = bts().staff_map[e.staff].display_name;
e.client_name = bts().client_map[e.client].display_name;
e.rate_name = bts().earnings_rate[e.rate].RatePerUnit + "-" + bts().earnings_rate[e.rate].Name;
e.saved = true;
if (e.ack != 0){
e.is_confirmed = true;
}
//console.log('attach %s %o to %o ', e.id, e, div);
});
//we do works, load timesheets
var template = $("#jobv1_item").html();
var html = Mustache.render(template, response);
$('div.workspace').append(html);
hide_loading_jobs();
//filter it if reqired
debounced_filter_workspace();
return;
} }
console.log('wating staff/client/tos info to be ready');
//console.log('wating staff/client/tos info to be ready');
setTimeout(function(){ setTimeout(function(){
display_jobs_after_staff_client_tos_info_ready(response); display_jobs_after_staff_client_tos_info_ready(response);
}, 500); //try it half seconds later }, 500); //try it half seconds later
function filter_workspace_by_staff(staffs) function filter_workspace_by_staff(staffs)
{ {
var class_name='to_be_shown';
//filter some of them; //filter some of them;
$('div.workspace div.divTable').each(function(i,e){
var job = $(e).data().job;
var s = job.get_staff();
if (staffs.indexOf(s) ==-1)
$(this).fadeOut();
else
$(this).fadeIn();
staffs.forEach(function(e){
$('div.workspace div.jobTable[data-staff="' + e + '"]').addClass(class_name);
}); });

$('div.workspace div.jobTable.' + class_name).fadeIn();
$('div.workspace div.jobTable:not(.'+ class_name +')').hide();
$('.' + class_name).removeClass(class_name);
} }
function filter_workspace_by_client(clients) function filter_workspace_by_client(clients)
{ {
var class_name='to_be_shown';
//filter some of them; //filter some of them;
$('div.workspace div.divTable').each(function(i,e){
var job = $(e).data().job;
var c = job.get_client();
if (clients.indexOf(c) ==-1)
$(this).fadeOut();
else
$(this).fadeIn();
clients.forEach(function(e){
$('div.workspace div.jobTable[data-client="' + e + '"]').addClass(class_name);
}); });

$('div.workspace div.jobTable.' + class_name).fadeIn();
$('div.workspace div.jobTable:not(.'+ class_name +')').hide();
$('.' + class_name).removeClass(class_name);
} }
function filter_workspace_by_both(staffs, clients) function filter_workspace_by_both(staffs, clients)
{ {
var class_name='hide';
//filter some of them; //filter some of them;
$('div.workspace div.divTable').each(function(i,e){
var job = $(e).data().job;
var s = job.get_staff();
var c = job.get_client();
if (staffs.indexOf(s) ==-1 || clients.indexOf(c) ==-1)
$(this).fadeOut();
else
$(this).fadeIn();
});
clients.forEach(function(e){
$('div.workspace div.jobTable:not([data-client="' + e + '"])').addClass(class_name);
});
staffs.forEach(function(e){
$('div.workspace div.jobTable:not([data-staff="' + e + '"])').addClass(class_name);
});
$('div.workspace div.jobTable.' + class_name).hide();
$('div.workspace div.jobTable:not(.'+ class_name +')').show();
$('.' + class_name).removeClass(class_name);
} }
function filter_workspace_by_weeks(){ function filter_workspace_by_weeks(){
}); });
function init_ts(){ function init_ts(){
show_loading_jobs();
setTimeout(list_staff, 5000); // for testing delayed loading of jobs only
//list_staff();
//list_clients();
setTimeout(list_clients, 8000); // for testing delayed loading of jobs only
//list_tos();
setTimeout(list_tos, 10000); // for testing delayed loading of jobs only
xero(false); xero(false);
wifi(false); wifi(false);
csv(false); csv(false);
show_loading_jobs();
list_staff();
list_clients();
list_tos();
ajax_earning_rate();
//setTimeout(list_staff, 5000); // for testing delayed loading of jobs only
//setTimeout(list_clients, 8000); // for testing delayed loading of jobs only
//setTimeout(list_tos, 10000); // for testing delayed loading of jobs only
init_user_search(); init_user_search();
reset_title_to_today(); reset_title_to_today();
load_timesheet(); load_timesheet();
do_staff(); do_staff();
} }
// function ajax_earning_rate(){
// $.post(bts().ajax_url, { // POST request
// _ajax_nonce: bts().nonce, // nonce
// action: "earnings_rate", // action
// }, function(response, status, xhr){
// bts().earnings_rate = response;
// console.log("%o", bts().earnings_rate);
// });
// }
function ajax_earning_rate(){
$.post(bts().ajax_url, { // POST request
_ajax_nonce: bts().nonce, // nonce
action: "earnings_rate", // action
}, function(response, status, xhr){
bts().earnings_rate = {};
response.options.forEach(function(e){
bts().earnings_rate[e.EarningsRateID]=e;
});
console.log("%o", bts().earnings_rate);
});
}


$( ".boundary_datepicker" ).datepicker(); $( ".boundary_datepicker" ).datepicker();

+ 1
- 1
ts.php Просмотреть файл

'userid'=> $this->bts_user_id, 'userid'=> $this->bts_user_id,
'load_user_img'=> plugins_url('img/loading_user.gif', __FILE__), 'load_user_img'=> plugins_url('img/loading_user.gif', __FILE__),
'load_job_img'=> plugins_url('img/loading_job.gif', __FILE__), 'load_job_img'=> plugins_url('img/loading_job.gif', __FILE__),
'earnings_rate'=> get_option('bts_payitem_earnings_rate'),
'high_pay_keywords' => ['sat ', 'sun ', 'high ', 'public holiday'], //space is important 'high_pay_keywords' => ['sat ', 'sun ', 'high ', 'public holiday'], //space is important
) ); ) );
} }
'login' => $s->user_login, 'login' => $s->user_login,
'firstname'=> $s->first_name, 'firstname'=> $s->first_name,
'lastname'=> $s->last_name, 'lastname'=> $s->last_name,
'display_name' => $s->display_name,
'mobile'=> get_user_meta($s->ID, 'mobile', true), 'mobile'=> get_user_meta($s->ID, 'mobile', true),
'email'=> $s->user_email, 'email'=> $s->user_email,
'wages'=> 0, 'wages'=> 0,

Загрузка…
Отмена
Сохранить