Merge branch 'trunk'

This commit is contained in:
Olivier Legat 2022-03-15 17:36:00 +01:00
commit 3c770e173c
12 changed files with 50 additions and 905 deletions

View file

@ -1,3 +1,12 @@
### 15.03.2022
- le presse-papier du planning n'est plus vidé après un collage
### 08.03.2022 -> 1.08
- passage à 8 slots dans le planning
### 03.01.2022 -> 1.0.7
- nouveau stockage pour le planning
### 01.12 -> 1.0.6
- Ajout d'un nouveau type de Ticket : Demande relative aux Newsletters

View file

@ -1,65 +0,0 @@
<?php
namespace App\Http\Controllers;
use App\Enums\Role;
use App\Http\Requests\EraseCellContentRequest;
use App\Http\Requests\SetCellContentRequest;
use App\Models\User;
use App\Models\WeekPlanning;
use Illuminate\Http\Request;
use Illuminate\Support\Carbon;
class PlanningController extends Controller
{
public function index(Request $request)
{
$date = Carbon::now()->startOfWeek();
if ($request->p) {
$date = Carbon::createFromTimestamp($request->p)->startOfWeek();
}
$userIds = User::where('role', Role::developper())->pluck('id');
$weeks = WeekPlanning::whereDate('start', $date)
->with('user')->get();
foreach ($userIds as $id) {
// auto create missing planning for user
if ($date >= Carbon::now()->startOfWeek() and !$weeks->contains('user.id', $id)) {
$wp = new WeekPlanning([
'start' => $date,
'planning' => WeekPlanning::getWeekBlock($date),
'user_id' => $id
]);
$wp->saveOrFail();
$weeks->push($wp);
}
}
return view('planning.index', compact('weeks', 'date'));
}
public function setCellContent(SetCellContentRequest $request)
{
$wp = WeekPlanning::findOrFail($request->id);
if (!isset($wp->planning[$request->day][$request->row])) {
abort(422, trans('Ce jour et ce moment n\'existent pas.'));
}
$planning = $wp->planning;
$planning[$request->day][$request->row] =
array_merge(WeekPlanning::getCell(), array_intersect_key($request->all(), WeekPlanning::getCell()));
$wp->planning = $planning;
$wp->saveOrFail();
return \response()->json(['status' => true]);
}
public function eraseCellContent(EraseCellContentRequest $request)
{
$wp = WeekPlanning::findOrFail($request->id);
if (!isset($wp->planning[$request->day][$request->row])) {
abort(422, trans('Ce jour et ce moment n\'existent pas.'));
}
$planning = $wp->planning;
$planning[$request->day][$request->row] = WeekPlanning::getCell();
$wp->planning = $planning;
$wp->saveOrFail();
return \response()->json(['status' => true]);
}
}

View file

