update doing
This commit is contained in:
		
							parent
							
								
									cfe9ee5da9
								
							
						
					
					
						commit
						8c06526757
					
				| 
						 | 
					@ -246,4 +246,18 @@ class JiraController extends Controller
 | 
				
			||||||
        // dd($tasksByUser);
 | 
					        // dd($tasksByUser);
 | 
				
			||||||
        return $tasksByUser;
 | 
					        return $tasksByUser;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function getAllUserDoing(Request $request)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            $doing = $this->jiraService->getAllUserDoing();
 | 
				
			||||||
 | 
					            return response()->json([
 | 
				
			||||||
 | 
					                'data' => $doing,
 | 
				
			||||||
 | 
					                'status' => true
 | 
				
			||||||
 | 
					            ], 200);
 | 
				
			||||||
 | 
					        } catch (\Exception $e) {
 | 
				
			||||||
 | 
					            return response()->json(['error' => $e->getMessage()], 500);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -149,6 +149,7 @@ class TimekeepingController extends Controller
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return response()->json(['status' => true, 'message' => 'Add successfully']);
 | 
					        return response()->json(['status' => true, 'message' => 'Add successfully']);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function updateCacheMonth(Request $request)
 | 
					    public function updateCacheMonth(Request $request)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -103,6 +103,7 @@ Route::middleware('api')
 | 
				
			||||||
                Route::get('/all-project', [JiraController::class, 'getAllProject']);
 | 
					                Route::get('/all-project', [JiraController::class, 'getAllProject']);
 | 
				
			||||||
                Route::get('/all-issue-by-project', [JiraController::class, 'fetchIssuesByProject']);
 | 
					                Route::get('/all-issue-by-project', [JiraController::class, 'fetchIssuesByProject']);
 | 
				
			||||||
                Route::get('/worklogs', [JiraController::class, 'getAllUserWorkLogs'])->middleware('check.permission:admin.staff');
 | 
					                Route::get('/worklogs', [JiraController::class, 'getAllUserWorkLogs'])->middleware('check.permission:admin.staff');
 | 
				
			||||||
 | 
					                Route::get('/allocation', [JiraController::class, 'getAllUserDoing'])->middleware('check.permission:admin.staff');
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            Route::group([
 | 
					            Route::group([
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -73,7 +73,7 @@ class JiraService
 | 
				
			||||||
            'expand' => ['names', 'schema', 'operations'],
 | 
					            'expand' => ['names', 'schema', 'operations'],
 | 
				
			||||||
            'fields' => ['summary', 'status', 'timeoriginalestimate', 'timespent', 'assignee', 'project'],
 | 
					            'fields' => ['summary', 'status', 'timeoriginalestimate', 'timespent', 'assignee', 'project'],
 | 
				
			||||||
            'jql' => sprintf(
 | 
					            'jql' => sprintf(
 | 
				
			||||||
                "assignee = '%s' AND status IN ('backlog', 'todo', 'in progress')",
 | 
					                "assignee = '%s' AND status IN ('backlog', 'to do', 'in progress')",
 | 
				
			||||||
                $accountId
 | 
					                $accountId
 | 
				
			||||||
            ),
 | 
					            ),
 | 
				
			||||||
            'maxResults' => 50,
 | 
					            'maxResults' => 50,
 | 
				
			||||||
| 
						 | 
					@ -188,4 +188,64 @@ class JiraService
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return $workLogs;
 | 
					        return $workLogs;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function getAllUserDoing()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $users = $this->getAllUsers();
 | 
				
			||||||
 | 
					        // $projects = $this->getAllProjects();
 | 
				
			||||||
 | 
					        $groupedIssues = [];
 | 
				
			||||||
 | 
					        $users_data = [];
 | 
				
			||||||
 | 
					        foreach ($users as $user) {
 | 
				
			||||||
 | 
					            $users_data[$user['displayName']]['user'] = $user; 
 | 
				
			||||||
 | 
					            $users_data[$user['displayName']]['total_spent'] = 0; 
 | 
				
			||||||
 | 
					            $users_data[$user['displayName']]['total_est'] = 0; 
 | 
				
			||||||
 | 
					            $body = [
 | 
				
			||||||
 | 
					                'expand' => ['names', 'schema'],
 | 
				
			||||||
 | 
					                'fields' => ['summary', 'status', 'timeoriginalestimate', 'timespent', 'assignee', 'project'],
 | 
				
			||||||
 | 
					                'jql' => sprintf(
 | 
				
			||||||
 | 
					                    "assignee = '%s' AND status IN ('to do', 'in progress')",
 | 
				
			||||||
 | 
					                    $user['accountId']
 | 
				
			||||||
 | 
					                ),
 | 
				
			||||||
 | 
					                'maxResults' => 50,
 | 
				
			||||||
 | 
					                'startAt' => 0
 | 
				
			||||||
 | 
					            ];
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					            $response = $this->client->post('/rest/api/3/search', [
 | 
				
			||||||
 | 
					                'body' => json_encode($body)
 | 
				
			||||||
 | 
					            ]);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					            $issues = json_decode($response->getBody()->getContents(), true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            foreach ($issues['issues'] as $issue) {
 | 
				
			||||||
 | 
					                $projectName = $issue['fields']['project']['name'];
 | 
				
			||||||
 | 
					                $username = $issue['fields']['assignee']['displayName'];
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					                if (!isset($groupedIssues[$projectName])) {
 | 
				
			||||||
 | 
					                    $groupedIssues[$projectName] = [];
 | 
				
			||||||
 | 
					                    $groupedIssues[$projectName]['project'] = $issue['fields']['project'];
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (!isset($groupedIssues[$projectName]['users'][$username])) {
 | 
				
			||||||
 | 
					                    $groupedIssues[$projectName]['users'][$username] = [];
 | 
				
			||||||
 | 
					                    $groupedIssues[$projectName]['users'][$username]['user'] = $issue['fields']['assignee'];
 | 
				
			||||||
 | 
					                    $groupedIssues[$projectName]['users'][$username]['p_total_spent'] = 0;
 | 
				
			||||||
 | 
					                    $groupedIssues[$projectName]['users'][$username]['p_total_est'] = 0;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					                $groupedIssues[$projectName]['users'][$username]['issues'][] = $issue;
 | 
				
			||||||
 | 
					                $groupedIssues[$projectName]['users'][$username]['p_total_spent'] = $groupedIssues[$projectName]['users'][$username]['p_total_spent'] + $issue['fields']['timespent'];
 | 
				
			||||||
 | 
					                $groupedIssues[$projectName]['users'][$username]['p_total_est'] = $groupedIssues[$projectName]['users'][$username]['p_total_est'] + ($issue['fields']['timeoriginalestimate'] ?? 0);
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                $users_data[$user['displayName']]['total_spent'] = $users_data[$user['displayName']]['total_spent'] + $issue['fields']['timespent'];
 | 
				
			||||||
 | 
					                $users_data[$user['displayName']]['total_est'] = $users_data[$user['displayName']]['total_est'] + ($issue['fields']['timeoriginalestimate'] ?? 0); 
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return ['projects' => $groupedIssues, 'users' => $users_data];
 | 
				
			||||||
 | 
					        // return $projects;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,28 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use Illuminate\Database\Migrations\Migration;
 | 
				
			||||||
 | 
					use Illuminate\Database\Schema\Blueprint;
 | 
				
			||||||
 | 
					use Illuminate\Support\Facades\Schema;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					return new class extends Migration
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Run the migrations.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function up(): void
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        Schema::table('users', function (Blueprint $table) {
 | 
				
			||||||
 | 
					            $table->string('avatar');
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Reverse the migrations.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function down(): void
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        Schema::table('users', function (Blueprint $table) {
 | 
				
			||||||
 | 
					            $table->dropColumn('avatar');
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
| 
						 | 
					@ -14,6 +14,7 @@ export const exportIssues = API_URL + 'v1/admin/jira/export-issues'
 | 
				
			||||||
export const getAllProjects = API_URL + 'v1/admin/jira/all-project'
 | 
					export const getAllProjects = API_URL + 'v1/admin/jira/all-project'
 | 
				
			||||||
export const getAllIssuesByProject = API_URL + 'v1/admin/jira/all-issue-by-project'
 | 
					export const getAllIssuesByProject = API_URL + 'v1/admin/jira/all-issue-by-project'
 | 
				
			||||||
export const getAllUserWorklogs = API_URL + 'v1/admin/jira/worklogs'
 | 
					export const getAllUserWorklogs = API_URL + 'v1/admin/jira/worklogs'
 | 
				
			||||||
 | 
					export const getAllUserDoing = API_URL + 'v1/admin/jira/allocation'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//Timekeeping
 | 
					//Timekeeping
 | 
				
			||||||
export const getTheTimesheet = API_URL + 'v1/admin/timekeeping'
 | 
					export const getTheTimesheet = API_URL + 'v1/admin/timekeeping'
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -20,11 +20,13 @@ import {
 | 
				
			||||||
} from '@mantine/core'
 | 
					} from '@mantine/core'
 | 
				
			||||||
import { notifications } from '@mantine/notifications'
 | 
					import { notifications } from '@mantine/notifications'
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
 | 
					  IconBinaryTree2,
 | 
				
			||||||
  IconCalendar,
 | 
					  IconCalendar,
 | 
				
			||||||
  IconCalendarClock,
 | 
					  IconCalendarClock,
 | 
				
			||||||
  IconDevices,
 | 
					  IconDevices,
 | 
				
			||||||
  IconLayoutSidebarLeftExpand,
 | 
					  IconLayoutSidebarLeftExpand,
 | 
				
			||||||
  IconLayoutSidebarRightExpand,
 | 
					  IconLayoutSidebarRightExpand,
 | 
				
			||||||
 | 
					  IconListCheck,
 | 
				
			||||||
  IconLogout,
 | 
					  IconLogout,
 | 
				
			||||||
  // IconMail,
 | 
					  // IconMail,
 | 
				
			||||||
  IconMoon,
 | 
					  IconMoon,
 | 
				
			||||||
| 
						 | 
					@ -35,13 +37,12 @@ import {
 | 
				
			||||||
  IconSun,
 | 
					  IconSun,
 | 
				
			||||||
  IconTicket,
 | 
					  IconTicket,
 | 
				
			||||||
  IconUsersGroup,
 | 
					  IconUsersGroup,
 | 
				
			||||||
  IconZoomExclamation,
 | 
					  IconZoomExclamation
 | 
				
			||||||
} from '@tabler/icons-react'
 | 
					} from '@tabler/icons-react'
 | 
				
			||||||
import { useCallback, useEffect, useState } from 'react'
 | 
					import { useCallback, useEffect, useState } from 'react'
 | 
				
			||||||
import { useLocation, useNavigate } from 'react-router-dom'
 | 
					import { useLocation, useNavigate } from 'react-router-dom'
 | 
				
			||||||
import PasswordRequirementInput from '../PasswordRequirementInput/PasswordRequirementInput'
 | 
					import PasswordRequirementInput from '../PasswordRequirementInput/PasswordRequirementInput'
 | 
				
			||||||
import classes from './NavbarSimpleColored.module.css'
 | 
					import classes from './NavbarSimpleColored.module.css'
 | 
				
			||||||
import { IconListCheck } from '@tabler/icons-react'
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
const data = [
 | 
					const data = [
 | 
				
			||||||
  // { link: '/dashboard', label: 'Dashboard', icon: IconHome },
 | 
					  // { link: '/dashboard', label: 'Dashboard', icon: IconHome },
 | 
				
			||||||
| 
						 | 
					@ -94,6 +95,12 @@ const data = [
 | 
				
			||||||
    icon: IconZoomExclamation,
 | 
					    icon: IconZoomExclamation,
 | 
				
			||||||
    group: 'admin',
 | 
					    group: 'admin',
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    link: '/allocation',
 | 
				
			||||||
 | 
					    label: 'Personnel allocation',
 | 
				
			||||||
 | 
					    icon: IconBinaryTree2,
 | 
				
			||||||
 | 
					    group: 'admin',
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
  // { link: '/jira', label: 'Jira', icon: IconSubtask },
 | 
					  // { link: '/jira', label: 'Jira', icon: IconSubtask },
 | 
				
			||||||
  // { link: '/custom-theme', label: 'Custom Theme', icon: IconBrush },
 | 
					  // { link: '/custom-theme', label: 'Custom Theme', icon: IconBrush },
 | 
				
			||||||
  // { link: '/general-setting', label: 'General Setting', icon: IconSettings },
 | 
					  // { link: '/general-setting', label: 'General Setting', icon: IconSettings },
 | 
				
			||||||
| 
						 | 
					@ -400,7 +407,7 @@ const Navbar = ({
 | 
				
			||||||
            </span>
 | 
					            </span>
 | 
				
			||||||
          </a>
 | 
					          </a>
 | 
				
			||||||
          <div className={classes.footer}></div>
 | 
					          <div className={classes.footer}></div>
 | 
				
			||||||
          <a href="#" className={classes.link} onClick={handleSetCompactMenu}>
 | 
					          <a href="#" className={classes.link} onClick={handleSetCompactMenu} style={{margin:"0 20px", padding:"0 0 10px 0"}}>
 | 
				
			||||||
            {isCompactMenu ? (
 | 
					            {isCompactMenu ? (
 | 
				
			||||||
              <IconLayoutSidebarLeftExpand
 | 
					              <IconLayoutSidebarLeftExpand
 | 
				
			||||||
                className={classes.linkIcon}
 | 
					                className={classes.linkIcon}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -48,7 +48,7 @@
 | 
				
			||||||
  font-size: var(--mantine-font-size-sm);
 | 
					  font-size: var(--mantine-font-size-sm);
 | 
				
			||||||
  color: rgb(161, 161, 161);
 | 
					  color: rgb(161, 161, 161);
 | 
				
			||||||
  padding: var(--mantine-spacing-xs) var(--mantine-spacing-sm);
 | 
					  padding: var(--mantine-spacing-xs) var(--mantine-spacing-sm);
 | 
				
			||||||
  margin: var(--mantine-spacing-xs);
 | 
					  margin: 0 var(--mantine-spacing-xs);
 | 
				
			||||||
  border-radius: var(--mantine-radius-sm);
 | 
					  border-radius: var(--mantine-radius-sm);
 | 
				
			||||||
  font-weight: 500;
 | 
					  font-weight: 500;
 | 
				
			||||||
  cursor: pointer;
 | 
					  cursor: pointer;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| 
						 | 
					@ -2,6 +2,7 @@
 | 
				
			||||||
import ResetPassword from '@/components/Authentication/ResetPassword'
 | 
					import ResetPassword from '@/components/Authentication/ResetPassword'
 | 
				
			||||||
import BasePage from '@/components/BasePage/BasePage'
 | 
					import BasePage from '@/components/BasePage/BasePage'
 | 
				
			||||||
import ProtectedRoute from '@/components/ProtectedRoute/ProtectedRoute'
 | 
					import ProtectedRoute from '@/components/ProtectedRoute/ProtectedRoute'
 | 
				
			||||||
 | 
					import Allocation from '@/pages/Allocation/Allocation'
 | 
				
			||||||
import PageLogin from '@/pages/Auth/Login/Login'
 | 
					import PageLogin from '@/pages/Auth/Login/Login'
 | 
				
			||||||
import LeaveManagement from '@/pages/LeaveManagement/LeaveManagement'
 | 
					import LeaveManagement from '@/pages/LeaveManagement/LeaveManagement'
 | 
				
			||||||
import PageNotFound from '@/pages/NotFound/NotFound'
 | 
					import PageNotFound from '@/pages/NotFound/NotFound'
 | 
				
			||||||
| 
						 | 
					@ -174,6 +175,20 @@ const mainRoutes = [
 | 
				
			||||||
      </ProtectedRoute>
 | 
					      </ProtectedRoute>
 | 
				
			||||||
    ),
 | 
					    ),
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    path: '/allocation',
 | 
				
			||||||
 | 
					    element: (
 | 
				
			||||||
 | 
					      <ProtectedRoute mode="route" permission="admin">
 | 
				
			||||||
 | 
					        <BasePage
 | 
				
			||||||
 | 
					          main={
 | 
				
			||||||
 | 
					            <>
 | 
				
			||||||
 | 
					              <Allocation />
 | 
				
			||||||
 | 
					            </>
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        ></BasePage>
 | 
				
			||||||
 | 
					      </ProtectedRoute>
 | 
				
			||||||
 | 
					    ),
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
  // {
 | 
					  // {
 | 
				
			||||||
  //   path: '/packages',
 | 
					  //   path: '/packages',
 | 
				
			||||||
  //   element: (
 | 
					  //   element: (
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue