- WIP on lean-api visual

This commit is contained in:
Dave Mc Nicoll 2025-10-06 17:28:08 +00:00
parent c5ec582bd1
commit c9b107809d
6 changed files with 46 additions and 36 deletions

View File

@ -6,6 +6,7 @@ use Lean\Api\Factory\MessageFactoryInterface;
use Lean\LanguageHandler; use Lean\LanguageHandler;
use Picea\Ui\Method\FormContextInterface; use Picea\Ui\Method\FormContextInterface;
use Ulmus\Entity\EntityInterface; use Ulmus\Entity\EntityInterface;
use Ulmus\EntityCollection;
trait FormTrait trait FormTrait
{ {
@ -29,7 +30,7 @@ trait FormTrait
return $this->languageHandler->languageFromKey($key, $variables); return $this->languageHandler->languageFromKey($key, $variables);
} }
public function getEntity() : EntityInterface public function getEntity() : EntityInterface|EntityCollection
{ {
if (! isset($this->entity)) { if (! isset($this->entity)) {
throw new \InvalidArgumentException($this->lang("lean.api.form.error.entity")); throw new \InvalidArgumentException($this->lang("lean.api.form.error.entity"));

View File

@ -33,11 +33,11 @@ class ApiRenderer implements MiddlewareInterface {
'data' => [ 'data' => [
# 'error_id' => $errorId, # 'error_id' => $errorId,
'message' => $ex->getMessage(), 'message' => $ex->getMessage(),
] + (getenv('DEBUG') ? [
'file' => $ex->getFile(), 'file' => $ex->getFile(),
'line' => $ex->getLine(), 'line' => $ex->getLine(),
'code' => $ex->getCode(), 'code' => $ex->getCode(),
'backtrace' => $ex->getTrace(), 'backtrace' => $ex->getTrace(), ] : [])
]
], 500); ], 500);
} }

View File

@ -11,12 +11,11 @@
<div class="entities"> <div class="entities">
{% foreach $entities as $name => $entity %} {% foreach $entities as $name => $entity %}
<div class="entity-wrapper" style="padding-left: 15px;border-left: 3px solid #eaa1af;"> <div class="entity-wrapper" style="padding-left: 15px;border-left: 3px solid #eaa1af;">
<h4 class='entity-name'>{{ $name }}</h4> <h4 class='entity-name' title="{{ $name }}">{{ $entity['className'] }}</h4>
<div class='description'>{{ $entity['description'] }}</div> <div class='description'>{{ $entity['description'] }}</div>
<hr style="margin-top:15px"> <hr style="margin-top:15px">
<h5>Champs</h5>
<ol class='fields'> <ol class='fields'>
{% foreach $entity['fields'] as $field %} {% foreach $entity['fields'] as $field %}
<li class="odd-even"> <li class="odd-even">
@ -37,11 +36,13 @@
</ol> </ol>
</div> </div>
{% if $entity['searchRequestFields'] %}
<div class="search-request-wrapper"> <div class="search-request-wrapper">
<h4 class='search-request-name'>{{ $name }}::searchRequest()</h4> <h4 class='search-request-name' title="{{ $name }}">{{ $entity['className'] }}::searchRequest()</h4>
<h5>Requêtes</h5> {% if $entity['searchRequestDescription'] %}
<div class='description' style="margin-bottom:10px">{{ $entity['searchRequestDescription'] }}</div> <div class='description' style="margin-bottom:10px">{{ $entity['searchRequestDescription'] }}</div>
{% endif %}
<ol class='requests'> <ol class='requests'>
{% foreach $entity['searchRequestFields'] as $field %} {% foreach $entity['searchRequestFields'] as $field %}
@ -63,6 +64,7 @@
{% endforeach %} {% endforeach %}
</ol> </ol>
</div> </div>
{% endif %}
{% or %} {% or %}
<i style="color:#585858; padding:0 12px">{% _ "none" %}</i> <i style="color:#585858; padding:0 12px">{% _ "none" %}</i>
{% endforeach %} {% endforeach %}

