patrick 6 лет назад
Родитель
Сommit
eb12d6e5f8
4 измененных файлов: 369 добавлений и 25 удалений
  1. +42
    -1
      css/bts_timesheet.css
  2. +13
    -11
      html/job.html
  3. +272
    -10
      js/bts_timesheet.js
  4. +42
    -3
      ts.php

+ 42
- 1
css/bts_timesheet.css Просмотреть файл

@@ -8,6 +8,14 @@ body {
z-index: -1;
}

.blink_me {
animation: blinker 0.3s linear infinite;
}

@keyframes blinker {
50% { opacity: 0; }
}

.titlebar_gradient {
/* Permalink - use to edit and share this gradient: https://colorzilla.com/gradient-editor/#f6e6b4+0,ed9017+100 */
background: rgb(246,230,180); /* Old browsers */
@@ -17,6 +25,14 @@ body {
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f6e6b4', endColorstr='#ed9017',GradientType=0 ); /* IE6-9 */
}


.sheettitle h1:hover{
text-decoration: underline;
font-weight: bolder;
cursor: pointer;
animation: blinker 1s linear infinite;
}

.timesheets {
width: calc(100vw - 300px);
height: 100vh;
@@ -673,13 +689,15 @@ div.brate,
div.bstaff,
div.bclient,
div.bconfirmed,
div.bsave,
div.brating,
div.bdelete {
width: 10%;
height: 30px;
}

div.btos {
width: 20%;
width: 15%;
}

div.brate{
@@ -693,11 +711,34 @@ div.brate{


div.bdelete,
div.bsave,
div.bconfirmed {
text-align:center;
width: 5%;
}

div.brating{
text-align: center;
cursor: pointer;
}


.brating {
unicode-bidi: bidi-override;
direction: rtl;
}
.brating > span:hover:before,
.brating > span:hover ~ span:before {
content: "\2605";
position: absolute;
}


div.bsave.saved span{
display: none;
}


/* short code for the table */
div.btos select,
div.bstart input,

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

@@ -3,26 +3,28 @@
<div class="divTableRow">
<input type='hidden' name='id' value=''>
<div class="divTableCell btos">
<select>
<option value="personalcare">Personal Care (stanard)</option>
<option value="personalcare_h">Personal Care(Complex)</option>
<option value="lunch">Lunch (stanard)</option>
<option value="lunch_h">Lunch(Complex)</option>
<option value="community">Community(stanard)</option>
<option value="community_h">Community(Complex)</option>
<option value="turn">Turn(stanard)</option>
<option value="turn_h">Turn(Complex)</option>
</select>
[bts_type_of_service]
</div>
<div class="divTableCell bstart"><input class="datepicker" placeholder="2019-07-10 01:00:00" value=""></input></div>
<div class="divTableCell bfinish"><input class="datepicker" placeholder="2019-07-10 01:00:00" value=""></input></div>
<div class="divTableCell brate">[bts_rate_options]</div>
<div class="divTableCell bstaff">[bts_select_staff]</div>
<div class="divTableCell bclient">[bts_select_client]</div>
<div class="divTableCell bconfirmed"><input type=checkbox checked> <span class="ticon ticon-save"></span></div>
<div class="divTableCell bconfirmed"><input type=checkbox checked ></div>
<div class="divTableCell brating">
<span data-rating=5>☆</span>
<span data-rating=4>☆</span>
<span data-rating=3>☆</span>
<span data-rating=2>☆</span>
<span data-rating=1>☆</span>
</div>
<div class="divTableCell bdelete">
<span class="ticon ticon-trash"></span>
</div>
<div class="divTableCell bsave saved">
<span class="ticon ticon-save"></span>
</div>
</div>
</div>
</div>

+ 272
- 10
js/bts_timesheet.js Просмотреть файл

@@ -254,8 +254,28 @@
jQuery('div.workspace').append(this.el);
this.load_data(data);
dtp_init();
this.init_start_rating();
}
init_start_rating(){
var self = this;
this.el.find("div.brating span").click(function(){
var r = $(this).attr('data-rating');
self.set_rating(r);
})
this.el.find("div.brating").mouseenter(function(){
//change to all hollow star
$(this).find('span').html('☆');
});
this.el.find("div.brating").mouseleave(function(){
self.set_rating(self.data.rating);
});
}
load_data(data)
{
this.set_job_id(data.id);
@@ -347,6 +367,27 @@
return;
return this.el.find('div.bconfirmed input').prop('checked', val!=0);
}
get_rating(){
var count =0;
this.el.find('div.brating span').each(function(i,e){
if ($(e).html()=='★')
count +=1;
});
return count;
}
set_rating(num){
if (!(1 <= num && num <=5))
return;
this.data.rating=num;
this.el.find('div.brating span').each(function(i,e){
var rating = $(e).attr('data-rating');
var rating = parseInt(rating);
if (rating <= num)
$(e).html('★');
else
$(e).html('☆');
});
}
get_record_from_ui(){
var record = {};
@@ -410,19 +451,240 @@
$(s).trigger('click');
}
setTimeout(function(){
set_modal_title('warning', 'suck title');
set_modal_content('warning', 'fucking details');
open_modal('warning');
}, 1000);
// setTimeout(function(){
// set_modal_title('warning', 'suck title');
// set_modal_content('warning', 'fucking details');
// //open_modal('warning');
// }, 1000);
//
// setTimeout(function(){
// set_modal_title('error', 'error title');
// set_modal_content('error', 'error details');
// //open_modal('error');
// }, 5000);
$(document).on('mouseenter', 'div.week1 div', function(){
$(this).addClass('blink_me');
get_week2_partner(this).addClass('blink_me');
});
$(document).on('mouseleave', 'div.week1 div', function(){
$(this).removeClass('blink_me');
get_week2_partner(this).removeClass('blink_me');
});
function get_week2_partner(div){
var index = $(div).index()+1;
return $('div.week2 div:nth-child('+index+')');
}
function init_weekdays(){
var curr = new Date; // get current date
// First day is the day of the month - the day of the week
var first = curr.getDate() - curr.getDay() + 1; //+1 we want Mon as first
var last = first + 6; // last day is the first day + 6

//var firstday = new Date(curr.setDate(first)); //Mon
//var lastday = new Date(curr.setDate(last)); //Sun
var pos = 1; //first lot
for (var i=first; i<=last; i++)
{
var d1 = new Date(curr.setDate(i));
var d2 = new Date(curr.setDate(i+7));
set_day_number(1,pos, d1); //week 1
set_day_number(2,pos, d2); //week 2
pos +=1;
}
}
function set_day_number(week, index, date){
var selector = 'span[name="w'+week+'d'+index+'"]';
$(selector).html(date.getDate());
$(selector).data({date:date});
}
function format_date(date) {
var monthNames = [
"January", "February", "March",
"April", "May", "June", "July",
"August", "September", "October",
"November", "December"
];

var day = date.getDate();
var monthIndex = date.getMonth();
var year = date.getFullYear();

return day + ' ' + monthNames[monthIndex] + ' ' + year;
}
function set_today(){
var selector = 'div.sheettitle span[name="today"]';
var curr = new Date;
$(selector).html(format_date(curr));
}
Date.prototype.get_week_number = function(){
var d = new Date(Date.UTC(this.getFullYear(), this.getMonth(), this.getDate()));
var dayNum = d.getUTCDay() || 7;
d.setUTCDate(d.getUTCDate() + 4 - dayNum);
var yearStart = new Date(Date.UTC(d.getUTCFullYear(),0,1));
return Math.ceil((((d - yearStart) / 86400000) + 1)/7)
};
function set_week_number(){
var date = $('span[name="w1d1"]').data().date;
console.log("date %o", date);
var num = date.get_week_number();
$('div.weekly span[name="week1"]').html(num);
$('div.weekly span[name="week2"]').html(num+1);
}
$('div.prevweek.left').click(function(){
$('div.weekdays span.weekday').each(function(i, e){
var date = $(e).data().date;
var newdate = new Date(date.setDate(date.getDate() -7 ));
$(e).html(newdate.getDate());
$(e).data({data:newdate});
});
set_week_number();
load_timesheet();
});
$('div.nextweek.right').click(function(){
$('div.weekdays span.weekday').each(function(i, e){
var date = $(e).data().date;
var newdate = new Date(date.setDate(date.getDate() +7 ));
$(e).html(newdate.getDate());
$(e).data({data:newdate});
});
set_week_number();
load_timesheet();
});
$('div.weekly div.weekname.prev').click(function(){
if (!confirm ('copy entire week to next week? '))
return;
});
$('div.weekly div.weekname.next').click(function(){
if (!confirm ('copy entire week to previous week? '))
return;
});
$('div.week1 > div').click(function(){
if (!confirm ('copy to next week'))
return;
});
$('div.sheettitle h1').click(function(){
reset_title_to_today();
})

function reset_title_to_today(){
set_today();
init_weekdays();
set_week_number();
load_timesheet();
}

function load_timesheet()
{
clear_workspace();
var first = $('span[name="w1d1"]').data().date;
var last = $('span[name="w2d7"]').data().date;
$.post(bts().ajax_url, { // POST request
_ajax_nonce: bts().nonce, // nonce
action: "list_job", // action
start: format_date(first),
finish: format_date(last),
}, function(response, status, xhr){
if (response.status =='success'){
response.jobs.forEach(function(job){
new Job(job);
});
//filter it if reqired
do_filter_workspace();
}else{
alert('error loading job');
}
});
}
function format_date(date){
var dd = date.getDate();
var mm = date.getMonth() + 1; //January is 0!

setTimeout(function(){
set_modal_title('error', 'error title');
set_modal_content('error', 'error details');
open_modal('error');
}, 5000);
var yyyy = date.getFullYear();
if (dd < 10) {
dd = '0' + dd;
}
if (mm < 10) {
mm = '0' + mm;
}
return yyyy + '-' + mm + '-' +dd ;
}
function clear_workspace()//clear all timesheet jobs
{
$('div.workspace > div.divTable').remove();
//clear datetime picker
$('div.xdsoft_datetimepicker').remove();
}
$('button[name="confirmschedule"]').click(function(){
$('span.ticon.ticon-save').trigger('click');
});
$(document).on('click','div.userlist', debounce(do_filter_workspace));
function do_filter_workspace(){
var staffs =[];
$('div.stafflist div.peopleitem :checked').each(function(i, e){
var id = $(e).parent().attr('data-id');
//console.log("%o, id=%s", e, id);
staffs.push(id.substring(1));
});
var clients =[];
$('div.clientlist div.peopleitem :checked').each(function(i, e){
var id = $(e).parent().attr('data-id');
//console.log("%o, id=%s", e, id);
clients.push(id.substring(1));
});
console.log('staffs %o' , staffs);
console.log('clients %o' , clients);
filter_workspace(staffs, clients);
}
function filter_workspace(staffs, clients){
//if both array is empty
if( (staffs === undefined || staffs.length ==0) &&
(clients===undefined || clients.length ==0)){
//show all
$('div.workspace div.divTable').show();
return;
}
//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();
});
}

reset_title_to_today();
/*________________________________________________________________________*/
});
})(jQuery);

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

