Skip to content

Commit

Permalink
feat: add ability to add members to project (#301)
Browse files Browse the repository at this point in the history
  • Loading branch information
djaiss committed Oct 20, 2020
1 parent 913d816 commit dbb0e66
Show file tree
Hide file tree
Showing 23 changed files with 990 additions and 40 deletions.
41 changes: 36 additions & 5 deletions app/Console/Commands/Tests/SetupDummyAccount.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
use App\Services\Company\Employee\Worklog\LogWorklog;
use App\Services\Company\Project\CreateProjectStatus;
use App\Services\Company\Employee\Answer\CreateAnswer;
use App\Services\Company\Project\AddEmployeeToProject;
use App\Services\Company\Employee\Expense\CreateExpense;
use App\Services\Company\Employee\Manager\AssignManager;
use App\Services\Company\Adminland\Company\CreateCompany;
Expand Down Expand Up @@ -1584,7 +1585,7 @@ private function addProjects(): void
{
$this->info('☐ Add projects');

$project = (new CreateProject)->execute([
$infinity = (new CreateProject)->execute([
'company_id' => $this->company->id,
'author_id' => $this->michael->id,
'project_lead_id' => $this->jim->id,
Expand All @@ -1597,13 +1598,13 @@ private function addProjects(): void
(new StartProject)->execute([
'company_id' => $this->company->id,
'author_id' => $this->jim->id,
'project_id' => $project->id,
'project_id' => $infinity->id,
]);

(new CreateProjectLink)->execute([
'company_id' => $this->company->id,
'author_id' => $this->jim->id,
'project_id' => $project->id,
'project_id' => $infinity->id,
'type' => 'url',
'label' => 'Upcoming website',
'url' => 'https://dundermifflin.com/infinity',
Expand All @@ -1612,7 +1613,7 @@ private function addProjects(): void
(new CreateProjectLink)->execute([
'company_id' => $this->company->id,
'author_id' => $this->jim->id,
'project_id' => $project->id,
'project_id' => $infinity->id,
'type' => 'slack',
'label' => 'Slack channel of the project',
'url' => 'https://slack.com/infinity',
Expand All @@ -1621,11 +1622,41 @@ private function addProjects(): void
(new CreateProjectStatus)->execute([
'company_id' => $this->company->id,
'author_id' => $this->jim->id,
'project_id' => $project->id,
'project_id' => $infinity->id,
'status' => ProjectStatus::ON_TRACK,
'title' => 'Phase 2 is completed',
'description' => 'Yes, you have read it right. We have finally finished the second phase of the project, which makes us proud. We are on track with delivering the project at the promised date, and we will let you know how it is going.',
]);

// assign members to the project
(new AddEmployeeToProject)->execute([
'company_id' => $this->company->id,
'author_id' => $this->jim->id,
'project_id' => $infinity->id,
'employee_id' => $this->dwight->id,
'role' => 'Assistant to the project lead',
]);
(new AddEmployeeToProject)->execute([
'company_id' => $this->company->id,
'author_id' => $this->jim->id,
'project_id' => $infinity->id,
'employee_id' => $this->erin->id,
'role' => 'Secretary',
]);
(new AddEmployeeToProject)->execute([
'company_id' => $this->company->id,
'author_id' => $this->jim->id,
'project_id' => $infinity->id,
'employee_id' => $this->oscar->id,
'role' => 'Developer',
]);
(new AddEmployeeToProject)->execute([
'company_id' => $this->company->id,
'author_id' => $this->jim->id,
'project_id' => $infinity->id,
'employee_id' => $this->angela->id,
'role' => 'Developer',
]);
}

private function addSecondaryBlankAccount(): void
Expand Down
146 changes: 146 additions & 0 deletions app/Http/Controllers/Company/Project/ProjectMembersController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
<?php

namespace App\Http\Controllers\Company\Project;

use Carbon\Carbon;
use Inertia\Inertia;
use Inertia\Response;
use App\Helpers\DateHelper;
use Illuminate\Http\Request;
use App\Helpers\InstanceHelper;
use App\Models\Company\Project;
use Illuminate\Http\JsonResponse;
use App\Helpers\NotificationHelper;
use App\Http\Controllers\Controller;
use App\Services\Company\Project\AddEmployeeToProject;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use App\Http\ViewHelpers\Project\ProjectMembersViewHelper;
use App\Services\Company\Project\RemoveEmployeeFromProject;

class ProjectMembersController extends Controller
{
/**
* Display the list of members in the project.
*
* @param Request $request
* @param int $companyId
* @param int $projectId
*/
public function index(Request $request, int $companyId, int $projectId)
{
$company = InstanceHelper::getLoggedCompany();

try {
$project = Project::where('company_id', $company->id)
->with('employees')
->findOrFail($projectId);
} catch (ModelNotFoundException $e) {
return redirect('home');
}

return Inertia::render('Project/Members/Index', [
'tab' => 'members',
'project' => ProjectMembersViewHelper::info($project),
'members' => ProjectMembersViewHelper::members($project),
'notifications' => NotificationHelper::getNotifications(InstanceHelper::getLoggedEmployee()),
]);
}

/**
* Returns all potential members, displayed in the Add member modal.
*
* @param Request $request
* @param int $companyId
* @param int $projectId
* @return JsonResponse
*/
public function search(Request $request, int $companyId, int $projectId): JsonResponse
{
$company = InstanceHelper::getLoggedCompany();

try {
$project = Project::where('company_id', $company->id)
->with('employees')
->findOrFail($projectId);
} catch (ModelNotFoundException $e) {
return redirect('home');
}

$potentialMembers = ProjectMembersViewHelper::potentialMembers($project);

return response()->json([
'data' => $potentialMembers,
], 200);
}

/**
* Add an employee to the project.
*
* @param Request $request
* @param int $companyId
* @param int $projectId
* @return JsonResponse
*/
public function store(Request $request, int $companyId, int $projectId): JsonResponse
{
$loggedEmployee = InstanceHelper::getLoggedEmployee();
$loggedCompany = InstanceHelper::getLoggedCompany();

$data = [
'company_id' => $loggedCompany->id,
'author_id' => $loggedEmployee->id,
'project_id' => $projectId,
'employee_id' => $request->input('employee.value'),
'role' => $request->input('role'),
];

$employee = (new AddEmployeeToProject)->execute($data);

return response()->json([
'data' => [
'id' => $employee->id,
'name' => $employee->name,
'avatar' => $employee->avatar,
'role' => $request->input('role'),
'added_at' => DateHelper::formatDate(Carbon::now()),
'position' => (! $employee->position) ? null : [
'id' => $employee->position->id,
'title' => $employee->position->title,
],
'url' => route('employees.show', [
'company' => $loggedCompany,
'employee' => $employee,
]),
],
], 201);
}

/**
* Remove an employee from the project.
*
* @param Request $request
* @param int $companyId
* @param int $projectId
* @return JsonResponse
*/
public function remove(Request $request, int $companyId, int $projectId): JsonResponse
{
$loggedEmployee = InstanceHelper::getLoggedEmployee();
$loggedCompany = InstanceHelper::getLoggedCompany();

$data = [
'company_id' => $loggedCompany->id,
'author_id' => $loggedEmployee->id,
'project_id' => $projectId,
'employee_id' => $request->input('employee'),
];

(new RemoveEmployeeFromProject)->execute($data);

return response()->json([
'data' => [
'id' => $request->input('employee.value'),
],
], 201);
}
}
108 changes: 108 additions & 0 deletions app/Http/ViewHelpers/Project/ProjectMembersViewHelper.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
<?php

namespace App\Http\ViewHelpers\Project;

use App\Helpers\DateHelper;
use App\Models\Company\Project;

class ProjectMembersViewHelper
{
/**
* Array containing the information all the members in the project, and all
* the roles.
*
* @param Project $project
* @return array
*/
public static function members(Project $project): array
{
$members = $project->employees()
->where('locked', false)
->with('position')
->orderBy('pivot_created_at', 'desc')
->get();

$membersCollection = collect([]);
$roles = collect([]);
foreach ($members as $member) {
$membersCollection->push([
'id' => $member->id,
'name' => $member->name,
'avatar' => $member->avatar,
'role' => $member->pivot->role,
'added_at' => DateHelper::formatDate($member->pivot->created_at),
'position' => (! $member->position) ? null : [
'id' => $member->position->id,
'title' => $member->position->title,
],
'url' => route('employees.show', [
'company' => $project->company_id,
'employee' => $member,
]),
]);

if ($member->pivot->role) {
$roles->push([
'id' => $member->id,
'role' => $member->pivot->role,
]);
}
}

// filter the unique roles in the collection
$roles = $roles->unique('role')->sortBy('role');

return [
'members' => $membersCollection,
'roles' => $roles,
];
}

/**
* Array containing the information about the project itself.
*
* @param Project $project
* @return array
*/
public static function info(Project $project): array
{
return [
'id' => $project->id,
'name' => $project->name,
'code' => $project->code,
'summary' => $project->summary,
];
}

/**
* Returns the potential employees that can be assigned as members.
* This filters out the current members of the project (doh).
* It also contains all the current roles currently used in the project.
*
* @param Project $project
* @return array
*/
public static function potentialMembers(Project $project): array
{
$company = $project->company;
$employees = $company->employees()
->where('locked', false)
->get();

$currentMembers = $project->employees;

$potentialMembers = $employees->diff($currentMembers);

$potentialMembersCollection = collect([]);
foreach ($potentialMembers as $potential) {
$potentialMembersCollection->push([
'value' => $potential->id,
'label' => $potential->name,
]);
}

return [
'potential_members' => $potentialMembersCollection,
];
}
}
5 changes: 4 additions & 1 deletion app/Http/ViewHelpers/Team/TeamShowViewHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,10 @@ public static function employees(Team $team): Collection
*/
public static function recentShips(Team $team): Collection
{
$ships = $team->ships()->with('employees')->take(3)->get();
$ships = $team->ships()->with('employees')
->take(3)
->get();

$shipsCollection = collect([]);
foreach ($ships as $ship) {
$employees = $ship->employees;
Expand Down
2 changes: 1 addition & 1 deletion app/Models/Company/Employee.php
Original file line number Diff line number Diff line change
Expand Up @@ -439,7 +439,7 @@ public function gamesAsPersonToFind()
*/
public function projects()
{
return $this->belongsToMany(Project::class);
return $this->belongsToMany(Project::class)->withTimestamps()->withPivot('role', 'created_at');
}

/**
Expand Down
2 changes: 1 addition & 1 deletion app/Models/Company/Project.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ public function lead()
*/
public function employees()
{
return $this->belongsToMany(Employee::class);
return $this->belongsToMany(Employee::class)->withTimestamps()->withPivot('role', 'created_at');
}

/**
Expand Down

0 comments on commit dbb0e66

Please sign in to comment.