Intergate api Profiles
This commit is contained in:
parent
d7c7e56fc7
commit
cf7c8be280
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace Modules\Admin\app\Models;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Criteria extends Model
|
||||
|
|
|
|||
|
|
@ -48,4 +48,9 @@ class Sprint extends Model
|
|||
'criterias.description as criteria_description',
|
||||
);
|
||||
}
|
||||
|
||||
public function userCriterias()
|
||||
{
|
||||
return $this->hasMany(UserCriteria::class);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,4 +21,9 @@ class UserCriteria extends Model
|
|||
{
|
||||
return $this->belongsTo(Sprint::class);
|
||||
}
|
||||
|
||||
public function criteria()
|
||||
{
|
||||
return $this->belongsTo(Criteria::class);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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']);
|
||||
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -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'
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
}))}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -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: {
|
||||
|
|
|
|||
Loading…
Reference in New Issue