288 lines
15 KiB
PHTML
288 lines
15 KiB
PHTML
{% use Ulmus\Api\Common\MethodEnum %}
|
|
|
|
{% language.set "lean.api.request.debugger" %}
|
|
|
|
<div id="request-debugger" class="hide">
|
|
<div class="request-compose">
|
|
<div class="loading-anim">
|
|
<div class="la-ball-spin-clockwise-fade-rotating">
|
|
<div></div>
|
|
<div></div>
|
|
<div></div>
|
|
<div></div>
|
|
<div></div>
|
|
<div></div>
|
|
<div></div>
|
|
<div></div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="request-head">
|
|
<div class="method" style="">
|
|
{% ui.select "method", MethodEnum::generateArray(), post('method') %}
|
|
</div>
|
|
|
|
<div class="url" style="flex-grow: 1;">
|
|
{% ui:text "url" %}
|
|
{% ui:text "token", $this->session->jwt, [ 'placeholder' => "JWT Token" ] %}
|
|
<button class="request-btn">Envoyer</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="request-content">
|
|
<div id="request" style="min-height: 150px; width:100%; border:1px solid #ededed;">{}</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="request-response hide">
|
|
<div class="response-head">
|
|
<span class="response-code"></span>
|
|
<span class="response-message"></span>
|
|
</div>
|
|
<hr>
|
|
<pre id="response" class="code" ace-theme="ace/theme/cloud9_day"></pre>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
<style>
|
|
.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 select {background:none;border:0;font-size: inherit;text-align: center;color: inherit;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:active {filter:contrast(85%);}
|
|
|
|
.response-head {display: flex;border:1px solid #ececec;margin-bottom: 5px;border-top:0}
|
|
.response-head .response-code {background:#dfdfdf;padding:0 8px;font-weight: bold;line-height: 29px;font-size: 80%;}
|
|
.response-head .response-message {padding:0 10px;background:#fbfbfb;line-height: 30px;font-size: 80%;}
|
|
|
|
.request-compose {position:relative;}
|
|
.loading-anim {display:none;position:absolute;left:0;right:0;top:0;bottom:0;justify-content: center;align-items: center;z-index: 15;background: rgba(122, 121, 121, 0.25);}
|
|
.la-ball-spin-clockwise-fade-rotating {color: #0f6ab4!important;}
|
|
.loading .loading-anim {display: flex;}
|
|
|
|
#response {max-height: 66vh;}
|
|
/*!
|
|
* Load Awesome v1.1.0 (http://github.danielcardoso.net/load-awesome/)
|
|
* Copyright 2015 Daniel Cardoso <@DanielCardoso>
|
|
* Licensed under MIT
|
|
*/
|
|
.la-ball-spin-clockwise-fade-rotating,.la-ball-spin-clockwise-fade-rotating>div{position:relative;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.la-ball-spin-clockwise-fade-rotating{display:block;font-size:0;color:#fff}.la-ball-spin-clockwise-fade-rotating.la-dark{color:#333}.la-ball-spin-clockwise-fade-rotating>div{display:inline-block;float:none;background-color:currentColor;border:0 solid currentColor}.la-ball-spin-clockwise-fade-rotating{width:32px;height:32px;-webkit-animation:ball-spin-clockwise-fade-rotating-rotate 6s infinite linear;-moz-animation:ball-spin-clockwise-fade-rotating-rotate 6s infinite linear;-o-animation:ball-spin-clockwise-fade-rotating-rotate 6s infinite linear;animation:ball-spin-clockwise-fade-rotating-rotate 6s infinite linear}.la-ball-spin-clockwise-fade-rotating>div{position:absolute;top:50%;left:50%;width:8px;height:8px;margin-top:-4px;margin-left:-4px;border-radius:100%;-webkit-animation:ball-spin-clockwise-fade-rotating 1s infinite linear;-moz-animation:ball-spin-clockwise-fade-rotating 1s infinite linear;-o-animation:ball-spin-clockwise-fade-rotating 1s infinite linear;animation:ball-spin-clockwise-fade-rotating 1s infinite linear}.la-ball-spin-clockwise-fade-rotating>div:nth-child(1){top:5%;left:50%;-webkit-animation-delay:-.875s;-moz-animation-delay:-.875s;-o-animation-delay:-.875s;animation-delay:-.875s}.la-ball-spin-clockwise-fade-rotating>div:nth-child(2){top:18.1801948466%;left:81.8198051534%;-webkit-animation-delay:-.75s;-moz-animation-delay:-.75s;-o-animation-delay:-.75s;animation-delay:-.75s}.la-ball-spin-clockwise-fade-rotating>div:nth-child(3){top:50%;left:95%;-webkit-animation-delay:-.625s;-moz-animation-delay:-.625s;-o-animation-delay:-.625s;animation-delay:-.625s}.la-ball-spin-clockwise-fade-rotating>div:nth-child(4){top:81.8198051534%;left:81.8198051534%;-webkit-animation-delay:-.5s;-moz-animation-delay:-.5s;-o-animation-delay:-.5s;animation-delay:-.5s}.la-ball-spin-clockwise-fade-rotating>div:nth-child(5){top:94.9999999966%;left:50.0000000005%;-webkit-animation-delay:-.375s;-moz-animation-delay:-.375s;-o-animation-delay:-.375s;animation-delay:-.375s}.la-ball-spin-clockwise-fade-rotating>div:nth-child(6){top:81.8198046966%;left:18.1801949248%;-webkit-animation-delay:-.25s;-moz-animation-delay:-.25s;-o-animation-delay:-.25s;animation-delay:-.25s}.la-ball-spin-clockwise-fade-rotating>div:nth-child(7){top:49.9999750815%;left:5.0000051215%;-webkit-animation-delay:-.125s;-moz-animation-delay:-.125s;-o-animation-delay:-.125s;animation-delay:-.125s}.la-ball-spin-clockwise-fade-rotating>div:nth-child(8){top:18.179464974%;left:18.1803700518%;-webkit-animation-delay:0s;-moz-animation-delay:0s;-o-animation-delay:0s;animation-delay:0s}.la-ball-spin-clockwise-fade-rotating.la-sm{width:16px;height:16px}.la-ball-spin-clockwise-fade-rotating.la-sm>div{width:4px;height:4px;margin-top:-2px;margin-left:-2px}.la-ball-spin-clockwise-fade-rotating.la-2x{width:64px;height:64px}.la-ball-spin-clockwise-fade-rotating.la-2x>div{width:16px;height:16px;margin-top:-8px;margin-left:-8px}.la-ball-spin-clockwise-fade-rotating.la-3x{width:96px;height:96px}.la-ball-spin-clockwise-fade-rotating.la-3x>div{width:24px;height:24px;margin-top:-12px;margin-left:-12px}@-webkit-keyframes ball-spin-clockwise-fade-rotating-rotate{100%{-webkit-transform:rotate(-360deg);transform:rotate(-360deg)}}@-moz-keyframes ball-spin-clockwise-fade-rotating-rotate{100%{-moz-transform:rotate(-360deg);transform:rotate(-360deg)}}@-o-keyframes ball-spin-clockwise-fade-rotating-rotate{100%{-o-transform:rotate(-360deg);transform:rotate(-360deg)}}@keyframes ball-spin-clockwise-fade-rotating-rotate{100%{-webkit-transform:rotate(-360deg);-moz-transform:rotate(-360deg);-o-transform:rotate(-360deg);transform:rotate(-360deg)}}@-webkit-keyframes ball-spin-clockwise-fade-rotating{50%{opacity:.25;-webkit-transform:scale(.5);transform:scale(.5)}100%{opacity:1;-webkit-transform:scale(1);transform:scale(1)}}@-moz-keyframes ball-spin-clockwise-fade-rotating{50%{opacity:.25;-moz-transform:scale(.5);transform:scale(.5)}100%{opacity:1;-moz-transform:scale(1);transform:scale(1)}}@-o-keyframes ball-spin-clockwise-fade-rotating{50%{opacity:.25;-o-transform:scale(.5);transform:scale(.5)}100%{opacity:1;-o-transform:scale(1);transform:scale(1)}}@keyframes ball-spin-clockwise-fade-rotating{50%{opacity:.25;-webkit-transform:scale(.5);-moz-transform:scale(.5);-o-transform:scale(.5);transform:scale(.5)}100%{opacity:1;-webkit-transform:scale(1);-moz-transform:scale(1);-o-transform:scale(1);transform:scale(1)}}
|
|
</style>
|
|
|
|
<script src="{% asset 'static/ace/src-noconflict/ace.js' %}" type="text/javascript" charset="utf-8"></script>
|
|
<script src="{% asset 'static/ace/src-noconflict/ext-static_highlight.js' %}" type="text/javascript" charset="utf-8"></script>
|
|
|
|
<script>
|
|
let requestDebugger = document.getElementById('request-debugger'),
|
|
requestHead = requestDebugger.querySelector(".request-head"),
|
|
requestContent = requestDebugger.querySelector(".request-content"),
|
|
responseHead = requestDebugger.querySelector(".response-head"),
|
|
responseResponse = requestDebugger.querySelector(".request-response"),
|
|
method = requestHead.querySelector(".method"),
|
|
input = requestHead.querySelector("[name='url']"),
|
|
token = requestHead.querySelector("[name='token']"),
|
|
tokenValue = sessionStorage.getItem("token"),
|
|
button = requestHead.querySelector(".request-btn");
|
|
|
|
// Editor
|
|
let editor = ace.edit("request");
|
|
editor.setTheme("ace/theme/cloud9_day");
|
|
editor.session.setMode("ace/mode/json");
|
|
|
|
// Code highlighter
|
|
let highlight = ace.require("ace/ext/static_highlight"),
|
|
dom = ace.require("ace/lib/dom"),
|
|
responseEditorElement = responseResponse.querySelector('#response');
|
|
|
|
input.addEventListener('keydown', evt => evt.keyCode === 13 ? button.click() : null);
|
|
token.addEventListener('change', evt => sessionStorage.setItem("token", evt.target.value));
|
|
|
|
if (tokenValue) {
|
|
token.value = tokenValue;
|
|
}
|
|
|
|
document.addEventListener("DOMContentLoaded", (evt) => {
|
|
document.querySelectorAll(".form-name").forEach(elem => {
|
|
elem.insertAdjacentHTML('beforeend', '<a href="javascript:void(0)" class="btn debug">DEBUG</a>');
|
|
|
|
let formData = JSON.parse(elem.closest('.single-form').getAttribute('data-form'));
|
|
|
|
elem.querySelector(".btn.debug").addEventListener("click", (btn) => {
|
|
requestDebugger.classList.toggle('hide', false);
|
|
|
|
let json = {};
|
|
|
|
formData.fields.forEach((field) => {
|
|
const value = field.default ? field.default : ( field.allowNulls ? null : "" );
|
|
|
|
json[field.name] = value === "[]" ? [] : value;
|
|
});
|
|
|
|
editor.setValue(JSON.stringify(json, null, 2), -1);
|
|
});
|
|
});
|
|
|
|
document.querySelectorAll("li[class*='method-']").forEach( (url) => {
|
|
url.addEventListener("click", (evt) => {
|
|
evt.preventDefault();
|
|
|
|
let routeMethod = url.querySelector('.route-method');
|
|
|
|
method.style.color = getComputedStyle(routeMethod).getPropertyValue('background-color');
|
|
method.querySelector('select').value = routeMethod.innerText;
|
|
|
|
input.value = url.querySelector('.route-link a').getAttribute('href');
|
|
|
|
document.getElementById('request-debugger').classList.toggle('hide', false);
|
|
|
|
replaceUrlVariableUsingData();
|
|
|
|
input.focus();
|
|
});
|
|
});
|
|
|
|
let aceMode;
|
|
|
|
button.addEventListener("click", (evt) => {
|
|
let requestMethod = method.querySelector('select').value;
|
|
|
|
if (requestMethod === 'DELETE' && ! confirm("Attention ! Vous allez lancer une procédure de suppression de données.\n\nContinuer ?")) {
|
|
return;
|
|
}
|
|
|
|
launchRequest(requestMethod, input.value, editor.getValue())
|
|
.then((response) => {
|
|
console.log(response);
|
|
responseHead.querySelector('.response-code').innerText = response.status;
|
|
responseHead.querySelector('.response-message').innerText = response.statusText;
|
|
|
|
aceMode = parseContentType(response);
|
|
|
|
return response.text();
|
|
})
|
|
.then(body => {
|
|
console.log(aceMode);
|
|
if (aceMode === "json") {
|
|
body = JSON.stringify(JSON.parse(body), null, 2);
|
|
responseEditorElement.innerHTML = body;
|
|
}
|
|
else {
|
|
responseEditorElement.innerText = body;
|
|
}
|
|
|
|
formatResponse("ace/mode/" + aceMode);
|
|
}).finally(() => requestDebugger.classList.remove("loading"));
|
|
|
|
responseResponse.classList.toggle('hide', false);
|
|
});
|
|
|
|
let selectRoute = getQueryVariable("debug.route"),
|
|
presetData = getQueryVariable("debug.data");
|
|
|
|
if ( selectRoute ) {
|
|
if (presetData) {
|
|
editor.setValue(presetData);
|
|
}
|
|
|
|
document.querySelector(`[data-name="${selectRoute}"]`).click();
|
|
}
|
|
});
|
|
|
|
async function launchRequest(method = "POST", url = "", body = "{}") {
|
|
let headers = {
|
|
"Content-Type": "application/json"
|
|
};
|
|
|
|
if (token.value) {
|
|
headers['Authorization'] = `Bearer ${token.value}`;
|
|
}
|
|
|
|
method = method.toUpperCase();
|
|
|
|
let responseData = {
|
|
method: method,
|
|
mode: "cors",
|
|
cache: "no-cache",
|
|
credentials: headers.Authorization ? "omit" : "same-origin",
|
|
headers: headers,
|
|
redirect: "follow",
|
|
referrerPolicy: "no-referrer"
|
|
};
|
|
|
|
if ( [ "HEAD", "GET" ].indexOf(method) === -1 ) {
|
|
responseData.body = body;
|
|
}
|
|
|
|
requestDebugger.classList.add("loading");
|
|
|
|
return await fetch(url, responseData);
|
|
}
|
|
|
|
function formatResponse(mode) {
|
|
highlight(responseEditorElement, {
|
|
mode: mode,
|
|
theme: responseEditorElement.getAttribute("ace-theme"),
|
|
firstLineNumber: 1,
|
|
showGutter: responseEditorElement.getAttribute("ace-gutter"),
|
|
trim: true
|
|
});
|
|
}
|
|
|
|
function parseContentType(response) {
|
|
let type = response.headers.get('content-type').toLowerCase();
|
|
|
|
if ( type.indexOf('text/html') !== -1 ) {
|
|
return "html";
|
|
}
|
|
else if ( type.indexOf('text/css') !== -1 ) {
|
|
return "css";
|
|
}
|
|
else if ( type.indexOf('text/csv') !== -1 ) {
|
|
return "csv";
|
|
}
|
|
else if ( type.indexOf('text/xml') !== -1 ) {
|
|
return "xml";
|
|
}
|
|
else if ( type.indexOf('text/plain') !== -1 ) {
|
|
return "text";
|
|
}
|
|
else if ( type.indexOf('application/javascript') !== -1 ) {
|
|
return "javascript";
|
|
}
|
|
else if ( type.indexOf('application/json') !== -1 || type.indexOf('application/ld+json') !== -1 ) {
|
|
return "json";
|
|
}
|
|
}
|
|
|
|
function getQueryVariable(variable) {
|
|
retval = false;
|
|
|
|
window.location.search.substring(1).split("&").forEach(vars => {
|
|
var pair = vars.split("=");
|
|
|
|
if (pair.length === 2 && pair[0] === variable) {
|
|
return retval = decodeURI(pair[1]);
|
|
}
|
|
});
|
|
|
|
return retval;
|
|
}
|
|
|
|
function replaceUrlVariableUsingData() {
|
|
try {
|
|
let vars = input.value.match(/[^{}]+(?=})/g),
|
|
body = JSON.parse(editor.getValue());
|
|
|
|
vars.forEach(v => {
|
|
if (body[v]) {
|
|
input.value = input.value.replace("{" + v + "}", body[v]);
|
|
}
|
|
})
|
|
}
|
|
catch(e) {}
|
|
}
|
|
</script> |