svg
This commit is contained in:
@ -69,22 +69,30 @@ class IssueController extends AbstractController
|
||||
return new JsonResponse(['message' => 'Erreur Redmine : Déplacement Interdit'], 400);
|
||||
}
|
||||
|
||||
$payload = [
|
||||
'fixed_version_id' => $targetVersion,
|
||||
'agile_data_attributes' => ['agile_sprint_id' => $targetSprint],
|
||||
'status_id' => $targetStatus,
|
||||
];
|
||||
$this->redmineService->updateIssue($id, $payload, $this->getParameter('redmineApikey'));
|
||||
try {
|
||||
$payload = [
|
||||
'fixed_version_id' => $targetVersion,
|
||||
'agile_data_attributes' => ['agile_sprint_id' => $targetSprint],
|
||||
'status_id' => $targetStatus,
|
||||
];
|
||||
$this->redmineService->updateIssue($id, $payload, $this->getUser()->getApikey());
|
||||
} catch (\RuntimeException $e) {
|
||||
// Récupère le message de l'exception
|
||||
$errorMessage = $e->getMessage();
|
||||
dump($e->getMessage());
|
||||
|
||||
// Par exemple, retour JSON d'erreur :
|
||||
return new JsonResponse(['message' => $errorMessage], 400);
|
||||
}
|
||||
/*
|
||||
$payload =
|
||||
[
|
||||
'id' => $id,
|
||||
'issue' => [
|
||||
'status_id' => $targetStatus,
|
||||
'fixed_version_id' => $targetVersion,
|
||||
],
|
||||
'positions' => [],
|
||||
'id' => $id,
|
||||
'issue' => [
|
||||
'status_id' => $targetStatus,
|
||||
'fixed_version_id' => $targetVersion,
|
||||
],
|
||||
'positions' => [],
|
||||
];
|
||||
|
||||
foreach ($targetIssues as $key => $issue) {
|
||||
|
@ -299,7 +299,7 @@ class RedmineService
|
||||
public function getIssue(int $issueId, string $apiKey): array
|
||||
{
|
||||
try {
|
||||
$url = "{$this->baseUrl}/issues/{$issueId}.json?include=allowed_statuses";
|
||||
$url = "{$this->baseUrl}/issues/{$issueId}.json?include=allowed_statuses,journals";
|
||||
|
||||
$response = $this->client->request('GET', $url, [
|
||||
'headers' => [
|
||||
@ -345,7 +345,7 @@ class RedmineService
|
||||
}
|
||||
}
|
||||
|
||||
public function updateIssue(int $id, array $data, string $apiKey): array
|
||||
public function updateIssue(int $id, array $data, ?string $apiKey): array
|
||||
{
|
||||
$url = $this->baseUrl.'/issues/'.$id.'.json';
|
||||
|
||||
@ -358,25 +358,15 @@ class RedmineService
|
||||
'json' => ['issue' => $data],
|
||||
]);
|
||||
|
||||
$statusCode = $response->getStatusCode();
|
||||
$content = trim($response->getContent(false));
|
||||
if (200 !== $response->getStatusCode()) {
|
||||
if (401 === $response->getStatusCode()) {
|
||||
throw new \RuntimeException('Erreur Redmine ('.$response->getStatusCode().') : Opération non autorisée, avez-vous placé votre apikey redmine sur votre profil');
|
||||
}
|
||||
|
||||
// Si vide et code 200, c’est peut-être une réussite silencieuse
|
||||
if ('' === $content) {
|
||||
return ['success' => true, 'message' => 'OK, mais pas de contenu'];
|
||||
throw new \RuntimeException('Erreur de communication avec Redmine : '.$response->getStatusCode());
|
||||
}
|
||||
|
||||
$decoded = json_decode($content, true);
|
||||
|
||||
if (isset($decoded['errors']) && is_array($decoded['errors']) && count($decoded['errors']) > 0) {
|
||||
throw new \RuntimeException('Erreur Redmine : '.implode(', ', $decoded['errors']));
|
||||
}
|
||||
|
||||
return $decoded;
|
||||
} catch (ClientExceptionInterface|ServerExceptionInterface $e) {
|
||||
// Erreur HTTP (4xx ou 5xx)
|
||||
$errorBody = $e->getResponse()->getContent(false);
|
||||
throw new \RuntimeException('Erreur Redmine: '.$errorBody, $e->getCode(), $e);
|
||||
return $response->toArray();
|
||||
} catch (TransportExceptionInterface $e) {
|
||||
throw new \RuntimeException('Erreur de communication avec Redmine : '.$e->getMessage());
|
||||
}
|
||||
|
@ -6,7 +6,15 @@
|
||||
<div class="btn btn-secondary" onClick="hideIssue()"><i class="fas fa-window-close"></i></div>
|
||||
|
||||
</div>
|
||||
<small class="text-muted">Projet : {{ issue.redmine.project.name }} • Tracker : {{ issue.redmine.tracker.name }}</small>
|
||||
|
||||
<div class="d-flex">
|
||||
<small class="text-muted" style="flex-grow:1">Projet : {{ issue.redmine.project.name }} • Tracker : {{ issue.redmine.tracker.name }}</small>
|
||||
{% for field in issue.redmine.custom_fields %}
|
||||
{% if field.id==11 and field.value!="" %}
|
||||
<small class="text-muted"><strong>{{ field.name }} =</strong> <a href="{{field.value}}" target="_blank">{{field.value|split('/')|last}}</a></small>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="issueDescription card-body" style="height:500px;overflow-y:auto">
|
||||
@ -40,40 +48,43 @@
|
||||
<strong>Date de début =</strong> {{ issue.redmine.start_date|date('d/m/Y') }}<br>
|
||||
<strong>Date de fin =</strong> {{ issue.redmine.due_date|date('d/m/Y') }}<br><br>
|
||||
|
||||
<strong>Affecté à =</strong> {{(issue.redmine.assigned_to is defined?issue.redmine.assigned_to.name:'')}}<br>
|
||||
<strong>Affecté à =</strong> {{(issue.redmine.assigned_to is defined?issue.redmine.assigned_to.name:'')}}<br>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
{% for field in issue.redmine.custom_fields %}
|
||||
{% if field.id==32 %}
|
||||
<hr>
|
||||
<strong>{{ field.name }} </strong><br>
|
||||
{{ field.value|textile_to_html|raw }}<br>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
{% if issue.redmine.description %}
|
||||
<div class="mb-3">
|
||||
<hr>
|
||||
<strong>Description :</strong>
|
||||
<p>{{ issue.redmine.description|textile_to_html|raw }}</p>
|
||||
<hr>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if issue.redmine.custom_fields|length %}
|
||||
<div class="mb-3">
|
||||
<hr>
|
||||
<strong>Champs personnalisés :</strong>
|
||||
<ul class="list-group">
|
||||
{% for field in issue.redmine.custom_fields %}
|
||||
<li class="list-group-item d-flex justify-content-between align-items-center">
|
||||
{{ field.name }}
|
||||
<span class="text-muted">
|
||||
{% if field.multiple is defined and field.multiple and field.value is iterable %}
|
||||
{{ field.value|join(', ') }}
|
||||
{% elseif field.value %}
|
||||
{{ field.value }}
|
||||
{% else %}
|
||||
<em>—</em>
|
||||
{% endif %}
|
||||
</span>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% for journal in issue.redmine.journals %}
|
||||
{% if journal.notes != "" %}
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<strong>Auteur =</strong> {{journal.user.name}}</strong><br>
|
||||
<small class="text-muted">Créé le =</strong>{{ journal.created_on|date('d/m/Y H:i') }}</small>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
{{ journal.notes |textile_to_html|raw }}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
<hr>
|
||||
|
||||
{{dump(issue)}}
|
||||
<br><br>
|
||||
|
@ -192,8 +192,9 @@
|
||||
<div class='filtreContainer'>
|
||||
<label>Issue</label>
|
||||
<input type="number" id="issueSearchInput" class="form-control" placeholder="Rechercher une issue" />
|
||||
|
||||
<label>Statut</label>
|
||||
<a href="{{redmineUrl}}/projects/{{project.id}}/issues/new" target="_blank" class="btn btn-primary btn-sm"><i class="fas fa-file"></i> Nouvelle Demande</a>
|
||||
|
||||
<label style="margin-top:30px">Statut</label>
|
||||
<select id="statusFilter" class="select2 form-select" multiple="true" tabindex="-1" aria-hidden="true">
|
||||
{% for statut in project.redmine.issue_statuses %}
|
||||
{% if statut.id not in project.hiddenstatuses %}
|
||||
@ -381,9 +382,10 @@
|
||||
});
|
||||
|
||||
// Scroll horizontal (retourne une promesse)
|
||||
let paddingLeft = parseInt($('.scrumContainer').css('padding-left'), 315);
|
||||
const scrollLeftPromise = new Promise(resolve => {
|
||||
$('html, body').animate({
|
||||
scrollLeft: $element.offset().left - 315
|
||||
scrollLeft: $element.offset().left - paddingLeft
|
||||
}, 500, resolve);
|
||||
});
|
||||
|
||||
@ -530,7 +532,7 @@
|
||||
localStorage.removeItem(viewedIssueKey);
|
||||
|
||||
$('.issueContainer').hide();
|
||||
$('.scrumContainer').css('padding-left','0px');
|
||||
$('.scrumContainer').css('padding-left','300px');
|
||||
}
|
||||
|
||||
// Filtre sur les issues et backup des filtres en localstorage
|
||||
|
Reference in New Issue
Block a user