@ -72,7 +72,7 @@ class TicketController extends Controller
});
$tickets = $tickets->where('is_internal', 0);
}
$tickets = $tickets->where('status', ($request->status == TicketStatus::archived()) ?
$tickets = $tickets->where('status', ($request->st == TicketStatus::archived()) ?
'=' : '<>', TicketStatus::archived());
if ($request->search) {
$tickets = $this->searchTicket($tickets, $request);

View file

@ -1,61 +0,0 @@
<?php
namespace App\Models;
use App\Enums\Planning\TableRow;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Carbon;
class WeekPlanning extends Model
{
use HasFactory;
public $casts = [
'start' => 'date',
'planning' => 'array'
];
protected $fillable = [
'start', 'planning', 'user_id'
];
public static function getWeekBlock(Carbon $start): array
{
$start = $start->copy();
$out = [];
$daysOfWeek = 5;
for ($i = 1; $i <= $daysOfWeek; $i++) {
$out[$start->timestamp] = [];
foreach (TableRow::toArray() as $tableRow) {
$out[$start->timestamp][$tableRow->value] = \array_replace(
self::getCell(),
[
'row' => $tableRow->value
]
);
}
$day = $start->addDay();
}
return $out;
}
public static function getCell(): array
{
return [
/** @var \App\Enums\Planning\CellType */
'type' => null,
/** @var \App\Enums\Planning\TableRow */
'row' => null,
'foreign' => null,
/** @var \App\Enums\Planning\CellModel */
'cellModel' => null,
'text' => ''
];
}
public function user()
{
return $this->belongsTo(User::class);
}
}

View file

@ -1,6 +1,6 @@
{
"name": "ldcweb/supportweb",
"version": "1.0.6",
"version": "1.0.8",
"type": "project",
"description": "The Laravel Framework.",
"keywords": [

View file

@ -1,76 +0,0 @@
<?php
namespace Database\Factories;
use App\Enums\Planning\CellModel;
use App\Enums\Planning\CellType;
use App\Models\Project;
use App\Models\Site;
use App\Models\Ticket;
use App\Models\WeekPlanning;
use Illuminate\Database\Eloquent\Factories\Factory;
use ReflectionFunction;
class WeekPlanningFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* @var string
*/
protected $model = WeekPlanning::class;
/** @var \Illuminate\Support\Carbon */
private static $currentDate = null;
private static $user_id = null;
/**
* Define the model's default state.
*
* @return array
*/
public function definition()
{
$func = new ReflectionFunction(collect($this->states)->last());
if (static::$user_id and $func->getStaticVariables()['state']['user_id'] != static::$user_id) {
static::$currentDate = null;
}
if (!static::$currentDate) {
static::$user_id = $func->getStaticVariables()['state']['user_id'];
static::$currentDate = $func->getStaticVariables()['state']['start'];
} else {
static::$currentDate = static::$currentDate->endOfWeek()->addDay();
}
$wBlock = WeekPlanning::getWeekBlock(static::$currentDate);
foreach ($wBlock as &$dayRows) {
foreach ($dayRows as &$cell) {
$cell['type'] = collect(CellType::toArray())->random()->value;
if (rand(0, 3)) {
$cellModel = collect(CellModel::toArray())->random();
$cell['cellModel'] = $cellModel->value;
switch ($cellModel) {
case (new Ticket())->getTable():
$cell['foreign'] = Ticket::select(['id'])
->inRandomOrder()->first()->id;
break;
case (new Site())->getTable():
$cell['foreign'] = Site::select(['id'])
->inRandomOrder()->first()->id;
break;
case (new Project())->getTable():
$cell['foreign'] = Project::select(['id'])
->inRandomOrder()->first()->id;
break;
}
$cell['text'] = $this->faker->text(rand(20, 50));
}
}
}
return [
'start' => static::$currentDate,
'planning' => $wBlock
];
}
}

View file

@ -0,0 +1,37 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class DropWeekPlanningsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::dropIfExists('week_plannings');
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::create('week_plannings', function (Blueprint $table) {
$table->id();
$table->date('start');
$table->text('planning');
$table->foreignId('user_id')->constrained('users')->cascadeOnDelete();
$table->timestamps();
});
}
}

View file

@ -1,582 +0,0 @@
<template>
<div class="planning">
<table v-if="currentWeek" class="table table-bordered align-middle text-center">
<thead>
<tr>
<th rowspan="2">
<b>{{ currentWeek.user.name }}</b>
</th>
<th :colspan="daysOfWeek">
<span class="fs-5">S{{ moment(currentWeek.start).week() }}</span>
<span class="float-end me-5 mt-1">{{ moment(currentWeek.start).format('MMMM YYYY') }}</span>
</th>
</tr>
</thead>
<tbody>
<tr>
<td></td>
<td v-for="(day, timestamp) in currentWeek.planning"
:key="timestamp">
<b>{{ moment.unix(timestamp).format("dddd DD") }}</b>
</td>
</tr>
<tr v-for="row in rows" :key="row.value">
<td><b>{{ row.label }}</b></td>
<template v-for="(day, timestamp) in currentWeek.planning">
<td :key="timestamp" class="dynCell" :style="'background-color:' + day[row.value]['type'] + ';'">
<b v-if="day[row.value]['cellModel']">
<a target="_blank" class="text-light bg-dark"
:href="getCellObjectInfo(day[row.value]).url">{{ getCellObjectInfo(day[row.value]).text }}</a>
</b>
<span v-else-if="!day[row.value]['text'].length">Rien</span><br>
{{ day[row.value]["text"] | str_limit(25) }}
<button class="btn btn-edit" type="button" data-bs-toggle="modal"
:data-bs-target="'#editModal'+currentWeek.id" @click="setModalData(timestamp, row)">✎</button>
<button :class="'btn btn-paste '+(!clipBoard.week ? 'hide' : '') " type="button"
@click="pasteCell(timestamp, row)">📋</button>
<button class="btn btn-copy" type="button"
@click="copyCell(timestamp, row)">
<span style="font-size: .875em; margin-right: .125em; position: relative; top: -.25em; left: -.125em">
📄<span style="position: absolute; top: .25em; left: .25em">📄</span>
</span></button>
<button class="btn btn-clear" @click="eraseCell(timestamp, row)">⌫</button>
</td>
</template>
</tr>
</tbody>
</table>
<!-- Modal -->
<div v-if="currentWeek" class="modal fade" :id="'editModal'+currentWeek.id" tabindex="-1" :aria-labelledby="'modalLabel'+currentWeek.id" aria-hidden="true" >
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" :id="'modalLabel'+currentWeek.id" ref="modalLabel">Modal title</h5>
<button ref="close" type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close" ></button>
</div>
<div class="modal-body">
<div class="container">
<div class="row justify-content-center">
<div v-if="error" class="alert alert-danger" role="alert">
{{ error }}
</div>
<div class="col-8">
<div class="form-group mb-3">
<label :for="'type'+currentWeek.id" class="col-form-label text-md-right ms-5">Categorie</label>
<select :id="'type'+currentWeek.id" ref="type" class="form-select" aria-label="Sélectionnez une catégorie">
<option value="" :selected="!currentType">Sélectionnez une catégorie</option>
<option v-for="type in types" :key="type.value" :value="type.value"
:selected="type.value === currentType"
:style="'background-color:'+ type.value+';'">{{ type.label }}</option>
</select>
</div>
<div class="form-group mb-3">
<label :for="'morph'+currentWeek.id" class="col-form-label text-md-right ms-5">Type d'élément lié</label>
<select :id="'morph'+currentWeek.id" ref="morph" class="form-select" @change="selectChange" aria-label="Sélectionnez un élément à lier">
<option value="" :selected="!currentModel">Sélectionnez un élément à lier</option>
<option v-for="model in models" :key="model.value" :selected="model.value === currentModel" :value="model.value">{{ model.label }}</option>
</select>
</div>
<div class="form-group mb-3" v-if="dDisplay">
<label :for="'select'+currentWeek.id" class="col-form-label text-md-right ms-5">Élément lié</label>
<v-select
:id="'select'+currentWeek.id"
ref="select"
:loading="loading"
v-model="value"
:clearable="false"
label="label"
:options='data'
@search="search"
:disabled="dReadonly||dDisabled"
:filterable="true"
:searchable="true">
<li slot="list-footer" class="pagination">
<button
@click="$event.preventDefault(); page -= 1"
:disabled="!hasPrevPage"
class="btn btn-sm btn-primary mt-2 mb-2 ms-2 me-2">Précédent</button>
<button
@click="$event.preventDefault(); page += 1"
:disabled="!hasNextPage"
class="btn btn-sm btn-primary mt-2 mb-2">Suivant</button>
</li>
</v-select>
</div>
<div class="form-group mb-3">
<label :for="'text'+currentWeek.id" class="col-form-label text-md-right ms-5">Description courte</label>
<textarea ref="text" class="form-control" name="text"
:id="'text'+currentWeek.id" rows="2" placeholder="" @keydown="limitLines($event)" ></textarea>
</div>
</div>
</div>
<div class="row justify-content-center">
<div class="col-8 text-center">
<button class="btn btn-primary me-3" @click="saveCell()">Valider</button>
<button class="btn btn-danger" @click="$refs.close.click()">Fermer</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import Toastify from 'toastify-js'
export default {
mounted() {
window.Toastify = Toastify
this.models = this.dbModels
this.types = this.dbTypes
this.rows = this.dbRows
this.$set(this, 'currentWeek', this.dbCurrentWeek)
this.search(false)
},
props: ["dbModels", "dbTypes", "dbRows", "dbCurrentWeek"],
data() {
return {
clipBoard: {
week: null,
timestamp: null,
row: null
},
textLimit: 90,
daysOfWeek: 5,
types: [],
rows: [],
models: [],
currentWeek: null,
currentTimestamp: null,
currentRow: null,
currentModel: null,
currentType: null,
error: false,
// v-select
dDisplay : false,
dDisabled : false,
dReadonly : false,
value: {
label: null,
value: null
},
loading: false,
searchText: '',
data: [],
page: 1,
perPage: 15,
hasNextPage: true,
hasPrevPage: false
};
},
watch: {
dbRows() {
this.rows = this.dbRows;
},
dbTypes() {
this.types = this.dbTypes;
},
dbModels() {
this.models = this.dbModels;
},
dbCurrentWeek() {
this.currentWeek = this.dbCurrentWeek;
},
page() {
if(this.page < 1) {
this.page = 1
}
if(this.page > 1) {
this.hasPrevPage = true
} else {
this.hasPrevPage = false
}
this.search()
},
data() {
if(this.data.length == this.perPage) {
this.hasNextPage = true
} else {
this.hasNextPage = false
}
}
},
methods: {
sendToast(message) {
Toastify({
text: message,
duration: 3000,
gravity: "top",
position: "right",
offset: {
x: '2rem',
y: '3rem'
},
style: {
background: "linear-gradient(to right, #00317d, #0058ca)",
}
}).showToast();
},
clearClipBoard() {
this.clipBoard = {
week: null,
timestamp: null,
row: null
}
},
copyCell(timestamp, row) {
this.clipBoard = {
week: this.currentWeek.id,
timestamp: timestamp,
row: row
}
this.sendToast('Cellule copiée')
},
pasteCell(timestamp, row) {
const cell = this.currentWeek.planning[this.clipBoard.timestamp][this.clipBoard.row.value]
const data = {
'id': this.clipBoard.week,
'day': timestamp,
'type': cell.type,
'row': row.value,
'cellModel': cell.cellModel,
'foreign': cell.foreign,
'text': cell.text,
}
if(!data.text.length) {
this.eraseCell(timestamp, row)
return;
}
this.saveCellOnServer(timestamp, row.value, data)
this.clearClipBoard()
this.sendToast('Cellule collée')
},
eraseCell(timestamp, row) {
this.clearClipBoard()
this.setModalData(timestamp, row)
const data = {
'id': this.currentWeek.id,
'day': this.currentTimestamp,
'row': this.currentRow.value,
}
axios.post(this.route('planning.eraseCellContent'), data)
.then(response => {
if(response.data.status) {
this.$set(this.currentWeek.planning[this.currentTimestamp], this.currentRow.value, {
'type': '',
'foreign': null,
'cellModel': null,
'text': '',
})
} else {
console.error('Unknown response')
}
})
.catch(error => {
if(error.response.status === 429) {
location.reload()
}
console.error(error)
})
},
saveCell() {
this.error = false
const data = {
'id': this.currentWeek.id,
'day': this.currentTimestamp,
'type': this.$refs.type.value,
'row': this.currentRow.value,
'cellModel': this.$refs.morph.value,
'foreign': this.value.value,
'text': this.$refs.text.value,
}
this.saveCellOnServer(this.currentTimestamp, this.currentRow.value, data)
},
saveCellOnServer(timestamp, row, data) {
this.error = false
axios.post(this.route('planning.setCellContent'), data)
.then(response => {
if(response.data.status) {
console.log(this.currentWeek.planning[timestamp])
console.log(row)
this.$set(this.currentWeek.planning[timestamp], row, {
'type': data['type'],
'foreign': data['foreign'],
'cellModel': data['cellModel'],
'text': data['text'],
})
this.$refs.close.click()
} else {
this.error = 'Réponse inconnue';
}
})
.catch(error => {
if(error.response.status === 429) {
location.reload()
}
if(error.response.status === 422) {
if(error.response.data.errors) {
this.error = ''
for(let id in error.response.data.errors) {
let field = error.response.data.errors[id]
this.error += field.join('\n') + '\n'
}
return
} else if(error.response.data.message) {
this.error = error.response.data.message
return
}
}
this.error = error
})
},
selectChange() {
this.value = {
label: null,
value: null
}
switch(this.$refs.morph.value) {
case 'tickets':
case 'projects':
case 'sites':
this.dDisplay = true
this.search()
break
default: this.dDisplay = false
}
},
resetModalFields() {
this.$set(this, 'currentType' , null)
this.$set(this, 'value' , {
label: null,
value: null
})
this.$refs.type.value = ''
this.$refs.morph.value = ''
},
search (search = null) {
this.$nextTick(() => {
this.error = null
let route;
switch(this.$refs.morph.value) {
case 'tickets':
route = this.route('ticket.index')
break
case 'projects':
route = this.route('projects.index')
break
case 'sites':
route = this.route('sites.index')
break
default: return
}
if(search !== false && search !== null) {
this.searchText = search
}
let init = search === false ? true : false
route += '?page='+this.page
route += '&s='+this.searchText
this.loading = true
axios.get(route)
.then(response => {
this.data = response.data
})
.catch(error => {
if(error.response.status === 429) {
location.reload()
}
this.error = error
}).then(() => {
this.loading = false
})
});
},
getModel(cellModelValue) {
for (let model of this.models) {
if (model.value === cellModelValue) {
return model;
}
}
throw new Error("Unknown cell model value " + cellModelValue);
},
getCellObjectInfo(cellData) {
for(let model of this.models) {
if(cellData['cellModel'] === model.value && model.value == 'tickets') {
return {
'url': this.route('ticket.show', { TICKET: cellData['foreign']}),
'text': this.getModel(cellData["cellModel"]).label
}
}
if(cellData['cellModel'] === model.value && model.value == 'sites') {
return {
'url': this.route('sites.show', { SITE: cellData['foreign']}),
'text': this.getModel(cellData["cellModel"]).label
}
}
if(cellData['cellModel'] === model.value && model.value == 'projects') {
return {
'url': this.route('projects.show', { PROJECT: cellData['foreign']}),
'text': this.getModel(cellData["cellModel"]).label
}
}
}
return null
},
setModalData(timestamp, row) {
this.currentTimestamp = timestamp
this.currentRow = row
this.currentType = this.currentWeek.planning[this.currentTimestamp][this.currentRow.value].type
this.currentModel = this.currentWeek.planning[this.currentTimestamp][this.currentRow.value].cellModel
let cellData = this.currentWeek.planning[timestamp][row.value]
this.$refs.modalLabel.innerHTML = 'Jour : <u>' +
this.moment.unix(timestamp).format("dddd, D MMMM YYYY")+ '</u>' +
'&nbsp;&nbsp;&nbsp;&nbsp;<b>' + row.label + '<b/>';
this.$refs.text.value = cellData.text
this.$nextTick(() => {
let route = null
this.resetModalFields()
switch(this.currentModel) {
case 'tickets':
this.dDisplay = true
route = this.route('ticket.show', {
TICKET: this.currentWeek.planning[this.currentTimestamp][this.currentRow.value].foreign
})
break
case 'projects':
this.dDisplay = true
route = this.route('projects.show', {
PROJECT: this.currentWeek.planning[this.currentTimestamp][this.currentRow.value].foreign
})
break
case 'sites':
this.dDisplay = true
route = this.route('sites.show', {
SITE: this.currentWeek.planning[this.currentTimestamp][this.currentRow.value].foreign
})
break
default: this.dDisplay = false
}
})
},
limitLines(e) {
let keynum, lines = this.$refs.text.value.split('\n').length;
// IE
if(window.event) {
keynum = e.keyCode;
// Netscape/Firefox/Opera
} else if(e.which) {
keynum = e.which;
}
if(keynum != 8 && this.$refs.text.value.length >= this.textLimit) {
e.preventDefault()
return false;
}
if(keynum == 13 && lines == this.$refs.text.rows) {
e.preventDefault()
return false;
}
}
}
};
</script>
<style lang="scss">
@import "toastify-js/src/toastify.css";
@import "vue-select/src/scss/vue-select.scss";
.planning {
overflow: auto;
td {
height: 50px;
}
#text {
height: 5.5rem;
padding: 1rem 2rem;
resize: none;
width: 37rem;
margin: 0 auto;
}
.dynCell {
position: relative;
&:hover .btn {
opacity: 1;
}
$buttonBgColor: #4d4d4d;
// Reset button Style to nice one
button {
display: inline;
border: none;
padding: 0.6rem 3rem;
margin: 0;
text-decoration: none;
background: $buttonBgColor;
font-size: 1rem;
cursor: pointer;
text-align: center;
transition: background 250ms ease-in-out, transform 150ms ease;
-webkit-appearance: none;
-moz-appearance: none;
}
button:disabled,
button[disabled] {
color: #aaa;
}
button:hover,
button:focus {
background: darken($buttonBgColor, 10%);
}
button:focus {
outline: 1px solid #fff;
outline-offset: -4px;
}
button:active {
transform: scale(0.99);
}
.btn {
position: absolute;
top: 0.1rem;
right: 0.1rem;
padding: 0;
width: 1.8rem;
height: 1.8rem;
margin: 0;
background-color: $buttonBgColor;
opacity: 0;
transition: 200ms opacity;
&.hide {
opacity: 0 !important;
}
&:hover,
&:focus {
background-color: darken($buttonBgColor, 10%);
}
&.btn-clear {
color: darken($color: #fff, $amount: 5);
}
&:nth-last-child(2) {
right: inherit;
left: 0.1rem;
}
&:nth-last-child(3) {
right: inherit;
top: 2.1rem;
left: 0.1rem;
}
&:nth-last-child(1) {
top: 2.1rem;
right: 0.1rem;
}
}
}
}
</style>

View file

@ -1,68 +0,0 @@
<template>
<div class="plannings">
<div class="row justify-content-center">
<div class="col-1 text-center">
<button class="sticky-top btn btn-primary mt-5" @click="goToPlanning(false)">←</button>
</div>
<div class="col-10" v-if="weeks.length">
<template v-for="week in weeks">
<planning-component
:key="week.id"
:db-current-week='week'
:db-models='models'
:db-types='types'
:db-rows='rows'></planning-component>
</template>
</div>
<div v-else class="col-10">
<h3>Pas de planning à afficher</h3>
</div>
<div class="col-1 text-center">
<button class="sticky-top btn btn-primary mt-5" @click="goToPlanning(true)">→</button>
</div>
</div>
</div>
</template>
<script>
export default {
mounted() {
this.weeks = JSON.parse(this.dbWeeks);
this.models = JSON.parse(this.dbModels);
this.types = JSON.parse(this.dbTypes);
this.rows = JSON.parse(this.dbRows);
this.currentDate = JSON.parse(this.browseDate);
},
props: ["browseDate", "dbWeeks", "dbModels", "dbTypes", "dbRows"],
data() {
return {
currentDate: null,
types: [],
rows: [],
models: [],
weeks: []
};
},
watch: {
},
methods: {
goToPlanning(forward) {
let date = this.moment(this.currentDate).startOf('week').subtract(1, 'day');
if(forward) {
date = this.moment(this.currentDate).endOf('week').add(1, 'day')
}
let url = new URL(this.route('planning.index'))
location = url.origin+ url.pathname + '?p='+date.unix()
}
}
};
</script>
<style lang="scss">
@import "vue-select/src/scss/vue-select.scss";
.plannings {
.sticky-top {
top: 20rem !important;
}
}
</style>

View file

@ -467,7 +467,8 @@ export default {
'description': this.clipBoard.description,
}
this.saveCellOnServer(data)
this.clearClipBoard()
//do not clear clipboard
//this.clearClipBoard()
this.sendToast('Cellule collée')
},
clearClipBoard() {

View file

@ -1,41 +0,0 @@
@extends('layout.app')
@section('content')
<div id="planning" class="container container-xxl vueComponent">
<div class="row mb-3 sticky-top bg-white">
<div class="col-2">
<h1><a href="{{ route('planning.index') }}">{{__('Planning') }}</a></h1>
</div>
<div class="col pt-2">
<h4 class="d-inline me-3">Légende</h4>
<div class="d-inline">
@foreach(CellType::toArray() as $type)
<span style="background-color: {{ $type->value }}; border: 1px solid black;">{{ $type->label }}</span>
@endforeach
</div>
</div>
</div>
<plannings-component
browse-date='@json($date)'
db-weeks='@json($weeks)'
db-models='@json(CellModel::toArray())'
db-types='@json(CellType::toArray())'
db-rows='@json(TableRow::toArray())'></plannings-component>
</div>
@endsection
@push('scriptsConstants')
<script>
window._routes = {
"planning.index": "{{ route('planning.index') }}",
"ticket.show": "{{ route('ticket.show', 'TICKET') }}",
"projects.show": "{{ route('projects.show', 'PROJECT') }}",
"sites.show": "{{ route('sites.show', 'SITE') }}",
"ticket.index": "{{ route('ticket.index') }}",
"projects.index": "{{ route('projects.index') }}",
"sites.index": "{{ route('sites.index') }}",
"planning.setCellContent": "{{ route('planning.setCellContent') }}",
"planning.eraseCellContent": "{{ route('planning.eraseCellContent') }}"
};
</script>
@endpush

View file

@ -3,7 +3,6 @@
use App\Http\Controllers\FileController;
use App\Http\Controllers\HomeController;
use App\Http\Controllers\LogController;
use App\Http\Controllers\PlanningController;
use App\Http\Controllers\ProjectController;
use App\Http\Controllers\ScheduleController;
use App\Http\Controllers\SiteController;
@ -77,14 +76,6 @@ Route::middleware(['auth'])->group(function () {
->name('message.create');
});
// Route::prefix('/planning')->name('planning.')->group(function () {
// Route::get('/', [PlanningController::class, 'index'])->name('index');
// Route::post('/setCellContent', [PlanningController::class, 'setCellContent'])
// ->name('setCellContent');
// Route::post('/eraseCellContent', [PlanningController::class, 'eraseCellContent'])
// ->name('eraseCellContent');
// });
Route::prefix('/schedule')->name('schedule.')->group(function () {
Route::get('/', [ScheduleController::class, 'index'])->name('index');
Route::post('/setCellContent', [ScheduleController::class, 'setCellContent'])