timesheet source code
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

388 lines
11KB

  1. (function ($) {
  2. $(function () {
  3. // http://davidwalsh.name/javascript-debounce-function
  4. function debounce(func, wait, immediate) {
  5. var timeout;
  6. return function () {
  7. var context = this, args = arguments;
  8. var later = function () {
  9. timeout = null;
  10. if (!immediate)
  11. func.apply(context, args);
  12. };
  13. var callNow = immediate && !timeout;
  14. clearTimeout(timeout);
  15. timeout = setTimeout(later, wait);
  16. if (callNow)
  17. func.apply(context, args);
  18. };
  19. };
  20. /*____________________________________________________________________________________*/
  21. class People{
  22. constructor(selector, template, data){
  23. this.selector = selector;
  24. this.data = data;
  25. this.template = template;
  26. // this.sample_people = {
  27. // login: '01515b52-6936-46b2-a000-9ad4cd7a5b50',
  28. // firstname: "first",
  29. // lastname: "last",
  30. // phone: '041122221',
  31. // email: 'abc@gmail.com',
  32. // pay: 0,
  33. // hour: 12,
  34. // OT: 3,
  35. // petrol: 50,
  36. // rating: 1,
  37. // };
  38. this.load_data(this.data);
  39. }
  40. load_data(data){
  41. var template = $(this.template).html();
  42. var html = Mustache.render(template, data);
  43. $(this.selector).html(html);
  44. //save it
  45. $(this.selector).data(data);
  46. //draw rating star
  47. this.set_ratings(this.data.rating);
  48. this.set_unconfirmed_job(this.data.unconfirmedjob);
  49. }
  50. set_ratings(num){
  51. for (var i=1; i<= 5; i++){
  52. if (i <=num){
  53. $(this.selector + " div[name='rating'] span:nth-child(" +i+ ")").addClass('checked');
  54. }else{
  55. $(this.selector + " div[name='rating'] span:nth-child(" +i+ ")").removeClass('checked');
  56. }
  57. }
  58. this.data.rating = num;
  59. }
  60. set_unconfirmed_job(num){
  61. if( num == 0 )
  62. $(this.selector + " span[name='badge']").hide();
  63. else
  64. $(this.selector + " span[name='badge']").show();
  65. this.data.unconfirmedjob = num;
  66. }
  67. }//end of class People
  68. function bts_staff_html(data){
  69. var template = $('#staff_item').html();
  70. var head = '<div class="peopleitem" id="p'+ data.login +'">';
  71. r = head + '</div>' ;
  72. return r;
  73. }
  74. function bts_client_html(data){
  75. var template = $('#client_item').html();
  76. var head = '<div class="peopleitem" id="p'+ data.login +'">';
  77. r = head + '</div>' ;
  78. return r;
  79. }
  80. function sample_staff(){
  81. for (var i=1; i<100; i++){
  82. var sample_people = {
  83. login: '01515b52-6936-46b2-a000-9ad4cd7a5b50' +i,
  84. firstname: "first"+i,
  85. lastname: "last",
  86. mobile: '041122221' +i,
  87. email: 'abc@gmail.com' + i,
  88. wages: 0,
  89. hour: i,
  90. OT: 3,
  91. petrol: 50 +i,
  92. rating: Math.floor(Math.random() * Math.floor(5)),
  93. unconfirmedjob: Math.floor(Math.random() * Math.floor(30)),
  94. };
  95. var html = bts_staff_html(sample_people);
  96. jQuery('div.stafflist').append(html);
  97. new People("#p" + sample_people.login, sample_people);
  98. }
  99. }
  100. function list_staff() {
  101. show_loading_staff();
  102. $('div.stafflist div.peopleitem').remove();
  103. $.post(bts().ajax_url, { // POST request
  104. _ajax_nonce: bts().nonce, // nonce
  105. action: "list_staff", // action
  106. }, function(response, status, xhr){
  107. if (response.status =='success'){
  108. hide_loading_staff();
  109. response.users.forEach(function(u){
  110. var html = bts_staff_html(u);
  111. jQuery('div.stafflist').append(html);
  112. new People("#p" + u.login,'#staff_item', u);
  113. });
  114. }else{
  115. alert('error getting staff list');
  116. }
  117. });
  118. }
  119. function list_clients() {
  120. show_loading_client();
  121. $('div.clientlist div.peopleitem').remove(); //clear it
  122. $.post(bts().ajax_url, { // POST request
  123. _ajax_nonce: bts().nonce, // nonce
  124. action: "list_client", // action
  125. }, function(response, status, xhr){
  126. if (response.status =='success'){
  127. response.users.forEach(function(u){
  128. hide_loading_client();
  129. var html = bts_client_html(u);
  130. jQuery('div.clientlist').append(html);
  131. new People("#p" + u.login, '#client_item' ,u);
  132. });
  133. }else{
  134. alert('error getting Client list');
  135. }
  136. });
  137. }
  138. function show_loading_staff(){
  139. jQuery('div.stafflist img').attr('src', bts().load_user_img).show();
  140. }
  141. function show_loading_client(){
  142. jQuery('div.clientlist img').attr('src', bts().load_user_img).show();
  143. }
  144. function hide_loading_staff(){
  145. jQuery('div.stafflist img').hide();;
  146. }
  147. function hide_loading_client(){
  148. jQuery('div.clientlist img').hide();
  149. }
  150. function xero(t){
  151. if (t)
  152. $('div.xero i').show();
  153. else
  154. $('div.xero i').hide();
  155. }
  156. function wifi(t){
  157. if (t)
  158. $('div.wifi i').show();
  159. else
  160. $('div.wifi i').hide();
  161. }
  162. function init_user_search(){
  163. $('div.b_search input').keyup(debounce(function(e){
  164. filter_user(e.target);
  165. }, 500));
  166. }
  167. function filter_user(input){
  168. var value = $(input).attr('value');
  169. value = value.toLowerCase();
  170. var selector = get_selector_for_filter_people(input);
  171. $.each( $(selector).find('div.peopleitem'), function(index, e){
  172. var html = $(e).find('div[name="title"] a').html();
  173. html = html.toLowerCase();
  174. if (-1 != html.indexOf(value)){//we find it;
  175. $(e).show();
  176. }else{
  177. $(e).hide();
  178. }
  179. });
  180. }
  181. function get_selector_for_filter_people(input){
  182. var selector='';
  183. var role = $(input).attr('placeholder');
  184. if (role == 'staff') //we filter staff
  185. selector = 'div.stafflist';
  186. else if (role = 'client')
  187. selector = 'div.clientlist';
  188. return selector;
  189. }
  190. function init_ts(){
  191. list_staff();
  192. list_clients();
  193. xero(false);
  194. wifi(false);
  195. init_user_search();
  196. ajax_earning_rate();
  197. }
  198. function ajax_earning_rate(){
  199. $.post(bts().ajax_url, { // POST request
  200. _ajax_nonce: bts().nonce, // nonce
  201. action: "earnings_rate", // action
  202. }, function(response, status, xhr){
  203. bts().earnings_rate = response;
  204. console.log("%o", bts().earnings_rate);
  205. });
  206. }
  207. init_ts();
  208. $(document).on('click', 'div.divTableHead.bdelete', function(){
  209. for (var i=1; i<10; i++){
  210. // var html = jQuery("#job_item").html();
  211. // var o = jQuery('div.workspace').append(html);
  212. var o = new Job({i:i});
  213. o.debug();
  214. }
  215. reset_date_time_picker();
  216. });
  217. function reset_date_time_picker(){
  218. //$('div.xdsoft_datetimepicker.xdsoft_noselect.xdsoft_default').remove();
  219. dtp_init();
  220. }
  221. $(document).on('click', 'div.divTableCell.bdelete', function(){
  222. if (confirm('delete this job?'))
  223. $(this).closest('div.divTable').remove();
  224. });
  225. $(document).on('mouseenter', 'div.divTableCell', function(){
  226. $(this).closest('div.divTable').addClass('highlight');
  227. });
  228. $(document).on('mouseleave', 'div.divTableCell', function(){
  229. $(this).closest('div.divTable').removeClass('highlight');
  230. });
  231. $(document).on('click', 'span.ticon.ticon-save', function(){
  232. var table = $(this).closest('div.divTable')
  233. console.log('clicked table data = %o', $(table).data());
  234. var r = get_record_from_ui(table);
  235. do_save_record(r);
  236. });
  237. function do_save_record(r){
  238. $.post(bts().ajax_url, { // POST request
  239. _ajax_nonce: bts().nonce, // nonce
  240. action: "save_job", // action
  241. record: r,
  242. }, function(response, status, xhr){
  243. console.log("response for save %o", response);
  244. });
  245. }
  246. function get_record_from_ui(table){
  247. var record = {};
  248. record.id = get_job_id(table);
  249. record.tos = get_tos(table);
  250. record.start = get_start(table);
  251. record.finish = get_finish(table);
  252. record.rate = get_rate(table);
  253. record.staff = get_staff(table);
  254. record.client = get_client(table);
  255. record.ack = get_ack(table);
  256. return record;
  257. }
  258. class Job{
  259. constructor(data){
  260. var html = jQuery("#job_item").html();
  261. this.el = $(html);
  262. this.data = data;
  263. this.el.data({obj:this, data:data});
  264. jQuery('div.workspace').append(this.el);
  265. }
  266. debug(){
  267. console.log("data %o", this.el.data());
  268. }
  269. load_data(data)
  270. {
  271. $(selector).data(data);//save data to object
  272. //update gui;
  273. set_job_id(data.id);
  274. }
  275. get_job_id(){
  276. return $(this.selector).find('input[name="id"]').attr('value');
  277. }
  278. set_job_id(val){
  279. return $(this.selector).find('input[name="id"]').attr('value', val);
  280. }
  281. get_tos()
  282. {
  283. return $(this.selector).find('div.btos select').children("option:selected").val();
  284. }
  285. set_tos(val)
  286. {
  287. return $(this.selector).find('div.btos select').children("option:selected").val();
  288. }
  289. get_start(){
  290. }
  291. }
  292. function get_job_id(table)
  293. {
  294. $(table).find('input[name="id"]').attr('value');
  295. }
  296. function get_tos(table)
  297. {
  298. return $(table).find('div.btos select').children("option:selected").val();
  299. }
  300. function get_start(table){
  301. return $(table).find('div.bstart input').attr('value');
  302. }
  303. function get_finish(table)
  304. {
  305. return $(table).find('div.bfinish input').attr('value');
  306. }
  307. function get_rate(table)
  308. {
  309. return $(table).find('div.brate select').children("option:selected").val();
  310. }
  311. function get_staff(table)
  312. {
  313. return $(table).find('div.bstaff select').children("option:selected").val();
  314. }
  315. function get_client(table)
  316. {
  317. return $(table).find('div.bclient select').children("option:selected").val();
  318. }
  319. function get_ack(table)
  320. {
  321. return $(table).find('div.bconfirmed input:checked').length > 0;
  322. }
  323. /*________________________________________________________________________*/
  324. });
  325. })(jQuery);
  326. /*______________scrolling______________________________________________*/
  327. jQuery(document).ready(function(){
  328. var timeoutid =0;
  329. jQuery('button.peoplelist[name="down"]').mousedown(function(){
  330. var button = this;
  331. timeoutid = setInterval(function(){
  332. //console.log("down scrotop %d ", jQuery(button).parent().find(".userlist").get(0).scrollTop );
  333. jQuery(button).parent().find(".userlist").get(0).scrollTop +=240;
  334. }, 100);
  335. }).on('mouseup mouseleave', function(){
  336. clearTimeout(timeoutid);
  337. });
  338. jQuery('button.peoplelist[name="up"]').mousedown(function(){
  339. var button = this;
  340. timeoutid = setInterval(function(){
  341. //console.log("up scrotop %d ", jQuery(button).parent().find(".userlist").get(0).scrollTop );
  342. jQuery(button).parent().find(".userlist").get(0).scrollTop -=240;
  343. }, 100);
  344. }).on('mouseup mouseleave', function(){
  345. clearTimeout(timeoutid);
  346. });
  347. });