Intergate api Profiles

This commit is contained in:
Truong Vo 2024-09-18 03:45:26 +07:00
parent d7c7e56fc7
commit cf7c8be280
8 changed files with 111 additions and 72 deletions

View File

@ -3,12 +3,14 @@
namespace Modules\Admin\app\Http\Controllers;
use App\Http\Controllers\Controller;
use App\Services\JiraService;
use App\Traits\AnalyzeData;
use App\Traits\HasFilterRequest;
use App\Traits\HasOrderByRequest;
use App\Traits\HasSearchRequest;
use Illuminate\Http\Request;
use Modules\Admin\app\Models\Sprint;
use Modules\Admin\app\Models\UserCriteria;
class ProfileController extends Controller
{
@ -17,5 +19,58 @@ class ProfileController extends Controller
use HasSearchRequest;
use AnalyzeData;
protected $jiraService;
public function __construct(JiraService $jiraService)
{
$this->jiraService = $jiraService;
}
public function getProfilesData()
{
$user = auth('admins')->user();
$userEmail = $user->email;
$userEmail = "vincent.vo@apactech.io";
$projects = $this->jiraService->getAllProjects();
$userCriterias = UserCriteria::with([
'sprint', // Join với bảng sprint
'criteria', // Join với bảng criteria
])->where('user_email', $userEmail)->get();
// Xử lý dữ liệu thành cấu trúc mong muốn
$projectsData = $userCriterias->groupBy('sprint.project_id')->map(function ($userCriteriasByProject, $projectId) use ($projects) {
$result = self::getProjectById($projects, $projectId);
return [
'name' => $result['name'],
'sprints' => $userCriteriasByProject->groupBy('sprint.id')->map(function ($userCriteriasBySprint, $sprintId) {
$sprint = $userCriteriasBySprint->first()->sprint;
return [
'name' => $sprint->name,
'criterias' => $userCriteriasBySprint->map(function ($userCriteria) {
$criteria = $userCriteria->criteria;
return [
'criteria' => $criteria->name,
'note' => $userCriteria->note ?? '',
'createdBy' => auth('admins')->user()->name ?? '', // Lấy tên user từ auth
'point' => $userCriteria->point ?? '',
];
})
];
})->values()
];
})->values();
// Trả về kết quả
return AbstractController::ResultSuccess($projectsData);
}
public function getProjectById($projects, $inputId)
{
$filteredProjects = array_filter($projects, function ($project) use ($inputId) {
return $project['id'] == $inputId;
});
return array_values($filteredProjects) ? array_values($filteredProjects)[0] : array_values($filteredProjects);
}
}

View File

@ -2,6 +2,7 @@
namespace Modules\Admin\app\Models;
use App\Models\User;
use Illuminate\Database\Eloquent\Model;
class Criteria extends Model

View File

@ -48,4 +48,9 @@ class Sprint extends Model
'criterias.description as criteria_description',
);
}
public function userCriterias()
{
return $this->hasMany(UserCriteria::class);
}
}

View File

@ -21,4 +21,9 @@ class UserCriteria extends Model
{
return $this->belongsTo(Sprint::class);
}
public function criteria()
{
return $this->belongsTo(Criteria::class);
}
}

View File

@ -16,6 +16,7 @@ use Modules\Admin\app\Http\Controllers\TicketController;
use Modules\Admin\app\Http\Controllers\TimekeepingController;
use Modules\Admin\app\Http\Controllers\TrackingController;
use Modules\Admin\app\Http\Controllers\CriteriasController;
use Modules\Admin\app\Http\Controllers\ProfileController;
use Modules\Admin\app\Http\Controllers\TestCaseForSprintController;
use Modules\Admin\app\Http\Middleware\AdminMiddleware;
@ -168,6 +169,9 @@ Route::middleware('api')
Route::get('/test-cases/getAll/{sprintId}', [TestCaseForSprintController::class, 'getAllReportsForSprint'])->middleware('check.permission:admin,tester');
Route::post('/test-cases/{sprintId}', [TestCaseForSprintController::class, 'createTestReport'])->middleware('check.permission:admin,tester');
Route::get('/test-cases/delete', [TestCaseForSprintController::class, 'deleteTestReport'])->middleware('check.permission:admin,tester');
Route::get('/profiles-data', [ProfileController::class, 'getProfilesData']);
});
});
});

View File

@ -70,3 +70,6 @@ export const updateSprintReview = API_URL + 'v1/admin/sprint-review/update'
export const getAllTestCase = API_URL + 'v1/admin/criterias/test-cases/getAll'
export const deleteTestCase = API_URL + 'v1/admin/criterias/test-cases/delete'
export const createTestCase = API_URL + 'v1/admin/criterias/test-cases'
//Profile
export const getProfilesData = API_URL + 'v1/admin/criterias/profiles-data'

View File

