svg
This commit is contained in:
@ -30,3 +30,35 @@ $(document).ready(function () {
|
|||||||
}, 0);
|
}, 0);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$(document).ready(function () {
|
||||||
|
$('.select2').select2({
|
||||||
|
theme: 'bootstrap-5',
|
||||||
|
templateResult: function (data) {
|
||||||
|
if (!data.id) return data.text;
|
||||||
|
|
||||||
|
const $result = $('<span>').text(data.text);
|
||||||
|
|
||||||
|
const customClass = $(data.element).attr('class');
|
||||||
|
if (customClass) {
|
||||||
|
$result.addClass(customClass);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
},
|
||||||
|
templateSelection: function (data) {
|
||||||
|
if (!data.id) return data.text;
|
||||||
|
|
||||||
|
const $selection = $('<span>').text(data.text);
|
||||||
|
|
||||||
|
const customClass = $(data.element).attr('class');
|
||||||
|
if (customClass) {
|
||||||
|
$selection.addClass(customClass);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $selection;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
193
public/lib/app/selbg.css
Normal file
193
public/lib/app/selbg.css
Normal file
@ -0,0 +1,193 @@
|
|||||||
|
/* ==== DARK THEMES ==== */
|
||||||
|
|
||||||
|
.selbg-darkblue {
|
||||||
|
background-color: #0d6efd;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selbg-darkindigo {
|
||||||
|
background-color: #6610f2;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selbg-darkpurple {
|
||||||
|
background-color: #6f42c1;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selbg-darkpink {
|
||||||
|
background-color: #d63384;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selbg-darkred {
|
||||||
|
background-color: #dc3545;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selbg-darkorange {
|
||||||
|
background-color: #fd7e14;
|
||||||
|
color: #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selbg-darkyellow {
|
||||||
|
background-color: #ffc107;
|
||||||
|
color: #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selbg-darkgreen {
|
||||||
|
background-color: #198754;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selbg-darkteal {
|
||||||
|
background-color: #20c997;
|
||||||
|
color: #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selbg-darkcyan {
|
||||||
|
background-color: #0dcaf0;
|
||||||
|
color: #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selbg-darkgray {
|
||||||
|
background-color: #343a40;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selbg-darkbrown {
|
||||||
|
background-color: #5c4033;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selbg-darknavy {
|
||||||
|
background-color: #001f3f;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selbg-darkmaroon {
|
||||||
|
background-color: #800000;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selbg-darkolive {
|
||||||
|
background-color: #3d9970;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selbg-darksteel {
|
||||||
|
background-color: #2f4f4f;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selbg-darkcharcoal {
|
||||||
|
background-color: #222222;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selbg-darksmoke {
|
||||||
|
background-color: #555555;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selbg-darkforest {
|
||||||
|
background-color: #228B22;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selbg-darkmidnight {
|
||||||
|
background-color: #191970;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ==== LIGHT THEMES ==== */
|
||||||
|
|
||||||
|
.selbg-lightblue {
|
||||||
|
background-color: #cfe2ff;
|
||||||
|
color: #084298;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selbg-lightindigo {
|
||||||
|
background-color: #e0ccff;
|
||||||
|
color: #52057f;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selbg-lightpurple {
|
||||||
|
background-color: #e2d9f3;
|
||||||
|
color: #4c287b;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selbg-lightpink {
|
||||||
|
background-color: #f7d6e6;
|
||||||
|
color: #6f042e;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selbg-lightred {
|
||||||
|
background-color: #f8d7da;
|
||||||
|
color: #842029;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selbg-lightorange {
|
||||||
|
background-color: #ffe5b4;
|
||||||
|
color: #7f3f00;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selbg-lightyellow {
|
||||||
|
background-color: #fff3cd;
|
||||||
|
color: #664d03;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selbg-lightgreen {
|
||||||
|
background-color: #d1e7dd;
|
||||||
|
color: #0f5132;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selbg-lightteal {
|
||||||
|
background-color: #d2f4ea;
|
||||||
|
color: #0f625d;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selbg-lightcyan {
|
||||||
|
background-color: #cff4fc;
|
||||||
|
color: #055160;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selbg-lightgray {
|
||||||
|
background-color: #f8f9fa;
|
||||||
|
color: #212529;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selbg-lightlinen {
|
||||||
|
background-color: #faf0e6;
|
||||||
|
color: #333333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selbg-lightbeige {
|
||||||
|
background-color: #f5f5dc;
|
||||||
|
color: #222222;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selbg-lightmint {
|
||||||
|
background-color: #e6fff5;
|
||||||
|
color: #225e4c;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selbg-lightlavender {
|
||||||
|
background-color: #e6e6fa;
|
||||||
|
color: #3f3f7f;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selbg-lightsky {
|
||||||
|
background-color: #e0f7ff;
|
||||||
|
color: #004466;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selbg-lightrose {
|
||||||
|
background-color: #ffe0e9;
|
||||||
|
color: #75002f;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selbg-lightice {
|
||||||
|
background-color: #f0ffff;
|
||||||
|
color: #003b4d;
|
||||||
|
}
|
@ -2,8 +2,10 @@
|
|||||||
|
|
||||||
namespace App\Controller;
|
namespace App\Controller;
|
||||||
|
|
||||||
|
use App\Form\IssueType;
|
||||||
use App\Repository\IssueRepository;
|
use App\Repository\IssueRepository;
|
||||||
use App\Service\RedmineService;
|
use App\Service\RedmineService;
|
||||||
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
use Symfony\Component\HttpFoundation\File\Exception\AccessDeniedException;
|
use Symfony\Component\HttpFoundation\File\Exception\AccessDeniedException;
|
||||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||||
@ -37,6 +39,36 @@ class IssueController extends AbstractController
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[Route('/user/issue/update/{id}', name: 'app_issue_update')]
|
||||||
|
public function updateIssue(int $id, Request $request, IssueRepository $issueRepository, EntityManagerInterface $em): Response
|
||||||
|
{
|
||||||
|
$issue = $issueRepository->find($id);
|
||||||
|
if (!$issue) {
|
||||||
|
throw new NotFoundHttpException('La ressource demandée est introuvable.');
|
||||||
|
}
|
||||||
|
if (!$issue->getProject()->getUsers()->contains($this->getUser())) {
|
||||||
|
throw new AccessDeniedException('Vous n\'avez pas accès à cette ressource.');
|
||||||
|
}
|
||||||
|
|
||||||
|
$form = $this->createForm(IssueType::class, $issue, ['mode' => 'update']);
|
||||||
|
$form->handleRequest($request);
|
||||||
|
if ($form->isSubmitted() && $form->isValid()) {
|
||||||
|
$em->flush();
|
||||||
|
// return $this->redirectToRoute('app_admin_project');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->render('issue/edit.html.twig', [
|
||||||
|
'usemenu' => true,
|
||||||
|
'usesidebar' => true,
|
||||||
|
'title' => $issue->getRedmine()['subject'],
|
||||||
|
'routecancel' => 'app_admin_project',
|
||||||
|
'routedelete' => 'app_admin_project_delete',
|
||||||
|
'mode' => 'update',
|
||||||
|
'form' => $form,
|
||||||
|
'issue' => $issue,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
#[Route('/user/issue/order/{id}', name: 'app_issue_order', methods: ['POST'])]
|
#[Route('/user/issue/order/{id}', name: 'app_issue_order', methods: ['POST'])]
|
||||||
public function orderIssue(int $id, Request $request, IssueRepository $issueRepository): JsonResponse
|
public function orderIssue(int $id, Request $request, IssueRepository $issueRepository): JsonResponse
|
||||||
{
|
{
|
||||||
@ -77,13 +109,9 @@ class IssueController extends AbstractController
|
|||||||
];
|
];
|
||||||
$this->redmineService->updateIssue($id, $payload, $this->getUser()->getApikey());
|
$this->redmineService->updateIssue($id, $payload, $this->getUser()->getApikey());
|
||||||
} catch (\RuntimeException $e) {
|
} catch (\RuntimeException $e) {
|
||||||
// Récupère le message de l'exception
|
return new JsonResponse(['message' => $e->getMessage()], 400);
|
||||||
$errorMessage = $e->getMessage();
|
|
||||||
dump($e->getMessage());
|
|
||||||
|
|
||||||
// Par exemple, retour JSON d'erreur :
|
|
||||||
return new JsonResponse(['message' => $errorMessage], 400);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
$payload =
|
$payload =
|
||||||
[
|
[
|
||||||
|
@ -30,6 +30,9 @@ class Issue
|
|||||||
#[ORM\Column(nullable: false)]
|
#[ORM\Column(nullable: false)]
|
||||||
private int $rowissue = 0;
|
private int $rowissue = 0;
|
||||||
|
|
||||||
|
#[ORM\Column(nullable: true)]
|
||||||
|
private string $color = '';
|
||||||
|
|
||||||
#[ORM\ManyToOne(targetEntity: Project::class, inversedBy: 'issues')]
|
#[ORM\ManyToOne(targetEntity: Project::class, inversedBy: 'issues')]
|
||||||
#[ORM\JoinColumn(nullable: false)]
|
#[ORM\JoinColumn(nullable: false)]
|
||||||
private Project $project;
|
private Project $project;
|
||||||
@ -125,6 +128,18 @@ class Issue
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getColor(): ?string
|
||||||
|
{
|
||||||
|
return $this->rowsprint;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setColor(?string $color): static
|
||||||
|
{
|
||||||
|
$this->color = $color;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
public function getProject(): Project
|
public function getProject(): Project
|
||||||
{
|
{
|
||||||
return $this->project;
|
return $this->project;
|
||||||
|
33
src/Form/IssueType.php
Normal file
33
src/Form/IssueType.php
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Form;
|
||||||
|
|
||||||
|
use App\Entity\Issue;
|
||||||
|
use App\Form\Type\SelbgType;
|
||||||
|
use Symfony\Component\Form\AbstractType;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
|
||||||
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
|
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||||
|
|
||||||
|
class IssueType extends AbstractType
|
||||||
|
{
|
||||||
|
public function buildForm(FormBuilderInterface $builder, array $options): void
|
||||||
|
{
|
||||||
|
$builder
|
||||||
|
->add('submit', SubmitType::class, [
|
||||||
|
'label' => 'Valider',
|
||||||
|
'attr' => ['class' => 'btn btn-success no-print'],
|
||||||
|
])
|
||||||
|
|
||||||
|
->add('color', SelbgType::class)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function configureOptions(OptionsResolver $resolver): void
|
||||||
|
{
|
||||||
|
$resolver->setDefaults([
|
||||||
|
'data_class' => Issue::class,
|
||||||
|
'mode' => 'submit',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
53
src/Form/Type/SelbgType.php
Normal file
53
src/Form/Type/SelbgType.php
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Form\Type;
|
||||||
|
|
||||||
|
use Symfony\Component\Form\AbstractType;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
||||||
|
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||||
|
|
||||||
|
class SelbgType extends AbstractType
|
||||||
|
{
|
||||||
|
public function configureOptions(OptionsResolver $resolver): void
|
||||||
|
{
|
||||||
|
$choices = $this->loadCssClasses();
|
||||||
|
|
||||||
|
// clef => valeur
|
||||||
|
$choices = array_combine($choices, $choices);
|
||||||
|
|
||||||
|
$resolver->setDefaults([
|
||||||
|
'choices' => $choices,
|
||||||
|
'choice_attr' => function ($choice, $key, $value) {
|
||||||
|
return ['class' => $value];
|
||||||
|
},
|
||||||
|
'required' => false,
|
||||||
|
'placeholder' => 'Sélectionnez un thème…',
|
||||||
|
'label' => 'Thème de couleur',
|
||||||
|
'attr' => ['class' => 'select2'],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getParent(): string
|
||||||
|
{
|
||||||
|
return ChoiceType::class;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function loadCssClasses(): array
|
||||||
|
{
|
||||||
|
$path = __DIR__.'/../../../public/lib/app/selbg.css';
|
||||||
|
|
||||||
|
if (!is_readable($path)) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$content = file_get_contents($path);
|
||||||
|
|
||||||
|
// match les classes du style `.selbg-xxx {`
|
||||||
|
preg_match_all('/\.selbg-[\w\-]+(?=\s*\{)/', $content, $matches);
|
||||||
|
|
||||||
|
// Supprime les points au début
|
||||||
|
return array_map(function ($class) {
|
||||||
|
return ltrim($class, '.');
|
||||||
|
}, $matches[0] ?? []);
|
||||||
|
}
|
||||||
|
}
|
@ -16,6 +16,7 @@
|
|||||||
<link rel="stylesheet" href="{{ asset('lib/imgareaselect/css/imgareaselect-default.css') }}">
|
<link rel="stylesheet" href="{{ asset('lib/imgareaselect/css/imgareaselect-default.css') }}">
|
||||||
|
|
||||||
<link rel="stylesheet" href="{{ asset('lib/app/app.css') }}">
|
<link rel="stylesheet" href="{{ asset('lib/app/app.css') }}">
|
||||||
|
<link rel="stylesheet" href="{{ asset('lib/app/selbg.css') }}">
|
||||||
|
|
||||||
<script src="{{ asset('lib/jquery/jquery.min.js') }}"></script>
|
<script src="{{ asset('lib/jquery/jquery.min.js') }}"></script>
|
||||||
<script src="{{ asset('lib/bootstrap/js/bootstrap.bundle.min.js') }}"></script>
|
<script src="{{ asset('lib/bootstrap/js/bootstrap.bundle.min.js') }}"></script>
|
||||||
|
62
templates/issue/edit.html.twig
Normal file
62
templates/issue/edit.html.twig
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
{% extends 'base.html.twig' %}
|
||||||
|
|
||||||
|
{% block localstyle %}
|
||||||
|
<style>
|
||||||
|
</style>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block title %}
|
||||||
|
Modification Issue = {{title}}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block body %}
|
||||||
|
<h1>
|
||||||
|
Modification Issue<br>
|
||||||
|
</h1>
|
||||||
|
<small class="text-muted" style="margin-top:-20px">{{title}}</small>
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
{{ form_start(form) }}
|
||||||
|
{{ form_widget(form.submit) }}
|
||||||
|
<a href="{{ path(routecancel) }}" class="btn btn-secondary ms-1">Annuler</a>
|
||||||
|
|
||||||
|
{% include('include/error.html.twig') %}
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-6 mx-auto">
|
||||||
|
<div class="card mt-3">
|
||||||
|
<div class="card-header">Information</div>
|
||||||
|
<div class="card-body">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-6 mx-auto">
|
||||||
|
<div class="card mt-3">
|
||||||
|
<div class="card-header">Permissions</div>
|
||||||
|
<div class="card-body">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% if mode=="update" %}
|
||||||
|
<div class="card mt-3">
|
||||||
|
<div class="card-header">Détail Redmine</div>
|
||||||
|
<div class="card-body">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
{{ form_end(form) }}
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block localscript %}
|
||||||
|
<script>
|
||||||
|
$(document).ready(function() {
|
||||||
|
$("#project_title").focus();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
{% endblock %}
|
Reference in New Issue
Block a user