ikinci temizlik tamamlandı

This commit is contained in:
Ümit Tunç
2026-04-28 21:15:09 +03:00
parent f80443aec0
commit 37e7296527
8313 changed files with 2400677 additions and 0 deletions
View File
+61
View File
@@ -0,0 +1,61 @@
<!DOCTYPE html>
<html lang="{{ app()->getLocale() }}">
<head>
<meta charset="utf-8">
<title>elFinder 2.0</title>
<!-- jQuery and jQuery UI (REQUIRED) -->
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/themes/smoothness/jquery-ui.css" />
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/jquery-ui.min.js"></script>
<!-- elFinder CSS (REQUIRED) -->
<link rel="stylesheet" type="text/css" href="{{ asset($dir.'/css/elfinder.min.css') }}">
<link rel="stylesheet" type="text/css" href="{{ asset($dir.'/css/theme.css') }}">
<!-- elFinder JS (REQUIRED) -->
<script src="{{ asset($dir.'/js/elfinder.min.js') }}"></script>
@if($locale)
<!-- elFinder translation (OPTIONAL) -->
<script src="{{ asset($dir."/js/i18n/elfinder.$locale.js") }}"></script>
@endif
<!-- elFinder initialization (REQUIRED) -->
<script type="text/javascript" charset="utf-8">
// Helper function to get parameters from the query string.
function getUrlParam(paramName) {
var reParam = new RegExp('(?:[\?&]|&amp;)' + paramName + '=([^&]+)', 'i') ;
var match = window.location.search.match(reParam) ;
return (match && match.length > 1) ? match[1] : '' ;
}
$().ready(function() {
var funcNum = getUrlParam('CKEditorFuncNum');
var elf = $('#elfinder').elfinder({
// set your elFinder options here
@if($locale)
lang: '{{ $locale }}', // locale
@endif
customData: {
_token: '{{ csrf_token() }}'
},
url: '{{ route("elfinder.connector") }}', // connector URL
soundPath: '{{ asset($dir.'/sounds') }}',
getFileCallback : function(file) {
window.opener.CKEDITOR.tools.callFunction(funcNum, file.url);
window.close();
}
}).elfinder('instance');
});
</script>
</head>
<body>
<!-- Element where elFinder will be created (REQUIRED) -->
<div id="elfinder"></div>
</body>
</html>
+61
View File
@@ -0,0 +1,61 @@
<!DOCTYPE html>
<html lang="<?= app()->getLocale() ?>">
<head>
<meta charset="utf-8">
<title>elFinder 2.0</title>
<!-- jQuery and jQuery UI (REQUIRED) -->
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/themes/smoothness/jquery-ui.css" />
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/jquery-ui.min.js"></script>
<!-- elFinder CSS (REQUIRED) -->
<link rel="stylesheet" type="text/css" href="<?= asset($dir.'/css/elfinder.min.css') ?>">
<link rel="stylesheet" type="text/css" href="<?= asset($dir.'/css/theme.css') ?>">
<!-- elFinder JS (REQUIRED) -->
<script src="<?= asset($dir.'/js/elfinder.min.js') ?>"></script>
<?php if($locale){ ?>
<!-- elFinder translation (OPTIONAL) -->
<script src="<?= asset($dir."/js/i18n/elfinder.$locale.js") ?>"></script>
<?php } ?>
<!-- elFinder initialization (REQUIRED) -->
<script type="text/javascript" charset="utf-8">
// Helper function to get parameters from the query string.
function getUrlParam(paramName) {
var reParam = new RegExp('(?:[\?&]|&amp;)' + paramName + '=([^&]+)', 'i') ;
var match = window.location.search.match(reParam) ;
return (match && match.length > 1) ? match[1] : '' ;
}
$().ready(function() {
var funcNum = getUrlParam('CKEditorFuncNum');
var elf = $('#elfinder').elfinder({
// set your elFinder options here
<?php if($locale){ ?>
lang: '<?= $locale ?>', // locale
<?php } ?>
customData: {
_token: '<?= csrf_token() ?>'
},
url: '<?= route("elfinder.connector") ?>', // connector URL
soundPath: '<?= asset($dir.'/sounds') ?>',
getFileCallback : function(file) {
window.opener.CKEDITOR.tools.callFunction(funcNum, file.url);
window.close();
}
}).elfinder('instance');
});
</script>
</head>
<body>
<!-- Element where elFinder will be created (REQUIRED) -->
<div id="elfinder"></div>
</body>
</html>
+133
View File
@@ -0,0 +1,133 @@
<!DOCTYPE html>
<html lang="{{ app()->getLocale() }}">
<head>
<meta charset="utf-8">
<title>elFinder 2.0</title>
<!-- jQuery and jQuery UI (REQUIRED) -->
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/themes/smoothness/jquery-ui.css" />
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/jquery-ui.min.js"></script>
<!-- elFinder CSS (REQUIRED) - CDN -->
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/elfinder/2.1.65/css/elfinder.min.css">
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/elfinder/2.1.65/css/theme.css">
<!-- elFinder JS (REQUIRED) - CDN -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/elfinder/2.1.65/js/elfinder.min.js"></script>
<!-- elFinder Edit Plugin - CDN -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/elfinder/2.1.65/js/extras/editors.default.min.js"></script>
@if($locale)
<!-- elFinder translation (OPTIONAL) -->
<script src="{{ asset($dir."/js/i18n/elfinder.$locale.js") }}"></script>
@endif
<!-- elFinder initialization (REQUIRED) -->
<script type="text/javascript" charset="utf-8">
// Documentation for client options:
// https://github.com/Studio-42/elFinder/wiki/Client-configuration-options
$().ready(function() {
// Check if user is admin from parent window
var isAdmin = false;
try {
if (window.parent && window.parent.document) {
var iframe = window.parent.document.getElementById('elfinder-iframe');
if (iframe) {
var permissionLevel = iframe.getAttribute('data-permission-level');
isAdmin = (permissionLevel === 'full_control');
}
}
} catch(e) {
console.log('Could not check admin status:', e);
}
var elfinderInstance = $('#elfinder').elfinder({
// set your elFinder options here
@if($locale)
lang: '{{ $locale }}', // locale
@endif
customData: {
_token: '{{ csrf_token() }}'
},
url : '{{ route("elfinder.connector") }}', // connector URL
requestType : 'post', // Performance optimization for large folders
soundPath: '{{ asset($dir.'/sounds') }}',
height: $(window).height() - 20,
checkSubfolders: false,
// Enable edit command and plugin
commands: ['open', 'reload', 'home', 'up', 'back', 'forward', 'getfile', 'quicklook', 'download', 'rm', 'duplicate', 'rename', 'mkdir', 'mkfile', 'upload', 'copy', 'cut', 'paste', 'view', 'resize', 'sort', 'search', 'help', 'info'],
plugins: [],
// Force edit to be available
ui: ['toolbar', 'tree', 'path', 'stat'],
toolbar: isAdmin ? [
// Admin toolbar - full access
['reload'],
['home', 'up'],
['mkdir', 'mkfile', 'upload'],
['open', 'download', 'getfile'],
['info'],
['quicklook'],
['copy', 'cut', 'paste'],
['rm'],
['duplicate', 'rename', 'resize', 'rotate'],
['extract', 'archive'],
['search'],
['view', 'sort']
] : [
// Regular user toolbar
['reload'],
['home', 'up'],
['mkdir', 'mkfile', 'upload'],
['open', 'download', 'getfile'],
['info'],
['quicklook'],
['copy', 'cut', 'paste'],
['rm'],
['duplicate', 'rename', 'resize', 'rotate'],
['extract', 'archive'],
['search'],
['view', 'sort']
]
}).elfinder('instance');
// Admin override - force full permissions display
if (isAdmin) {
console.log('Admin user detected - applying full permissions override');
// Override permission display for admin users
elfinderInstance.bind('load', function() {
// Force all items to show full permissions for admin
setTimeout(function() {
$('.elfinder-cwd-view .elfinder-cwd-file').each(function() {
var $this = $(this);
var $perm = $this.find('.elfinder-cwd-filename .elfinder-cwd-perms');
if ($perm.length && $perm.text().indexOf('read') !== -1) {
$perm.text('read and write').removeClass('elfinder-perms-read').addClass('elfinder-perms-write');
}
});
}, 1000);
});
}
// Edit button removed - using standard Elfinder functionality
var resizeTimer = null;
$(window).resize(function() {
resizeTimer && clearTimeout(resizeTimer);
resizeTimer = setTimeout(function() {
var h = parseInt($(window).height()) - 20;
if (h != parseInt($('#elfinder').height())) {
elfinderInstance.resize('100%', h);
}
}, 200);
});
});
</script>
</head>
<body>
<!-- Element where elFinder will be created (REQUIRED) -->
<div id="elfinder"></div>
</body>
</html>
+49
View File
@@ -0,0 +1,49 @@
<!DOCTYPE html>
<html lang="<?= app()->getLocale() ?>">
<head>
<meta charset="utf-8">
<title>elFinder 2.0</title>
<!-- jQuery and jQuery UI (REQUIRED) -->
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/themes/smoothness/jquery-ui.css" />
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/jquery-ui.min.js"></script>
<!-- elFinder CSS (REQUIRED) -->
<link rel="stylesheet" type="text/css" href="<?= asset($dir.'/css/elfinder.min.css') ?>">
<link rel="stylesheet" type="text/css" href="<?= asset($dir.'/css/theme.css') ?>">
<!-- elFinder JS (REQUIRED) -->
<script src="<?= asset($dir.'/js/elfinder.min.js') ?>"></script>
<?php if($locale){ ?>
<!-- elFinder translation (OPTIONAL) -->
<script src="<?= asset($dir."/js/i18n/elfinder.$locale.js") ?>"></script>
<?php } ?>
<!-- elFinder initialization (REQUIRED) -->
<script type="text/javascript" charset="utf-8">
// Documentation for client options:
// https://github.com/Studio-42/elFinder/wiki/Client-configuration-options
$().ready(function() {
$('#elfinder').elfinder({
// set your elFinder options here
<?php if($locale){ ?>
lang: '<?= $locale ?>', // locale
<?php } ?>
customData: {
_token: '<?= csrf_token() ?>'
},
url : '<?= route("elfinder.connector") ?>', // connector URL
soundPath: '<?= asset($dir.'/sounds') ?>'
});
});
</script>
</head>
<body>
<!-- Element where elFinder will be created (REQUIRED) -->
<div id="elfinder"></div>
</body>
</html>
+82
View File
@@ -0,0 +1,82 @@
<!DOCTYPE html>
<html lang="{{ app()->getLocale() }}">
<head>
<meta charset="utf-8">
<title>elFinder 2.0</title>
<!-- jQuery and jQuery UI (REQUIRED) -->
<link rel="stylesheet" type="text/css" href="//ajax.googleapis.com/ajax/libs/jqueryui/1.8.23/themes/smoothness/jquery-ui.css">
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/jquery-ui.min.js"></script>
<!-- elFinder CSS (REQUIRED) -->
<link rel="stylesheet" type="text/css" href="{{ asset($dir . '/css/elfinder.min.css') }}">
<link rel="stylesheet" type="text/css" href="{{ asset($dir . '/css/theme.css') }}">
<!-- elFinder JS (REQUIRED) -->
<script src="{{ asset($dir . '/js/elfinder.min.js') }}"></script>
@if($locale)
<!-- elFinder translation (OPTIONAL) -->
<script src="{{ asset($dir . "/js/i18n/elfinder.$locale.js") }}"></script>
@endif
<!-- Include jQuery, jQuery UI, elFinder (REQUIRED) -->
<script type="text/javascript">
$().ready(function () {
var elf = $('#elfinder').elfinder({
// set your elFinder options here
@if($locale)
lang: '{{ $locale }}', // locale
@endif
customData: {
_token: '{{ csrf_token() }}'
},
url: '{{ route("elfinder.connector") }}', // connector URL
soundPath: '{{ asset($dir.'/sounds') }}',
resizable: false,
ui: ['toolbar', 'path','stat'],
onlyMimes: [{{ $mimeTypes }}],
rememberLastDir : false,
height: 300,
defaultView: 'list',
getFileCallback: function (file) {
window.parent.processSelectedFile(file, '{{ $input_id }}');
console.log(file);
},
uiOptions : {
// toolbar configuration
toolbar : [
['home', 'up'],
['upload'],
['quicklook'],
],
// directories tree options
tree : {
// expand current root on init
openRootOnLoad : true,
// auto load current dir parents
syncTree : true
},
// navbar options
navbar : {
minWidth : 150,
maxWidth : 500
},
// current working directory options
cwd : {
// display parent directory in listing as ".."
oldSchool : false
}
}
}).elfinder('instance');
});
</script>
</head>
<body style="margin: 0;">
<!-- Element where elFinder will be created (REQUIRED) -->
<div id="elfinder"></div>
</body>
</html>
+83
View File
@@ -0,0 +1,83 @@
<!DOCTYPE html>
<html lang="<?= app()->getLocale() ?>">
<head>
<meta charset="utf-8">
<title>elFinder 2.0</title>
<!-- jQuery and jQuery UI (REQUIRED) -->
<link rel="stylesheet" type="text/css" href="//ajax.googleapis.com/ajax/libs/jqueryui/1.8.23/themes/smoothness/jquery-ui.css">
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/jquery-ui.min.js"></script>
<!-- elFinder CSS (REQUIRED) -->
<link rel="stylesheet" type="text/css" href="<?= asset($dir . '/css/elfinder.min.css') ?>">
<link rel="stylesheet" type="text/css" href="<?= asset($dir . '/css/theme.css') ?>">
<!-- elFinder JS (REQUIRED) -->
<script src="<?= asset($dir . '/js/elfinder.min.js') ?>"></script>
<?php if ($locale) { ?>
<!-- elFinder translation (OPTIONAL) -->
<script src="<?= asset($dir . "/js/i18n/elfinder.$locale.js") ?>"></script>
<?php } ?>
<!-- Include jQuery, jQuery UI, elFinder (REQUIRED) -->
<script type="text/javascript">
$().ready(function () {
var elf = $('#elfinder').elfinder({
// set your elFinder options here
<?php if($locale){ ?>
lang: '<?= $locale ?>', // locale
<?php } ?>
customData: {
_token: '<?= csrf_token() ?>'
},
url: '<?= route("elfinder.connector") ?>', // connector URL
soundPath: '<?= asset($dir.'/sounds') ?>',
resizable: false,
ui: ['toolbar', 'path','stat'],
onlyMimes: [<?= $mimeTypes ?>],
rememberLastDir : false,
height: 300,
defaultView: 'list',
getFileCallback: function (file) {
window.parent.processSelectedFile(file, '<?= $input_id?>');
console.log(file);
},
uiOptions : {
// toolbar configuration
toolbar : [
['home', 'up'],
['upload'],
['quicklook'],
],
// directories tree options
tree : {
// expand current root on init
openRootOnLoad : true,
// auto load current dir parents
syncTree : true
},
// navbar options
navbar : {
minWidth : 150,
maxWidth : 500
},
// current working directory options
cwd : {
// display parent directory in listing as ".."
oldSchool : false
}
}
}).elfinder('instance');
});
</script>
</head>
<body style="margin: 0;">
<!-- Element where elFinder will be created (REQUIRED) -->
<div id="elfinder"></div>
</body>
</html>
@@ -0,0 +1,59 @@
<!DOCTYPE html>
<html lang="{{ app()->getLocale() }}">
<head>
<meta charset="utf-8">
<title>elFinder 2.0</title>
<!-- jQuery and jQuery UI (REQUIRED) -->
<link rel="stylesheet" type="text/css" href="//ajax.googleapis.com/ajax/libs/jqueryui/1.8.23/themes/smoothness/jquery-ui.css">
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/jquery-ui.min.js"></script>
<!-- elFinder CSS (REQUIRED) -->
<link rel="stylesheet" type="text/css" href="{{ asset($dir . '/css/elfinder.min.css') }}">
<link rel="stylesheet" type="text/css" href="{{ asset($dir . '/css/theme.css') }}">
<!-- elFinder JS (REQUIRED) -->
<script src="{{ asset($dir . '/js/elfinder.min.js') }}"></script>
@if($locale)
<!-- elFinder translation (OPTIONAL) -->
<script src="{{ asset($dir . "/js/i18n/elfinder.$locale.js") }}"></script>
@endif
<!-- Include jQuery, jQuery UI, elFinder (REQUIRED) -->
<script type="text/javascript">
$().ready(function () {
var elf = $('#elfinder').elfinder({
// set your elFinder options here
@if($locale)
lang: '{{ $locale }}', // locale
@endif
customData: {
_token: '{{ csrf_token() }}'
},
url: '{{ route("elfinder.connector") }}', // connector URL
soundPath: '{{ asset($dir.'/sounds') }}',
dialog: {width: 900, modal: true, title: 'Select a file'},
resizable: false,
commandsOptions: {
getfile: {
oncomplete: 'destroy'
}
},
getFileCallback: function (file) {
window.parent.processSelectedFile(file.path, '{{ $input_id }}');
parent.jQuery.colorbox.close();
}
}).elfinder('instance');
});
</script>
</head>
<body>
<!-- Element where elFinder will be created (REQUIRED) -->
<div id="elfinder"></div>
</body>
</html>
+60
View File
@@ -0,0 +1,60 @@
<!DOCTYPE html>
<html lang="<?= app()->getLocale() ?>">
<head>
<meta charset="utf-8">
<title>elFinder 2.0</title>
<!-- jQuery and jQuery UI (REQUIRED) -->
<link rel="stylesheet" type="text/css" href="//ajax.googleapis.com/ajax/libs/jqueryui/1.8.23/themes/smoothness/jquery-ui.css">
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/jquery-ui.min.js"></script>
<!-- elFinder CSS (REQUIRED) -->
<link rel="stylesheet" type="text/css" href="<?= asset($dir . '/css/elfinder.min.css') ?>">
<link rel="stylesheet" type="text/css" href="<?= asset($dir . '/css/theme.css') ?>">
<!-- elFinder JS (REQUIRED) -->
<script src="<?= asset($dir . '/js/elfinder.min.js') ?>"></script>
<?php if ($locale)
{ ?>
<!-- elFinder translation (OPTIONAL) -->
<script src="<?= asset($dir . "/js/i18n/elfinder.$locale.js") ?>"></script>
<?php } ?>
<!-- Include jQuery, jQuery UI, elFinder (REQUIRED) -->
<script type="text/javascript">
$().ready(function () {
var elf = $('#elfinder').elfinder({
// set your elFinder options here
<?php if($locale){ ?>
lang: '<?= $locale ?>', // locale
<?php } ?>
customData: {
_token: '<?= csrf_token() ?>'
},
url: '<?= route("elfinder.connector") ?>', // connector URL
soundPath: '<?= asset($dir.'/sounds') ?>',
dialog: {width: 900, modal: true, title: 'Select a file'},
resizable: false,
commandsOptions: {
getfile: {
oncomplete: 'destroy'
}
},
getFileCallback: function (file) {
window.parent.processSelectedFile(file.path, '<?= $input_id?>');
parent.jQuery.colorbox.close();
}
}).elfinder('instance');
});
</script>
</head>
<body>
<!-- Element where elFinder will be created (REQUIRED) -->
<div id="elfinder"></div>
</body>
</html>
+83
View File
@@ -0,0 +1,83 @@
<!DOCTYPE html>
<html lang="{{ app()->getLocale() }}">
<head>
<meta charset="utf-8">
<title>elFinder 2.0</title>
<!-- jQuery and jQuery UI (REQUIRED) -->
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/themes/smoothness/jquery-ui.css" />
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/jquery-ui.min.js"></script>
<!-- elFinder CSS (REQUIRED) -->
<link rel="stylesheet" type="text/css" href="{{ asset($dir.'/css/elfinder.min.css') }}">
<link rel="stylesheet" type="text/css" href="{{ asset($dir.'/css/theme.css') }}">
<!-- elFinder JS (REQUIRED) -->
<script src="{{ asset($dir.'/js/elfinder.min.js') }}"></script>
<!-- TinyMCE Popup class (REQUIRED) -->
<script type="text/javascript" src="{{ asset($dir.'/js/tiny_mce_popup.js') }}"></script>
@if($locale)
<!-- elFinder translation (OPTIONAL) -->
<script src="{{ asset($dir."/js/i18n/elfinder.$locale.js") }}"></script>
@endif
<script type="text/javascript">
var FileBrowserDialogue = {
init: function() {
// Here goes your code for setting your custom things onLoad.
},
mySubmit: function (URL) {
var win = tinyMCEPopup.getWindowArg('window');
// pass selected file path to TinyMCE
win.document.getElementById(tinyMCEPopup.getWindowArg('input')).value = URL;
// are we an image browser?
if (typeof(win.ImageDialog) != 'undefined') {
// update image dimensions
if (win.ImageDialog.getImageData) {
win.ImageDialog.getImageData();
}
// update preview if necessary
if (win.ImageDialog.showPreviewImage) {
win.ImageDialog.showPreviewImage(URL);
}
}
// close popup window
tinyMCEPopup.close();
}
}
tinyMCEPopup.onInit.add(FileBrowserDialogue.init, FileBrowserDialogue);
$().ready(function() {
var elf = $('#elfinder').elfinder({
// set your elFinder options here
@if($locale)
lang: '{{ $locale }}', // locale
@endif
customData: {
_token: '{{ csrf_token() }}'
},
url : '{{ route("elfinder.connector") }}', // connector URL
soundPath: '{{ asset($dir.'/sounds') }}',
getFileCallback: function(file) { // editor callback
FileBrowserDialogue.mySubmit(file.url); // pass selected file path to TinyMCE
}
}).elfinder('instance');
});
</script>
</head>
<body>
<!-- Element where elFinder will be created (REQUIRED) -->
<div id="elfinder"></div>
</body>
</html>
+82
View File
@@ -0,0 +1,82 @@
<!DOCTYPE html>
<html lang="<?= app()->getLocale() ?>">
<head>
<meta charset="utf-8">
<title>elFinder 2.0</title>
<!-- jQuery and jQuery UI (REQUIRED) -->
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/themes/smoothness/jquery-ui.css" />
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/jquery-ui.min.js"></script>
<!-- elFinder CSS (REQUIRED) -->
<link rel="stylesheet" type="text/css" href="<?= asset($dir.'/css/elfinder.min.css') ?>">
<link rel="stylesheet" type="text/css" href="<?= asset($dir.'/css/theme.css') ?>">
<!-- elFinder JS (REQUIRED) -->
<script src="<?= asset($dir.'/js/elfinder.min.js') ?>"></script>
<!-- TinyMCE Popup class (REQUIRED) -->
<script type="text/javascript" src="<?= asset($dir.'/js/tiny_mce_popup.js') ?>"></script>
<?php if($locale){ ?>
<!-- elFinder translation (OPTIONAL) -->
<script src="<?= asset($dir."/js/i18n/elfinder.$locale.js") ?>"></script>
<?php } ?>
<script type="text/javascript">
var FileBrowserDialogue = {
init: function() {
// Here goes your code for setting your custom things onLoad.
},
mySubmit: function (URL) {
var win = tinyMCEPopup.getWindowArg('window');
// pass selected file path to TinyMCE
win.document.getElementById(tinyMCEPopup.getWindowArg('input')).value = URL;
// are we an image browser?
if (typeof(win.ImageDialog) != 'undefined') {
// update image dimensions
if (win.ImageDialog.getImageData) {
win.ImageDialog.getImageData();
}
// update preview if necessary
if (win.ImageDialog.showPreviewImage) {
win.ImageDialog.showPreviewImage(URL);
}
}
// close popup window
tinyMCEPopup.close();
}
}
tinyMCEPopup.onInit.add(FileBrowserDialogue.init, FileBrowserDialogue);
$().ready(function() {
var elf = $('#elfinder').elfinder({
// set your elFinder options here
<?php if($locale){ ?>
lang: '<?= $locale ?>', // locale
<?php } ?>
customData: {
_token: '<?= csrf_token() ?>'
},
url : '<?= route("elfinder.connector") ?>', // connector URL
soundPath: '<?= asset($dir.'/sounds') ?>',
getFileCallback: function(file) { // editor callback
FileBrowserDialogue.mySubmit(file.url); // pass selected file path to TinyMCE
}
}).elfinder('instance');
});
</script>
</head>
<body>
<!-- Element where elFinder will be created (REQUIRED) -->
<div id="elfinder"></div>
</body>
</html>
+63
View File
@@ -0,0 +1,63 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>elFinder 2.0</title>
<!-- jQuery and jQuery UI (REQUIRED) -->
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/themes/smoothness/jquery-ui.css" />
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/jquery-ui.min.js"></script>
<!-- elFinder CSS (REQUIRED) -->
<link rel="stylesheet" type="text/css" href="{{ asset($dir.'/css/elfinder.min.css') }}">
<link rel="stylesheet" type="text/css" href="{{ asset($dir.'/css/theme.css') }}">
<!-- elFinder JS (REQUIRED) -->
<script src="{{ asset($dir.'/js/elfinder.min.js') }}"></script>
@if($locale)
<!-- elFinder translation (OPTIONAL) -->
<script src="{{ asset($dir."/js/i18n/elfinder.$locale.js") }}"></script>
@endif
<!-- elFinder initialization (REQUIRED) -->
<script type="text/javascript">
var FileBrowserDialogue = {
init: function() {
// Here goes your code for setting your custom things onLoad.
},
mySubmit: function (URL) {
// pass selected file path to TinyMCE
parent.tinymce.activeEditor.windowManager.getParams().setUrl(URL);
// close popup window
parent.tinymce.activeEditor.windowManager.close();
}
}
$().ready(function() {
var elf = $('#elfinder').elfinder({
// set your elFinder options here
@if($locale)
lang: '{{ $locale }}', // locale
@endif
customData: {
_token: '{{ csrf_token() }}'
},
url: '{{ route("elfinder.connector") }}', // connector URL
soundPath: '{{ asset($dir.'/sounds') }}',
getFileCallback: function(file) { // editor callback
FileBrowserDialogue.mySubmit(file.url); // pass selected file path to TinyMCE
}
}).elfinder('instance');
});
</script>
</head>
<body>
<!-- Element where elFinder will be created (REQUIRED) -->
<div id="elfinder"></div>
</body>
</html>
+63
View File
@@ -0,0 +1,63 @@
<!DOCTYPE html>
<html lang="<?= app()->getLocale() ?>">
<head>
<meta charset="utf-8">
<title>elFinder 2.0</title>
<!-- jQuery and jQuery UI (REQUIRED) -->
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/themes/smoothness/jquery-ui.css" />
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/jquery-ui.min.js"></script>
<!-- elFinder CSS (REQUIRED) -->
<link rel="stylesheet" type="text/css" href="<?= asset($dir.'/css/elfinder.min.css') ?>">
<link rel="stylesheet" type="text/css" href="<?= asset($dir.'/css/theme.css') ?>">
<!-- elFinder JS (REQUIRED) -->
<script src="<?= asset($dir.'/js/elfinder.min.js') ?>"></script>
<?php if($locale){ ?>
<!-- elFinder translation (OPTIONAL) -->
<script src="<?= asset($dir."/js/i18n/elfinder.$locale.js") ?>"></script>
<?php } ?>
<!-- elFinder initialization (REQUIRED) -->
<script type="text/javascript">
var FileBrowserDialogue = {
init: function() {
// Here goes your code for setting your custom things onLoad.
},
mySubmit: function (URL) {
// pass selected file path to TinyMCE
parent.tinymce.activeEditor.windowManager.getParams().setUrl(URL);
// close popup window
parent.tinymce.activeEditor.windowManager.close();
}
}
$().ready(function() {
var elf = $('#elfinder').elfinder({
// set your elFinder options here
<?php if($locale){ ?>
lang: '<?= $locale ?>', // locale
<?php } ?>
customData: {
_token: '<?= csrf_token() ?>'
},
url: '<?= route("elfinder.connector") ?>', // connector URL
soundPath: '<?= asset($dir.'/sounds') ?>',
getFileCallback: function(file) { // editor callback
FileBrowserDialogue.mySubmit(file.url); // pass selected file path to TinyMCE
}
}).elfinder('instance');
});
</script>
</head>
<body>
<!-- Element where elFinder will be created (REQUIRED) -->
<div id="elfinder"></div>
</body>
</html>
+64
View File
@@ -0,0 +1,64 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>elFinder 2.0</title>
<!-- jQuery and jQuery UI (REQUIRED) -->
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/themes/smoothness/jquery-ui.css" />
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/jquery-ui.min.js"></script>
<!-- elFinder CSS (REQUIRED) -->
<link rel="stylesheet" type="text/css" href="{{ asset($dir.'/css/elfinder.min.css') }}">
<link rel="stylesheet" type="text/css" href="{{ asset($dir.'/css/theme.css') }}">
<!-- elFinder JS (REQUIRED) -->
<script src="{{ asset($dir.'/js/elfinder.min.js') }}"></script>
@if($locale)
<!-- elFinder translation (OPTIONAL) -->
<script src="{{ asset($dir."/js/i18n/elfinder.$locale.js") }}"></script>
@endif
<!-- elFinder initialization (REQUIRED) -->
<script type="text/javascript">
var FileBrowserDialogue = {
init: function() {
// Here goes your code for setting your custom things onLoad.
},
mySubmit: function (file) {
window.parent.postMessage({
mceAction: 'fileSelected',
data: {
file: file
}
}, '*');
}
};
$().ready(function() {
var elf = $('#elfinder').elfinder({
// set your elFinder options here
@if($locale)
lang: '{{ $locale }}', // locale
@endif
customData: {
_token: '{{ csrf_token() }}'
},
url: '{{ route("elfinder.connector") }}', // connector URL
soundPath: '{{ asset($dir.'/sounds') }}',
getFileCallback: function(file) { // editor callback
FileBrowserDialogue.mySubmit(file); // pass selected file path to TinyMCE
}
}).elfinder('instance');
});
</script>
</head>
<body>
<!-- Element where elFinder will be created (REQUIRED) -->
<div id="elfinder"></div>
</body>
</html>
+64
View File
@@ -0,0 +1,64 @@
<!DOCTYPE html>
<html lang="<?= app()->getLocale() ?>">
<head>
<meta charset="utf-8">
<title>elFinder 2.0</title>
<!-- jQuery and jQuery UI (REQUIRED) -->
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/themes/smoothness/jquery-ui.css" />
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/jquery-ui.min.js"></script>
<!-- elFinder CSS (REQUIRED) -->
<link rel="stylesheet" type="text/css" href="<?= asset($dir.'/css/elfinder.min.css') ?>">
<link rel="stylesheet" type="text/css" href="<?= asset($dir.'/css/theme.css') ?>">
<!-- elFinder JS (REQUIRED) -->
<script src="<?= asset($dir.'/js/elfinder.min.js') ?>"></script>
<?php if($locale){ ?>
<!-- elFinder translation (OPTIONAL) -->
<script src="<?= asset($dir."/js/i18n/elfinder.$locale.js") ?>"></script>
<?php } ?>
<!-- elFinder initialization (REQUIRED) -->
<script type="text/javascript">
var FileBrowserDialogue = {
init: function() {
// Here goes your code for setting your custom things onLoad.
},
mySubmit: function (file) {
window.parent.postMessage({
mceAction: 'fileSelected',
data: {
file: file
}
}, '*');
}
};
$().ready(function() {
var elf = $('#elfinder').elfinder({
// set your elFinder options here
<?php if($locale){ ?>
lang: '<?= $locale ?>', // locale
<?php } ?>
customData: {
_token: '<?= csrf_token() ?>'
},
url: '<?= route("elfinder.connector") ?>', // connector URL
soundPath: '<?= asset($dir.'/sounds') ?>',
getFileCallback: function(file) { // editor callback
FileBrowserDialogue.mySubmit(file); // pass selected file path to TinyMCE
}
}).elfinder('instance');
});
</script>
</head>
<body>
<!-- Element where elFinder will be created (REQUIRED) -->
<div id="elfinder"></div>
</body>
</html>
+327
View File
@@ -0,0 +1,327 @@
<?php use App\Contents; ?>
@extends('layouts.app')
@section("title",__('Title'))
@section('content')
<!-- Slider -->
<section class="owl-carousel owl-theme h-auto" id="mainSlider2">
<?php $k = 0; $slider = Contents::where("type","Slider")->where("y","1")->get(); foreach($slider AS $s) {
$j = json_decode($s->json,true);
?>
<div class="item">
<a href="{{__($s->slug)}}" class="w-full-h-auto">
<img class="w-full-h-auto" src="{{url('storage/app/files/'.$s->cover)}}" alt="{{__(@$j['Title_1'])}}">
</a>
<div class="container-fluid">
<div class="row">
<div class="col-10 offset-1 col-md-10 offset-md-1 slider-texts">
<a href="{{__($s->slug)}}" class="w-full-h-auto">
<h3 class="first-line color-white white-text-shadow t-left fs-3rem w-full animated slideInRight">
{{__(@$j['Title_1'])}}
</h3>
<h3 class="second-line color-white white-text-shadow t-left fs-2rem w-full animated slideInRight delay-1s">
{{__(@$j['Title_2'])}}
</h3>
<h3 class="third-line color-white white-text-shadow t-left fs-1rem w-full animated slideInRight delay-1s">
{{__(@$j['Title_3'])}}
</h3>
</a>
</div>
</div>
</div>
</div>
<?php $k++; } ?>
</section>
<!-- Services -->
<section class="default-section large">
<div class="container">
<div class="row">
<h1 class="t-center fs-5rem w-full">{{__('Services')}}</h1>
<p class="tr-fancy-subtitle w-full t-center">
<span>{{__('Our Services')}}</span>
</p>
<?php
$services = Contents::where("kid","services")->take(4)->get();
foreach($services AS $s)
{
$j = json_decode($s['json'],true);
?>
<div class="col-12 col-sm-6 col-md-3 mt-10-xs-else-md">
<div class="tr-card">
<img class="w-full-h-auto card-img" src="{{url('storage/app/files/'.$s->cover)}}" alt="TR-CARD">
<h3 class="w-full-h-auto mt-10 t-center">
{{__($s->title)}}
</h3>
<p class="w-full-h-auto t-justify card-p">
{{__(@$j['Description'])}}
</p>
<a href="{{url($s->slug)}}" class="btn btn-info border-radius-5 color-white m-0-auto bg-color-2">{{__('Explore')}}</a>
</div>
</div>
<?php
}
?>
</div>
<a href="{{url('services')}}" class="btn btn-info border-radius-5 color-white bg-color-2 mt-50 m-0-auto plr-30">{{__('Explore All')}}</a>
</div>
</section>
<!-- Services -->
<section class="parallax-section h-70vh" style="background-image: url(storage/app/files/2019/10/sliders-consulting-011658.jpeg);"></section>
<!-- Descriptions -->
<section class="default-section large bg-e">
<div class="container">
<div class="row">
<h1 class="t-center fs-5rem w-full color-1-site">SHS</h1>
<p class="tr-fancy-subtitle w-full t-center">
<span class="bg-e-i color-2">Training</span>
</p>
<div class="col-12 col-md-6">
<ul class="tick-icon w-full">
<li>
<h3>{{__('Training Title 1')}}</h3>
<p class="t-justify">
{{__('Training 1 Description')}}
</p>
</li>
<li>
<h3>{{__('Training Title 2')}}</h3>
<p class="t-justify">
{{__('Training 2 Description')}}
</p>
</li>
<li>
<h3>{{__('Training Title 3')}}</h3>
<p class="t-justify">
{{__('Training 3 Description')}}
</p>
</li>
<li>
<h3>{{__('Training Title 4')}}</h3>
<p class="t-justify">
{{__('Training 4 Description')}}
</p>
</li>
<li>
<h3>{{__('Training Title 5')}}</h3>
<p class="t-justify">
{{__('Training 5 Description')}}
</p>
</li>
</ul>
</div>
<div class="col-12 col-md-6 mt-10-xs-else-md">
<p class="w-full t-justify">
{!! __('Training <br /> Right Description') !!}
</p>
</div>
</div>
</div>
</section>
<!-- /Desctiptions -->
<!-- Parallax -->
<section class="parallax-section-with-height" style="background-image: url(assets/images/parallax-section.jpg)">
<h1 class="parallax-section-title color-white white-text-shadow w-full t-center pl-0">
{{__('You are precious')}}
</h1>
</section>
<!-- /Parallax -->
<!-- Schedule -->
<section class="default-section large">
<div class="container">
<div class="row">
<h1 class="t-center fs-5rem w-full color-1-site">{{__('Schedule')}}</h1>
<p class="tr-fancy-subtitle w-full t-center mb-50">
<span class="bg-f color-3">{{__('Plan')}}</span>
</p>
<div class="col-12 col-md-4">
<div class="row">
<div class="col-12 calendar cal-light">
<div class="calendar_header">
<h1 class="header_title">SHS Training</h1>
<p class="header_copy"> Calendar Plan</p>
</div>
<?php $son = Contents::where("kid","courses")
->orderBy("json->Course_Date","ASC")
->first();
$js = j($son->json);
?>
<div class="calendar_plan">
<div class="cl_plan">
<div class="cl_title">{{__('Soon')}}</div>
<div class="cl_copy">{{$son->title}} <br /><small>{{$js['Course_Date']}}</small></div>
<a href="{{url($son->slug)}}" class="cl_add">
<i class="fas fa-plus"></i>
</a>
</div>
+19
View File
@@ -0,0 +1,19 @@
<table class="action" align="center" width="100%" cellpadding="0" cellspacing="0" role="presentation">
<tr>
<td align="center">
<table width="100%" border="0" cellpadding="0" cellspacing="0" role="presentation">
<tr>
<td align="center">
<table border="0" cellpadding="0" cellspacing="0" role="presentation">
<tr>
<td>
<a href="{{ $url }}" class="button button-{{ $color ?? 'primary' }}" target="_blank">{{ $slot }}</a>
</td>
</tr>
</table>
</td>
</tr>
</table>
</td>
</tr>
</table>
+11
View File
@@ -0,0 +1,11 @@
<tr>
<td>
<table class="footer" align="center" width="570" cellpadding="0" cellspacing="0" role="presentation">
<tr>
<td class="content-cell" align="center">
{{ Illuminate\Mail\Markdown::parse($slot) }}
</td>
</tr>
</table>
</td>
</tr>
+7
View File
@@ -0,0 +1,7 @@
<tr>
<td class="header">
<a href="{{ $url }}">
{{ $slot }}
</a>
</td>
</tr>
+54
View File
@@ -0,0 +1,54 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<style>
@media only screen and (max-width: 600px) {
.inner-body {
width: 100% !important;
}
.footer {
width: 100% !important;
}
}
@media only screen and (max-width: 500px) {
.button {
width: 100% !important;
}
}
</style>
<table class="wrapper" width="100%" cellpadding="0" cellspacing="0" role="presentation">
<tr>
<td align="center">
<table class="content" width="100%" cellpadding="0" cellspacing="0" role="presentation">
{{ $header ?? '' }}
<!-- Email Body -->
<tr>
<td class="body" width="100%" cellpadding="0" cellspacing="0">
<table class="inner-body" align="center" width="570" cellpadding="0" cellspacing="0" role="presentation">
<!-- Body content -->
<tr>
<td class="content-cell">
{{ Illuminate\Mail\Markdown::parse($slot) }}
{{ $subcopy ?? '' }}
</td>
</tr>
</table>
</td>
</tr>
{{ $footer ?? '' }}
</table>
</td>
</tr>
</table>
</body>
</html>
+27
View File
@@ -0,0 +1,27 @@
@component('mail::layout')
{{-- Header --}}
@slot('header')
@component('mail::header', ['url' => config('app.url')])
{{ config('app.name') }}
@endcomponent
@endslot
{{-- Body --}}
{{ $slot }}
{{-- Subcopy --}}
@isset($subcopy)
@slot('subcopy')
@component('mail::subcopy')
{{ $subcopy }}
@endcomponent
@endslot
@endisset
{{-- Footer --}}
@slot('footer')
@component('mail::footer')
© {{ date('Y') }} {{ config('app.name') }}. @lang('All rights reserved.')
@endcomponent
@endslot
@endcomponent
+13
View File
@@ -0,0 +1,13 @@
<table class="panel" width="100%" cellpadding="0" cellspacing="0" role="presentation">
<tr>
<td class="panel-content">
<table width="100%" cellpadding="0" cellspacing="0" role="presentation">
<tr>
<td class="panel-item">
{{ Illuminate\Mail\Markdown::parse($slot) }}
</td>
</tr>
</table>
</td>
</tr>
</table>
+7
View File
@@ -0,0 +1,7 @@
<table class="promotion" align="center" width="100%" cellpadding="0" cellspacing="0" role="presentation">
<tr>
<td align="center">
{{ Illuminate\Mail\Markdown::parse($slot) }}
</td>
</tr>
</table>
@@ -0,0 +1,13 @@
<table width="100%" border="0" cellpadding="0" cellspacing="0" role="presentation">
<tr>
<td align="center">
<table border="0" cellpadding="0" cellspacing="0" role="presentation">
<tr>
<td>
<a href="{{ $url }}" class="button button-green" target="_blank">{{ $slot }}</a>
</td>
</tr>
</table>
</td>
</tr>
</table>
+7
View File
@@ -0,0 +1,7 @@
<table class="subcopy" width="100%" cellpadding="0" cellspacing="0" role="presentation">
<tr>
<td>
{{ Illuminate\Mail\Markdown::parse($slot) }}
</td>
</tr>
</table>
+3
View File
@@ -0,0 +1,3 @@
<div class="table">
{{ Illuminate\Mail\Markdown::parse($slot) }}
</div>
+292
View File
@@ -0,0 +1,292 @@
/* Base */
body,
body *:not(html):not(style):not(br):not(tr):not(code) {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif,
'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol';
box-sizing: border-box;
}
body {
background-color: #f8fafc;
color: #74787e;
height: 100%;
hyphens: auto;
line-height: 1.4;
margin: 0;
-moz-hyphens: auto;
-ms-word-break: break-all;
width: 100% !important;
-webkit-hyphens: auto;
-webkit-text-size-adjust: none;
word-break: break-all;
word-break: break-word;
}
p,
ul,
ol,
blockquote {
line-height: 1.4;
text-align: left;
}
a {
color: #3869d4;
}
a img {
border: none;
}
/* Typography */
h1 {
color: #3d4852;
font-size: 19px;
font-weight: bold;
margin-top: 0;
text-align: left;
}
h2 {
color: #3d4852;
font-size: 16px;
font-weight: bold;
margin-top: 0;
text-align: left;
}
h3 {
color: #3d4852;
font-size: 14px;
font-weight: bold;
margin-top: 0;
text-align: left;
}
p {
color: #3d4852;
font-size: 16px;
line-height: 1.5em;
margin-top: 0;
text-align: left;
}
p.sub {
font-size: 12px;
}
img {
max-width: 100%;
}
/* Layout */
.wrapper {
background-color: #f8fafc;
margin: 0;
padding: 0;
width: 100%;
-premailer-cellpadding: 0;
-premailer-cellspacing: 0;
-premailer-width: 100%;
}
.content {
margin: 0;
padding: 0;
width: 100%;
-premailer-cellpadding: 0;
-premailer-cellspacing: 0;
-premailer-width: 100%;
}
/* Header */
.header {
padding: 25px 0;
text-align: center;
}
.header a {
color: #bbbfc3;
font-size: 19px;
font-weight: bold;
text-decoration: none;
text-shadow: 0 1px 0 white;
}
/* Body */
.body {
background-color: #ffffff;
border-bottom: 1px solid #edeff2;
border-top: 1px solid #edeff2;
margin: 0;
padding: 0;
width: 100%;
-premailer-cellpadding: 0;
-premailer-cellspacing: 0;
-premailer-width: 100%;
}
.inner-body {
background-color: #ffffff;
margin: 0 auto;
padding: 0;
width: 570px;
-premailer-cellpadding: 0;
-premailer-cellspacing: 0;
-premailer-width: 570px;
}
/* Subcopy */
.subcopy {
border-top: 1px solid #edeff2;
margin-top: 25px;
padding-top: 25px;
}
.subcopy p {
font-size: 12px;
}
/* Footer */
.footer {
margin: 0 auto;
padding: 0;
text-align: center;
width: 570px;
-premailer-cellpadding: 0;
-premailer-cellspacing: 0;
-premailer-width: 570px;
}
.footer p {
color: #aeaeae;
font-size: 12px;
text-align: center;
}
/* Tables */
.table table {
margin: 30px auto;
width: 100%;
-premailer-cellpadding: 0;
-premailer-cellspacing: 0;
-premailer-width: 100%;
}
.table th {
border-bottom: 1px solid #edeff2;
padding-bottom: 8px;
margin: 0;
}
.table td {
color: #74787e;
font-size: 15px;
line-height: 18px;
padding: 10px 0;
margin: 0;
}
.content-cell {
padding: 35px;
}
/* Buttons */
.action {
margin: 30px auto;
padding: 0;
text-align: center;
width: 100%;
-premailer-cellpadding: 0;
-premailer-cellspacing: 0;
-premailer-width: 100%;
}
.button {
border-radius: 3px;
box-shadow: 0 2px 3px rgba(0, 0, 0, 0.16);
color: #fff;
display: inline-block;
text-decoration: none;
-webkit-text-size-adjust: none;
}
.button-blue,
.button-primary {
background-color: #3490dc;
border-top: 10px solid #3490dc;
border-right: 18px solid #3490dc;
border-bottom: 10px solid #3490dc;
border-left: 18px solid #3490dc;
}
.button-green,
.button-success {
background-color: #38c172;
border-top: 10px solid #38c172;
border-right: 18px solid #38c172;
border-bottom: 10px solid #38c172;
border-left: 18px solid #38c172;
}
.button-red,
.button-error {
background-color: #e3342f;
border-top: 10px solid #e3342f;
border-right: 18px solid #e3342f;
border-bottom: 10px solid #e3342f;
border-left: 18px solid #e3342f;
}
/* Panels */
.panel {
margin: 0 0 21px;
}
.panel-content {
background-color: #f1f5f8;
padding: 16px;
}
.panel-item {
padding: 0;
}
.panel-item p:last-of-type {
margin-bottom: 0;
padding-bottom: 0;
}
/* Promotions */
.promotion {
background-color: #ffffff;
border: 2px dashed #9ba2ab;
margin: 0;
margin-bottom: 25px;
margin-top: 25px;
padding: 24px;
width: 100%;
-premailer-cellpadding: 0;
-premailer-cellspacing: 0;
-premailer-width: 100%;
}
.promotion h1 {
text-align: center;
}
.promotion p {
font-size: 15px;
text-align: center;
}
+1
View File
@@ -0,0 +1 @@
{{ $slot }}: {{ $url }}
+1
View File
@@ -0,0 +1 @@
{{ $slot }}
+1
View File
@@ -0,0 +1 @@
[{{ $slot }}]({{ $url }})
+9
View File
@@ -0,0 +1,9 @@
{!! strip_tags($header) !!}
{!! strip_tags($slot) !!}
@isset($subcopy)
{!! strip_tags($subcopy) !!}
@endisset
{!! strip_tags($footer) !!}
+27
View File
@@ -0,0 +1,27 @@
@component('mail::layout')
{{-- Header --}}
@slot('header')
@component('mail::header', ['url' => config('app.url')])
{{ config('app.name') }}
@endcomponent
@endslot
{{-- Body --}}
{{ $slot }}
{{-- Subcopy --}}
@isset($subcopy)
@slot('subcopy')
@component('mail::subcopy')
{{ $subcopy }}
@endcomponent
@endslot
@endisset
{{-- Footer --}}
@slot('footer')
@component('mail::footer')
© {{ date('Y') }} {{ config('app.name') }}. @lang('All rights reserved.')
@endcomponent
@endslot
@endcomponent
+1
View File
@@ -0,0 +1 @@
{{ $slot }}
+1
View File
@@ -0,0 +1 @@
{{ $slot }}
@@ -0,0 +1 @@
[{{ $slot }}]({{ $url }})
+1
View File
@@ -0,0 +1 @@
{{ $slot }}
+1
View File
@@ -0,0 +1 @@
{{ $slot }}
+63
View File
@@ -0,0 +1,63 @@
@component('mail::message')
{{-- Greeting --}}
@if (! empty($greeting))
# {{ $greeting }}
@else
@if ($level === 'error')
# @lang('Whoops!')
@else
# @lang('Hello!')
@endif
@endif
{{-- Intro Lines --}}
@foreach ($introLines as $line)
{{ $line }}
@endforeach
{{-- Action Button --}}
@isset($actionText)
<?php
switch ($level) {
case 'success':
case 'error':
$color = $level;
break;
default:
$color = 'primary';
}
?>
@component('mail::button', ['url' => $actionUrl, 'color' => $color])
{{ $actionText }}
@endcomponent
@endisset
{{-- Outro Lines --}}
@foreach ($outroLines as $line)
{{ $line }}
@endforeach
{{-- Salutation --}}
@if (! empty($salutation))
{{ $salutation }}
@else
@lang('Regards'),<br>
{{ config('app.name') }}
@endif
{{-- Subcopy --}}
@isset($actionText)
@slot('subcopy')
@lang(
"If youre having trouble clicking the \":actionText\" button, copy and paste the URL below\n".
'into your web browser: [:actionURL](:actionURL)',
[
'actionText' => $actionText,
'actionURL' => $actionUrl,
]
)
@endslot
@endisset
@endcomponent
+44
View File
@@ -0,0 +1,44 @@
@if ($paginator->hasPages())
<ul class="pagination" role="navigation">
{{-- Previous Page Link --}}
@if ($paginator->onFirstPage())
<li class="page-item disabled" aria-disabled="true" aria-label="@lang('pagination.previous')">
<span class="page-link" aria-hidden="true">&lsaquo;</span>
</li>
@else
<li class="page-item">
<a class="page-link" href="{{ $paginator->previousPageUrl() }}" rel="prev" aria-label="@lang('pagination.previous')">&lsaquo;</a>
</li>
@endif
{{-- Pagination Elements --}}
@foreach ($elements as $element)
{{-- "Three Dots" Separator --}}
@if (is_string($element))
<li class="page-item disabled" aria-disabled="true"><span class="page-link">{{ $element }}</span></li>
@endif
{{-- Array Of Links --}}
@if (is_array($element))
@foreach ($element as $page => $url)
@if ($page == $paginator->currentPage())
<li class="page-item active" aria-current="page"><span class="page-link">{{ $page }}</span></li>
@else
<li class="page-item"><a class="page-link" href="{{ $url }}">{{ $page }}</a></li>
@endif
@endforeach
@endif
@endforeach
{{-- Next Page Link --}}
@if ($paginator->hasMorePages())
<li class="page-item">
<a class="page-link" href="{{ $paginator->nextPageUrl() }}" rel="next" aria-label="@lang('pagination.next')">&rsaquo;</a>
</li>
@else
<li class="page-item disabled" aria-disabled="true" aria-label="@lang('pagination.next')">
<span class="page-link" aria-hidden="true">&rsaquo;</span>
</li>
@endif
</ul>
@endif
+44
View File
@@ -0,0 +1,44 @@
@if ($paginator->hasPages())
<ul class="pagination" role="navigation">
{{-- Previous Page Link --}}
@if ($paginator->onFirstPage())
<li class="disabled" aria-disabled="true" aria-label="@lang('pagination.previous')">
<span aria-hidden="true">&lsaquo;</span>
</li>
@else
<li>
<a href="{{ $paginator->previousPageUrl() }}" rel="prev" aria-label="@lang('pagination.previous')">&lsaquo;</a>
</li>
@endif
{{-- Pagination Elements --}}
@foreach ($elements as $element)
{{-- "Three Dots" Separator --}}
@if (is_string($element))
<li class="disabled" aria-disabled="true"><span>{{ $element }}</span></li>
@endif
{{-- Array Of Links --}}
@if (is_array($element))
@foreach ($element as $page => $url)
@if ($page == $paginator->currentPage())
<li class="active" aria-current="page"><span>{{ $page }}</span></li>
@else
<li><a href="{{ $url }}">{{ $page }}</a></li>
@endif
@endforeach
@endif
@endforeach
{{-- Next Page Link --}}
@if ($paginator->hasMorePages())
<li>
<a href="{{ $paginator->nextPageUrl() }}" rel="next" aria-label="@lang('pagination.next')">&rsaquo;</a>
</li>
@else
<li class="disabled" aria-disabled="true" aria-label="@lang('pagination.next')">
<span aria-hidden="true">&rsaquo;</span>
</li>
@endif
</ul>
@endif
+36
View File
@@ -0,0 +1,36 @@
@if ($paginator->hasPages())
<div class="ui pagination menu" role="navigation">
{{-- Previous Page Link --}}
@if ($paginator->onFirstPage())
<a class="icon item disabled" aria-disabled="true" aria-label="@lang('pagination.previous')"> <i class="left chevron icon"></i> </a>
@else
<a class="icon item" href="{{ $paginator->previousPageUrl() }}" rel="prev" aria-label="@lang('pagination.previous')"> <i class="left chevron icon"></i> </a>
@endif
{{-- Pagination Elements --}}
@foreach ($elements as $element)
{{-- "Three Dots" Separator --}}
@if (is_string($element))
<a class="icon item disabled" aria-disabled="true">{{ $element }}</a>
@endif
{{-- Array Of Links --}}
@if (is_array($element))
@foreach ($element as $page => $url)
@if ($page == $paginator->currentPage())
<a class="item active" href="{{ $url }}" aria-current="page">{{ $page }}</a>
@else
<a class="item" href="{{ $url }}">{{ $page }}</a>
@endif
@endforeach
@endif
@endforeach
{{-- Next Page Link --}}
@if ($paginator->hasMorePages())
<a class="icon item" href="{{ $paginator->nextPageUrl() }}" rel="next" aria-label="@lang('pagination.next')"> <i class="right chevron icon"></i> </a>
@else
<a class="icon item disabled" aria-disabled="true" aria-label="@lang('pagination.next')"> <i class="right chevron icon"></i> </a>
@endif
</div>
@endif
@@ -0,0 +1,25 @@
@if ($paginator->hasPages())
<ul class="pagination" role="navigation">
{{-- Previous Page Link --}}
@if ($paginator->onFirstPage())
<li class="page-item disabled" aria-disabled="true">
<span class="page-link">@lang('pagination.previous')</span>
</li>
@else
<li class="page-item">
<a class="page-link" href="{{ $paginator->previousPageUrl() }}" rel="prev">@lang('pagination.previous')</a>
</li>
@endif
{{-- Next Page Link --}}
@if ($paginator->hasMorePages())
<li class="page-item">
<a class="page-link" href="{{ $paginator->nextPageUrl() }}" rel="next">@lang('pagination.next')</a>
</li>
@else
<li class="page-item disabled" aria-disabled="true">
<span class="page-link">@lang('pagination.next')</span>
</li>
@endif
</ul>
@endif
@@ -0,0 +1,17 @@
@if ($paginator->hasPages())
<ul class="pagination" role="navigation">
{{-- Previous Page Link --}}
@if ($paginator->onFirstPage())
<li class="disabled" aria-disabled="true"><span>@lang('pagination.previous')</span></li>
@else
<li><a href="{{ $paginator->previousPageUrl() }}" rel="prev">@lang('pagination.previous')</a></li>
@endif
{{-- Next Page Link --}}
@if ($paginator->hasMorePages())
<li><a href="{{ $paginator->nextPageUrl() }}" rel="next">@lang('pagination.next')</a></li>
@else
<li class="disabled" aria-disabled="true"><span>@lang('pagination.next')</span></li>
@endif
</ul>
@endif
@@ -0,0 +1,3 @@
@if($authenticated)@component('scribe::components.badges.base', ['colour' => "darkred", 'text' => 'requires authentication'])
@endcomponent
@endif
@@ -0,0 +1 @@
<small class="badge badge-{{ $colour }}">{{ $text }}</small>
@@ -0,0 +1,5 @@
@if($deprecated !== false)
@php($text = $deprecated === true ? 'deprecated' : "deprecated:$deprecated")
@component('scribe::components.badges.base', ['colour' => 'darkgoldenrod', 'text' => $text])
@endcomponent
@endif
@@ -0,0 +1,5 @@
@component('scribe::components.badges.base', [
'colour' => \Knuckles\Scribe\Tools\WritingUtils::$httpMethodToCssColour[$method],
'text' => $method,
])
@endcomponent
@@ -0,0 +1,76 @@
@php
$html ??= []; $class = $html['class'] ?? null;
@endphp
<b style="line-height: 2;"><code>{{ $name }}</code></b>&nbsp;&nbsp;
@if($type)<small>{{ $type }}</small>@endif&nbsp;
@if($isInput && !$required)<i>optional</i>@endif &nbsp;
@if($isInput && $deprecated)<i>deprecated</i>@endif &nbsp;
@if($isInput && empty($hasChildren))
@php
$isList = Str::endsWith($type, '[]');
$fullName = str_replace('[]', '.0', $fullName ?? $name);
$baseType = $isList ? substr($type, 0, -2) : $type;
// Ignore the first '[]': the frontend will take care of it
while (\Str::endsWith($baseType, '[]')) {
$fullName .= '.0';
$baseType = substr($baseType, 0, -2);
}
// When the body is an array, the item names will be ".0.thing"
$fullName = ltrim($fullName, '.');
$inputType = match($baseType) {
'number', 'integer' => 'number',
'file' => 'file',
default => 'text',
};
@endphp
@if($type === 'boolean')
<label data-endpoint="{{ $endpointId }}" style="display: none">
<input type="radio" name="{{ $fullName }}"
value="{{$component === 'body' ? 'true' : 1}}"
data-endpoint="{{ $endpointId }}"
data-component="{{ $component }}" @if($class)class="{{ $class }}"@endif
>
<code>true</code>
</label>
<label data-endpoint="{{ $endpointId }}" style="display: none">
<input type="radio" name="{{ $fullName }}"
value="{{$component === 'body' ? 'false' : 0}}"
data-endpoint="{{ $endpointId }}"
data-component="{{ $component }}" @if($class)class="{{ $class }}"@endif
>
<code>false</code>
</label>
@elseif($isList)
<input type="{{ $inputType }}" style="display: none"
@if($inputType === 'number')step="any"@endif
name="{{ $fullName."[0]" }}" @if($class)class="{{ $class }}"@endif
data-endpoint="{{ $endpointId }}"
data-component="{{ $component }}">
<input type="{{ $inputType }}" style="display: none"
name="{{ $fullName."[1]" }}" @if($class)class="{{ $class }}"@endif
data-endpoint="{{ $endpointId }}"
data-component="{{ $component }}">
@else
<input type="{{ $inputType }}" style="display: none"
@if($inputType === 'number')step="any"@endif
name="{{ $fullName }}" @if($class)class="{{ $class }}"@endif
data-endpoint="{{ $endpointId }}"
value="{!! (isset($example) && (is_string($example) || is_numeric($example))) ? $example : '' !!}"
data-component="{{ $component }}">
@endif
@endif
<br>
@php
if($example !== null && $example !== '' && !is_array($example)) {
$exampleAsString = $example;
if (is_bool($example)) {
$exampleAsString = $example ? "true" : "false";
}
$description .= " Example: `$exampleAsString`";
}
@endphp
{!! Parsedown::instance()->text(trim($description)) !!}
@if(!empty($enumValues))
Must be one of:
<ul style="list-style-type: square;">{!! implode(" ", array_map(fn($val) => "<li><code>$val</code></li>", $enumValues)) !!}</ul>
@endif
@@ -0,0 +1,105 @@
@php
$isInput ??= true;
$level ??= 0;
@endphp
@foreach($fields as $name => $field)
@if($name === '[]')
@php
$description = "The request body is an array (<code>{$field['type']}</code>`)";
$description .= !empty($field['description']) ? ", representing ".lcfirst($field['description'])."." : '.';
if(count($field['__fields'])) $description .= " Each item has the following properties:";
@endphp
{!! Parsedown::instance()->text($description) !!}
@foreach($field['__fields'] as $subfieldName => $subfield)
@if(!empty($subfield['__fields']))
<x-scribe::nested-fields
:fields="[$subfieldName => $subfield]" :endpointId="$endpointId" :isInput="$isInput" :level="$level + 2"
/>
@else
<div style="margin-left: {{ ($level + 2) * 14 }}px; clear: unset;">
@component('scribe::components.field-details', [
'name' => $subfieldName,
'fullName' => $subfield['name'],
'type' => $subfield['type'] ?? 'string',
'required' => $subfield['required'] ?? false,
'deprecated' => $subfield['deprecated'] ?? false,
'description' => $subfield['description'] ?? '',
'example' => $subfield['example'] ?? '',
'enumValues' => $subfield['enumValues'] ?? null,
'endpointId' => $endpointId,
'hasChildren' => false,
'component' => 'body',
'isInput' => $isInput,
])
@endcomponent
</div>
@endif
@endforeach
@elseif(!empty($field['__fields']))
<div style="@if($level) margin-left: {{ $level * 14 }}px;@else padding-left: 28px; @endif clear: unset;">
<details>
<summary style="padding-bottom: 10px;">
@component('scribe::components.field-details', [
'name' => $name,
'fullName' => $field['name'],
'type' => $field['type'] ?? 'string',
'required' => $field['required'] ?? false,
'deprecated' => $field['deprecated'] ?? false,
'description' => $field['description'] ?? '',
'example' => $field['example'] ?? '',
'enumValues' => $field['enumValues'] ?? null,
'endpointId' => $endpointId,
'hasChildren' => true,
'component' => 'body',
'isInput' => $isInput,
])
@endcomponent
</summary>
@foreach($field['__fields'] as $subfieldName => $subfield)
@if(!empty($subfield['__fields']))
<x-scribe::nested-fields
:fields="[$subfieldName => $subfield]" :endpointId="$endpointId" :isInput="$isInput" :level="$level + 1"
/>
@else
<div style="margin-left: {{ ($level + 1) * 14 }}px; clear: unset;">
@component('scribe::components.field-details', [
'name' => $subfieldName,
'fullName' => $subfield['name'],
'type' => $subfield['type'] ?? 'string',
'required' => $subfield['required'] ?? false,
'deprecated' => $subfield['deprecated'] ?? false,
'description' => $subfield['description'] ?? '',
'example' => $subfield['example'] ?? '',
'enumValues' => $subfield['enumValues'] ?? null,
'endpointId' => $endpointId,
'hasChildren' => false,
'component' => 'body',
'isInput' => $isInput,
])
@endcomponent
</div>
@endif
@endforeach
</details>
</div>
@else
<div style="@if($level) margin-left: {{ ($level + 1) * 14 }}px;@else padding-left: 28px; @endif clear: unset;">
@component('scribe::components.field-details', [
'name' => $name,
'fullName' => $field['name'],
'type' => $field['type'] ?? 'string',
'required' => $field['required'] ?? false,
'deprecated' => $field['deprecated'] ?? false,
'description' => $field['description'] ?? '',
'example' => $field['example'] ?? '',
'enumValues' => $field['enumValues'] ?? null,
'endpointId' => $endpointId,
'hasChildren' => false,
'component' => 'body',
'isInput' => $isInput,
])
@endcomponent
</div>
@endif
@endforeach
@@ -0,0 +1,34 @@
<!-- See https://github.com/stoplightio/elements/blob/main/docs/getting-started/elements/elements-options.md for config -->
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>{!! $metadata['title'] !!}</title>
<!-- Embed elements Elements via Web Component -->
<script src="https://unpkg.com/@stoplight/elements/web-components.min.js"></script>
<link rel="stylesheet" href="https://unpkg.com/@stoplight/elements/styles.min.css">
<style>
body {
height: 100vh;
}
</style>
</head>
<body>
<elements-api
@foreach($htmlAttributes as $attribute => $value)
{{-- Attributes specified first override later ones --}}
{!! $attribute !!}="{!! $value !!}"
@endforeach
apiDescriptionUrl="{!! $metadata['openapi_spec_url'] !!}"
router="hash"
layout="sidebar"
hideTryIt="{!! ($tryItOut['enabled'] ?? true) ? '' : 'true'!!}"
@if(!empty($metadata['logo']))
logo="{!! $metadata['logo'] !!}"
@endif
/>
</body>
</html>
@@ -0,0 +1,23 @@
<!-- See https://rapidocweb.com/api.html for options -->
<!doctype html> <!-- Important: must specify -->
<html>
<head>
<meta charset="utf-8"> <!-- Important: rapi-doc uses utf8 characters -->
<script type="module" src="https://unpkg.com/rapidoc/dist/rapidoc-min.js"></script>
</head>
<body>
<rapi-doc
@foreach($htmlAttributes as $attribute => $value)
{{-- Attributes specified first override later ones --}}
{!! $attribute !!}="{!! $value !!}"
@endforeach
spec-url="{!! $metadata['openapi_spec_url'] !!}"
render-style="read"
allow-try="{!! ($tryItOut['enabled'] ?? true) ? 'true' : 'false'!!}"
>
@if($metadata['logo'])
<img slot="logo" src="{!! $metadata['logo'] !!}"/>
@endif
</rapi-doc>
</body>
</html>
+140
View File
@@ -0,0 +1,140 @@
<!doctype html>
<html>
<head>
<title>{!! $metadata['title'] !!}</title>
<meta charset="utf-8"/>
<meta
name="viewport"
content="width=device-width, initial-scale=1"/>
<style>
body {
margin: 0;
}
#token-manager {
position: fixed;
bottom: 20px;
right: 20px;
z-index: 99999;
background: #1e1e20;
padding: 15px;
border-radius: 8px;
box-shadow: 0 4px 12px rgba(0,0,0,0.5);
font-family: sans-serif;
display: flex;
gap: 10px;
align-items: center;
border: 1px solid #333;
}
#token-manager input {
padding: 8px;
border-radius: 4px;
border: 1px solid #444;
background: #2d2d30;
color: #fff;
width: 250px;
outline: none;
}
#token-manager button {
padding: 8px 15px;
border-radius: 4px;
border: none;
background: #6c5ce7;
color: white;
cursor: pointer;
font-weight: bold;
}
#token-manager button:hover {
background: #5b4cc4;
}
</style>
</head>
<body>
<!-- Token Manager UI -->
<div id="token-manager">
<input type="text" id="manual-token-input" placeholder="Paste your Bearer Token here...">
<button onclick="saveManualToken()">Save & Reload</button>
</div>
<script>
function saveManualToken() {
const token = document.getElementById('manual-token-input').value.trim();
if(token) {
localStorage.setItem('token', token);
// Also ensure configuration is updated before reload (optional but good for consistency)
alert('Token saved to localStorage! The page will reload.');
window.location.reload();
} else {
localStorage.removeItem('token');
alert('Token removed from localStorage!');
window.location.reload();
}
}
// Load existing token into input for visibility
// Run immediately to avoid flash if possible, or on load
window.addEventListener('load', function() {
const token = localStorage.getItem('token') || localStorage.getItem('access_token');
if(token) {
const input = document.getElementById('manual-token-input');
if(input) input.value = token;
}
});
</script>
<script
id="api-reference"
@foreach($htmlAttributes as $attribute => $value)
{{-- Attributes specified first override later ones --}}
{!! $attribute !!}="{!! $value !!}"
@endforeach
data-url="{!! $metadata['openapi_spec_url'] !!}">
</script>
<script>
// Auto-fill auth token from localStorage for Scribe/Scalar
// Runs immediately after the element is defined but before Scalar loads
(function() {
try {
const token = localStorage.getItem('token') || localStorage.getItem('access_token') || localStorage.getItem('auth_token');
if (token) {
const referenceElement = document.getElementById('api-reference');
if (referenceElement) {
// Prepare Scalar configuration
const config = {
authentication: {
preferredSecurityScheme: 'default',
http: {
bearer: {
token: token
}
}
}
};
// Merge with existing configuration
let existingConfig = {};
try {
if (referenceElement.dataset.configuration) {
existingConfig = JSON.parse(referenceElement.dataset.configuration);
}
} catch (e) {
console.error('Error parsing Scalar config:', e);
}
const newConfig = { ...existingConfig, ...config };
// Update the attribute synchronously before Scalar script loads
referenceElement.dataset.configuration = JSON.stringify(newConfig);
}
}
} catch (e) {
console.error('Error auto-filling token:', e);
}
})();
</script>
<script src="https://cdn.jsdelivr.net/npm/@scalar/api-reference"></script>
</body>
</html>
+12
View File
@@ -0,0 +1,12 @@
@php
use Knuckles\Scribe\Tools\Utils as u;
@endphp
# {{ u::trans("scribe::headings.auth") }}
@if(!$isAuthed)
{!! u::trans("scribe::auth.none") !!}
@else
{!! $authDescription !!}
{!! $extraAuthInfo !!}
@endif
+13
View File
@@ -0,0 +1,13 @@
@php
use Knuckles\Scribe\Tools\Utils as u;
@endphp
# {{ u::trans("scribe::headings.introduction") }}
{!! $description !!}
<aside>
<strong>{{ u::trans("scribe::labels.base_url") }}</strong>: <code>{!! $baseUrl !!}</code>
</aside>
{!! $introText !!}
@@ -0,0 +1,34 @@
@php
use Knuckles\Scribe\Tools\WritingUtils as u;
/** @var Knuckles\Camel\Output\OutputEndpointData $endpoint */
@endphp
```bash
curl --request {{$endpoint->httpMethods[0]}} \
{{$endpoint->httpMethods[0] == 'GET' ? '--get ' : ''}}"{!! rtrim($baseUrl, '/') !!}/{{ ltrim($endpoint->boundUri, '/') }}@if(count($endpoint->cleanQueryParameters))?{!! u::printQueryParamsAsString($endpoint->cleanQueryParameters) !!}@endif"@if(count($endpoint->headers)) \
@foreach($endpoint->headers as $header => $value)
--header "{{$header}}: {{ addslashes($value) }}"@if(! ($loop->last) || ($loop->last && count($endpoint->bodyParameters))) \
@endif
@endforeach
@endif
@if($endpoint->hasFiles() || (isset($endpoint->headers['Content-Type']) && $endpoint->headers['Content-Type'] == 'multipart/form-data' && count($endpoint->cleanBodyParameters)))
@foreach($endpoint->cleanBodyParameters as $parameter => $value)
@foreach(u::getParameterNamesAndValuesForFormData($parameter, $value) as $key => $actualValue)
--form "{!! "$key=".$actualValue !!}"@if(!($loop->parent->last) || count($endpoint->fileParameters))\
@endif
@endforeach
@endforeach
@foreach($endpoint->fileParameters as $parameter => $value)
@foreach(u::getParameterNamesAndValuesForFormData($parameter, $value) as $key => $file)
--form "{!! "$key=@".$file->path() !!}" @if(!($loop->parent->last))\
@endif
@endforeach
@endforeach
@elseif(count($endpoint->cleanBodyParameters))
@if ($endpoint->headers['Content-Type'] == 'application/x-www-form-urlencoded')
--data "{!! http_build_query($endpoint->cleanBodyParameters, '', '&') !!}"
@else
--data "{!! addslashes(json_encode($endpoint->cleanBodyParameters, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT)) !!}"
@endif
@endif
```
@@ -0,0 +1,62 @@
@php
use Knuckles\Scribe\Tools\WritingUtils as u;
/** @var Knuckles\Camel\Output\OutputEndpointData $endpoint */
@endphp
```javascript
const url = new URL(
"{!! rtrim($baseUrl, '/') !!}/{{ ltrim($endpoint->boundUri, '/') }}"
);
@if(count($endpoint->cleanQueryParameters))
const params = {!! u::printQueryParamsAsKeyValue($endpoint->cleanQueryParameters, "\"", ":", 4, "{}") !!};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
@endif
@if(!empty($endpoint->headers))
const headers = {
@foreach($endpoint->headers as $header => $value)
"{{$header}}": "{{$value}}",
@endforeach
@empty($endpoint->headers['Accept'])
"Accept": "application/json",
@endempty
};
@endif
@if($endpoint->hasFiles() || (isset($endpoint->headers['Content-Type']) && $endpoint->headers['Content-Type'] == 'multipart/form-data' && count($endpoint->cleanBodyParameters)))
const body = new FormData();
@foreach($endpoint->cleanBodyParameters as $parameter => $value)
@foreach( u::getParameterNamesAndValuesForFormData($parameter, $value) as $key => $actualValue)
body.append('{!! $key !!}', '{!! $actualValue !!}');
@endforeach
@endforeach
@foreach($endpoint->fileParameters as $parameter => $value)
@foreach( u::getParameterNamesAndValuesForFormData($parameter, $value) as $key => $file)
body.append('{!! $key !!}', document.querySelector('input[name="{!! $key !!}"]').files[0]);
@endforeach
@endforeach
@elseif(count($endpoint->cleanBodyParameters))
@if ($endpoint->headers['Content-Type'] == 'application/x-www-form-urlencoded')
let body = "{!! http_build_query($endpoint->cleanBodyParameters, '', '&') !!}";
@else
let body = {!! json_encode($endpoint->cleanBodyParameters, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE) !!};
@endif
@endif
fetch(url, {
method: "{{$endpoint->httpMethods[0]}}",
@if(count($endpoint->headers))
headers,
@endif
@if($endpoint->hasFiles() || (isset($endpoint->headers['Content-Type']) && $endpoint->headers['Content-Type'] == 'multipart/form-data' && count($endpoint->cleanBodyParameters)))
body,
@elseif(count($endpoint->cleanBodyParameters))
@if ($endpoint->headers['Content-Type'] == 'application/x-www-form-urlencoded')
body,
@else
body: JSON.stringify(body),
@endif
@endif
}).then(response => response.json());
```
@@ -0,0 +1,51 @@
@php
use Knuckles\Scribe\Tools\WritingUtils as u;
/** @var Knuckles\Camel\Output\OutputEndpointData $endpoint */
@endphp
```php
$client = new \GuzzleHttp\Client();
$url = '{!! rtrim($baseUrl, '/') . '/' . ltrim($endpoint->boundUri, '/') !!}';
@if($endpoint->hasHeadersOrQueryOrBodyParams())
$response = $client->{{ strtolower($endpoint->httpMethods[0]) }}(
$url,
[
@if(!empty($endpoint->headers))
'headers' => {!! u::printPhpValue($endpoint->headers, 8) !!},
@endif
@if(!empty($endpoint->cleanQueryParameters))
'query' => {!! u::printQueryParamsAsKeyValue($endpoint->cleanQueryParameters, "'", " =>", 12, "[]", 8) !!},
@endif
@if($endpoint->hasFiles() || (isset($endpoint->headers['Content-Type']) && $endpoint->headers['Content-Type'] == 'multipart/form-data' && !empty($endpoint->cleanBodyParameters)))
'multipart' => [
@foreach($endpoint->cleanBodyParameters as $parameter => $value)
@foreach(u::getParameterNamesAndValuesForFormData($parameter, $value) as $key => $actualValue)
[
'name' => '{!! $key !!}',
'contents' => '{!! $actualValue !!}'
],
@endforeach
@endforeach
@foreach($endpoint->fileParameters as $parameter => $value)
@foreach(u::getParameterNamesAndValuesForFormData($parameter, $value) as $key => $file)
[
'name' => '{!! $key !!}',
'contents' => fopen('{!! $file->path() !!}', 'r')
],
@endforeach
@endforeach
],
@elseif(count($endpoint->cleanBodyParameters))
@if ($endpoint->headers['Content-Type'] == 'application/x-www-form-urlencoded')
'form_params' => {!! u::printPhpValue($endpoint->cleanBodyParameters, 8) !!},
@else
'json' => {!! u::printPhpValue($endpoint->cleanBodyParameters, 8) !!},
@endif
@endif
]
);
@else
$response = $client->{{ strtolower($endpoint->httpMethods[0]) }}($url);
@endif
$body = $response->getBody();
print_r(json_decode((string) $body));
```
@@ -0,0 +1,52 @@
@php
use Knuckles\Scribe\Tools\WritingUtils as u;
/** @var Knuckles\Camel\Output\OutputEndpointData $endpoint */
@endphp
```python
import requests
import json
url = '{!! rtrim($baseUrl, '/') !!}/{{ $endpoint->boundUri }}'
@if($endpoint->hasFiles() || (isset($endpoint->headers['Content-Type']) && $endpoint->headers['Content-Type'] == 'multipart/form-data' && count($endpoint->cleanBodyParameters)))
files = {
@foreach($endpoint->cleanBodyParameters as $parameter => $value)
@foreach(u::getParameterNamesAndValuesForFormData($parameter, $value) as $key => $actualValue)
'{!! $key !!}': (None, '{!! $actualValue !!}')@if(!($loop->parent->last) || count($endpoint->fileParameters)),
@endif
@endforeach
@endforeach
@foreach($endpoint->fileParameters as $parameter => $value)
@foreach(u::getParameterNamesAndValuesForFormData($parameter, $value) as $key => $file)
'{!! $key !!}': open('{!! $file->path() !!}', 'rb')@if(!($loop->parent->last)),
@endif
@endforeach
@endforeach
}
@endif
@if(count($endpoint->cleanBodyParameters))
payload = {!! json_encode($endpoint->cleanBodyParameters, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE) !!}
@endif
@if(count($endpoint->cleanQueryParameters))
params = {!! u::printQueryParamsAsKeyValue($endpoint->cleanQueryParameters, "'", ":", 2, "{}") !!}
@endif
@if(!empty($endpoint->headers))
headers = {
@foreach($endpoint->headers as $header => $value)
'{{$header}}': '{{$value}}'@if(!($loop->last)),
@endif
@endforeach
}
@endif
@php
$optionalArguments = [];
if (count($endpoint->headers)) $optionalArguments[] = "headers=headers";
if (count($endpoint->fileParameters)) $optionalArguments[] = "files=files";
if (count($endpoint->cleanBodyParameters) && $endpoint->headers['Content-Type'] != 'multipart/form-data') $optionalArguments[] = (count($endpoint->fileParameters) || $endpoint->headers['Content-Type'] == 'application/x-www-form-urlencoded' ? "data=payload" : "json=payload");
if (count($endpoint->cleanQueryParameters)) $optionalArguments[] = "params=params";
$optionalArguments = implode(', ',$optionalArguments);
@endphp
response = requests.request('{{$endpoint->httpMethods[0]}}', url, {{ $optionalArguments }})
response.json()
```
@@ -0,0 +1,190 @@
@php
use Knuckles\Scribe\Tools\Utils as u;
/** @var Knuckles\Camel\Output\OutputEndpointData $endpoint */
@endphp
<h2 id="{!! $endpoint->fullSlug() !!}">{{ $endpoint->name() }}</h2>
<p>
@component('scribe::components.badges.auth', ['authenticated' => $endpoint->isAuthed()])
@endcomponent
@component('scribe::components.badges.deprecated', ['deprecated' => $endpoint->metadata->deprecated])
@endcomponent
</p>
{!! Parsedown::instance()->text($endpoint->metadata->description ?: '') !!}
<span id="example-requests-{!! $endpoint->endpointId() !!}">
<blockquote>{{ u::trans("scribe::endpoint.example_request") }}:</blockquote>
@foreach($metadata['example_languages'] as $language)
<div class="{{ $language }}-example">
@include("scribe::partials.example-requests.$language")
</div>
@endforeach
</span>
<span id="example-responses-{!! $endpoint->endpointId() !!}">
@if($endpoint->isGet() || $endpoint->hasResponses())
@foreach($endpoint->responses as $response)
<blockquote>
<p>{{ u::trans("scribe::endpoint.example_response") }} ({{ $response->fullDescription() }}):</p>
</blockquote>
@if(count($response->headers))
<details class="annotation">
<summary style="cursor: pointer;">
<small onclick="textContent = parentElement.parentElement.open ? 'Show headers' : 'Hide headers'">Show headers</small>
</summary>
<pre><code class="language-http">@foreach($response->headers as $header => $value)
{{ $header }}: {{ is_array($value) ? implode('; ', $value) : $value }}
@endforeach </code></pre></details> @endif
<pre>
@if(is_string($response->content) && Str::startsWith($response->content, "<<binary>>"))
<code>{!! u::trans("scribe::endpoint.responses.binary") !!} - {{ htmlentities(str_replace("<<binary>>", "", $response->content)) }}</code>
@elseif($response->status == 204)
<code>{!! u::trans("scribe::endpoint.responses.empty") !!}</code>
@else
@php($parsed = json_decode($response->content))
{{-- If response is a JSON string, prettify it. Otherwise, just print it --}}
<code class="language-json" style="max-height: 300px;">{!! htmlentities($parsed != null ? json_encode($parsed, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) : $response->content) !!}</code>
@endif </pre>
@endforeach
@endif
</span>
<span id="execution-results-{{ $endpoint->endpointId() }}" hidden>
<blockquote>{{ u::trans("scribe::try_it_out.received_response") }}<span
id="execution-response-status-{{ $endpoint->endpointId() }}"></span>:
</blockquote>
<pre class="json"><code id="execution-response-content-{{ $endpoint->endpointId() }}"
data-empty-response-text="<{{ u::trans("scribe::endpoint.responses.empty") }}>" style="max-height: 400px;"></code></pre>
</span>
<span id="execution-error-{{ $endpoint->endpointId() }}" hidden>
<blockquote>{{ u::trans("scribe::try_it_out.request_failed") }}:</blockquote>
<pre><code id="execution-error-message-{{ $endpoint->endpointId() }}">{{ "\n\n".u::trans("scribe::try_it_out.error_help") }}</code></pre>
</span>
<form id="form-{{ $endpoint->endpointId() }}" data-method="{{ $endpoint->httpMethods[0] }}"
data-path="{{ $endpoint->uri }}"
data-authed="{{ $endpoint->isAuthed() ? 1 : 0 }}"
data-hasfiles="{{ $endpoint->hasFiles() ? 1 : 0 }}"
data-isarraybody="{{ $endpoint->isArrayBody() ? 1 : 0 }}"
autocomplete="off"
onsubmit="event.preventDefault(); executeTryOut('{{ $endpoint->endpointId() }}', this);">
<h3>
{{ u::trans("scribe::endpoint.request") }}&nbsp;&nbsp;&nbsp;
@if($metadata['try_it_out']['enabled'] ?? false)
<button type="button"
style="background-color: #8fbcd4; padding: 5px 10px; border-radius: 5px; border-width: thin;"
id="btn-tryout-{{ $endpoint->endpointId() }}"
onclick="tryItOut('{{ $endpoint->endpointId() }}');">{{ u::trans("scribe::try_it_out.open") }}
</button>
<button type="button"
style="background-color: #c97a7e; padding: 5px 10px; border-radius: 5px; border-width: thin;"
id="btn-canceltryout-{{ $endpoint->endpointId() }}"
onclick="cancelTryOut('{{ $endpoint->endpointId() }}');" hidden>{{ u::trans("scribe::try_it_out.cancel") }}
</button>&nbsp;&nbsp;
<button type="submit"
style="background-color: #6ac174; padding: 5px 10px; border-radius: 5px; border-width: thin;"
id="btn-executetryout-{{ $endpoint->endpointId() }}"
data-initial-text="{{ u::trans("scribe::try_it_out.send") }}"
data-loading-text="{{ u::trans("scribe::try_it_out.loading") }}"
hidden>{{ u::trans("scribe::try_it_out.send") }}
</button>
@endif
</h3>
@foreach($endpoint->httpMethods as $method)
<p>
@component('scribe::components.badges.http-method', ['method' => $method])@endcomponent
<b><code>{{$endpoint->uri}}</code></b>
</p>
@endforeach
@if(count($endpoint->headers))
<h4 class="fancy-heading-panel"><b>{{ u::trans("scribe::endpoint.headers") }}</b></h4>
@foreach($endpoint->headers as $name => $example)
<?php
$htmlOptions = [];
if ($endpoint->isAuthed() && $metadata['auth']['location'] == 'header' && $metadata['auth']['name'] == $name) {
$htmlOptions = [ 'class' => 'auth-value', ];
}
?>
<div style="padding-left: 28px; clear: unset;">
@component('scribe::components.field-details', [
'name' => $name,
'type' => null,
'required' => true,
'deprecated' => false,
'description' => null,
'example' => $example,
'endpointId' => $endpoint->endpointId(),
'component' => 'header',
'isInput' => true,
'html' => $htmlOptions,
])
@endcomponent
</div>
@endforeach
@endif
@if(count($endpoint->urlParameters))
<h4 class="fancy-heading-panel"><b>{{ u::trans("scribe::endpoint.url_parameters") }}</b></h4>
@foreach($endpoint->urlParameters as $attribute => $parameter)
<div style="padding-left: 28px; clear: unset;">
@component('scribe::components.field-details', [
'name' => $parameter->name,
'type' => $parameter->type ?? 'string',
'required' => $parameter->required,
'deprecated' => $parameter->deprecated,
'description' => $parameter->description,
'example' => $parameter->example ?? '',
'enumValues' => $parameter->enumValues,
'endpointId' => $endpoint->endpointId(),
'component' => 'url',
'isInput' => true,
])
@endcomponent
</div>
@endforeach
@endif
@if(count($endpoint->queryParameters))
<h4 class="fancy-heading-panel"><b>{{ u::trans("scribe::endpoint.query_parameters") }}</b></h4>
@foreach($endpoint->queryParameters as $attribute => $parameter)
<?php
$htmlOptions = [];
if ($endpoint->isAuthed() && $metadata['auth']['location'] == 'query' && $metadata['auth']['name'] == $attribute) {
$htmlOptions = [ 'class' => 'auth-value', ];
}
?>
<div style="padding-left: 28px; clear: unset;">
@component('scribe::components.field-details', [
'name' => $parameter->name,
'type' => $parameter->type,
'required' => $parameter->required,
'deprecated' => $parameter->deprecated,
'description' => $parameter->description,
'example' => $parameter->example ?? '',
'enumValues' => $parameter->enumValues,
'endpointId' => $endpoint->endpointId(),
'component' => 'query',
'isInput' => true,
'html' => $htmlOptions,
])
@endcomponent
</div>
@endforeach
@endif
@if(count($endpoint->nestedBodyParameters))
<h4 class="fancy-heading-panel"><b>{{ u::trans("scribe::endpoint.body_parameters") }}</b></h4>
<x-scribe::nested-fields
:fields="$endpoint->nestedBodyParameters" :endpointId="$endpoint->endpointId()"
/>
@endif
</form>
@if(count($endpoint->responseFields))
<h3>{{ u::trans("scribe::endpoint.response") }}</h3>
<h4 class="fancy-heading-panel"><b>{{ u::trans("scribe::endpoint.response_fields") }}</b></h4>
<x-scribe::nested-fields
:fields="$endpoint->nestedResponseFields" :endpointId="$endpoint->endpointId()"
:isInput="false"
/>
@endif
@@ -0,0 +1,21 @@
@foreach($groupedEndpoints as $group)
<h1 id="{!! Str::slug($group['name']) !!}">{!! $group['name'] !!}</h1>
{!! Parsedown::instance()->text($group['description']) !!}
@foreach($group['subgroups'] as $subgroupName => $subgroup)
@if($subgroupName !== "")
<h2 id="{!! Str::slug($group['name']) !!}-{!! Str::slug($subgroupName) !!}">{{ $subgroupName }}</h2>
@php($subgroupDescription = collect($subgroup)->first(fn ($e) => $e->metadata->subgroupDescription)?->metadata?->subgroupDescription)
@if($subgroupDescription)
<p>
{!! Parsedown::instance()->text($subgroupDescription) !!}
</p>
@endif
@endif
@foreach($subgroup as $endpoint)
@include("scribe::themes.default.endpoint")
@endforeach
@endforeach
@endforeach
@@ -0,0 +1,74 @@
@php
use Knuckles\Scribe\Tools\WritingUtils as u;
@endphp
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta content="IE=edge,chrome=1" http-equiv="X-UA-Compatible">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title>{!! $metadata['title'] !!}</title>
<link href="https://fonts.googleapis.com/css?family=Open+Sans&display=swap" rel="stylesheet">
<link rel="stylesheet" href="{!! $assetPathPrefix !!}css/theme-default.style.css" media="screen">
<link rel="stylesheet" href="{!! $assetPathPrefix !!}css/theme-default.print.css" media="print">
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.10/lodash.min.js"></script>
<link rel="stylesheet"
href="https://unpkg.com/@highlightjs/cdn-assets@11.6.0/styles/obsidian.min.css">
<script src="https://unpkg.com/@highlightjs/cdn-assets@11.6.0/highlight.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jets/0.14.1/jets.min.js"></script>
@if(isset($metadata['example_languages']))
<style id="language-style">
/* starts out as display none and is replaced with js later */
@foreach($metadata['example_languages'] as $lang)
body .content .{{ $lang }}-example code { display: none; }
@endforeach
</style>
@endif
@if($tryItOut['enabled'] ?? true)
<script>
var tryItOutBaseUrl = "{!! $tryItOut['base_url'] ?? $baseUrl !!}";
var useCsrf = Boolean({!! $tryItOut['use_csrf'] ?? null !!});
var csrfUrl = "{!! $tryItOut['csrf_url'] ?? null !!}";
</script>
<script src="{{ u::getVersionedAsset($assetPathPrefix.'js/tryitout.js') }}"></script>
@endif
<script src="{{ u::getVersionedAsset($assetPathPrefix.'js/theme-default.js') }}"></script>
</head>
<body data-languages="{{ json_encode($metadata['example_languages'] ?? []) }}">
@include("scribe::themes.default.sidebar")
<div class="page-wrapper">
<div class="dark-box"></div>
<div class="content">
{!! $intro !!}
{!! $auth !!}
@include("scribe::themes.default.groups")
{!! $append !!}
</div>
<div class="dark-box">
@if(isset($metadata['example_languages']))
<div class="lang-selector">
@foreach($metadata['example_languages'] as $name => $lang)
@php if (is_numeric($name)) $name = $lang; @endphp
<button type="button" class="lang-button" data-language-name="{{$lang}}">{{$name}}</button>
@endforeach
</div>
@endif
</div>
</div>
</body>
</html>
@@ -0,0 +1,69 @@
@php
use Knuckles\Scribe\Tools\Utils as u;
@endphp
<a href="#" id="nav-button">
<span>
MENU
<img src="{!! $assetPathPrefix !!}images/navbar.png" alt="navbar-image"/>
</span>
</a>
<div class="tocify-wrapper">
@if($metadata['logo'] != false)
<img src="{{ $metadata['logo'] }}" alt="logo" class="logo" style="padding-top: 10px;" width="100%"/>
@endif
@isset($metadata['example_languages'])
<div class="lang-selector">
@foreach($metadata['example_languages'] as $name => $lang)
@php if (is_numeric($name)) $name = $lang; @endphp
<button type="button" class="lang-button" data-language-name="{{ $lang }}">{{ $name }}</button>
@endforeach
</div>
@endisset
<div class="search">
<input type="text" class="search" id="input-search" placeholder="{{ u::trans("scribe::labels.search") }}">
</div>
<div id="toc">
@foreach($headings as $h1)
<ul id="tocify-header-{{ $h1['slug'] }}" class="tocify-header">
<li class="tocify-item level-1" data-unique="{!! $h1['slug'] !!}">
<a href="#{!! $h1['slug'] !!}">{!! $h1['name'] !!}</a>
</li>
@if(count($h1['subheadings']) > 0)
<ul id="tocify-subheader-{!! $h1['slug'] !!}" class="tocify-subheader">
@foreach($h1['subheadings'] as $h2)
<li class="tocify-item level-2" data-unique="{!! $h2['slug'] !!}">
<a href="#{!! $h2['slug'] !!}">{!! $h2['name'] !!}</a>
</li>
@if(count($h2['subheadings']) > 0)
<ul id="tocify-subheader-{!! $h2['slug'] !!}" class="tocify-subheader">
@foreach($h2['subheadings'] as $h3)
<li class="tocify-item level-3" data-unique="{!! $h3['slug'] !!}">
<a href="#{!! $h3['slug'] !!}">{!! $h3['name'] !!}</a>
</li>
@endforeach
</ul>
@endif
@endforeach
</ul>
@endif
</ul>
@endforeach
</div>
<ul class="toc-footer" id="toc-footer">
@if($metadata['postman_collection_url'])
<li style="padding-bottom: 5px;"><a href="{!! $metadata['postman_collection_url'] !!}">{!! u::trans("scribe::links.postman") !!}</a></li>
@endif
@if($metadata['openapi_spec_url'])
<li style="padding-bottom: 5px;"><a href="{!! $metadata['openapi_spec_url'] !!}">{!! u::trans("scribe::links.openapi") !!}</a></li>
@endif
<li><a href="http://github.com/knuckleswtf/scribe">Documentation powered by Scribe </a></li>
</ul>
<ul class="toc-footer" id="last-updated">
<li>{{ $metadata['last_updated'] }}</li>
</ul>
</div>
@@ -0,0 +1,70 @@
@php
$hasChildren ??= false;
$isArrayBody = $name == "[]";
$expandable = $hasChildren && !$isArrayBody;
@endphp
<div class="sl-flex sl-relative sl-max-w-full sl-py-2 sl-pl-3">
<div class="sl-w-1 sl-mt-2 sl-mr-3 sl--ml-3 sl-border-t"></div>
<div class="sl-stack sl-stack--vertical sl-stack--1 sl-flex sl-flex-1 sl-flex-col sl-items-stretch sl-max-w-full sl-ml-2 @if($expandable) sl-cursor-pointer @endif">
<div class="sl-flex sl-items-center sl-max-w-full">
@if($expandable)
<div class="sl-flex sl-justify-center sl-w-8 sl--ml-8 sl-pl-3 sl-text-muted expansion-chevrons" role="button">
<svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="chevron-right"
class="svg-inline--fa fa-chevron-right fa-fw fa-sm sl-icon" role="img"
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512">
<path fill="currentColor"
d="M96 480c-8.188 0-16.38-3.125-22.62-9.375c-12.5-12.5-12.5-32.75 0-45.25L242.8 256L73.38 86.63c-12.5-12.5-12.5-32.75 0-45.25s32.75-12.5 45.25 0l192 192c12.5 12.5 12.5 32.75 0 45.25l-192 192C112.4 476.9 104.2 480 96 480z"></path>
</svg>
</div>
@endif
@unless($isArrayBody)
<div class="sl-flex sl-items-baseline sl-text-base">
<div class="sl-font-mono sl-font-semibold sl-mr-2">{{ $name }}</div>
@if($type)
<span class="sl-truncate sl-text-muted">{{ $type }}</span>
@endif
</div>
@if($required || $deprecated)
<div class="sl-flex-1 sl-h-px sl-mx-3"></div>
<div class="sl-flex sl-items-center">
@if($required)
<span class="sl-ml-2 sl-text-warning">required</span>
@endif
@if($deprecated)
<span class="sl-ml-2 sl-text-warning">deprecated</span>
@endif
</div>
@endif
@endunless
</div>
@if($description)
<div class="sl-prose sl-markdown-viewer" style="font-size: 12px;">
{!! Parsedown::instance()->text($description) !!}
</div>
@endif
@if(!empty($enumValues))
Must be one of:
<ul style="list-style-position: inside; list-style-type: square;">{!! implode(" ", array_map(fn($val) => "<li><code>$val</code></li>", $enumValues)) !!}</ul>
@endif
@if($isArrayBody)
<div class="sl-flex sl-items-baseline sl-text-base">
<div class="sl-font-mono sl-font-semibold sl-mr-2">array of:</div>
@if($required)
<div class="sl-flex-1 sl-h-px sl-mx-3"></div>
<span class="sl-ml-2 sl-text-warning">required</span>
@endif
</div>
@endif
@if(!$hasChildren && !is_null($example) && $example !== '')
<div class="sl-stack sl-stack--horizontal sl-stack--2 sl-flex sl-flex-row sl-items-baseline sl-text-muted">
<span>Example:</span> <!-- <span> important for spacing -->
<div class="sl-flex sl-flex-1 sl-flex-wrap" style="gap: 4px;">
<div class="sl-max-w-full sl-break-all sl-px-1 sl-bg-canvas-tint sl-text-muted sl-rounded sl-border">
{{ is_array($example) || is_bool($example) ? json_encode($example) : $example }}
</div>
</div>
</div>
@endif
</div>
</div>
@@ -0,0 +1,38 @@
@php
$level ??= 0;
$levelNestingClass = match($level) {
0 => "sl-ml-px",
default => "sl-ml-7"
};
$expandable ??= !isset($fields["[]"]);
@endphp
@foreach($fields as $name => $field)
<div class="{{ $expandable ? 'expandable' : '' }} sl-text-sm sl-border-l {{ $levelNestingClass }}">
@component('scribe::themes.elements.components.field-details', [
'name' => $name,
'type' => $field['type'] ?? 'string',
'required' => $field['required'] ?? false,
'deprecated' => $field['deprecated'] ?? false,
'description' => $field['description'] ?? '',
'example' => $field['example'] ?? '',
'enumValues' => $field['enumValues'] ?? null,
'endpointId' => $endpointId,
'hasChildren' => !empty($field['__fields']),
'component' => 'body',
])
@endcomponent
@if(!empty($field['__fields']))
<div class="children" style="{{ $expandable ? 'display: none;' : '' }}">
@component('scribe::themes.elements.components.nested-fields', [
'fields' => $field['__fields'],
'endpointId' => $endpointId,
'level' => $level + 1,
'expandable'=> $expandable,
])
@endcomponent
</div>
@endif
</div>
@endforeach
@@ -0,0 +1,281 @@
@php
use Knuckles\Scribe\Tools\Utils as u;
/** @var Knuckles\Camel\Output\OutputEndpointData $endpoint */
@endphp
<div class="sl-stack sl-stack--vertical sl-stack--8 HttpOperation sl-flex sl-flex-col sl-items-stretch sl-w-full">
<div class="sl-stack sl-stack--vertical sl-stack--5 sl-flex sl-flex-col sl-items-stretch">
<div class="sl-relative">
<div class="sl-stack sl-stack--horizontal sl-stack--5 sl-flex sl-flex-row sl-items-center">
<h2 class="sl-text-3xl sl-leading-tight sl-font-prose sl-text-heading sl-mt-5 sl-mb-1"
id="{!! $endpoint->fullSlug() !!}">
{{ $endpoint->name() }}
</h2>
</div>
</div>
<div class="sl-relative">
<div title="{!! rtrim($baseUrl, '/') . '/'. ltrim($endpoint->uri, '/') !!}"
class="sl-stack sl-stack--horizontal sl-stack--3 sl-inline-flex sl-flex-row sl-items-center sl-max-w-full sl-font-mono sl-py-2 sl-pr-4 sl-bg-canvas-50 sl-rounded-lg"
>
@foreach($endpoint->httpMethods as $method)
<div class="sl-text-lg sl-font-semibold sl-px-2.5 sl-py-1 sl-text-on-primary sl-rounded-lg"
style="background-color: {{ \Knuckles\Scribe\Tools\WritingUtils::$httpMethodToCssColour[$method] }};"
>
{{ $method }}
</div>
@endforeach
<div class="sl-flex sl-overflow-x-hidden sl-text-lg sl-select-all">
<div dir="rtl"
class="sl-overflow-x-hidden sl-truncate sl-text-muted">{!! rtrim($baseUrl, '/') !!}</div>
<div class="sl-flex-1 sl-font-semibold">/{{ ltrim($endpoint->uri, '/') }}</div>
</div>
@if($endpoint->metadata->authenticated)
<div class="sl-font-prose sl-font-semibold sl-px-1.5 sl-py-0.5 sl-text-on-primary sl-rounded-lg"
style="background-color: darkred"
>requires authentication
</div>
@endif
@if($endpoint->metadata->deprecated === true)
<div class="sl-font-prose sl-font-semibold sl-px-1.5 sl-py-0.5 sl-text-on-primary sl-rounded-lg"
style="background-color: darkgoldenrod"
>deprecated
</div>
@endif
@if(is_string($endpoint->metadata->deprecated))
<div class="sl-font-prose sl-font-semibold sl-px-1.5 sl-py-0.5 sl-text-on-primary sl-rounded-lg"
style="background-color: darkgoldenrod"
>deprecated:{{$endpoint->metadata->deprecated}}
</div>
@endif
</div>
</div>
{!! Parsedown::instance()->text($endpoint->metadata->description ?: '') !!}
</div>
<div class="sl-flex">
<div data-testid="two-column-left" class="sl-flex-1 sl-w-0">
<div class="sl-stack sl-stack--vertical sl-stack--10 sl-flex sl-flex-col sl-items-stretch">
<div class="sl-stack sl-stack--vertical sl-stack--8 sl-flex sl-flex-col sl-items-stretch">
@if(count($endpoint->headers))
<div class="sl-stack sl-stack--vertical sl-stack--5 sl-flex sl-flex-col sl-items-stretch">
<h3 class="sl-text-2xl sl-leading-snug sl-font-prose">
{{ u::trans("scribe::endpoint.headers") }}
</h3>
<div class="sl-text-sm">
@foreach($endpoint->headers as $header => $value)
@component('scribe::themes.elements.components.field-details', [
'name' => $header,
'type' => null,
'required' => false,
'deprecated' => false,
'description' => null,
'example' => $value,
'endpointId' => $endpoint->endpointId(),
'component' => 'header',
'isInput' => true,
])
@endcomponent
@endforeach
</div>
</div>
@endif
@if(count($endpoint->urlParameters))
<div class="sl-stack sl-stack--vertical sl-stack--6 sl-flex sl-flex-col sl-items-stretch">
<h3 class="sl-text-2xl sl-leading-snug sl-font-prose">{{ u::trans("scribe::endpoint.url_parameters") }}</h3>
<div class="sl-text-sm">
@foreach($endpoint->urlParameters as $attribute => $parameter)
@component('scribe::themes.elements.components.field-details', [
'name' => $parameter->name,
'type' => $parameter->type ?? 'string',
'required' => $parameter->required,
'deprecated' => $parameter->deprecated,
'description' => $parameter->description,
'example' => $parameter->example ?? '',
'enumValues' => $parameter->enumValues,
'endpointId' => $endpoint->endpointId(),
'component' => 'url',
'isInput' => true,
])
@endcomponent
@endforeach
</div>
</div>
@endif
@if(count($endpoint->queryParameters))
<div class="sl-stack sl-stack--vertical sl-stack--6 sl-flex sl-flex-col sl-items-stretch">
<h3 class="sl-text-2xl sl-leading-snug sl-font-prose">{{ u::trans("scribe::endpoint.query_parameters") }}</h3>
<div class="sl-text-sm">
@foreach($endpoint->queryParameters as $attribute => $parameter)
@component('scribe::themes.elements.components.field-details', [
'name' => $parameter->name,
'type' => $parameter->type,
'required' => $parameter->required,
'deprecated' => $parameter->deprecated,
'description' => $parameter->description,
'example' => $parameter->example ?? '',
'enumValues' => $parameter->enumValues,
'endpointId' => $endpoint->endpointId(),
'component' => 'query',
'isInput' => true,
])
@endcomponent
@endforeach
</div>
</div>
@endif
@if(count($endpoint->nestedBodyParameters))
<div class="sl-stack sl-stack--vertical sl-stack--6 sl-flex sl-flex-col sl-items-stretch">
<h3 class="sl-text-2xl sl-leading-snug sl-font-prose">{{ u::trans("scribe::endpoint.body_parameters") }}</h3>
<div class="sl-text-sm">
@component('scribe::themes.elements.components.nested-fields', [
'fields' => $endpoint->nestedBodyParameters,
'endpointId' => $endpoint->endpointId(),
])
@endcomponent
</div>
</div>
@endif
@if(count($endpoint->responseFields))
<div class="sl-stack sl-stack--vertical sl-stack--6 sl-flex sl-flex-col sl-items-stretch">
<h3 class="sl-text-2xl sl-leading-snug sl-font-prose">{{ u::trans("scribe::endpoint.response_fields") }}</h3>
<div class="sl-text-sm">
@component('scribe::themes.elements.components.nested-fields', [
'fields' => $endpoint->nestedResponseFields,
'endpointId' => $endpoint->endpointId(),
'isInput' => false,
])
@endcomponent
</div>
</div>
@endif
</div>
</div>
</div>
<div data-testid="two-column-right" class="sl-relative sl-w-2/5 sl-ml-16" style="max-width: 500px;">
<div class="sl-stack sl-stack--vertical sl-stack--6 sl-flex sl-flex-col sl-items-stretch">
@if($metadata['try_it_out']['enabled'] ?? false)
@include("scribe::themes.elements.try_it_out")
@endif
@if($metadata['example_languages'])
<div class="sl-panel sl-outline-none sl-w-full sl-rounded-lg">
<div class="sl-panel__titlebar sl-flex sl-items-center sl-relative focus:sl-z-10 sl-text-base sl-leading-none sl-pr-3 sl-pl-4 sl-bg-canvas-200 sl-text-body sl-border-input focus:sl-border-primary sl-select-none">
<div class="sl-flex sl-flex-1 sl-items-center sl-h-lg">
<div class="sl--ml-2">
{{ u::trans("scribe::endpoint.example_request") }}:
<select class="example-request-lang-toggle sl-text-base"
aria-label="Request Sample Language"
onchange="switchExampleLanguage(event.target.value);">
@foreach($metadata['example_languages'] as $language)
<option>{{ $language }}</option>
@endforeach
</select>
</div>
</div>
</div>
@foreach($metadata['example_languages'] as $index => $language)
<div class="sl-bg-canvas-100 example-request example-request-{{ $language }}"
style="{{ $index == 0 ? '' : 'display: none;' }}">
<div class="sl-px-0 sl-py-1">
<div style="max-height: 400px;" class="sl-overflow-y-auto sl-rounded">
@include("scribe::partials.example-requests.$language")
</div>
</div>
</div>
@endforeach
</div>
@endif
@if($endpoint->isGet() || $endpoint->hasResponses())
<div class="sl-panel sl-outline-none sl-w-full sl-rounded-lg">
<div class="sl-panel__titlebar sl-flex sl-items-center sl-relative focus:sl-z-10 sl-text-base sl-leading-none sl-pr-3 sl-pl-4 sl-bg-canvas-200 sl-text-body sl-border-input focus:sl-border-primary sl-select-none">
<div class="sl-flex sl-flex-1 sl-items-center sl-py-2">
<div class="sl--ml-2">
<div class="sl-h-sm sl-text-base sl-font-medium sl-px-1.5 sl-text-muted sl-rounded sl-border-transparent sl-border">
<div class="sl-mb-2 sl-inline-block">{{ u::trans("scribe::endpoint.example_response") }}:</div>
<div class="sl-mb-2 sl-inline-block">
<select
class="example-response-{{ $endpoint->endpointId() }}-toggle sl-text-base"
aria-label="Response sample"
onchange="switchExampleResponse('{{ $endpoint->endpointId() }}', event.target.value);">
@foreach($endpoint->responses as $index => $response)
<option value="{{ $index }}">{{ $response->fullDescription() }}</option>
@endforeach
</select></div>
</div>
</div>
</div>
<button type="button"
class="sl-button sl-h-sm sl-text-base sl-font-medium sl-px-1.5 hover:sl-bg-canvas-50 active:sl-bg-canvas-100 sl-text-muted hover:sl-text-body focus:sl-text-body sl-rounded sl-border-transparent sl-border disabled:sl-opacity-70">
<div class="sl-mx-0">
<svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="copy"
class="svg-inline--fa fa-copy fa-fw fa-sm sl-icon" role="img"
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
<path fill="currentColor"
d="M384 96L384 0h-112c-26.51 0-48 21.49-48 48v288c0 26.51 21.49 48 48 48H464c26.51 0 48-21.49 48-48V128h-95.1C398.4 128 384 113.6 384 96zM416 0v96h96L416 0zM192 352V128h-144c-26.51 0-48 21.49-48 48v288c0 26.51 21.49 48 48 48h192c26.51 0 48-21.49 48-48L288 416h-32C220.7 416 192 387.3 192 352z"></path>
</svg>
</div>
</button>
</div>
@foreach($endpoint->responses as $index => $response)
<div class="sl-panel__content-wrapper sl-bg-canvas-100 example-response-{{ $endpoint->endpointId() }} example-response-{{ $endpoint->endpointId() }}-{{ $index }}"
style=" {{ $index == 0 ? '' : 'display: none;' }}"
>
<div class="sl-panel__content sl-p-0">@if(count($response->headers))
<details class="sl-pl-2">
<summary style="cursor: pointer; list-style: none;">
<small>
<span class="expansion-chevrons">
<svg aria-hidden="true" focusable="false" data-prefix="fas"
data-icon="chevron-right"
class="svg-inline--fa fa-chevron-right fa-fw sl-icon sl-text-muted"
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512">
<path fill="currentColor"
d="M96 480c-8.188 0-16.38-3.125-22.62-9.375c-12.5-12.5-12.5-32.75 0-45.25L242.8 256L73.38 86.63c-12.5-12.5-12.5-32.75 0-45.25s32.75-12.5 45.25 0l192 192c12.5 12.5 12.5 32.75 0 45.25l-192 192C112.4 476.9 104.2 480 96 480z"></path>
</svg>
</span>
Headers
</small>
</summary>
@php
$headerLines = [];
foreach($response->headers as $header => $value) {
$headerLines[] = $header . ': ' . (is_array($value) ? implode('; ', $value) : $value);
}
@endphp
<pre><code class="language-http">{{ implode("\n", $headerLines) }}</code></pre>
</details>
@endif
@if(is_string($response->content) && Str::startsWith($response->content, "<<binary>>"))
<pre><code>[{{ u::trans("scribe::endpoint.responses.binary") }}] - {{ htmlentities(str_replace("<<binary>>", "", $response->content)) }}</code></pre>
@elseif($response->status == 204)
<pre><code>[{{ u::trans("scribe::endpoint.responses.empty") }}]</code></pre>
@else
@php($parsed = json_decode($response->content))
{{-- If response is a JSON string, prettify it. Otherwise, just print it --}}
<pre><code style="max-height: 300px;"
class="language-json sl-overflow-x-auto sl-overflow-y-auto">{!! htmlentities($parsed != null ? json_encode($parsed, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) : $response->content) !!}</code></pre>
@endif
</div>
</div>
@endforeach
</div>
@endif
</div>
</div>
</div>
@@ -0,0 +1,28 @@
@foreach($groupedEndpoints as $group)
<h1 id="{!! Str::slug($group['name']) !!}"
class="sl-text-5xl sl-leading-tight sl-font-prose sl-text-heading"
>
{!! $group['name'] !!}
</h1>
{!! Parsedown::instance()->text($group['description']) !!}
@foreach($group['subgroups'] as $subgroupName => $subgroup)
@if($subgroupName !== "")
<h2 id="{!! Str::slug($group['name']) !!}-{!! Str::slug($subgroupName) !!}"
class="sl-text-3xl sl-leading-tight sl-font-prose sl-text-heading sl-mt-5 sl-mb-3"
>
{{ $subgroupName }}
</h2>
@php($subgroupDescription = collect($subgroup)->first(fn ($e) => $e->metadata->subgroupDescription)?->metadata?->subgroupDescription)
@if($subgroupDescription)
{!! Parsedown::instance()->text($subgroupDescription) !!}
@endif
<br>
@endif
@foreach($subgroup as $endpoint)
@include("scribe::themes.elements.endpoint")
@endforeach
@endforeach
@endforeach
@@ -0,0 +1,360 @@
@php
use Knuckles\Scribe\Tools\WritingUtils as u;
@endphp
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta content="IE=edge,chrome=1" http-equiv="X-UA-Compatible">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title>{!! $metadata['title'] !!}</title>
<link href="https://fonts.googleapis.com/css?family=PT+Sans&display=swap" rel="stylesheet">
<link rel="stylesheet" href="{!! $assetPathPrefix !!}css/theme-elements.style.css" media="screen">
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.10/lodash.min.js"></script>
<link rel="stylesheet"
href="https://unpkg.com/@highlightjs/cdn-assets@11.6.0/styles/docco.min.css">
<script src="https://unpkg.com/@highlightjs/cdn-assets@11.6.0/highlight.min.js"></script>
<script>hljs.highlightAll();</script>
<script type="module">
import {CodeJar} from 'https://medv.io/codejar/codejar.js'
window.CodeJar = CodeJar;
</script>
@if($tryItOut['enabled'] ?? true)
<script>
var tryItOutBaseUrl = "{!! $tryItOut['base_url'] ?? $baseUrl !!}";
var useCsrf = Boolean({{ $tryItOut['use_csrf'] ?? null }});
var csrfUrl = "{{ $tryItOut['csrf_url'] ?? null }}";
</script>
<script src="{{ u::getVersionedAsset($assetPathPrefix.'js/tryitout.js') }}"></script>
<style>
.code-editor, .response-content {
color: whitesmoke;
background-color: transparent;
}
/*
Problem: we want syntax highlighting for the Try It Out JSON body code editor
However, the Try It Out area uses a dark background, while request and response samples
(which are already highlighted) use a light background. HighlightJS can only use one theme per document.
Our options:
1. Change the bg of one. => No, it looks out of place on the page.
2. Use the same highlighting for both. => Nope, one would be unreadable.
3. Copy styles for a dark-bg h1js theme and prefix them for the CodeEditor, which is what we're doing.
Since it's only JSON, we only need a few styles anyway.
Styles taken from the Nord theme: https://github.com/highlightjs/highlight.js/blob/3997c9b430a568d5ad46d96693b90a74fc01ea7f/src/styles/nord.css#L2
*/
.code-editor > .hljs-attr {
color: #8FBCBB;
}
.code-editor > .hljs-string {
color: #A3BE8C;
}
.code-editor > .hljs-number {
color: #B48EAD;
}
.code-editor > .hljs-literal{
color: #81A1C1;
}
</style>
<script>
function tryItOut(btnElement) {
btnElement.disabled = true;
let endpointId = btnElement.dataset.endpoint;
let errorPanel = document.querySelector(`.tryItOut-error[data-endpoint=${endpointId}]`);
errorPanel.hidden = true;
let responsePanel = document.querySelector(`.tryItOut-response[data-endpoint=${endpointId}]`);
responsePanel.hidden = true;
let form = btnElement.form;
let { method, path, hasjsonbody: hasJsonBody} = form.dataset;
let body = {};
if (hasJsonBody === "1") {
body = form.querySelector('.code-editor').textContent;
} else if (form.dataset.hasfiles === "1") {
body = new FormData();
form.querySelectorAll('input[data-component=body]')
.forEach(el => {
if (el.type === 'file') {
if (el.files[0]) body.append(el.name, el.files[0])
} else body.append(el.name, el.value);
});
} else {
form.querySelectorAll('input[data-component=body]').forEach(el => {
_.set(body, el.name, el.value);
});
}
const urlParameters = form.querySelectorAll('input[data-component=url]');
urlParameters.forEach(el => (path = path.replace(new RegExp(`\\{${el.name}\\??}`), el.value)));
const headers = Object.fromEntries(Array.from(form.querySelectorAll('input[data-component=header]'))
.map(el => [el.name, (el.dataset.prefix || '') + el.value]));
const query = {}
form.querySelectorAll('input[data-component=query]').forEach(el => {
_.set(query, el.name, el.value);
});
let preflightPromise = Promise.resolve();
if (window.useCsrf && window.csrfUrl) {
preflightPromise = makeAPICall('GET', window.csrfUrl).then(() => {
headers['X-XSRF-TOKEN'] = getCookie('XSRF-TOKEN');
});
}
// content type has to be unset otherwise file upload won't work
if (form.dataset.hasfiles === "1") {
delete headers['Content-Type'];
}
return preflightPromise.then(() => makeAPICall(method, path, body, query, headers, endpointId))
.then(([responseStatus, statusText, responseContent, responseHeaders]) => {
responsePanel.hidden = false;
responsePanel.querySelector(`.response-status`).textContent = responseStatus + " " + statusText ;
let contentEl = responsePanel.querySelector(`.response-content`);
if (responseContent === '') {
contentEl.textContent = contentEl.dataset.emptyResponseText;
return;
}
// Prettify it if it's JSON
let isJson = false;
try {
const jsonParsed = JSON.parse(responseContent);
if (jsonParsed !== null) {
isJson = true;
responseContent = JSON.stringify(jsonParsed, null, 4);
}
} catch (e) {}
// Replace HTML entities
responseContent = responseContent.replace(/[<>&]/g, (i) => '&#' + i.charCodeAt(0) + ';');
contentEl.innerHTML = responseContent;
isJson && window.hljs.highlightElement(contentEl);
})
.catch(err => {
console.log(err);
let errorMessage = err.message || err;
errorPanel.hidden = false;
errorPanel.querySelector(`.error-message`).textContent = errorMessage;
})
.finally(() => { btnElement.disabled = false } );
}
window.addEventListener('DOMContentLoaded', () => {
document.querySelectorAll('.tryItOut-btn').forEach(el => {
el.addEventListener('click', () => tryItOut(el));
});
})
</script>
@endif
</head>
<body>
@if($metadata['example_languages'])
<script>
function switchExampleLanguage(lang) {
document.querySelectorAll(`.example-request`).forEach(el => el.style.display = 'none');
document.querySelectorAll(`.example-request-${lang}`).forEach(el => el.style.display = 'initial');
document.querySelectorAll(`.example-request-lang-toggle`).forEach(el => el.value = lang);
}
</script>
@endif
<script>
function switchExampleResponse(endpointId, index) {
document.querySelectorAll(`.example-response-${endpointId}`).forEach(el => el.style.display = 'none');
document.querySelectorAll(`.example-response-${endpointId}-${index}`).forEach(el => el.style.display = 'initial');
document.querySelectorAll(`.example-response-${endpointId}-toggle`).forEach(el => el.value = index);
}
/*
* Requirement: a div with class `expansion-chevrons`
* (or `expansion-chevrons-solid` to use the solid version).
* Also add the `expanded` class if your div is expanded by default.
*/
function toggleExpansionChevrons(evt) {
let elem = evt.currentTarget;
let chevronsArea = elem.querySelector('.expansion-chevrons');
const solid = chevronsArea.classList.contains('expansion-chevrons-solid');
const newState = chevronsArea.classList.contains('expanded') ? 'expand' : 'expanded';
if (newState === 'expanded') {
const selector = solid ? '#expanded-chevron-solid' : '#expanded-chevron';
const template = document.querySelector(selector);
const chevron = template.content.cloneNode(true);
chevronsArea.replaceChildren(chevron);
chevronsArea.classList.add('expanded');
} else {
const selector = solid ? '#expand-chevron-solid' : '#expand-chevron';
const template = document.querySelector(selector);
const chevron = template.content.cloneNode(true);
chevronsArea.replaceChildren(chevron);
chevronsArea.classList.remove('expanded');
}
}
/**
* 1. Make sure the children are inside the parent element
* 2. Add `expandable` class to the parent
* 3. Add `children` class to the children.
* 4. Wrap the default chevron SVG in a div with class `expansion-chevrons`
* (or `expansion-chevrons-solid` to use the solid version).
* Also add the `expanded` class if your div is expanded by default.
*/
function toggleElementChildren(evt) {
let elem = evt.currentTarget;
let children = elem.querySelector(`.children`);
if (!children) return;
if (children.contains(event.target)) return;
let oldState = children.style.display
if (oldState === 'none') {
children.style.removeProperty('display');
toggleExpansionChevrons(evt);
} else {
children.style.display = 'none';
toggleExpansionChevrons(evt);
}
evt.stopPropagation();
}
function highlightSidebarItem(evt = null) {
if (evt && evt.oldURL) {
let oldHash = new URL(evt.oldURL).hash.slice(1);
if (oldHash) {
let previousItem = window['sidebar'].querySelector(`#toc-item-${oldHash}`);
previousItem.classList.remove('sl-bg-primary-tint');
previousItem.classList.add('sl-bg-canvas-100');
}
}
let newHash = location.hash.slice(1);
if (newHash) {
let item = window['sidebar'].querySelector(`#toc-item-${newHash}`);
item.classList.remove('sl-bg-canvas-100');
item.classList.add('sl-bg-primary-tint');
}
}
addEventListener('DOMContentLoaded', () => {
highlightSidebarItem();
document.querySelectorAll('.code-editor').forEach(elem => CodeJar(elem, (editor) => {
// highlight.js does not trim old tags,
// which means highlighting doesn't update on type (only on paste)
// See https://github.com/antonmedv/codejar/issues/18
editor.textContent = editor.textContent
return hljs.highlightElement(editor)
}));
document.querySelectorAll('.expandable').forEach(el => {
el.addEventListener('click', toggleElementChildren);
});
document.querySelectorAll('details').forEach(el => {
el.addEventListener('toggle', toggleExpansionChevrons);
});
});
addEventListener('hashchange', highlightSidebarItem);
</script>
<div class="sl-elements sl-antialiased sl-h-full sl-text-base sl-font-ui sl-text-body sl-flex sl-inset-0">
@include("scribe::themes.elements.sidebar")
<div class="sl-overflow-y-auto sl-flex-1 sl-w-full sl-px-16 sl-bg-canvas sl-py-16" style="max-width: 1500px;">
<div class="sl-mb-10">
<div class="sl-mb-4">
<h1 class="sl-text-5xl sl-leading-tight sl-font-prose sl-font-semibold sl-text-heading">
{!! $metadata['title'] !!}
</h1>
@if($metadata['postman_collection_url'])
<a title="Download Postman collection" class="sl-mx-1"
href="{!! $metadata['postman_collection_url'] !!}" target="_blank">
<small>Postman collection </small>
</a>
@endif
@if($metadata['openapi_spec_url'])
<a title="Download OpenAPI spec" class="sl-mx-1"
href="{!! $metadata['openapi_spec_url'] !!}" target="_blank">
<small>OpenAPI spec </small>
</a>
@endif
</div>
<div class="sl-prose sl-markdown-viewer sl-my-4">
{!! $intro !!}
{!! $auth !!}
</div>
</div>
@include("scribe::themes.elements.groups")
<div class="sl-prose sl-markdown-viewer sl-my-5">
{!! $append !!}
</div>
</div>
</div>
<template id="expand-chevron">
<svg aria-hidden="true" focusable="false" data-prefix="fas"
data-icon="chevron-right"
class="svg-inline--fa fa-chevron-right fa-fw sl-icon sl-text-muted"
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512">
<path fill="currentColor"
d="M96 480c-8.188 0-16.38-3.125-22.62-9.375c-12.5-12.5-12.5-32.75 0-45.25L242.8 256L73.38 86.63c-12.5-12.5-12.5-32.75 0-45.25s32.75-12.5 45.25 0l192 192c12.5 12.5 12.5 32.75 0 45.25l-192 192C112.4 476.9 104.2 480 96 480z"></path>
</svg>
</template>
<template id="expanded-chevron">
<svg aria-hidden="true" focusable="false" data-prefix="fas"
data-icon="chevron-down"
class="svg-inline--fa fa-chevron-down fa-fw sl-icon sl-text-muted"
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512">
<path fill="currentColor"
d="M224 416c-8.188 0-16.38-3.125-22.62-9.375l-192-192c-12.5-12.5-12.5-32.75 0-45.25s32.75-12.5 45.25 0L224 338.8l169.4-169.4c12.5-12.5 32.75-12.5 45.25 0s12.5 32.75 0 45.25l-192 192C240.4 412.9 232.2 416 224 416z"></path>
</svg>
</template>
<template id="expand-chevron-solid">
<svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="caret-right"
class="svg-inline--fa fa-caret-right fa-fw sl-icon" role="img" xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 256 512">
<path fill="currentColor"
d="M118.6 105.4l128 127.1C252.9 239.6 256 247.8 256 255.1s-3.125 16.38-9.375 22.63l-128 127.1c-9.156 9.156-22.91 11.9-34.88 6.943S64 396.9 64 383.1V128c0-12.94 7.781-24.62 19.75-29.58S109.5 96.23 118.6 105.4z"></path>
</svg>
</template>
<template id="expanded-chevron-solid">
<svg aria-hidden="true" focusable="false" data-prefix="fas"
data-icon="caret-down"
class="svg-inline--fa fa-caret-down fa-fw sl-icon" role="img"
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512">
<path fill="currentColor"
d="M310.6 246.6l-127.1 128C176.4 380.9 168.2 384 160 384s-16.38-3.125-22.63-9.375l-127.1-128C.2244 237.5-2.516 223.7 2.438 211.8S19.07 192 32 192h255.1c12.94 0 24.62 7.781 29.58 19.75S319.8 237.5 310.6 246.6z"></path>
</svg>
</template>
</body>
</html>
@@ -0,0 +1,92 @@
<div id="sidebar" class="sl-flex sl-overflow-y-auto sl-flex-col sl-sticky sl-inset-y-0 sl-pt-8 sl-bg-canvas-100 sl-border-r"
style="width: calc((100% - 1800px) / 2 + 300px); padding-left: calc((100% - 1800px) / 2); min-width: 300px; max-height: 100vh">
<div class="sl-flex sl-items-center sl-mb-5 sl-ml-4">
@if($metadata['logo'] != false)
<div class="sl-inline sl-overflow-x-hidden sl-overflow-y-hidden sl-mr-3 sl-rounded-lg"
style="background-color: transparent;">
<img src="{{ $metadata['logo'] }}" height="30px" width="30px" alt="logo">
</div>
@endif
<h4 class="sl-text-paragraph sl-leading-snug sl-font-prose sl-font-semibold sl-text-heading">
{{ $metadata['title'] }}
</h4>
</div>
<div class="sl-flex sl-overflow-y-auto sl-flex-col sl-flex-grow sl-flex-shrink">
<div class="sl-overflow-y-auto sl-w-full sl-bg-canvas-100">
<div class="sl-my-3">
@foreach($headings as $h1)
<div class="expandable">
<div title="{!! $h1['name'] !!}" id="toc-item-{!! $h1['slug'] !!}"
class="sl-flex sl-items-center sl-h-md sl-pr-4 sl-pl-4 sl-bg-canvas-100 hover:sl-bg-canvas-200 sl-cursor-pointer sl-select-none">
<a href="#{!! $h1['slug'] !!}"
class="sl-flex-1 sl-items-center sl-truncate sl-mr-1.5 sl-p-0">{!! $h1['name'] !!}</a>
@if(count($h1['subheadings']) > 0)
<div class="sl-flex sl-items-center sl-text-xs expansion-chevrons">
<svg aria-hidden="true" focusable="false" data-prefix="fas"
data-icon="chevron-right"
class="svg-inline--fa fa-chevron-right fa-fw sl-icon sl-text-muted"
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512">
<path fill="currentColor"
d="M96 480c-8.188 0-16.38-3.125-22.62-9.375c-12.5-12.5-12.5-32.75 0-45.25L242.8 256L73.38 86.63c-12.5-12.5-12.5-32.75 0-45.25s32.75-12.5 45.25 0l192 192c12.5 12.5 12.5 32.75 0 45.25l-192 192C112.4 476.9 104.2 480 96 480z"></path>
</svg>
</div>
@endif
</div>
@if(count($h1['subheadings']) > 0)
<div class="children" style="display: none;">
@foreach($h1['subheadings'] as $h2)
<div class="expandable">
<div class="sl-flex sl-items-center sl-h-md sl-pr-4 sl-pl-8 sl-bg-canvas-100 hover:sl-bg-canvas-200 sl-cursor-pointer sl-select-none"
id="toc-item-{!! $h2['slug'] !!}">
<div class="sl-flex-1 sl-items-center sl-truncate sl-mr-1.5 sl-p-0" title="{!! $h2['name'] !!}">
<a class="ElementsTableOfContentsItem sl-block sl-no-underline"
href="#{!! $h2['slug'] !!}">
{!! $h2['name'] !!}
</a>
</div>
@if(count($h2['subheadings']) > 0)
<div class="sl-flex sl-items-center sl-text-xs expansion-chevrons">
<svg aria-hidden="true" focusable="false" data-prefix="fas"
data-icon="chevron-right"
class="svg-inline--fa fa-chevron-right fa-fw sl-icon sl-text-muted"
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512">
<path fill="currentColor"
d="M96 480c-8.188 0-16.38-3.125-22.62-9.375c-12.5-12.5-12.5-32.75 0-45.25L242.8 256L73.38 86.63c-12.5-12.5-12.5-32.75 0-45.25s32.75-12.5 45.25 0l192 192c12.5 12.5 12.5 32.75 0 45.25l-192 192C112.4 476.9 104.2 480 96 480z"></path>
</svg>
</div>
@endif
</div>
@if(count($h2['subheadings']) > 0)
<div class="children" style="display: none;">
@foreach($h2['subheadings'] as $h3)
<a class="ElementsTableOfContentsItem sl-block sl-no-underline"
href="#{!! $h3['slug'] !!}">
<div title="{!! $h3['name'] !!}" id="toc-item-{!! $h3['slug'] !!}"
class="sl-flex sl-items-center sl-h-md sl-pr-4 sl-pl-12 sl-bg-canvas-100 hover:sl-bg-canvas-200 sl-cursor-pointer sl-select-none">
{!! $h3['name'] !!}
</div>
</a>
@endforeach
</div>
@endif
</div>
@endforeach
</div>
@endif
</div>
@endforeach
</div>
</div>
<div class="sl-flex sl-items-center sl-px-4 sl-py-3 sl-border-t">
{{ $metadata['last_updated'] }}
</div>
<div class="sl-flex sl-items-center sl-px-4 sl-py-3 sl-border-t">
<a href="http://github.com/knuckleswtf/scribe">Documentation powered by Scribe </a>
</div>
</div>
</div>
@@ -0,0 +1,322 @@
@php
use Knuckles\Scribe\Tools\Utils as u;
/** @var \Knuckles\Camel\Output\OutputEndpointData $endpoint */
@endphp
<div class="sl-inverted">
<div class="sl-overflow-y-hidden sl-rounded-lg">
<form class="TryItPanel sl-bg-canvas-100 sl-rounded-lg"
data-method="{{ $endpoint->httpMethods[0] }}"
data-path="{{ $endpoint->uri }}"
data-hasfiles="{{ $endpoint->hasFiles() ? 1 : 0 }}"
data-hasjsonbody="{{ $endpoint->hasJsonBody() ? 1 : 0 }}">
@if($endpoint->isAuthed() && $metadata['auth']['location'] !== 'body')
<div class="sl-panel sl-outline-none sl-w-full expandable">
<div class="sl-panel__titlebar sl-flex sl-items-center sl-relative focus:sl-z-10 sl-text-base sl-leading-none sl-pr-4 sl-pl-3 sl-bg-canvas-200 sl-text-body sl-border-input focus:sl-border-primary sl-cursor-pointer sl-select-none"
role="button">
<div class="sl-flex sl-flex-1 sl-items-center sl-h-lg">
<div class="sl-flex sl-items-center sl-mr-1.5 expansion-chevrons expansion-chevrons-solid expanded">
<svg aria-hidden="true" focusable="false" data-prefix="fas"
data-icon="caret-down"
class="svg-inline--fa fa-caret-down fa-fw sl-icon" role="img"
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512">
<path fill="currentColor"
d="M310.6 246.6l-127.1 128C176.4 380.9 168.2 384 160 384s-16.38-3.125-22.63-9.375l-127.1-128C.2244 237.5-2.516 223.7 2.438 211.8S19.07 192 32 192h255.1c12.94 0 24.62 7.781 29.58 19.75S319.8 237.5 310.6 246.6z"></path>
</svg>
</div>
Auth
</div>
</div>
<div class="sl-panel__content-wrapper sl-bg-canvas-100 children" role="region">
<div class="ParameterGrid sl-p-4">
<label aria-hidden="true"
for="auth-{{ $endpoint->endpointId() }}">{{ $metadata['auth']['name'] }}</label>
<span class="sl-mx-3">:</span>
<div class="sl-flex sl-flex-1">
<div class="sl-input sl-flex-1 sl-relative">
<code>{{ $metadata['auth']['prefix'] }}</code>
<input aria-label="{{ $metadata['auth']['name'] }}"
id="auth-{{ $endpoint->endpointId() }}"
data-component="{{ $metadata['auth']['location'] }}"
data-prefix="{{ $metadata['auth']['prefix'] }}"
name="{{ $metadata['auth']['name'] }}"
placeholder="{{ $metadata['auth']['placeholder'] }}"
class="auth-value sl-relative {{ $metadata['auth']['prefix'] ? 'sl-w-3/5' : 'sl-w-full sl-pr-2.5 sl-pl-2.5' }} sl-h-md sl-text-base sl-rounded sl-border-transparent hover:sl-border-input focus:sl-border-primary sl-border">
</div>
</div>
</div>
</div>
</div>
@endif
@if(count($endpoint->headers))
<div class="sl-panel sl-outline-none sl-w-full expandable">
<div class="sl-panel__titlebar sl-flex sl-items-center sl-relative focus:sl-z-10 sl-text-base sl-leading-none sl-pr-4 sl-pl-3 sl-bg-canvas-200 sl-text-body sl-border-input focus:sl-border-primary sl-cursor-pointer sl-select-none"
role="button">
<div class="sl-flex sl-flex-1 sl-items-center sl-h-lg">
<div class="sl-flex sl-items-center sl-mr-1.5 expansion-chevrons expansion-chevrons-solid expanded">
<svg aria-hidden="true" focusable="false" data-prefix="fas"
data-icon="caret-down"
class="svg-inline--fa fa-caret-down fa-fw sl-icon" role="img"
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512">
<path fill="currentColor"
d="M310.6 246.6l-127.1 128C176.4 380.9 168.2 384 160 384s-16.38-3.125-22.63-9.375l-127.1-128C.2244 237.5-2.516 223.7 2.438 211.8S19.07 192 32 192h255.1c12.94 0 24.62 7.781 29.58 19.75S319.8 237.5 310.6 246.6z"></path>
</svg>
</div>
Headers
</div>
</div>
<div class="sl-panel__content-wrapper sl-bg-canvas-100 children" role="region">
<div class="ParameterGrid sl-p-4">
@foreach($endpoint->headers as $name => $example)
@php
if($endpoint->isAuthed() && $metadata['auth']['location'] === 'header' && $name === $metadata['auth']['name']) continue;
@endphp
<label aria-hidden="true"
for="header-{{ $endpoint->endpointId() }}-{{ $name }}">{{ $name }}</label>
<span class="sl-mx-3">:</span>
<div class="sl-flex sl-flex-1">
<div class="sl-input sl-flex-1 sl-relative">
<input aria-label="{{ $name }}" name="{{ $name }}"
id="header-{{ $endpoint->endpointId() }}-{{ $name }}"
value="{{ $example }}" data-component="header"
class="sl-relative sl-w-full sl-h-md sl-text-base sl-pr-2.5 sl-pl-2.5 sl-rounded sl-border-transparent hover:sl-border-input focus:sl-border-primary sl-border">
</div>
</div>
@endforeach
</div>
</div>
</div>
@endif
@if(count($endpoint->urlParameters))
<div class="sl-panel sl-outline-none sl-w-full expandable">
<div class="sl-panel__titlebar sl-flex sl-items-center sl-relative focus:sl-z-10 sl-text-base sl-leading-none sl-pr-4 sl-pl-3 sl-bg-canvas-200 sl-text-body sl-border-input focus:sl-border-primary sl-cursor-pointer sl-select-none"
role="button">
<div class="sl-flex sl-flex-1 sl-items-center sl-h-lg">
<div class="sl-flex sl-items-center sl-mr-1.5 expansion-chevrons expansion-chevrons-solid expanded">
<svg aria-hidden="true" focusable="false" data-prefix="fas"
data-icon="caret-down"
class="svg-inline--fa fa-caret-down fa-fw sl-icon" role="img"
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512">
<path fill="currentColor"
d="M310.6 246.6l-127.1 128C176.4 380.9 168.2 384 160 384s-16.38-3.125-22.63-9.375l-127.1-128C.2244 237.5-2.516 223.7 2.438 211.8S19.07 192 32 192h255.1c12.94 0 24.62 7.781 29.58 19.75S319.8 237.5 310.6 246.6z"></path>
</svg>
</div>
URL Parameters
</div>
</div>
<div class="sl-panel__content-wrapper sl-bg-canvas-100 children" role="region">
<div class="ParameterGrid sl-p-4">
@foreach($endpoint->urlParameters as $name => $parameter)
<label aria-hidden="true"
for="urlparam-{{ $endpoint->endpointId() }}-{{ $name }}">{{ $name }}</label>
<span class="sl-mx-3">:</span>
<div class="sl-flex sl-flex-1">
<div class="sl-input sl-flex-1 sl-relative">
<input aria-label="{{ $name }}" name="{{ $name }}"
id="urlparam-{{ $endpoint->endpointId() }}-{{ $name }}"
placeholder="{{ $parameter->description }}"
value="{{ $parameter->example }}" data-component="url"
class="sl-relative sl-w-full sl-h-md sl-text-base sl-pr-2.5 sl-pl-2.5 sl-rounded sl-border-transparent hover:sl-border-input focus:sl-border-primary sl-border">
</div>
</div>
@endforeach
</div>
</div>
</div>
@endif
@if(count($endpoint->queryParameters))
<div class="sl-panel sl-outline-none sl-w-full expandable">
<div class="sl-panel__titlebar sl-flex sl-items-center sl-relative focus:sl-z-10 sl-text-base sl-leading-none sl-pr-4 sl-pl-3 sl-bg-canvas-200 sl-text-body sl-border-input focus:sl-border-primary sl-cursor-pointer sl-select-none"
role="button">
<div class="sl-flex sl-flex-1 sl-items-center sl-h-lg">
<div class="sl-flex sl-items-center sl-mr-1.5 expansion-chevrons expansion-chevrons-solid expanded">
<svg aria-hidden="true" focusable="false" data-prefix="fas"
data-icon="caret-down"
class="svg-inline--fa fa-caret-down fa-fw sl-icon" role="img"
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512">
<path fill="currentColor"
d="M310.6 246.6l-127.1 128C176.4 380.9 168.2 384 160 384s-16.38-3.125-22.63-9.375l-127.1-128C.2244 237.5-2.516 223.7 2.438 211.8S19.07 192 32 192h255.1c12.94 0 24.62 7.781 29.58 19.75S319.8 237.5 310.6 246.6z"></path>
</svg>
</div>
Query Parameters
</div>
</div>
<div class="sl-panel__content-wrapper sl-bg-canvas-100 children" role="region">
<div class="ParameterGrid sl-p-4">
@foreach($endpoint->queryParameters as $name => $parameter)
@php
/** @var \Knuckles\Camel\Output\Parameter $parameter */
if ($parameter->type == 'object') // Skip; individual object children are listed
continue;
if (str_contains($name, "[]"))
// This likely belongs to an obj-array (eg objs[].a); we only show the parent (objs[]), so skip
continue;
if($endpoint->isAuthed() && $metadata['auth']['location'] === 'query'
&& $name === $metadata['auth']['name']) continue;
@endphp
<label aria-hidden="true"
for="queryparam-{{ $endpoint->endpointId() }}-{{ $name }}">{{ $name }}</label>
<span class="sl-mx-3">:</span>
<div class="sl-flex sl-flex-1">
<div class="sl-input sl-flex-1 sl-relative">
@if(str_ends_with($parameter->type, '[]'))
<input aria-label="{{ $name }}" name="{{ $name }}"
id="queryparam-{{ $endpoint->endpointId() }}-{{ $name }}"
placeholder="{{ $parameter->description }}"
value="{{ json_encode($parameter->example) }}" data-component="query"
class="sl-relative sl-w-full sl-h-md sl-text-base sl-pr-2.5 sl-pl-2.5 sl-rounded sl-border-transparent hover:sl-border-input focus:sl-border-primary sl-border"
>
@else
<input aria-label="{{ $name }}" name="{{ $name }}"
id="queryparam-{{ $endpoint->endpointId() }}-{{ $name }}"
placeholder="{{ $parameter->description }}"
value="{{ $parameter->example }}" data-component="query"
class="sl-relative sl-w-full sl-h-md sl-text-base sl-pr-2.5 sl-pl-2.5 sl-rounded sl-border-transparent hover:sl-border-input focus:sl-border-primary sl-border"
>
@endif
</div>
</div>
@endforeach
</div>
</div>
</div>
@endif
@if(count($endpoint->bodyParameters))
<div class="sl-panel sl-outline-none sl-w-full expandable">
<div class="sl-panel__titlebar sl-flex sl-items-center sl-relative focus:sl-z-10 sl-text-base sl-leading-none sl-pr-4 sl-pl-3 sl-bg-canvas-200 sl-text-body sl-border-input focus:sl-border-primary sl-cursor-pointer sl-select-none"
role="button">
<div class="sl-flex sl-flex-1 sl-items-center sl-h-lg">
<div class="sl-flex sl-items-center sl-mr-1.5 expansion-chevrons expansion-chevrons-solid expanded">
<svg aria-hidden="true" focusable="false" data-prefix="fas"
data-icon="caret-down"
class="svg-inline--fa fa-caret-down fa-fw sl-icon" role="img"
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512">
<path fill="currentColor"
d="M310.6 246.6l-127.1 128C176.4 380.9 168.2 384 160 384s-16.38-3.125-22.63-9.375l-127.1-128C.2244 237.5-2.516 223.7 2.438 211.8S19.07 192 32 192h255.1c12.94 0 24.62 7.781 29.58 19.75S319.8 237.5 310.6 246.6z"></path>
</svg>
</div>
Body
</div>
</div>
<div class="sl-panel__content-wrapper sl-bg-canvas-100 children" role="region">
@if($endpoint->hasJsonBody())
<div class="TextRequestBody sl-p-4">
<div class="code-editor language-json"
id="json-body-{{ $endpoint->endpointId() }}"
style="font-family: var(--font-code); font-size: 12px; line-height: var(--lh-code);"
>{!! json_encode($endpoint->getSampleBody(), JSON_PRETTY_PRINT) !!}</div>
</div>
@else
<div class="ParameterGrid sl-p-4">
@foreach($endpoint->bodyParameters as $name => $parameter)
@php
/** @var \Knuckles\Camel\Output\Parameter $parameter */
if ($parameter->type == 'object') // Skip; individual object children are listed
continue;
if (str_contains($name, "[]"))
// This likely belongs to an obj-array (eg objs[].a); we only show the parent (objs[]), so skip
continue;
@endphp
<label aria-hidden="true"
for="bodyparam-{{ $endpoint->endpointId() }}-{{ $name }}">{{ $name }}</label>
<span class="sl-mx-3">:</span>
<div class="sl-flex sl-flex-1">
<div class="sl-input sl-flex-1 sl-relative">
@if($parameter->type == 'file')
<input aria-label="{{ $name }}" name="{{ $name }}"
id="bodyparam-{{ $endpoint->endpointId() }}-{{ $name }}"
type="file" data-component="body"
class="sl-relative sl-w-full sl-h-md sl-text-base sl-pr-2.5 sl-pl-2.5 sl-rounded sl-border-transparent hover:sl-border-input focus:sl-border-primary sl-border"
>
@elseif(str_ends_with($parameter->type, '[]'))
<input aria-label="{{ $name }}" name="{{ $name }}"
id="bodyparam-{{ $endpoint->endpointId() }}-{{ $name }}"
placeholder="{{ $parameter->description }}"
value="{{ json_encode($parameter->example) }}" data-component="body"
class="sl-relative sl-w-full sl-h-md sl-text-base sl-pr-2.5 sl-pl-2.5 sl-rounded sl-border-transparent hover:sl-border-input focus:sl-border-primary sl-border"
>
@else
<input aria-label="{{ $name }}" name="{{ $name }}"
id="bodyparam-{{ $endpoint->endpointId() }}-{{ $name }}"
placeholder="{{ $parameter->description }}"
value="{{ $parameter->example }}" data-component="body"
class="sl-relative sl-w-full sl-h-md sl-text-base sl-pr-2.5 sl-pl-2.5 sl-rounded sl-border-transparent hover:sl-border-input focus:sl-border-primary sl-border"
>
@endif
</div>
</div>
@endforeach
</div>
@endif
</div>
</div>
@endif
<div class="SendButtonHolder sl-mt-4 sl-p-4 sl-pt-0">
<div class="sl-stack sl-stack--horizontal sl-stack--2 sl-flex sl-flex-row sl-items-center">
<button type="button" data-endpoint="{{ $endpoint->endpointId() }}"
class="tryItOut-btn sl-button sl-h-sm sl-text-base sl-font-medium sl-px-1.5 sl-bg-primary hover:sl-bg-primary-dark active:sl-bg-primary-darker disabled:sl-bg-canvas-100 sl-text-on-primary disabled:sl-text-body sl-rounded sl-border-transparent sl-border disabled:sl-opacity-70"
>
{{ u::trans("scribe::try_it_out.send") }}
</button>
</div>
</div>
<div data-endpoint="{{ $endpoint->endpointId() }}"
class="tryItOut-error expandable sl-panel sl-outline-none sl-w-full" hidden>
<div class="sl-panel__titlebar sl-flex sl-items-center sl-relative focus:sl-z-10 sl-text-base sl-leading-none sl-pr-4 sl-pl-3 sl-bg-canvas-200 sl-text-body sl-border-input focus:sl-border-primary sl-cursor-pointer sl-select-none"
role="button">
<div class="sl-flex sl-flex-1 sl-items-center sl-h-lg">
<div class="sl-flex sl-items-center sl-mr-1.5 expansion-chevrons expansion-chevrons-solid expanded">
<svg aria-hidden="true" focusable="false" data-prefix="fas"
data-icon="caret-down"
class="svg-inline--fa fa-caret-down fa-fw sl-icon" role="img"
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512">
<path fill="currentColor"
d="M310.6 246.6l-127.1 128C176.4 380.9 168.2 384 160 384s-16.38-3.125-22.63-9.375l-127.1-128C.2244 237.5-2.516 223.7 2.438 211.8S19.07 192 32 192h255.1c12.94 0 24.62 7.781 29.58 19.75S319.8 237.5 310.6 246.6z"></path>
</svg>
</div>
{{ u::trans("scribe::try_it_out.request_failed") }}
</div>
</div>
<div class="sl-panel__content-wrapper sl-bg-canvas-100 children" role="region">
<div class="sl-panel__content sl-p-4">
<p class="sl-pb-2"><strong class="error-message"></strong></p>
<p class="sl-pb-2">{{ u::trans("scribe::try_it_out.error_help") }}</p>
</div>
</div>
</div>
<div data-endpoint="{{ $endpoint->endpointId() }}"
class="tryItOut-response expandable sl-panel sl-outline-none sl-w-full" hidden>
<div class="sl-panel__titlebar sl-flex sl-items-center sl-relative focus:sl-z-10 sl-text-base sl-leading-none sl-pr-4 sl-pl-3 sl-bg-canvas-200 sl-text-body sl-border-input focus:sl-border-primary sl-cursor-pointer sl-select-none"
role="button">
<div class="sl-flex sl-flex-1 sl-items-center sl-h-lg">
<div class="sl-flex sl-items-center sl-mr-1.5 expansion-chevrons expansion-chevrons-solid expanded">
<svg aria-hidden="true" focusable="false" data-prefix="fas"
data-icon="caret-down"
class="svg-inline--fa fa-caret-down fa-fw sl-icon" role="img"
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512">
<path fill="currentColor"
d="M310.6 246.6l-127.1 128C176.4 380.9 168.2 384 160 384s-16.38-3.125-22.63-9.375l-127.1-128C.2244 237.5-2.516 223.7 2.438 211.8S19.07 192 32 192h255.1c12.94 0 24.62 7.781 29.58 19.75S319.8 237.5 310.6 246.6z"></path>
</svg>
</div>
{{ u::trans("scribe::try_it_out.received_response") }}
</div>
</div>
<div class="sl-panel__content-wrapper sl-bg-canvas-100 children" role="region">
<div class="sl-panel__content sl-p-4">
<p class="sl-pb-2 response-status"></p>
<pre><code class="sl-pb-2 response-content language-json"
data-empty-response-text="<{{ u::trans("scribe::endpoint.responses.empty") }}>"
style="max-height: 300px;"></code></pre>
</div>
</div>
</div>
</form>
</div>
</div>