@ -1,7 +1,8 @@
import { getProfilesData } from '@/api/Admin'
import { changePassword } from '@/api/Auth'
import PasswordRequirementInput from '@/components/PasswordRequirementInput/PasswordRequirementInput'
import { logout } from '@/rtk/dispatches/auth'
import { post } from '@/rtk/helpers/apiService'
import { get, post } from '@/rtk/helpers/apiService'
import { requirementsPassword } from '@/rtk/helpers/variables'
import { useAppDispatch, useAppSelector } from '@/rtk/hooks'
import {
@ -17,7 +18,7 @@ import {
} from '@mantine/core'
import { notifications } from '@mantine/notifications'
import { IconCornerDownRight, IconPasswordUser } from '@tabler/icons-react'
import { useCallback, useState } from 'react'
import { useCallback, useEffect, useState } from 'react'
import { useNavigate } from 'react-router-dom'
import classes from './Profile.module.css'
@ -62,63 +63,6 @@ const CriteriaTable = ({ data }: { data: TableRow[] }) => (
</Table>
)
const projectsData = [
{
name: 'Project Name 1',
sprints: [
{
name: 'Sprint 1',
criterias: [
{
criteria: 'Criteria 1',
note: 'String (default when selecting point)',
createdBy: 'User 1',
point: '1-5',
},
{
criteria: 'Criteria 2',
note: 'String (default when selecting point)',
createdBy: 'User 2',
point: '1-5',
},
],
},
{
name: 'Sprint 2',
criterias: [
{
criteria: 'Criteria 3',
note: 'String (default when selecting point)',
createdBy: 'User 3',
point: '1-5',
},
{
criteria: 'Criteria 4',
note: 'String (default when selecting point)',
createdBy: 'User 4',
point: '1-5',
},
],
},
],
},
{
name: 'Project Name 2',
sprints: [
{
name: 'Sprint 1',
criterias: [
{
criteria: 'Criteria 7',
note: 'String (default when selecting point)',
createdBy: 'User 7',
point: '1-5',
},
],
},
],
},
]
const isCompactMenu = false
const Profile = () => {
const user = useAppSelector((state) => state.authentication.user)
@ -129,6 +73,7 @@ const Profile = () => {
confirm_password: '',
})
const [loading, setLoading] = useState(false)
const [dataProfile, setDataProfile] = useState<any>([])
// const [projects, setProjects] = useState(projectsData)
const [expandedProjects, setExpandedProjects] = useState<ExpandedProjects>({})
@ -140,10 +85,30 @@ const Profile = () => {
const passwordRegex =
/^(?=.*[A-Z])(?=.*[a-z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/
// const { setColorScheme } = useMantineColorScheme()
// const computedColorScheme = useComputedColorScheme('light', {
// getInitialValueInEffect: true,
// })
const getListProfilesData = async () => {
try {
const params = {}
const res = await get(getProfilesData, params)
if (res.status) {
return res.data
}
} catch (error: any) {
notifications.show({
title: 'Error',
message: error.message ?? error,
color: 'red',
})
}
return []
}
useEffect(() => {
const fetchData = async () => {
const result = await getListProfilesData()
setDataProfile(result ?? [])
}
fetchData()
}, [])
const handleChangePassword = async () => {
try {
@ -231,7 +196,6 @@ const Profile = () => {
},
}))
}
console.log(user, 'user')
return (
<div>
@ -333,7 +297,7 @@ const Profile = () => {
<Box className={classes.projectInvolvement}>
<Title order={3}>Project Involved</Title>
<Box className={classes.project} mt="lg">
{projectsData.map((project) => (
{dataProfile.map((project: any) => (
<div key={project.name}>
{/* Project Header */}
<Box
@ -348,7 +312,7 @@ const Profile = () => {
{/* Project's Sprints */}
{expandedProjects[project.name] && (
<Box className={classes.sprintList}>
{project.sprints.map((sprint) => (
{project.sprints.map((sprint: any) => (
<div key={sprint.name}>
<Box
className={classes.sprintHeader}
@ -371,7 +335,7 @@ const Profile = () => {
<Box className={classes.criteriaTable}>
{/* <CriteriaTable data={sprint.criteria} /> */}
<CriteriaTable
data={sprint.criterias.map((criteria) => ({
data={sprint.criterias.map((criteria: any) => ({
...criteria,
}))}
/>

View File

@ -3,7 +3,7 @@ import {
getAllCriteriasBySprint,
getAllProject,
getAllSprintByIdBoard,
updateSprintReview
updateSprintReview,
} from '@/api/Admin'
import { get } from '@/rtk/helpers/apiService'
import { update } from '@/rtk/helpers/CRUD'
@ -69,7 +69,7 @@ const SprintReview = () => {
})
const [dataProject, setDataProject] = useState<DataProject[]>([])
const [dataSprint, setDataSprint] = useState<DataSprint[]>([])
const [finalPoint, setFinalPoint] = useState('')
const getListDataProject = async () => {
try {
const params = {}
@ -188,6 +188,7 @@ const SprintReview = () => {
if (result) {
setCriteriaSprint(result.criterias ?? [])
setCriteriaUsers(result.users ?? [])
setFinalPoint(result.point ?? '')
setLoading(false)
}
}
@ -478,7 +479,8 @@ const SprintReview = () => {
<Select
data={pointsOptions}
defaultValue={'0'}
value={'0'}
value={finalPoint}
onChange={(value) => setFinalPoint(value ?? '')}
size="xs"
styles={() => ({
input: {