View File

@ -8,7 +8,7 @@
{% foreach $forms as $name => $form %} {% foreach $forms as $name => $form %}
<div class="single-form" style="padding-left:15px;border-left: 3px solid #9ccce6;" data-form="{% json.html $form %}"> <div class="single-form" style="padding-left:15px;border-left: 3px solid #9ccce6;" data-form="{% json.html $form %}">
<h4 class='form-name'> <h4 class='form-name'>
<span>{{ $name }}</span> <span title="{{ $name }}">{{ $form['className'] }}</span>
</h4> </h4>
<div class='description'>{{ $form['description'] }}</div> <div class='description'>{{ $form['description'] }}</div>
<hr style="margin-top:15px"> <hr style="margin-top:15px">

View File

@ -10,6 +10,7 @@
<div class="url" style="flex-grow: 1;"> <div class="url" style="flex-grow: 1;">
{% ui:text "url" %} {% ui:text "url" %}
{% ui:text "token", $this->session->jwt %}
<button class="request-btn">Envoyer</button> <button class="request-btn">Envoyer</button>
</div> </div>
</div> </div>
@ -33,7 +34,9 @@
.request-head {display:flex;padding-top: 4px;border:1px solid #e1e1e1;border-bottom:0} .request-head {display:flex;padding-top: 4px;border:1px solid #e1e1e1;border-bottom:0}
.request-head .method {width: 90px;text-align: center;line-height: 34px;font-weight: bold;} .request-head .method {width: 90px;text-align: center;line-height: 34px;font-weight: bold;}
.request-head .method select {background:none;border:0;font-size: inherit;text-align: center;color: inherit;font-weight: bold;} .request-head .method select {background:none;border:0;font-size: inherit;text-align: center;color: inherit;font-weight: bold;}
.request-head .url input {width: calc(100% - 94px); border:0;color: #6f6f6f;background: #f9f9f9;font-size: 80%;font-weight: bold;} .request-head .url input {border:0;color: #6f6f6f;background: #f9f9f9;font-size: 80%;font-weight: bold;}
.request-head .url [name="url"] {width: calc(65% - 80px);}
.request-head .url [name="token"] {width:calc(35% - 10px);font-size:60%}
.request-head .url button {font-size: 80%;width: 80px;border-radius:0;border: 1px solid #ccc;height:26px;padding: 0;background:#f9f9f9;color: #6f6f6f;cursor: pointer;} .request-head .url button {font-size: 80%;width: 80px;border-radius:0;border: 1px solid #ccc;height:26px;padding: 0;background:#f9f9f9;color: #6f6f6f;cursor: pointer;}
.request-head .url button:active {filter:contrast(85%);} .request-head .url button:active {filter:contrast(85%);}
@ -55,6 +58,7 @@
responseResponse = requestDebugger.querySelector(".request-response"), responseResponse = requestDebugger.querySelector(".request-response"),
method = requestHead.querySelector(".method"), method = requestHead.querySelector(".method"),
input = requestHead.querySelector("[name='url']"), input = requestHead.querySelector("[name='url']"),
token = requestHead.querySelector("[name='token']"),
button = requestHead.querySelector(".request-btn"); button = requestHead.querySelector(".request-btn");
// Editor // Editor
@ -159,10 +163,10 @@
method: method, method: method,
mode: "cors", mode: "cors",
cache: "no-cache", cache: "no-cache",
credentials: "same-origin", credentials: "omit",
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
'Authorization': 'Bearer {{ $this->session->jwt }}' 'Authorization': `Bearer ${token.value}`
}, },
redirect: "follow", redirect: "follow",
referrerPolicy: "no-referrer" referrerPolicy: "no-referrer"

View File

@ -21,7 +21,7 @@
ol{background: #eff4f2;padding-top:20px;padding-bottom:20px;border:1px solid #e3e3ec} ol{background: #eff4f2;padding-top:20px;padding-bottom:20px;border:1px solid #e3e3ec}
h4{background:#e0f7ed;padding:6px 12px; font-weight: bold!important;font-size:100%;margin-top:0} h4{background:#e0f7ed;padding:6px 12px; font-weight: bold!important;font-size:100%;margin-top:0}
h5{text-decoration: underline} h5{text-decoration: underline}
h3 {display: flex;align-items: center;height: 60px;padding: 0 15px 0 15px;font-variant: small-caps;} h3 {display: flex;align-items: center;padding: 0 15px 0 15px;font-variant: small-caps;border-bottom: 5px solid #ccc;line-height: 60px;}
li.odd-even{border-top:1px solid #ccc;margin:10px 0;padding:15px 15px 10px 5px} li.odd-even{border-top:1px solid #ccc;margin:10px 0;padding:15px 15px 10px 5px}
li.odd-even:first-child{border:0} li.odd-even:first-child{border:0}
input, button {padding:5px; font-size:1em;margin:0} input, button {padding:5px; font-size:1em;margin:0}
@ -39,7 +39,7 @@
.forms .form-name span {color: #284168;font-size:110%} .forms .form-name span {color: #284168;font-size:110%}
.forms .form-name .btn {background:rgba(50,50,50,0.5);padding:0 15px;border: 1px solid rgba(50,50,50,0.8);font-family: 'Déja Vu', 'Courier New', Courier, monospace, serif;font-size: 90%;color: #fff;text-decoration: underline;} .forms .form-name .btn {background:rgba(50,50,50,0.5);padding:0 15px;border: 1px solid rgba(50,50,50,0.8);font-family: 'Déja Vu', 'Courier New', Courier, monospace, serif;font-size: 90%;color: #fff;text-decoration: underline;}
.routes-wrapper {padding:8px} .routes-wrapper {padding:5px}
.routes-wrapper li {display:flex;border: 1px solid #ccc;align-items: stretch;cursor:pointer} .routes-wrapper li {display:flex;border: 1px solid #ccc;align-items: stretch;cursor:pointer}
.routes-wrapper li:hover {filter: contrast(85%)} .routes-wrapper li:hover {filter: contrast(85%)}
.routes-wrapper li + li {margin-top: 5px;} .routes-wrapper li + li {margin-top: 5px;}
@ -70,12 +70,15 @@
.routes-wrapper li.method-put .route-method {background:#d7bf3c;} .routes-wrapper li.method-put .route-method {background:#d7bf3c;}
.routes-wrapper li.method-put .route-link a, .routes-wrapper li.method-put .route-name {color: #aa941c;} .routes-wrapper li.method-put .route-link a, .routes-wrapper li.method-put .route-name {color: #aa941c;}
.forms{background: #e8f7ff;padding: 5px;}
.entities {background: #f0e0e0;padding:5px;}
.entity-wrapper .entity-name {background:#eaa1af;color: #682828;font-size:110%} .entity-wrapper .entity-name {background:#eaa1af;color: #682828;font-size:110%}
.entity-wrapper ol {background: #f0ddcd;} .entity-wrapper ol {background: #e3d0d0;}
.entity-wrapper li {border-color: #ae8585;} .entity-wrapper li {border-color: #ae8585;}
.search-request-name {background: #b6e6ae;color: #395332;font-size:110%} .search-request-name {background: #b6e6ae;color: #395332;font-size:110%}
.search-request-wrapper {padding-left: 15px;border-left: 3px solid #72886a;} .search-request-wrapper {padding: 15px;margin-top:5px;border-left: 3px solid #72886a;background: #eeffe6;}
.search-request-wrapper ol {background: #d8f0cd;} .search-request-wrapper ol {background: #d8f0cd;}
.search-request-wrapper li {border-color: #72886a;} .search-request-wrapper li {border-color: #72886a;}
</style> </style>