fix(ui): polish create flows and terminal navigation
Open the global terminal outside Livewire navigation, clarify that image tag and SHA256 digest are mutually exclusive, inset the GitLab empty state, and show loading on Dockerfile create. Add regression tests.
This commit is contained in:
parent
c07f66cb5e
commit
fff83884da
9 changed files with 62 additions and 12 deletions
|
|
@ -89,7 +89,7 @@ class="{{ request()->is('project/*') || request()->is('projects') ? 'menu-item m
|
|||
</li>
|
||||
@can('canAccessTerminal')
|
||||
<li>
|
||||
<a title="Terminal" {{ wireNavigate() }}
|
||||
<a title="Terminal"
|
||||
class="{{ request()->is('terminal*') ? 'menu-item-active menu-item' : 'menu-item' }}"
|
||||
:class="collapsed && 'lg:justify-center lg:px-0'" href="{{ route('terminal') }}">
|
||||
<x-reicon name="browser-terminal" class="menu-item-icon" />
|
||||
|
|
|
|||
|
|
@ -14,9 +14,14 @@ class="mt-8 w-full max-w-[920px] lg:mt-3">
|
|||
placeholder="nginx, ghcr.io/user/app:v1.2.3, or nginx:stable@sha256:…"
|
||||
helper="Paste a complete image reference, or enter a name and use one of the optional fields below."
|
||||
required autofocus />
|
||||
<div class="grid gap-4 sm:grid-cols-2">
|
||||
<div class="grid gap-3 sm:grid-cols-[minmax(0,1fr)_auto_minmax(0,1fr)] sm:items-end"
|
||||
aria-label="Tag and SHA256 digest are mutually exclusive">
|
||||
<x-forms.input id="imageTag" label="Tag" placeholder="latest"
|
||||
helper="Use a mutable tag such as latest or v1.2.3." />
|
||||
<div
|
||||
class="flex items-center justify-center text-xs font-semibold text-neutral-400 sm:h-9 dark:text-fg-faint">
|
||||
<span>OR</span>
|
||||
</div>
|
||||
<x-forms.input id="imageSha256" label="SHA256 digest"
|
||||
placeholder="59e02939b1bf39f16c93138a28727aec…"
|
||||
helper="Use the 64-character digest without the sha256: prefix." />
|
||||
|
|
|
|||
|
|
@ -7,15 +7,17 @@
|
|||
<p>Connect a GitLab App before selecting a private repository.</p>
|
||||
</div>
|
||||
</div>
|
||||
<x-empty title="No GitLab Apps"
|
||||
description="Create an app to grant Coolify access to selected repositories."
|
||||
icon-name="sources">
|
||||
<x-slot:contents>
|
||||
<x-modal-input buttonTitle="+ Add GitLab App" title="New GitLab App" closeOutside="false">
|
||||
<livewire:source.gitlab.create />
|
||||
</x-modal-input>
|
||||
</x-slot:contents>
|
||||
</x-empty>
|
||||
<div class="application-settings-section-body">
|
||||
<x-empty title="No GitLab Apps"
|
||||
description="Create an app to grant Coolify access to selected repositories."
|
||||
icon-name="sources">
|
||||
<x-slot:contents>
|
||||
<x-modal-input buttonTitle="+ Add GitLab App" title="New GitLab App" closeOutside="false">
|
||||
<livewire:source.gitlab.create />
|
||||
</x-modal-input>
|
||||
</x-slot:contents>
|
||||
</x-empty>
|
||||
</div>
|
||||
</section>
|
||||
@elseif ($current_step === 'gitlab_apps')
|
||||
<section class="application-settings-section">
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
<h2>Dockerfile</h2>
|
||||
<p>Create an application directly from a Dockerfile without connecting a Git repository.</p>
|
||||
</div>
|
||||
<x-forms.button type="submit" isHighlighted>Create application</x-forms.button>
|
||||
<x-forms.button type="submit" wire:target="submit" isHighlighted>Create application</x-forms.button>
|
||||
</div>
|
||||
<div class="application-settings-section-body p-0!">
|
||||
<x-forms.textarea useMonacoEditor monacoEditorLanguage="dockerfile" rows="20"
|
||||
|
|
|
|||
9
tests/Feature/DockerImageCreateViewTest.php
Normal file
9
tests/Feature/DockerImageCreateViewTest.php
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
it('shows that image tag and digest are mutually exclusive', function () {
|
||||
$view = file_get_contents(resource_path('views/livewire/project/new/docker-image.blade.php'));
|
||||
|
||||
expect($view)
|
||||
->toContain('aria-label="Tag and SHA256 digest are mutually exclusive"')
|
||||
->toContain('>OR</span>');
|
||||
});
|
||||
|
|
@ -46,6 +46,12 @@
|
|||
});
|
||||
|
||||
describe('GitLab App authorization', function () {
|
||||
test('empty gitlab app state is inset from the section edges', function () {
|
||||
$view = file_get_contents(resource_path('views/livewire/project/new/gitlab-private-repository.blade.php'));
|
||||
|
||||
expect($view)->toContain("<div class=\"application-settings-section-body\">\n <x-empty title=\"No GitLab Apps\"");
|
||||
});
|
||||
|
||||
test('unrelated users cannot inspect system-wide source secrets in the component payload', function () {
|
||||
$otherTeam = Team::factory()->create();
|
||||
$systemWideSource = GitlabApp::create([
|
||||
|
|
|
|||
|
|
@ -15,6 +15,18 @@
|
|||
->not->toContain('<x-loading text="Loading containers" />');
|
||||
});
|
||||
|
||||
it('provides opt-in diagnostics for connected terminal theme changes', function () {
|
||||
$terminalClient = file_get_contents(resource_path('js/terminal.js'));
|
||||
|
||||
expect($terminalClient)
|
||||
->toContain('terminal-debug')
|
||||
->toContain("'[Terminal Theme] Applying theme'")
|
||||
->toContain("'[Terminal Theme] Theme applied'")
|
||||
->toContain('requestedTheme: themeName')
|
||||
->toContain('shellTheme: shell?.dataset.consoleTheme')
|
||||
->toContain("getComputedStyle(shell, '::before').background");
|
||||
});
|
||||
|
||||
it('starts a single discovered resource container without waiting for a missed browser event', function () {
|
||||
$terminalComponent = file_get_contents(app_path('Livewire/Project/Shared/ExecuteContainerCommand.php'));
|
||||
$terminalView = file_get_contents(resource_path('views/livewire/project/shared/execute-container-command.blade.php'));
|
||||
|
|
|
|||
7
tests/Feature/SimpleDockerfileCreateViewTest.php
Normal file
7
tests/Feature/SimpleDockerfileCreateViewTest.php
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
<?php
|
||||
|
||||
it('shows a loading indicator while creating the application', function () {
|
||||
$view = file_get_contents(resource_path('views/livewire/project/new/simple-dockerfile.blade.php'));
|
||||
|
||||
expect($view)->toContain('<x-forms.button type="submit" wire:target="submit" isHighlighted>');
|
||||
});
|
||||
|
|
@ -54,6 +54,15 @@
|
|||
->toMatch('/\.terminal-session-panel\s*\{[^}]*box-shadow:\s*none;/s');
|
||||
});
|
||||
|
||||
it('opens the global terminal outside Livewire navigation like resource terminals', function () {
|
||||
$navbar = file_get_contents(resource_path('views/components/navbar.blade.php'));
|
||||
|
||||
expect($navbar)
|
||||
->toContain('<a title="Terminal"')
|
||||
->toContain('href="{{ route(\'terminal\') }}"')
|
||||
->not->toMatch('/<a title="Terminal"[^>]*wireNavigate\(\)/s');
|
||||
});
|
||||
|
||||
it('uses floating rounded controls instead of the legacy terminal header bar', function () {
|
||||
$view = file_get_contents(resource_path('views/livewire/terminal/index.blade.php'));
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue