WIP: Road to 1.0.0 #1
|
@ -2,11 +2,14 @@
|
|||
<module type="WEB_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/database/factories" isTestSource="false" packagePrefix="Database\Factories\" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/tests" isTestSource="true" packagePrefix="Tests\" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/database/seeders" isTestSource="false" packagePrefix="Database\Seeders\" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/spec" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/app" isTestSource="false" packagePrefix="App\" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/almasaeed2010/adminlte" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/asm89/stack-cors" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/awssat/discord-notification-channel" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/barryvdh/laravel-debugbar" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/brick/math" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/clue/stream-filter" />
|
||||
|
@ -27,6 +30,7 @@
|
|||
<excludeFolder url="file://$MODULE_DIR$/vendor/filp/whoops" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/fruitcake/laravel-cors" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/fzaninotto/faker" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/graham-campbell/result-type" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/guzzlehttp/guzzle" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/guzzlehttp/promises" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/guzzlehttp/psr7" />
|
||||
|
@ -67,6 +71,7 @@
|
|||
<excludeFolder url="file://$MODULE_DIR$/vendor/phpspec/prophecy" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/php-code-coverage" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/php-file-iterator" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/php-invoker" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/php-text-template" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/php-timer" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/php-token-stream" />
|
||||
|
@ -83,12 +88,16 @@
|
|||
<excludeFolder url="file://$MODULE_DIR$/vendor/ramsey/collection" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/ramsey/uuid" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/scrivo/highlight.php" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/cli-parser" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/code-unit" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/code-unit-reverse-lookup" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/comparator" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/complexity" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/diff" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/environment" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/exporter" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/global-state" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/lines-of-code" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/object-enumerator" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/object-reflector" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/recursion-context" />
|
||||
|
@ -107,6 +116,8 @@
|
|||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/event-dispatcher" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/event-dispatcher-contracts" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/finder" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/http-client" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/http-client-contracts" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/http-foundation" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/http-kernel" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/mime" />
|
||||
|
|
|
@ -142,9 +142,18 @@
|
|||
<path value="$PROJECT_DIR$/vendor/league/mime-type-detection" />
|
||||
<path value="$PROJECT_DIR$/vendor/mcamara/laravel-localization" />
|
||||
<path value="$PROJECT_DIR$/vendor/mpociot/teamwork" />
|
||||
<path value="$PROJECT_DIR$/vendor/sebastian/code-unit" />
|
||||
<path value="$PROJECT_DIR$/vendor/sebastian/cli-parser" />
|
||||
<path value="$PROJECT_DIR$/vendor/sebastian/complexity" />
|
||||
<path value="$PROJECT_DIR$/vendor/sebastian/lines-of-code" />
|
||||
<path value="$PROJECT_DIR$/vendor/graham-campbell/result-type" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/http-client" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/http-client-contracts" />
|
||||
<path value="$PROJECT_DIR$/vendor/phpunit/php-invoker" />
|
||||
<path value="$PROJECT_DIR$/vendor/awssat/discord-notification-channel" />
|
||||
</include_path>
|
||||
</component>
|
||||
<component name="PhpProjectSharedConfiguration" php_language_level="7.2" />
|
||||
<component name="PhpProjectSharedConfiguration" php_language_level="7.3" />
|
||||
<component name="PhpUnit">
|
||||
<phpunit_settings>
|
||||
<PhpUnitSettings configuration_file_path="$PROJECT_DIR$/phpunit.xml" custom_loader_path="$PROJECT_DIR$/vendor/autoload.php" use_configuration_file="true" />
|
||||
|
|
|
@ -16,6 +16,7 @@ use Mpociot\Teamwork\Exceptions\UserNotInTeamException;
|
|||
use Mpociot\Teamwork\Facades\Teamwork;
|
||||
use Mpociot\Teamwork\TeamInvite;
|
||||
|
||||
|
||||
class TeamController extends Controller
|
||||
{
|
||||
/**
|
||||
|
@ -82,7 +83,7 @@ class TeamController extends Controller
|
|||
return view('dashboard.teams.edit-team')
|
||||
->with('team', $team)
|
||||
->with('users', User::all())
|
||||
->with('vacancies', Vacancy::all());
|
||||
->with('vacancies', Vacancy::with('teams')->get()->all());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -115,7 +116,7 @@ class TeamController extends Controller
|
|||
}
|
||||
|
||||
public function invite(SendInviteRequest $request, Team $team)
|
||||
{
|
||||
{
|
||||
$user = User::findOrFail($request->user);
|
||||
|
||||
if (!$team->openJoin)
|
||||
|
@ -126,29 +127,29 @@ class TeamController extends Controller
|
|||
Teamwork::inviteToTeam($user, $team, function(TeamInvite $invite) use ($user) {
|
||||
Mail::to($user)->send(new InviteToTeam($invite));
|
||||
});
|
||||
|
||||
|
||||
$request->session()->flash('success', 'Invite sent! They can now accept or deny it.');
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
$request->session()->flash('error', 'This user has already been invited.');
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
$request->session()->flash('error', 'You can\'t invite users to public teams.');
|
||||
}
|
||||
|
||||
return redirect()->back();
|
||||
return redirect()->back();
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function processInviteAction(Request $request, $action, $token)
|
||||
{
|
||||
|
||||
|
||||
switch($action)
|
||||
{
|
||||
case 'accept':
|
||||
|
@ -168,7 +169,7 @@ class TeamController extends Controller
|
|||
break;
|
||||
|
||||
case 'deny':
|
||||
|
||||
|
||||
$invite = Teamwork::getInviteFromDenyToken($token);
|
||||
|
||||
if ($invite && $invite->user->is(Auth::user()))
|
||||
|
@ -182,10 +183,10 @@ class TeamController extends Controller
|
|||
}
|
||||
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
$request->session()->flash('error', 'Sorry, but the invite URL you followed was malformed. Try asking for another invite, or submit a bug report.');
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
@ -209,4 +210,53 @@ class TeamController extends Controller
|
|||
|
||||
return redirect()->back();
|
||||
}
|
||||
|
||||
|
||||
// Since it's a separate form, we shouldn't use the same update method
|
||||
public function assignVacancies(Request $request, Team $team)
|
||||
{
|
||||
// P.S. To future developers
|
||||
// This method gave me a lot of trouble lol. It's hard to write code when you're half asleep.
|
||||
// There may be an n+1 query in the view and I don't think there's a way to avoid that without writing a lot of extra code.
|
||||
|
||||
$requestVacancies = $request->assocVacancies;
|
||||
$currentVacancies = $team->vacancies->pluck('id')->all();
|
||||
|
||||
if (is_null($requestVacancies))
|
||||
{
|
||||
|
||||
foreach ($team->vacancies as $vacancy)
|
||||
{
|
||||
$team->vacancies()->detach($vacancy->id);
|
||||
}
|
||||
|
||||
$request->session()->flash('success', 'Removed all vacancy associations.');
|
||||
return redirect()->back();
|
||||
}
|
||||
|
||||
$vacancyDiff = array_diff($requestVacancies, $currentVacancies);
|
||||
$deselectedDiff = array_diff($currentVacancies, $requestVacancies);
|
||||
|
||||
|
||||
if (!empty($vacancyDiff) || !empty($deselectedDiff))
|
||||
{
|
||||
foreach ($vacancyDiff as $selectedVacancy)
|
||||
{
|
||||
$team->vacancies()->attach($selectedVacancy);
|
||||
}
|
||||
|
||||
foreach ($deselectedDiff as $deselectedVacancy)
|
||||
{
|
||||
$team->vacancies()->detach($deselectedVacancy);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$team->vacancies()->attach($requestVacancies);
|
||||
}
|
||||
|
||||
$request->session()->flash('success', 'Assignments changed successfully.');
|
||||
return redirect()->back();
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -80,4 +80,32 @@ class Vacancy extends Model
|
|||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if the Modal is attached to the $checkingTeam Model
|
||||
*
|
||||
* @param Team $checkingTeam The mdoel you want to check against
|
||||
* @return boolean Whether the models are attached
|
||||
*/
|
||||
public function hasTeam(Team $checkingTeam): bool
|
||||
{
|
||||
$myTeams = $this->teams;
|
||||
|
||||
if (empty($myTeams))
|
||||
{
|
||||
// no associated teams
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach($myTeams as $team)
|
||||
{
|
||||
if ($team->id === $checkingTeam->id)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
"ext-imagick": "*",
|
||||
"ext-json": "*",
|
||||
"arcanedev/log-viewer": "^8.0",
|
||||
"awssat/discord-notification-channel": "^1.4",
|
||||
"doctrine/dbal": "^2.10",
|
||||
"fideloper/proxy": "^4.2",
|
||||
"fruitcake/laravel-cors": "^1.0",
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "db269f8f20690fd92cc9b51dbbca3fc5",
|
||||
"content-hash": "b91b3c69e28100abbffdb9bb256025fd",
|
||||
"packages": [
|
||||
{
|
||||
"name": "almasaeed2010/adminlte",
|
||||
|
@ -225,6 +225,61 @@
|
|||
],
|
||||
"time": "2019-12-24T22:41:47+00:00"
|
||||
},
|
||||
{
|
||||
"name": "awssat/discord-notification-channel",
|
||||
"version": "1.4.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/awssat/discord-notification-channel.git",
|
||||
"reference": "514df4bb5db48f624658240d6b1f9b8ee468a46f"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/awssat/discord-notification-channel/zipball/514df4bb5db48f624658240d6b1f9b8ee468a46f",
|
||||
"reference": "514df4bb5db48f624658240d6b1f9b8ee468a46f",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"guzzlehttp/guzzle": "^6.0|^7.0",
|
||||
"illuminate/notifications": "~5.8.0|^6.0|^7.0|^8.0",
|
||||
"laravel/slack-notification-channel": "^2.0",
|
||||
"php": "^7.1.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"mockery/mockery": "^1.0",
|
||||
"phpunit/phpunit": "^7.0|^8.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"Awssat\\Notifications\\DiscordChannelServiceProvider"
|
||||
]
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Awssat\\Notifications\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Bader Almutairi",
|
||||
"email": "phpfalcon@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "Discord Notification Channel for laravel.",
|
||||
"keywords": [
|
||||
"discord",
|
||||
"laravel",
|
||||
"notifications"
|
||||
],
|
||||
"time": "2020-09-09T20:42:43+00:00"
|
||||
},
|
||||
{
|
||||
"name": "bacon/bacon-qr-code",
|
||||
"version": "2.0.2",
|
||||
|
|
|
@ -60,13 +60,13 @@
|
|||
<tbody>
|
||||
|
||||
@foreach ($team->users as $teammate)
|
||||
|
||||
|
||||
<tr>
|
||||
<td>{{ $teammate->id }}</td>
|
||||
<td><a target="_blank" href="{{ route('showSingleProfile', ['user' => $teammate->id]) }}">{{ $teammate->name }}</a></td>
|
||||
<td>
|
||||
@foreach ($teammate->roles as $teammate_role)
|
||||
|
||||
|
||||
<span class="badge badge-secondary">{{ $teammate_role->name }}</span>
|
||||
|
||||
@endforeach
|
||||
|
@ -123,21 +123,21 @@
|
|||
</div>
|
||||
|
||||
<div class="card-body">
|
||||
|
||||
|
||||
<form id="editTeam" method="POST" action="{{ route('teams.update', ['team' => $team->id]) }}">
|
||||
|
||||
@csrf
|
||||
@method('PATCH')
|
||||
|
||||
<div class="form-group">
|
||||
|
||||
|
||||
<label for="teamName">Team name</label>
|
||||
<input type="text" class="form-control" id="teamName" value="{{ $team->name }}" disabled>
|
||||
|
||||
|
||||
<label for="teamDescription">Team description</label>
|
||||
<textarea class="form-control" rows="4" name="teamDescription" id="teamDescription">{{ $team->description }}</textarea>
|
||||
<span class="text-left text-muted text-sm"><a href="https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet"><i class="fab fa-markdown"></i></a> Markdown supported</span>
|
||||
|
||||
|
||||
<div class="controlbuttons mt-3">
|
||||
|
||||
<span rel="spanTxtTooltip" data-toggle="tooltip" title="This setting controls whether people can join the team freely." data-placement="top">
|
||||
|
@ -147,11 +147,11 @@
|
|||
|
||||
<button onclick="$('#addUserModal').modal('show')" type="button" id="inviteUser" name="inviteUser" class="btn btn-success" {{ ($team->openJoin) ? 'disabled' : '' }}><i class="fas fa-user-plus"></i> Invite user</button>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</form>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div class="card-footer">
|
||||
|
@ -176,14 +176,18 @@
|
|||
<div class="card-body">
|
||||
|
||||
<span class="text-muted"><i class="fas fa-info-circle"></i> The vacancies you select determine what applications your team members see. All applications under the vacancies you choose will be displayed.</span>
|
||||
|
||||
<form>
|
||||
|
||||
<select id="assocVacancies" name="assocVacancies" multiple="multiple">
|
||||
<form method="POST" id="vacancyChangeForm" action="{{ route('assignVacancies', ['team' => $team->id]) }}">
|
||||
|
||||
@csrf
|
||||
@method('PATCH')
|
||||
|
||||
<select id="assocVacancies" name="assocVacancies[]" multiple="multiple">
|
||||
|
||||
@foreach($vacancies as $vacancy)
|
||||
|
||||
<option value="{{ $vacancy->id }}">{{ $vacancy->vacancyName }}</option>
|
||||
<!-- fixme: n+1 query here -->
|
||||
<option {{ ($vacancy->hasTeam($team)) ? 'selected' : '' }} value="{{ $vacancy->id }}">{{ $vacancy->vacancyName }}</option>
|
||||
|
||||
@endforeach
|
||||
|
||||
|
@ -193,6 +197,12 @@
|
|||
|
||||
</div>
|
||||
|
||||
<div class="card-footer">
|
||||
|
||||
<button onclick="$('#vacancyChangeForm').submit()" type="button" class="btn btn-success"><i class="far fa-save"></i> Update Assignments</button>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
@ -200,4 +210,4 @@
|
|||
|
||||
</div>
|
||||
|
||||
@stop
|
||||
@stop
|
||||
|
|
|
@ -60,22 +60,24 @@ Route::group(['prefix' => LaravelLocalization::setLocale(), 'middleware' => [ 'l
|
|||
->name('directory');
|
||||
|
||||
|
||||
|
||||
Route::resource('teams', TeamController::class);
|
||||
|
||||
|
||||
Route::post('teams/{team}/invites/send', [TeamController::class, 'invite'])
|
||||
Route::post('teams/{team}/invites/send', [TeamController::class, 'invite'])
|
||||
->name('sendInvite');
|
||||
|
||||
Route::get('teams/{team}/switch', [TeamController::class, 'switchTeam'])
|
||||
Route::get('teams/{team}/switch', [TeamController::class, 'switchTeam'])
|
||||
->name('switchTeam');
|
||||
|
||||
Route::patch('teams/{team}/vacancies/update', [TeamController::class, 'assignVacancies'])
|
||||
->name('assignVacancies');
|
||||
|
||||
|
||||
Route::get('teams/invites/{action}/{token}', [TeamController::class, 'processInviteAction'])
|
||||
->name('processInvite');
|
||||
|
||||
|
||||
// WARNING: This is a resource, might not work under laravel 8.
|
||||
Route::resource('teams', TeamController::class);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Route::group(['prefix' => '/applications'], function (){
|
||||
|
||||
|
@ -251,7 +253,7 @@ Route::group(['prefix' => LaravelLocalization::setLocale(), 'middleware' => [ 'l
|
|||
Route::delete('forms/destroy/{form}', [FormController::class, 'destroy'])
|
||||
->name('destroyForm');
|
||||
|
||||
Route::get('forms', [FormController::class, 'showFormBuilder'])
|
||||
Route::get('forms', [FormController::class, 'index'])
|
||||
->name('showForms');
|
||||
|
||||
Route::get('forms/preview/{form}', [FormController::class, 'preview'])
|
||||
|
|
Loading…
Reference in New Issue