Infrastructure
Forge Deploy Script Editor code
Copy the implementation or inspect every file that belongs to this component unit.
resources/views/components/ui/forge-deploy-script-editor.blade.php
@props([
'name' => 'deploy_script',
'value' => '',
'macros' => ['$CREATE_RELEASE()', 'cd $FORGE_RELEASE_DIRECTORY', '$ACTIVATE_RELEASE()', '$RESTART_QUEUES()'],
'rows' => 12,
])
@php
/*
| Deploy script textarea with quick insert buttons for Forge deployment
| macros. Useful for standard and zero-downtime deployment settings panels.
|
| Usage:
| <x-ui.forge-deploy-script-editor :value="$script" />
*/
@endphp
<section
x-data="{
script: @js($value),
escapeHtml(value) {
return String(value)
.replaceAll('&', '&')
.replaceAll('<', '<')
.replaceAll('>', '>')
.replaceAll('"', '&quot;');
},
highlight(value) {
return this.escapeHtml(value || '')
.split('\n')
.map((line) => {
if (line.trim().startsWith('#')) {
return '<span class="tok-com">' + line + '</span>';
}
return line
.replace(/(\$[A-Z_]+(?:\(\))?)/g, '<span class="tok-var">$1</span>')
.replace(/(^|\s)(php|composer|npm|git|sudo|cd|echo|curl|forge)(?=\s|$)/g, '$1<span class="tok-fn">$2</span>')
.replace(/(\s--?[A-Za-z0-9][A-Za-z0-9-]*)/g, '<span class="tok-key">$1</span>')
.replace(/(\b\d+(?:\.\d+)?\b)/g, '<span class="tok-num">$1</span>');
})
.join('\n');
},
insert(text) {
const textarea = this.$refs.script;
const start = textarea.selectionStart ?? this.script.length;
const end = textarea.selectionEnd ?? this.script.length;
const before = this.script.slice(0, start);
const after = this.script.slice(end);
const prefix = before.length && ! before.endsWith('\n') ? '\n' : '';
const suffix = after.length && ! after.startsWith('\n') ? '\n' : '';
this.script = before + prefix + text + suffix + after;
this.$nextTick(() => {
textarea.focus();
const cursor = (before + prefix + text).length;
textarea.setSelectionRange(cursor, cursor);
});
},
}"
{{ $attributes->merge(['class' => 'min-w-0 overflow-hidden rounded-xl border border-gray-200 bg-white shadow-sm dark:border-gray-800 dark:bg-gray-900']) }}
>
<div class="flex flex-col gap-3 border-b border-gray-200 px-4 py-3 dark:border-gray-800 lg:flex-row lg:items-center lg:justify-between">
<div class="min-w-0">
<h3 class="text-sm font-semibold text-gray-900 dark:text-white">Deploy script</h3>
<p class="mt-1 text-xs text-gray-500 dark:text-gray-400">Insert Forge macros without leaving the editor.</p>
</div>
<div class="flex flex-wrap gap-2">
@foreach ($macros as $macro)
<button
type="button"
class="rounded-md border border-gray-200 bg-white px-2.5 py-1.5 font-mono text-xs font-medium text-gray-700 transition hover:border-brand-300 hover:text-brand-700 dark:border-gray-700 dark:bg-gray-950 dark:text-gray-300 dark:hover:border-brand-700 dark:hover:text-brand-300"
@click="insert(@js($macro))"
>
{{ $macro }}
</button>
@endforeach
</div>
</div>
<textarea
x-ref="script"
x-model="script"
name="{{ $name }}"
rows="{{ $rows }}"
spellcheck="false"
class="block w-full resize-y border-0 bg-gray-950 px-3 py-4 font-mono text-[12px] leading-6 text-gray-100 outline-none focus:ring-0 sm:px-4 sm:text-[13px]"
></textarea>
<div class="border-t border-gray-800 bg-gray-950 px-3 py-3 sm:px-4">
<div class="mb-2 text-xs font-medium text-gray-500">
Highlighted preview
</div>
<pre class="max-h-56 overflow-auto rounded-lg border border-gray-800 bg-gray-900/70 p-3 font-mono text-[12px] leading-6 text-gray-200 sm:text-[13px] [&_.tok-key]:text-brand-300 [&_.tok-fn]:text-amber-300 [&_.tok-str]:text-green-300 [&_.tok-com]:text-gray-500 [&_.tok-com]:italic [&_.tok-num]:text-amber-200 [&_.tok-var]:text-gray-100"><code x-html="highlight(script)"></code></pre>
</div>
</section>