@@ -41,6 +41,8 @@ class AcareOffice{
add_shortcode( 'bts_rate_options', array($this, 'bts_rate_options'));
add_shortcode( 'bts_select_staff', array($this, 'bts_select_staff'));
add_shortcode( 'bts_select_client', array($this, 'bts_select_client'));
add_shortcode( 'bts_type_of_service', array($this, 'bts_type_of_service'));
add_action('wp_ajax_list_staff', array($this,'list_staff' ));
add_action('wp_ajax_list_client', array($this,'list_client' ));
@@ -227,6 +229,21 @@ class AcareOffice{
return $result;
}
public function bts_type_of_service($attr){
$result = ' <select>
<option value="personalcare">Personal Care (stanard)</option>
<option value="personalcare_h">Personal Care(Complex)</option>
<option value="lunch">Lunch (stanard)</option>
<option value="lunch_h">Lunch(Complex)</option>
<option value="community">Community(stanard)</option>
<option value="community_h">Community(Complex)</option>
<option value="turn">Turn(stanard)</option>
<option value="turn_h">Turn(Complex)</option>
</select>
';
return $result;
}
//generate template based on html file
private function template($id, $file)
{
@@ -411,12 +428,34 @@ class AcareOffice{
//ajax browse job with different filters
function list_job(){
check_ajax_referer('acaresydney');
$r = $_POST['record'];
$response = array();
$start = $_POST['start'];
$finish = $_POST['finish'];
$response = array(
'status'=>'success',
'jobs' => [],
);
$sql = "SELECT * FROM $this->table_name WHERE start>='%s' and start <='%s'";
$jobs = $this->db->get_results($this->db->prepare ($sql, array($start, $finish)));
if (! empty($jobs)){
$response['status'] = 'success';
foreach( $jobs as $s){
$response['jobs'][] = array(
'id' => $s->id,
'tos' => $s->tos,
'start'=> $s->start,
'finish'=> $s->finish,
'rate'=> $s->rate,
'staff'=> $s->staff,
'client'=> $s->client,
'ack' => $s->ack,
);
}
}
wp_send_json($response);
wp_die();
}
}

$bb = new AcareOffice();

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