Add ability to edit Vacancies
This commit is contained in:
parent
4b390ea536
commit
bd0664ce0d
|
@ -15,15 +15,12 @@ class HomeController extends Controller
|
|||
*/
|
||||
public function index()
|
||||
{
|
||||
// TODO: Relationships for Applications, Users and Responses
|
||||
// Also prevent apps if user already has one in the space of 30d
|
||||
// Display apps in the relevant menus
|
||||
|
||||
$positions = DB::table('vacancies')
|
||||
->where('vacancyStatus', 'OPEN')
|
||||
->where('vacancyCount', '!=', 0)
|
||||
$positions = Vacancy::where('vacancyStatus', 'OPEN')
|
||||
->where('vacancyCount', '<>', 0)
|
||||
->get();
|
||||
|
||||
|
||||
return view('home')
|
||||
->with('positions', $positions);
|
||||
}
|
||||
|
|
|
@ -3,12 +3,13 @@
|
|||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Http\Requests\VacancyRequest;
|
||||
use App\Http\Requests\VacancyEditRequest;
|
||||
|
||||
use App\Vacancy;
|
||||
use App\User;
|
||||
use App\Form;
|
||||
|
||||
use App\Notifications\VacancyClosed;
|
||||
use GrahamCampbell\Markdown\Facades\Markdown;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Str;
|
||||
|
@ -34,11 +35,16 @@ class VacancyController extends Controller
|
|||
|
||||
if (!is_null($form))
|
||||
{
|
||||
/* note: since we can't convert HTML back to Markdown, we'll have to do the converting when the user requests a page,
|
||||
* and leave the database with Markdown only so it can be used and edited everywhere.
|
||||
* for several vacancies, this would require looping through all of them and replacing MD with HTML, which is obviously not the most clean solution;
|
||||
* however, the Model can be configured to return MD instead of HTML on that specific field saving us from looping.
|
||||
*/
|
||||
Vacancy::create([
|
||||
|
||||
'vacancyName' => $request->vacancyName,
|
||||
'vacancyDescription' => $request->vacancyDescription,
|
||||
'vacancyFullDescription' => Markdown::convertToHTML($request->vacancyFullDescription),
|
||||
'vacancyFullDescription' => $request->vacancyFullDescription,
|
||||
'vacancySlug' => Str::slug($request->vacancyName),
|
||||
'permissionGroupName' => $request->permissionGroup,
|
||||
'discordRoleID' => $request->discordRole,
|
||||
|
@ -105,4 +111,27 @@ class VacancyController extends Controller
|
|||
return redirect()->back();
|
||||
}
|
||||
|
||||
|
||||
public function edit(Request $request, Vacancy $position)
|
||||
{
|
||||
return view('dashboard.administration.editposition')
|
||||
->with('vacancy', $position);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function update(VacancyEditRequest $request, Vacancy $position)
|
||||
{
|
||||
|
||||
$position->vacancyFullDescription = $request->vacancyFullDescription;
|
||||
$position->vacancyDescription = $request->vacancyDescription;
|
||||
$position->vacancyCount = $request->vacancyCount;
|
||||
|
||||
$position->save();
|
||||
|
||||
$request->session()->flash('success', 'Vacancy successfully updated.');
|
||||
return redirect()->back();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
|
||||
class VacancyEditRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return Auth::user()->can('admin.hiring.vacancy.edit');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'vacancyDescription' => 'required|string',
|
||||
'vacancyFullDescription' => 'nullable|string',
|
||||
'vacancyCount' => 'required|integer|min:1'
|
||||
];
|
||||
}
|
||||
}
|
|
@ -6,12 +6,13 @@ use Illuminate\Bus\Queueable;
|
|||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Notifications\Messages\MailMessage;
|
||||
use Illuminate\Notifications\Notification;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
use App\Vacancy;
|
||||
|
||||
class VacancyClosed extends Notification implements ShouldQueue
|
||||
{
|
||||
use Queueable;
|
||||
use Queueable, SerializesModels;
|
||||
|
||||
protected $vacancy;
|
||||
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
<?php
|
||||
|
||||
namespace App\Observers;
|
||||
|
||||
use App\Vacancy;
|
||||
|
||||
|
||||
class VacancyObserver
|
||||
{
|
||||
/**
|
||||
* Handle the vacancy "created" event.
|
||||
*
|
||||
* @param \App\Vacancy $vacancy
|
||||
* @return void
|
||||
*/
|
||||
public function created(Vacancy $vacancy)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the vacancy "updated" event.
|
||||
*
|
||||
* @param \App\Vacancy $vacancy
|
||||
* @return void
|
||||
*/
|
||||
public function updated(Vacancy $vacancy)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the vacancy "deleted" event.
|
||||
*
|
||||
* @param \App\Vacancy $vacancy
|
||||
* @return void
|
||||
*/
|
||||
public function deleted(Vacancy $vacancy)
|
||||
{
|
||||
// TODO: Handle deletion of children's data
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the vacancy "restored" event.
|
||||
*
|
||||
* @param \App\Vacancy $vacancy
|
||||
* @return void
|
||||
*/
|
||||
public function restored(Vacancy $vacancy)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the vacancy "force deleted" event.
|
||||
*
|
||||
* @param \App\Vacancy $vacancy
|
||||
* @return void
|
||||
*/
|
||||
public function forceDeleted(Vacancy $vacancy)
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
|
@ -53,7 +53,7 @@ class VacancyPolicy
|
|||
*/
|
||||
public function update(User $user, Vacancy $vacancy)
|
||||
{
|
||||
return $user->hasRole('admin', 'hiringManager');
|
||||
return $user->hasAnyRole('admin', 'hiringManager');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -6,6 +6,9 @@ use Illuminate\Database\Eloquent\Model;
|
|||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
use GrahamCampbell\Markdown\Facades\Markdown;
|
||||
|
||||
|
||||
class Vacancy extends Model
|
||||
{
|
||||
public $fillable = [
|
||||
|
@ -22,6 +25,26 @@ class Vacancy extends Model
|
|||
|
||||
];
|
||||
|
||||
|
||||
/**
|
||||
* Get the HTML variant of the vacancyFullDescription attribute.
|
||||
*
|
||||
* @param string $value The original value
|
||||
* @return string
|
||||
*/
|
||||
public function getVacancyFullDescriptionAttribute($value)
|
||||
{
|
||||
if (!is_null($value))
|
||||
{
|
||||
return Markdown::convertToHTML($value);
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function forms()
|
||||
{
|
||||
return $this->belongsTo('App\Form', 'vacancyFormID', 'id');
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,155 @@
|
|||
@extends('adminlte::page')
|
||||
|
||||
@section('title', 'Raspberry Network | Edit Positions')
|
||||
|
||||
@section('content_header')
|
||||
|
||||
<h4>Administration / Positions / Edit</h4>
|
||||
|
||||
@stop
|
||||
|
||||
@section('js')
|
||||
|
||||
<x-global-errors>
|
||||
|
||||
</x-global-errors>
|
||||
|
||||
@stop
|
||||
|
||||
|
||||
@section('content')
|
||||
|
||||
|
||||
<div class="row">
|
||||
|
||||
<div class="col center">
|
||||
|
||||
<h3>Vacancy Editor</h3>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div class="row">
|
||||
|
||||
|
||||
<div class="col">
|
||||
|
||||
|
||||
<div class="card">
|
||||
|
||||
|
||||
<div class="card-header">
|
||||
|
||||
<h3 class="card-title"><i class="fas fa-clipboard"></i> {{ $vacancy->vacancyName }}</h3>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div class="card-body">
|
||||
|
||||
<p class="text-muted"><i class="fas fa-question-circle"></i> For consistency purposes, grayed out fields can't be edited.</p>
|
||||
|
||||
<form method="POST" id="editPositionForm" action="{{ route('updatePosition', ['position' => $vacancy->id]) }}">
|
||||
|
||||
@csrf
|
||||
@method('PATCH')
|
||||
|
||||
<div class="row">
|
||||
|
||||
<div class="col">
|
||||
|
||||
|
||||
<label for="vacancyName">Vacancy Name</label>
|
||||
<input type="text" value="{{ $vacancy->vacancyName }}" class="form-control" disabled />
|
||||
|
||||
</div>
|
||||
|
||||
<div class="col">
|
||||
|
||||
<label for="vacancyDescription">Vacancy description</label>
|
||||
<input type="vacancyDescription" class="form-control" name="vacancyDescription" value="{{ $vacancy->vacancyDescription }}" />
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
|
||||
<div class="col">
|
||||
|
||||
<!-- skipping the accessor for obvious reasons -->
|
||||
<label for="vacanyDetails">Vacancy details</label>
|
||||
<textarea name="vacancyFullDescription" class="form-control" placeholder="{{ (is_null($vacancy->vacancyFullDescription)) ? 'No details yet. Add some!' : '' }}" rows="20">{{ $vacancy->getAttributes()['vacancyFullDescription'] }}</textarea>
|
||||
<span class="text-muted"><i class="fab fa-markdown"></i> Markdown supported</span>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
|
||||
<div class="col">
|
||||
|
||||
<label for "permissionGroupName">Permission Group</label>
|
||||
<input type="text" class="form-control" value="{{ $vacancy->permissionGroupName }}" id="permissionGroupName" disabled />
|
||||
|
||||
</div>
|
||||
|
||||
<div class="col">
|
||||
|
||||
<label for "discordRoleID">Discord Role ID</label>
|
||||
<input type="text" class="form-control" value="{{ $vacancy->discordRoleID }}" id="discordRoleID" disabled />
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
|
||||
<div class="col">
|
||||
|
||||
<label for "currentForm">Current Form (uneditable)</label>
|
||||
<input type="text" class="form-control" value="{{ $vacancy->forms->formName }}" id="currentForm" disabled />
|
||||
|
||||
<label for "remainingSlots">Remaining slots</label>
|
||||
<input type="text" class="form-control" value="{{ $vacancy->vacancyCount }}" id="remainingSlots" name="vacancyCount" />
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</form>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="card-footer">
|
||||
|
||||
<button type="button" class="btn btn-warning" onclick="$('#editPositionForm').submit()"><i class="fas fa-edit"></i> Save Changes</button>
|
||||
<button type="button" class="btn btn-danger" onclick="window.location.href='{{ route('showPositions') }}'"><i class="fas fa-times"></i> Cancel</button>
|
||||
|
||||
@if($vacancy->vacancyStatus == 'OPEN')
|
||||
|
||||
<form method="POST" action="{{ route('updatePositionAvailability', ['id' => $vacancy->id, 'status' => 'close']) }}" style="display: inline">
|
||||
@method('PATCH')
|
||||
@csrf
|
||||
<button type="submit" class="ml-4 btn btn-danger"><i class="fas fa-ban"></i> Close Position</button>
|
||||
</form>
|
||||
|
||||
@endif
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
@stop
|
|
@ -34,6 +34,7 @@
|
|||
|
||||
@section('content')
|
||||
|
||||
<!-- todo: switch to modal component -->
|
||||
<div class="modal fade" tabindex="-1" id="newVacancyForm" role="dialog" aria-labelledby="modalFormLabel" aria-hidden="true">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
|
@ -188,12 +189,15 @@
|
|||
@endif
|
||||
<td>{{$vacancy->created_at}}</td>
|
||||
<td>
|
||||
|
||||
<button type="button" class="btn btn-sm btn-warning" onclick="window.location.href='{{ route('editPosition', ['position' => $vacancy->id]) }}'"><i class="fas fa-edit"></i></button>
|
||||
|
||||
@if ($vacancy->vacancyStatus == 'OPEN')
|
||||
|
||||
<form action="{{route('updatePositionAvailability', ['status' => 'close', 'id' => $vacancy->id])}}" method="POST" id="closePosition">
|
||||
@csrf
|
||||
@method('PATCH')
|
||||
<button type="submit" class="btn btn-sm btn-danger"><i class="fa fa-ban"></i> Close</button>
|
||||
<button type="submit" class="btn btn-sm btn-danger"><i class="fa fa-ban"></i></button>
|
||||
</form>
|
||||
|
||||
@else
|
||||
|
@ -201,7 +205,7 @@
|
|||
<form action="{{route('updatePositionAvailability', ['status' => 'open', 'id' => $vacancy->id])}}" method="POST" id="openPosition">
|
||||
@csrf
|
||||
@method('PATCH')
|
||||
<button type="submit" class="btn btn-sm btn-success"><i class="fa fa-check"></i> Open</button>
|
||||
<button type="submit" class="btn btn-sm btn-success"><i class="fa fa-check"></i></button>
|
||||
</form>
|
||||
|
||||
@endif
|
||||
|
|
|
@ -6,9 +6,7 @@
|
|||
|
||||
<!-- todo: details component -->
|
||||
|
||||
|
||||
@foreach($positions as $position)
|
||||
|
||||
<x-modal id="{{ $position->vacancySlug . '-details' }}" modal-label="{{ $position->vacancySlug . '-details-label' }}" modal-title="Opening details" include-close-button="true">
|
||||
|
||||
@if (is_null($position->vacancyFullDescription))
|
||||
|
|
|
@ -168,6 +168,13 @@ Route::group(['middleware' => ['auth', 'forcelogout']], function(){
|
|||
->name('savePosition');
|
||||
|
||||
|
||||
Route::get('positions/edit/{position}', 'VacancyController@edit')
|
||||
->name('editPosition');
|
||||
|
||||
Route::patch('positions/update/{position}', 'VacancyController@update')
|
||||
->name('updatePosition');
|
||||
|
||||
|
||||
Route::patch('positions/availability/{status}/{id}', 'VacancyController@updatePositionAvailability')
|
||||
->name('updatePositionAvailability');
|
||||
|
||||
|
|
Loading…
Reference in New Issue