diff --git a/.travis.yml b/.travis.yml index 0085995c9..942155601 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,10 +1,27 @@ language: php + +php: + - '7.2' + sudo: false + cache: directories: - $HOME/.composer/cache/files -install: travis_retry composer install --no-interaction --prefer-dist + - $HOME/.npm + - node_modules + +before_install: + - nvm install 'lts/*' + - npm i -g npm + +install: + - travis_retry composer install --no-interaction --prefer-dist + - npm install --no-audit --no-progress --quiet + - npm run production + script: vendor/bin/phpunit --verbose + notifications: slack: rooms: diff --git a/app/Events/StartTimer.php b/app/Events/StartTimer.php index 351c03f7d..53f774581 100644 --- a/app/Events/StartTimer.php +++ b/app/Events/StartTimer.php @@ -11,15 +11,16 @@ class StartTimer implements ShouldBroadcast { use Dispatchable, InteractsWithSockets, SerializesModels; + public $timerData; /** * Create a new event instance. * * @return void */ - public function __construct() + public function __construct($timerData = []) { - // + $this->timerData = $timerData; } /** @@ -31,4 +32,9 @@ public function broadcastOn() { return new PrivateChannel('stopwatch-event.'.getLoggedInUserId()); } + + public function broadcastWith() + { + return $this->timerData; + } } diff --git a/app/Http/Controllers/TimeEntryController.php b/app/Http/Controllers/TimeEntryController.php index acaad1290..8ed2c93c2 100644 --- a/app/Http/Controllers/TimeEntryController.php +++ b/app/Http/Controllers/TimeEntryController.php @@ -203,9 +203,9 @@ public function getTasks($projectId, Request $request) /** * @return \Illuminate\Http\JsonResponse */ - public function getStartTimer() + public function getStartTimer(Request $request) { - $this->timeEntryRepository->broadcastStartTimerEvent(); + $this->timeEntryRepository->broadcastStartTimerEvent($request->all()); return $this->sendSuccess('Start timer broadcasted successfully.'); } diff --git a/app/Http/Requests/CreateProjectRequest.php b/app/Http/Requests/CreateProjectRequest.php index 2c441fb74..965c5019e 100644 --- a/app/Http/Requests/CreateProjectRequest.php +++ b/app/Http/Requests/CreateProjectRequest.php @@ -33,7 +33,7 @@ public function authorize() public function rules() { $rules = Project::$rules; - $rules['prefix'] = 'required|alpha_num|max:4|min:2|unique:projects,prefix'; + $rules['prefix'] = 'required|alpha_num|max:6|min:2|unique:projects,prefix'; return $rules; } diff --git a/app/Http/Requests/UpdateUserProfileRequest.php b/app/Http/Requests/UpdateUserProfileRequest.php index 96a50114f..2138fc7b8 100644 --- a/app/Http/Requests/UpdateUserProfileRequest.php +++ b/app/Http/Requests/UpdateUserProfileRequest.php @@ -35,10 +35,12 @@ public function rules() { $id = Auth::user()->id; $rules = [ - 'name' => 'required|unique:users,name,'.$id, - 'email' => 'required|email|unique:users,email,'.$id.'|regex:/^[\w\-\.\+]+\@[a-zA-Z0-9\.\-]+\.[a-zA-z0-9]{2,4}$/', - 'phone' => 'nullable|numeric|digits:10', - 'photo' => 'mimes:jpeg,jpg,png', + 'name' => 'required|unique:users,name,'.$id, + 'email' => 'required|email|unique:users,email,'.$id.'|regex:/^[\w\-\.\+]+\@[a-zA-Z0-9\.\-]+\.[a-zA-z0-9]{2,4}$/', + 'phone' => 'nullable|numeric|digits:10', + 'photo' => 'mimes:jpeg,jpg,png', + 'password' => 'nullable|min:6|required_with:password_confirmation|same:password_confirmation', + 'password_confirmation' => 'nullable|min:6', ]; return $rules; diff --git a/app/Models/ActivityType.php b/app/Models/ActivityType.php index c1a614b51..dc65484a8 100644 --- a/app/Models/ActivityType.php +++ b/app/Models/ActivityType.php @@ -2,7 +2,7 @@ namespace App\Models; -use Eloquent as Model; +use Illuminate\Database\Eloquent\Model; /** * App\Models\ActivityType. diff --git a/app/Models/Client.php b/app/Models/Client.php index 2b68b438b..f69aef8a3 100644 --- a/app/Models/Client.php +++ b/app/Models/Client.php @@ -2,7 +2,7 @@ namespace App\Models; -use Eloquent as Model; +use Illuminate\Database\Eloquent\Model; /** * App\Models\Client. diff --git a/app/Models/Project.php b/app/Models/Project.php index f325fabe3..f4073fc17 100644 --- a/app/Models/Project.php +++ b/app/Models/Project.php @@ -2,7 +2,7 @@ namespace App\Models; -use Eloquent as Model; +use Illuminate\Database\Eloquent\Model; /** * App\Models\Project. diff --git a/app/Models/Report.php b/app/Models/Report.php index e9cd5c350..ab20d4ef4 100644 --- a/app/Models/Report.php +++ b/app/Models/Report.php @@ -3,7 +3,7 @@ namespace App\Models; use Carbon\Carbon; -use Eloquent as Model; +use Illuminate\Database\Eloquent\Model; /** * App\Models\Report. diff --git a/app/Models/Tag.php b/app/Models/Tag.php index eac898698..c59ba2d1a 100644 --- a/app/Models/Tag.php +++ b/app/Models/Tag.php @@ -2,7 +2,7 @@ namespace App\Models; -use Eloquent as Model; +use Illuminate\Database\Eloquent\Model; /** * App\Models\Tag. diff --git a/app/Models/Task.php b/app/Models/Task.php index a2b737b80..f3afdda18 100644 --- a/app/Models/Task.php +++ b/app/Models/Task.php @@ -3,8 +3,8 @@ namespace App\Models; use Carbon\Carbon; -use Eloquent as Model; use Illuminate\Database\Eloquent\Builder; +use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\SoftDeletes; /** diff --git a/app/Models/TimeEntry.php b/app/Models/TimeEntry.php index aaed60377..b153f0f53 100644 --- a/app/Models/TimeEntry.php +++ b/app/Models/TimeEntry.php @@ -2,8 +2,8 @@ namespace App\Models; -use Eloquent as Model; use Illuminate\Database\Eloquent\Builder; +use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\SoftDeletes; /** @@ -59,6 +59,7 @@ class TimeEntry extends Model use SoftDeletes; public $table = 'time_entries'; + public $appends = ['entry_type_string']; const STOPWATCH = 1; const VIA_FORM = 2; @@ -149,4 +150,13 @@ public function scopeOfCurrentUser(Builder $query) { return $query->ofUser(getLoggedInUserId()); } + + public function getEntryTypeStringAttribute() + { + if ($this->entry_type == self::STOPWATCH) { + return 'Stopwatch'; + } + + return 'Via Form'; + } } diff --git a/app/Queries/TaskDataTable.php b/app/Queries/TaskDataTable.php index c1d83a8f8..08443b4de 100644 --- a/app/Queries/TaskDataTable.php +++ b/app/Queries/TaskDataTable.php @@ -3,8 +3,8 @@ namespace App\Queries; use App\Models\Task; +use App\Repositories\ProjectRepository; use Illuminate\Database\Eloquent\Builder; -use Illuminate\Support\Facades\Auth; /** * Class TaskDataTable. @@ -18,7 +18,10 @@ class TaskDataTable */ public function get($input = []) { - $loginUserProjects = Auth::user()->projects()->get()->pluck('name', 'id')->toArray(); + /** @var ProjectRepository $projectRepo */ + $projectRepo = app(ProjectRepository::class); + $loginUserProjects = $projectRepo->getLoginUserAssignProjectsArr(); + $query = Task::whereIn('project_id', array_keys($loginUserProjects)) ->leftJoin('projects as p', 'p.id', '=', 'tasks.project_id') ->with(['project', 'taskAssignee', 'createdUser']) diff --git a/app/Queries/TimeEntryDataTable.php b/app/Queries/TimeEntryDataTable.php index 138e73c3e..2c43c5bff 100644 --- a/app/Queries/TimeEntryDataTable.php +++ b/app/Queries/TimeEntryDataTable.php @@ -21,8 +21,7 @@ class TimeEntryDataTable public function get($input) { /** @var TimeEntry $query */ - $query = TimeEntry::with(['task.project', 'user', 'activityType']) - ->select('time_entries.*', \DB::raw("IF(IFNULL(entry_type,1)=1,'Stopwatch','Via Form') as entry_type_string")); + $query = TimeEntry::with(['task.project', 'user', 'activityType'])->select('time_entries.*'); /** @var User $user */ $user = Auth::user(); @@ -33,11 +32,11 @@ function (Builder $q) use ($input) { }); $query->when(isset($input['filter_project']) && !empty($input['filter_project']), function (Builder $q) use ($input) { + $filterUserId = (isset($input['filter_user']) && !empty($input['filter_user'])) ? $input['filter_user'] : getLoggedInUser()->id; $taskIds = Task::whereProjectId($input['filter_project']) - ->where('status', '=', Task::STATUS_ACTIVE) - ->where(function ($q) { - $q->whereHas('taskAssignee', function ($q) { - $q->where('user_id', getLoggedInUser()->id); + ->where(function ($q) use ($filterUserId) { + $q->whereHas('taskAssignee', function ($q) use ($filterUserId) { + $q->where('user_id', $filterUserId); }); })->get()->pluck('id')->toArray(); $q->whereIn('task_id', $taskIds); diff --git a/app/Repositories/ProjectRepository.php b/app/Repositories/ProjectRepository.php index c2fb3be60..8947f90a4 100644 --- a/app/Repositories/ProjectRepository.php +++ b/app/Repositories/ProjectRepository.php @@ -47,6 +47,12 @@ public function model() */ public function getLoginUserAssignProjectsArr() { + $loggedInUser = getLoggedInUser(); + + if ($loggedInUser->can('manage_projects')) { + return $this->getProjectsList()->toArray(); + } + return Auth::user()->projects()->orderBy('name')->get()->pluck('name', 'id')->toArray(); } diff --git a/app/Repositories/ReportRepository.php b/app/Repositories/ReportRepository.php index 0db9c01af..a61abb802 100644 --- a/app/Repositories/ReportRepository.php +++ b/app/Repositories/ReportRepository.php @@ -145,12 +145,12 @@ public function updateReportFilter($input, $report) $clientId = $this->getClientId($report->id); if ($input['client_id'] != 0) { - if ($input['client_id'] !== $clientId) { + if ($input['client_id'] != $clientId) { $result[] = $this->createFilter($report->id, $input['client_id'], Client::class); } } - if (!empty($clientId) && $input['client_id'] !== $clientId) { + if (!empty($clientId) && $input['client_id'] != $clientId) { ReportFilter::ofParamType(Client::class)->whereParamId($clientId)->delete(); } diff --git a/app/Repositories/TaskRepository.php b/app/Repositories/TaskRepository.php index bb538063a..821303be3 100644 --- a/app/Repositories/TaskRepository.php +++ b/app/Repositories/TaskRepository.php @@ -16,6 +16,7 @@ use DB; use Exception; use Illuminate\Database\Eloquent\Builder; +use Illuminate\Database\Eloquent\Relations\HasMany; use Symfony\Component\HttpFoundation\File\Exception\UploadException; use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; @@ -66,7 +67,7 @@ public function find($id, $columns = ['*']) /** * @param array $input * - * @return Task|\Illuminate\Database\Eloquent\Model + * @return Task */ public function store($input) { @@ -261,7 +262,8 @@ public function attachTags($task, $tags) } /** - * @param int $id + * @param int $id + * @param array $input * * @return Task */ @@ -269,7 +271,7 @@ public function getTaskDetails($id, $input = []) { if (isset($input['user_id']) && $input['user_id'] > 0) { $task = Task::with([ - 'timeEntries' => function ($query) use ($input) { + 'timeEntries' => function (HasMany $query) use ($input) { $query->where('time_entries.user_id', '=', $input['user_id']) ->with('user'); }, @@ -284,6 +286,7 @@ public function getTaskDetails($id, $input = []) $totalDuration = sprintf('%02d Hours and %02d Minutes', floor($minutes / 60), $minutes % 60); } $task->totalDuration = $totalDuration; + $task->totalDurationMin = $minutes; return $task; } @@ -349,10 +352,10 @@ public function uploadFile($id, $file) $destinationPath = public_path(Task::PATH); $task = $this->findOrFail($id); - try { - $fileName = TaskAttachment::makeAttachment($file, TaskAttachment::PATH); - $attachment = new TaskAttachment(['task_id' => $task->id, 'file' => $fileName]); + $fileName = TaskAttachment::makeAttachment($file, TaskAttachment::PATH); + $attachment = new TaskAttachment(['task_id' => $task->id, 'file' => $fileName]); + try { DB::beginTransaction(); $task->attachments()->save($attachment); DB::commit(); @@ -424,7 +427,6 @@ public function getAttachments($id) public function addComment($input) { $input['created_by'] = Auth::id(); - $input['comment'] = $input['comment']; $comment = Comment::create($input); return Comment::with('createdUser')->findOrFail($comment->id); diff --git a/app/Repositories/TimeEntryRepository.php b/app/Repositories/TimeEntryRepository.php index 39198d56c..33d8fdd12 100644 --- a/app/Repositories/TimeEntryRepository.php +++ b/app/Repositories/TimeEntryRepository.php @@ -191,9 +191,9 @@ public function checkDuplicateEntry($input, $id = null) } } - public function broadcastStartTimerEvent() + public function broadcastStartTimerEvent($input) { - broadcast(new StartTimer())->toOthers(); + broadcast(new StartTimer($input))->toOthers(); } public function broadcastStopTimerEvent() diff --git a/composer.json b/composer.json index a5cfb2fbc..7e1a902ee 100644 --- a/composer.json +++ b/composer.json @@ -1,7 +1,7 @@ { "name": "infyomlabs/infy-tracker", "type": "project", - "version": "1.8.0-alpha", + "version": "1.8.1-alpha", "description": "Create Projects / Tasks, Track Time, Show Daily Reports", "keywords": [ "time", diff --git a/database/factories/TaskFactory.php b/database/factories/TaskFactory.php index da29bc3b7..46a58a230 100644 --- a/database/factories/TaskFactory.php +++ b/database/factories/TaskFactory.php @@ -16,6 +16,7 @@ 'description' => $faker->text, 'project_id' => $project->id, 'due_date' => $faker->dateTime, + 'status' => Task::STATUS_ALL, 'task_number' => $faker->unique()->randomDigitNotNull, ]; }); diff --git a/phpunit.xml b/phpunit.xml index 7599e1c7b..d346d4cd8 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -13,6 +13,10 @@ ./tests/Unit + + ./tests/Feature + + ./tests/Integration @@ -24,10 +28,6 @@ ./tests/Controllers - - - ./tests/Feature - diff --git a/resources/assets/js/custom.js b/resources/assets/js/custom.js index f9dabe4f6..d1bf03c29 100644 --- a/resources/assets/js/custom.js +++ b/resources/assets/js/custom.js @@ -165,5 +165,3 @@ window.displaySuccessMessage = function (message) { position: 'top-right', }); }; -//modal not closed on click outside -$('.modal').modal({show: false, backdrop: 'static'}); \ No newline at end of file diff --git a/resources/assets/js/profile/profile.js b/resources/assets/js/profile/profile.js index e5c81550e..a9d83f822 100644 --- a/resources/assets/js/profile/profile.js +++ b/resources/assets/js/profile/profile.js @@ -1,5 +1,9 @@ $('#editProfileForm').submit(function (event) { event.preventDefault(); + isValidate = validatePassword(); + if(!isValidate){ + return false; + } let loadingButton = jQuery(this).find("#btnEditSave"); loadingButton.button('loading'); $.ajax({ @@ -85,4 +89,35 @@ $(document).on('keyup', '#name', function (e) { $('#prefix').val(txtVal.toLocaleUpperCase()); } } -}); \ No newline at end of file +}); + +$(".confirm-pwd").hide(); +$(document).on('blur', '#pfNewPassword', function () { + let password = $("#pfNewPassword").val(); + if(password == '' || password.trim() == ''){ + $(".confirm-pwd").hide(); + return false; + } + + $(".confirm-pwd").show(); +}); +$(document).on('blur', '#pfNewConfirmPassword', function () { + let confirmPassword = $("#pfNewConfirmPassword").val(); + if(confirmPassword == '' || confirmPassword.trim() == ''){ + $(".confirm-pwd").hide(); + return false; + } + + $(".confirm-pwd").show(); +}); + +function validatePassword() { + let password = $("#pfNewPassword").val().trim(); + let confirmPassword = $("#pfNewConfirmPassword").val().trim(); + + if((confirmPassword == '' && password != '') || (confirmPassword != '' && password == '')) { + $('#editProfileValidationErrorsBox').show().html("Please enter password and confirm password"); + return false; + } + return true; +} \ No newline at end of file diff --git a/resources/assets/js/projects/project.js b/resources/assets/js/projects/project.js index 00c4d5445..fc5e19cdf 100644 --- a/resources/assets/js/projects/project.js +++ b/resources/assets/js/projects/project.js @@ -20,7 +20,6 @@ let tbl = $('#projects_table').DataTable({ columnDefs: [ { "targets": [0], - "orderable": false, "className": 'text-center', "width": '7%' }, diff --git a/resources/assets/js/report/report.js b/resources/assets/js/report/report.js index db8c64ce0..e2a152a06 100644 --- a/resources/assets/js/report/report.js +++ b/resources/assets/js/report/report.js @@ -20,6 +20,8 @@ $('#tagIds').select2({ }); $('#filterCreatedBy').select2(); +$(".select2-search__field").css('width','100%'); + $('#start_date').datetimepicker({ format: 'YYYY-MM-DD', useCurrent: true, @@ -181,6 +183,7 @@ let tbl = $('#report_table').DataTable({ }, { data: 'user.name', + defaultContent: "", name: 'user.name' }, { diff --git a/resources/assets/js/task/task.js b/resources/assets/js/task/task.js index c4d29df17..c139adec1 100644 --- a/resources/assets/js/task/task.js +++ b/resources/assets/js/task/task.js @@ -277,6 +277,7 @@ $(document).on('click', '.taskDetails', function (event) { startLoader(); $('#no-record-info-msg').hide(); $('#taskDetailsTable').hide(); + $('.time-entry-data').hide(); $.ajax({ url: taskUrl + id + '/' + 'users', @@ -305,6 +306,10 @@ $(document).on('click', '.taskDetails', function (event) { }); }); +function formatCollapsableRow(data) { + return '
' + data.note + '
'; +} + $(document).on('change', '#task_users', function () { let taskId = $(this).attr('data-task_id'); let taskUserId = $(this).val().split('-'); @@ -328,42 +333,64 @@ $(document).on('change', '#task_users', function () { } }); }); - window.drawTaskDetailTable = function (data) { - stopLoader(); if (data.totalDuration === 0) { $('#no-record-info-msg').show(); - $('#taskDetailsTable').hide(); + $('.time-entry-data').hide(); + stopLoader(); return true; - } else { - $('#taskDetailsTable').show(); - $('#user-drop-down-body').show(); - $('#no-record-info-msg').hide(); } - var table = $("#taskDetailsTable tbody").html(""); - let totalMin = 0; - $.each(data.time_entries, function (idx, elem) { - totalMin = totalMin + elem.duration; - table.append( - "" + - "" + - "" + - "" + elem.user.name + "" + - "" + elem.start_time + "" + - "" + elem.end_time + "" + - "" + elem.duration + "" + - "" + - "" + - "" - ); - table.append("
" + - "Notes:
" + elem.note + "
" + - "
"); + + let taskDetailsTable = $('#taskDetailsTable').DataTable({ + destroy: true, + paging: true, + data: data.time_entries, + searching: false, + lengthChange: false, + columns: [ + { + className: 'details-control', + defaultContent: "", + data: null, + orderable: false, + }, + {data: "user.name"}, + {data: "start_time"}, + {data: "end_time"}, + {data: "duration"}, + { + orderable: false, + data: function (data) { + return "" + + ""; + } + } + ], }); - table.append("" + - "Total duration in hours : " + data.totalDuration + "" + - "Total duration in minutes:" + totalMin + "" + - ""); + + $('.time-entry-data').show(); + $('#taskDetailsTable').show(); + $('#user-drop-down-body').show(); + $('#no-record-info-msg').hide(); + stopLoader(); + + $('#taskDetailsTable tbody').on('click', 'td.details-control', function () { + var tr = $(this).closest('tr'); + var row = taskDetailsTable.row(tr); + + if (row.child.isShown()) { + // This row is already open - close it + row.child.hide(); + tr.removeClass('shown'); + } else { + // Open this row + row.child(formatCollapsableRow(row.data())).show(); + tr.addClass('shown'); + } + }); + + $("#taskDetailsTable_wrapper").css('width', "100%"); + $("#total-duration").html("Total duration: " + data.totalDuration + " || " + data.totalDurationMin + " Minutes"); }; $('#addNewForm').submit(function (event) { @@ -467,6 +494,15 @@ $(function () { } }); +$(document).on('click', '.collapse-icon', function () { + let isShow = $(this).parent().parent().hasClass('shown'); + if(isShow) { + $(this).children().removeClass('fa-plus-circle').addClass("fa-minus-circle"); + } else { + $(this).children().removeClass('fa-minus-circle').addClass("fa-plus-circle"); + } +}); + window.manageCollapseIcon = function (id) { var isExpanded = $('#tdCollapse' + id).attr('aria-expanded'); if (isExpanded == 'true') { @@ -573,3 +609,6 @@ function loadProjectAssignees(projectId, selector) { } }); } + +//modal not closed on click outside +$('.modal').modal({show: false, backdrop: 'static'}); diff --git a/resources/assets/js/task/task_detail.js b/resources/assets/js/task/task_detail.js index 0ee0bd08f..84d08c33f 100644 --- a/resources/assets/js/task/task_detail.js +++ b/resources/assets/js/task/task_detail.js @@ -292,12 +292,12 @@ function addCommentSection(comment) { }; $('#btnComment').click(function (event) { - let loadingButton = $(this); - loadingButton.button('loading'); let comment = CKEDITOR.instances.comment.getData(); if(comment == '' || comment.trim() == ''){ return false; } + let loadingButton = $(this); + loadingButton.button('loading'); $.ajax({ url: baseUrl + 'tasks/' + taskId+ '/comments', type: 'post', @@ -456,3 +456,6 @@ CKEDITOR.replace( 'editDesc', { $(document).on('click', '#btnCancel', function () { CKEDITOR.instances.comment.setData(''); }); + +//modal not closed on click outside +$('.modal').modal({show: false, backdrop: 'static'}); diff --git a/resources/assets/js/time_tracker/time_tracker.js b/resources/assets/js/time_tracker/time_tracker.js index 9f5e3659b..05fe3b4eb 100644 --- a/resources/assets/js/time_tracker/time_tracker.js +++ b/resources/assets/js/time_tracker/time_tracker.js @@ -15,14 +15,14 @@ window.Echo.private(`stopwatch-event.${loggedInUserId}`) enableTimerData(); stopTimerData(); }) - .listen('StartTimer', () => { - startWatch(); - let projectId = localStorage.getItem('project_id'); - let taskId = localStorage.getItem('task_id'); - let activityId = localStorage.getItem('activity_id'); - $('#tmProjectId').val(projectId).trigger('change').attr('disabled', true); - $('#tmTaskId').val(taskId).trigger('change').attr('disabled', true); - $('#tmActivityId').val(activityId).trigger('change').attr('disabled', true); + .listen('StartTimer', (result) => { + $('#tmProjectId').val(result.project).trigger('change').attr('disabled', true); + $('#tmTaskId').val(result.task).trigger('change').attr('disabled', true); + $('#tmActivityId').val(result.activity).trigger('change').attr('disabled', true); + setTimeout(function () { + $('#tmTaskId').val(result.task).trigger('change').attr('disabled', true); + }, 1500); + setTimerData(result.activity, result.task, result.project); }); $('#tmActivityId,#tmTaskId,#tmProjectId').select2({ @@ -39,8 +39,8 @@ window.loadProjects = function() { $(result.data).each(function (i, e) { $("#tmProjectId").append($('').attr('value', e.id).text(e.name)); }); - if (localStorage.getItem('clockRunning') !== null) { - lastProjectId = localStorage.getItem('project_id'); + if (getItemFromLocalStorage('clockRunning') !== null) { + lastProjectId = getItemFromLocalStorage('project_id'); $('#tmProjectId').val(lastProjectId).trigger("change"); $('#tmProjectId').attr('disabled', true); } @@ -49,7 +49,7 @@ window.loadProjects = function() { }; loadProjects(); -let isClockRunning = localStorage.getItem('clockRunning'); +let isClockRunning = getItemFromLocalStorage('clockRunning'); $(window).on("load", function () { if (isClockRunning == null) { getUserLastTaskWork(); @@ -71,14 +71,14 @@ window.showStartTimeButton= function(){ }; window.startWatch = function () { - if(localStorage.getItem('clockRunning') == null) { + if(getItemFromLocalStorage('clockRunning') == null) { showStartTimeButton(); return; } $("#startTimer").hide(); $("#stopTimer").show(); - var stTime = (localStorage.getItem('start_time') !== null) ? localStorage.getItem('start_time') : getCurrentTime(); + var stTime = (getItemFromLocalStorage('start_time') !== null) ? getItemFromLocalStorage('start_time') : getCurrentTime(); var d1 = new Date($.now()); var d2 = new Date(moment(stTime).format("YYYY-MM-DD HH:mm:ss")); var diffMs = parseInt(d1 - d2); @@ -118,7 +118,7 @@ $('#imgTimer').click(() => { }); // if timer is running then set values as it is -if (localStorage.getItem('clockRunning') !== null) { +if (getItemFromLocalStorage('clockRunning') !== null) { startWatch(); } @@ -137,7 +137,12 @@ var entryStartTime, entryStopTime = 0; function startTimerEvent() { $.ajax({ url: startTimerUrl, - type: 'get', + type: 'post', + data: { + 'activity' : $('#tmActivityId').val(), + 'task' : $('#tmTaskId').val(), + 'project' : $('#tmProjectId').val() + }, success: function () { }, error: function (result) { @@ -151,30 +156,34 @@ $("#startTimer").click(function (e) { var project = $('#tmProjectId').val(); if (project != '' && activity != '' && (task != '' && !(task == null))) { e.preventDefault(); - $('#tmActivityId').attr('disabled', true); - $('#tmTaskId').attr('disabled', true); - $('#tmProjectId').attr('disabled', true); - - var setItems = { - 'user_id': loginUserId, - 'activity_id': activity, - 'task_id': task, - 'project_id': project, - 'clockRunning': true - }; - setItemToLocalStorage(setItems); - - entryStartTime = getCurrentTime(); - if (localStorage.getItem('start_time') !== null) { - entryStartTime = localStorage.getItem('start_time'); - } else { - localStorage.setItem('start_time', entryStartTime); - } - startWatch(); + setTimerData(activity, task, project); startTimerEvent(); } }); +function setTimerData(activity, task, project) { + $('#tmActivityId').attr('disabled', true); + $('#tmTaskId').attr('disabled', true); + $('#tmProjectId').attr('disabled', true); + + var setItems = { + 'user_id': loginUserId, + 'activity_id': activity, + 'task_id': task, + 'project_id': project, + 'clockRunning': true + }; + setItemToLocalStorage(setItems); + + entryStartTime = getCurrentTime(); + if (getItemFromLocalStorage('start_time') !== null) { + entryStartTime = getItemFromLocalStorage('start_time'); + } else { + setItemToLocalStorage({'start_time': entryStartTime}); + } + startWatch(); +} + $("#stopTimer").click(function (e) { e.preventDefault(); $(this).attr('disabled', 'true'); @@ -207,7 +216,7 @@ function stopTime() { } function storeTimeEntry() { - let startTime = localStorage.getItem('start_time'); + let startTime = getItemFromLocalStorage('start_time'); let endTime = getCurrentTime(); $.ajax({ @@ -263,13 +272,13 @@ function getCurrentTime(datetime = null) { function setItemToLocalStorage(items) { $.each(items, function (key, value) { - localStorage.setItem(key, value); + localStorage.setItem(key+'_'+loggedInUserId, value); }); } function removeItemsFromLocalStorage(items) { $.each(items, function (index, value) { - localStorage.removeItem(value); + localStorage.removeItem(value+'_'+loggedInUserId); }); } @@ -289,8 +298,8 @@ function loadTimerData(projectId) { $('#tmTaskId').find('option').remove().end().append(''); $('#tmTaskId').val("").trigger('change'); - let drpTaskId = localStorage.getItem('task_id'); - let drpActivityId = localStorage.getItem('activity_id'); + let drpTaskId = getItemFromLocalStorage('task_id'); + let drpActivityId = getItemFromLocalStorage('activity_id'); let isTaskEmpty = true; $(result.data.tasks).each(function (i, e) { $("#tmTaskId").append($('').attr('value', e.id).text(e.title)); @@ -307,7 +316,7 @@ function loadTimerData(projectId) { $("#tmTaskId").removeAttr('disabled'); // if timer is running then set values as it is - if (localStorage.getItem('clockRunning') !== null) { + if (getItemFromLocalStorage('clockRunning') !== null) { $('#tmActivityId').val(drpActivityId).trigger("change"); $('#tmTaskId').val(drpTaskId).trigger("change"); @@ -349,3 +358,7 @@ function getUserLastTaskWork() { } }); } + +function getItemFromLocalStorage(item) { + return localStorage.getItem(item+'_'+loggedInUserId); +} diff --git a/resources/assets/js/users/user.js b/resources/assets/js/users/user.js index 5b7eb0b1a..a6cd92def 100644 --- a/resources/assets/js/users/user.js +++ b/resources/assets/js/users/user.js @@ -11,7 +11,7 @@ $(function () { var tbl = $('#users_table').DataTable({ processing: true, serverSide: true, - "order": [[0, "desc"]], + "order": [[0, "asc"]], ajax: { url: usersUrl, }, diff --git a/resources/views/layouts/app.blade.php b/resources/views/layouts/app.blade.php index d7f9ef740..c675b5982 100644 --- a/resources/views/layouts/app.blade.php +++ b/resources/views/layouts/app.blade.php @@ -45,15 +45,12 @@ {!! Auth::user()->name !!}