From 663e311724a412f9519c4b5e6e2bbfc17939938e Mon Sep 17 00:00:00 2001 From: Mark Gregory Date: Mon, 12 Oct 2026 16:29:40 +0100 Subject: [PATCH] move into sonardesk --- ...6_10_12_160000_extend_download_products.php | 14 ++++++++++++-- ..._210000_repair_download_product_columns.php | 15 +++++++++++++++ .../Resources/views/downloads/index.blade.php | 10 ++++++---- .../views/downloads/product.blade.php | 4 +++- .../views/downloads/release.blade.php | 4 +++- public/css/sonardesk-product.css | 2 ++ resources/views/sonardesk/features.blade.php | 2 +- resources/views/sonardesk/home.blade.php | 8 ++++---- resources/views/sonardesk/layout.blade.php | 18 +++++++++++++----- resources/views/sonardesk/pricing.blade.php | 2 +- 10 files changed, 60 insertions(+), 19 deletions(-) create mode 100644 Modules/Licensing/Database/Migrations/2026_10_12_210000_repair_download_product_columns.php create mode 100644 public/css/sonardesk-product.css diff --git a/Modules/Licensing/Database/Migrations/2026_10_12_160000_extend_download_products.php b/Modules/Licensing/Database/Migrations/2026_10_12_160000_extend_download_products.php index 420dd74..bedbed4 100644 --- a/Modules/Licensing/Database/Migrations/2026_10_12_160000_extend_download_products.php +++ b/Modules/Licensing/Database/Migrations/2026_10_12_160000_extend_download_products.php @@ -3,6 +3,16 @@ use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; return new class extends Migration { - public function up(): void { Schema::table('download_products',function(Blueprint $table){$table->longText('release_notes')->nullable();$table->text('minimum_system')->nullable();$table->integer('sort_order')->default(0);}); } - public function down(): void {Schema::table('download_products',function(Blueprint $table){$table->dropColumn(['release_notes','minimum_system','sort_order']);});} + public function up(): void { + if (!Schema::hasTable('download_products')) return; + foreach (['release_notes' => 'longText', 'minimum_system' => 'text', 'sort_order' => 'integer'] as $column => $type) { + if (!Schema::hasColumn('download_products', $column)) { + Schema::table('download_products', function (Blueprint $table) use ($column, $type) { + $definition = $table->{$type}($column); + if ($column === 'sort_order') $definition->default(0); else $definition->nullable(); + }); + } + } + } + public function down(): void { /* Preserve existing download metadata. */ } }; diff --git a/Modules/Licensing/Database/Migrations/2026_10_12_210000_repair_download_product_columns.php b/Modules/Licensing/Database/Migrations/2026_10_12_210000_repair_download_product_columns.php new file mode 100644 index 0000000..a6789c8 --- /dev/null +++ b/Modules/Licensing/Database/Migrations/2026_10_12_210000_repair_download_product_columns.php @@ -0,0 +1,15 @@ +'longText','minimum_system'=>'text','sort_order'=>'integer'] as $column=>$type) { + if (!Schema::hasColumn('download_products',$column)) Schema::table('download_products',function(Blueprint $table) use ($column,$type) { + $c=$table->{$type}($column); if ($column==='sort_order') $c->default(0); else $c->nullable(); + }); + } + } + public function down(): void { /* Keep uploaded download metadata intact. */ } +}; diff --git a/Modules/Licensing/Resources/views/downloads/index.blade.php b/Modules/Licensing/Resources/views/downloads/index.blade.php index e799f9f..e0beb2c 100644 --- a/Modules/Licensing/Resources/views/downloads/index.blade.php +++ b/Modules/Licensing/Resources/views/downloads/index.blade.php @@ -1,4 +1,6 @@ -Product downloads · ABSDEV
ABSDEV
ABSDEV SOFTWARE

Downloads & releases

Get the latest versions of SonarDesk, SonarDisk and additional tools. Choose the installer that matches your system.

-@if($latest)
LATEST STABLE · SONARDESK

SonarDesk {{ $latest->version }}

{{ \Illuminate\Support\Str::limit(strip_tags($latest->release_notes ?: 'Native SonarQube monitoring for macOS.'),180) }}

SonarDeskNative code quality dashboard
@endif -@if($products->isNotEmpty())
SOFTWARE LIBRARY

Products & alternative downloads

Installers are grouped by product, with each available platform and version listed together.

@foreach($products->groupBy('name') as $name => $files)

{{ $name }}

{{ $files->first()->description ?: 'Available downloads and supporting files.' }}

{{ $files->count() }} {{ $files->count() === 1 ? 'download' : 'downloads' }}
@foreach($files as $file)
{{ $file->version ? 'Version '.$file->version : ($file->original_filename ?: 'Download') }}{{ $file->platform ?: 'All platforms' }} @if($file->file_size) · {{ number_format($file->file_size / 1048576,1) }} MB @endif
@endforeach
@endforeach
@endif -
RELEASE HISTORY

SonarDesk versions

Full release notes and system requirements are available on each release page.

@forelse($releases as $release)
SonarDesk {{ $release->version }}Build {{ $release->build_number }} · {{ ucfirst($release->channel) }}

{{ \Illuminate\Support\Str::limit(strip_tags($release->release_notes ?: 'Release information'),120) }}

@empty

No SonarDesk releases published yet.

@endforelse
{{ $releases->links() }}
\ No newline at end of file +@extends('sonardesk.layout') +@section('title','Software downloads and releases') +@section('content')
ABSDEV Software Library

Downloads & releases.

Find SonarDesk, SonarDisk and alternative installers, grouped by product. Release notes and system requirements are on the detail pages.

+@if($latest)
Latest stable · SonarDesk

SonarDesk {{ $latest->version }}

{{ \Illuminate\Support\Str::limit(strip_tags($latest->release_notes ?: 'Native SonarQube monitoring for macOS.'), 180) }}

Latest release
@endif +@if($products->isNotEmpty())
Product catalogue

Products & alternative downloads

Each product lists its available versions and platforms together.

@foreach($products->groupBy('name') as $name=>$files)

{{ $name }}

{{ $files->first()->description ?: 'Installers and supporting downloads.' }}

{{ $files->count() }} {{ $files->count() === 1 ? 'file' : 'files' }}
@foreach($files as $file)
{{ $file->version ? 'Version '.$file->version : ($file->original_filename ?: 'Download') }}{{ $file->platform ?: 'All platforms' }} @if($file->file_size) · {{ number_format($file->file_size/1048576,1) }} MB @endif

{{ \Illuminate\Support\Str::limit(strip_tags($file->release_notes ?: $file->description ?: ''),120) }}

@endforeach
@endforeach
@endif +
Release archive

SonarDesk release history

@forelse($releases as $release)
SonarDesk {{ $release->version }}Build {{ $release->build_number }} · {{ ucfirst($release->channel) }}

{{ \Illuminate\Support\Str::limit(strip_tags($release->release_notes ?: 'Release information'),125) }}

@empty

No SonarDesk releases have been published yet.

@endforelse
@endsection diff --git a/Modules/Licensing/Resources/views/downloads/product.blade.php b/Modules/Licensing/Resources/views/downloads/product.blade.php index 04a4955..e59b04d 100644 --- a/Modules/Licensing/Resources/views/downloads/product.blade.php +++ b/Modules/Licensing/Resources/views/downloads/product.blade.php @@ -1 +1,3 @@ -{{ $product->name }} · ABSDEV
ABSDEV
← All downloadsPRODUCT DOWNLOAD

{{ $product->name }}

{{ $product->description }}

Version {{ $product->version ?: 'Unspecified' }}{{ $product->platform ?: 'All platforms' }}
Download {{ $product->original_filename }} ↓@if($product->release_notes)

Release notes

{{ $product->release_notes }}
@endif@if($product->minimum_system)

System requirements

{{ $product->minimum_system }}
@endif
\ No newline at end of file +@extends('sonardesk.layout') +@section('title',$product->name.' download') +@section('content')
← All downloads

Product download

{{ $product->name }}

{{ $product->description }}

{{ $product->platform ?: 'All platforms' }}

Version {{ $product->version ?: 'Unspecified' }}

Download {{ $product->original_filename }} ↓@if($product->release_notes)

Full release notes

{{ $product->release_notes }}
@endif@if($product->minimum_system)

System requirements

{{ $product->minimum_system }}
@endif
@endsection diff --git a/Modules/Licensing/Resources/views/downloads/release.blade.php b/Modules/Licensing/Resources/views/downloads/release.blade.php index bf79a03..52c7a1b 100644 --- a/Modules/Licensing/Resources/views/downloads/release.blade.php +++ b/Modules/Licensing/Resources/views/downloads/release.blade.php @@ -1 +1,3 @@ -SonarDesk {{ $release->version }} · ABSDEV
ABSDEV
← All downloadsSONARDESK · {{ strtoupper($release->channel) }}

SonarDesk {{ $release->version }}

Build {{ $release->build_number }}

Download {{ $release->original_filename }} ↓

Release notes

{{ $release->release_notes ?: 'No release notes provided.' }}

System requirements

macOS {{ $release->minimum_macos ?: 'See application documentation' }} or later.

@if($release->sha256)

File verification

SHA-256

{{ $release->sha256 }}
@endif
\ No newline at end of file +@extends('sonardesk.layout') +@section('title','SonarDesk '.$release->version.' release notes') +@section('content')
← All downloads

SonarDesk · {{ strtoupper($release->channel) }}

SonarDesk {{ $release->version }}

Build {{ $release->build_number }}

Download {{ $release->original_filename }} ↓

Full release notes

{{ $release->release_notes ?: 'No release notes provided.' }}

System requirements

macOS {{ $release->minimum_macos ?: 'See application documentation' }} or later.

@if($release->sha256)

File verification · SHA-256

{{ $release->sha256 }}@endif
@endsection diff --git a/public/css/sonardesk-product.css b/public/css/sonardesk-product.css new file mode 100644 index 0000000..a0eabde --- /dev/null +++ b/public/css/sonardesk-product.css @@ -0,0 +1,2 @@ +/* SonarDesk product UI: follows the original light marketing design, ABSDEV orange accent. */ +:root{--orange:#f97316;--orange-deep:#c2410c;--ink:#172033;--muted:#667085;--line:#e4e7ec;--bg:#f7f9fc;--nav:#0b1220;--surface:#fff}*{box-sizing:border-box}html{scroll-behavior:smooth}body.product-site{margin:0;background:var(--bg);color:var(--ink);font:15px/1.65 -apple-system,BlinkMacSystemFont,"SF Pro Text","Segoe UI",sans-serif;-webkit-font-smoothing:antialiased}a{color:inherit}img{max-width:100%}.product-shell{max-width:1220px;margin:0 auto;padding:0 26px}.product-header{background:var(--nav);color:white;position:sticky;top:0;z-index:30;border-bottom:1px solid #ffffff1a}.header-inner{display:flex;align-items:center;gap:32px;min-height:74px}.product-brand{display:flex;align-items:center;gap:11px;text-decoration:none;white-space:nowrap;font-size:20px}.product-brand span:not(.brand-symbol){color:var(--orange)}.brand-symbol{width:38px;height:38px;display:grid;place-items:center;border-radius:11px;background:var(--orange);color:#fff;font-size:21px;font-weight:900}.product-nav{display:flex;align-items:center;gap:6px;flex:1}.product-nav a,.header-parent{font-weight:650;text-decoration:none;font-size:14px;color:#d7dfed;padding:9px 12px;border-radius:8px}.product-nav a:hover,.header-parent:hover{background:#ffffff18;color:white}.header-parent{color:#ffb784}.product-footer{background:var(--nav);color:#f1f5f9;padding:46px 0}.footer-inner{display:flex;justify-content:space-between;gap:32px}.footer-inner p{color:#aebcd0;margin:6px 0}.footer-links{display:flex;flex-wrap:wrap;gap:22px}.footer-links a{text-decoration:none;color:#d6e0ef}.footer-links a:hover{color:#ffb784}.product-hero{background:linear-gradient(120deg,#0b1220,#18253b);color:#fff;padding:92px 0 98px}.hero-grid{display:grid;grid-template-columns:1.08fr .92fr;gap:54px;align-items:center}.eyebrow{color:var(--orange);text-transform:uppercase;font-weight:850;font-size:12px;letter-spacing:.14em}.product-hero h1{font-size:clamp(46px,5vw,74px);line-height:1.04;letter-spacing:-.055em;margin:16px 0 22px}.product-hero h1 em{font-style:normal;color:#ff9c58}.lead{font-size:19px;line-height:1.65;color:#cdd7e6;max-width:670px}.actions{display:flex;flex-wrap:wrap;gap:12px;margin-top:27px}.button{display:inline-flex;align-items:center;justify-content:center;padding:13px 19px;border-radius:10px;background:var(--orange);color:#fff!important;font-weight:750;text-decoration:none;border:1px solid var(--orange)}.button:hover{background:var(--orange-deep)}.button.secondary{background:transparent;color:inherit!important;border-color:#ffffff55}.button.outline{background:white;color:var(--ink)!important;border-color:var(--line)}.button.small{padding:8px 13px;font-size:13px}.app-window{background:#fff;color:#172033;border-radius:16px;box-shadow:0 24px 70px #0006;overflow:hidden;border:1px solid #ffffff4a}.app-window-bar{background:#eef2f7;padding:14px 18px;display:flex;gap:7px;border-bottom:1px solid #dbe2ea}.app-window-bar i{width:11px;height:11px;border-radius:50%;background:#ff6057}.app-window-bar i:nth-child(2){background:#febc2e}.app-window-bar i:nth-child(3){background:#28c840}.app-window-body{padding:26px}.app-window h3{margin:0 0 18px}.app-stats{display:grid;grid-template-columns:repeat(2,1fr);gap:12px}.app-stat{padding:18px;border-radius:11px;border:1px solid var(--line);background:#fafbfc}.app-stat b{display:block;font-size:23px}.app-stat span{color:var(--muted);font-size:12px}.product-section{padding:76px 0}.product-section.alt{background:#fff}.section-heading{max-width:790px;margin-bottom:32px}.section-heading h2,.page-heading h1{font-size:clamp(34px,3.7vw,49px);letter-spacing:-.04em;line-height:1.12;margin:10px 0 14px}.section-heading p,.page-heading p{color:var(--muted);font-size:17px}.cards{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:18px}.card,.download-group,.detail-panel{background:white;border:1px solid var(--line);border-radius:16px;padding:27px;box-shadow:0 2px 12px #10182808}.card h3{font-size:20px;margin:8px 0}.card p{color:var(--muted)}.card a,.text-link{color:var(--orange-deep);font-weight:750;text-decoration:none}.card a:hover,.text-link:hover{text-decoration:underline}.page-heading{padding:66px 0 32px}.page-heading h1{max-width:850px}.price-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:20px;max-width:940px}.price-card{background:#fff;border:1px solid var(--line);border-radius:18px;padding:32px}.price-card.featured{border-color:var(--orange);box-shadow:0 16px 42px #f973161a}.price-number{font-size:39px;font-weight:850;letter-spacing:-.05em}.price-number small{font-size:15px;color:var(--muted);letter-spacing:0}.feature-list{padding-left:21px;color:#475467;line-height:2}.callout{background:#121c2e;color:white;border-radius:20px;padding:42px;display:flex;align-items:center;justify-content:space-between;gap:26px}.callout h2{margin:0 0 7px;font-size:29px}.callout p{color:#cbd5e1;margin:0}.download-group{margin:20px 0}.download-group-head{display:flex;justify-content:space-between;gap:16px;align-items:flex-start}.download-group h2{font-size:26px;margin:0 0 6px}.download-group-head p{color:var(--muted);margin:0 0 14px}.badge{display:inline-block;border-radius:999px;padding:4px 11px;background:#fff2e9;color:#a53c0a;font-weight:800;font-size:12px;white-space:nowrap}.download-row{border-top:1px solid var(--line);padding:19px 0;display:flex;justify-content:space-between;gap:20px;align-items:center}.download-row strong{display:block}.download-row small{display:block;color:var(--muted)}.download-row p{margin:5px 0 0;color:var(--muted);max-width:700px}.row-actions{display:flex;align-items:center;gap:15px;white-space:nowrap}.detail-panel{max-width:980px;margin:22px 0 64px}.detail-panel h2{margin:34px 0 10px}.preformatted{white-space:pre-wrap;overflow-wrap:anywhere;color:#475467}.hash{overflow-wrap:anywhere;display:block;padding:13px;background:#f3f5f8;border-radius:8px}.muted{color:var(--muted)}.pagination{margin:26px 0 50px}.pagination nav{max-width:100%}@media(max-width:980px){.hero-grid{grid-template-columns:1fr}.cards{grid-template-columns:repeat(2,1fr)}.product-nav{gap:0}.header-inner{gap:14px}}@media(max-width:700px){.product-header{position:static}.header-inner{flex-wrap:wrap;padding-top:12px;padding-bottom:12px}.product-nav{order:3;flex-basis:100%;overflow-x:auto}.product-nav a{white-space:nowrap}.header-parent{margin-left:auto}.product-hero{padding:60px 0}.cards,.price-grid{grid-template-columns:1fr}.download-row,.download-group-head,.callout,.footer-inner{flex-direction:column;align-items:flex-start}.row-actions{flex-wrap:wrap}.product-section{padding:50px 0}.app-window-body{padding:17px}.product-shell{padding-left:18px;padding-right:18px}} diff --git a/resources/views/sonardesk/features.blade.php b/resources/views/sonardesk/features.blade.php index 179e950..dd4ef15 100644 --- a/resources/views/sonardesk/features.blade.php +++ b/resources/views/sonardesk/features.blade.php @@ -1,3 +1,3 @@ @extends('sonardesk.layout') @section('title','SonarDesk Features') -@section('content')
Built for developers

Everything important. Nothing distracting.

A native Mac workspace for SonarQube project monitoring and issue investigation.

Quality gate status

Monitor project health and identify failing quality gates.

Bugs & vulnerabilities

Investigate reliability and security findings in context.

Code smells

See maintainability issues without switching between browser tabs.

Project management

Organise multiple projects and switch between them quickly.

Multiple SonarQube servers

Manage connections and access projects across servers.

Export reports

Generate project reports for review and further analysis.

@endsection +@section('content')
Features

A native workspace for SonarQube.

Stay close to your projects, quality gates and issues without the browser overhead.

Quality gates

Spot passing and failing projects immediately.

Bugs & vulnerabilities

Inspect reliability and security issues in context.

Code smells

Explore maintainability findings and issue details.

Multiple projects

Keep your project list organised and switch context quickly.

Multiple servers

Manage connections to your SonarQube environments.

Export reports

Produce project reports for sharing and AI-assisted analysis.

Download SonarDesk

Find current installers and complete release notes.

Downloads →
@endsection diff --git a/resources/views/sonardesk/home.blade.php b/resources/views/sonardesk/home.blade.php index 7743f22..8826aba 100644 --- a/resources/views/sonardesk/home.blade.php +++ b/resources/views/sonardesk/home.blade.php @@ -1,7 +1,7 @@ @extends('sonardesk.layout') -@section('title','SonarDesk — Native SonarQube monitoring for macOS') +@section('title','SonarDesk — Native SonarQube dashboard for macOS') @section('content') -
SonarDesk · Native macOS software

Code quality.
Clearly in view.

Bring SonarQube projects, quality gates, bugs, vulnerabilities and code smells together in a focused desktop experience. Spend less time navigating dashboards and more time shipping reliable code.

Project overview ● Quality gate passed
✓Quality gate
12Issues to review
3Projects
1Security hotspot

Illustrative dashboard — not live project data

-
Why SonarDesk

Your code health, at a glance.

A purpose-built native macOS companion for SonarQube, designed for developers who want useful signals without unnecessary complexity.

01 / Monitor

Quality gates

See project status, bugs, vulnerabilities and code smells from one dashboard.

02 / Investigate

Issue exploration

Review issues, navigate details and focus on the changes that matter.

03 / Organise

Multiple projects

Keep projects and servers organised in a native Mac workspace.

-
Get started

Everything you need to get moving.

Simple pricing

Choose Personal or Professional licensing for your needs.

Compare plans →

Downloads & updates

Find published installers, release history and detailed release notes.

Browse downloads →
+
Native macOS · SonarQube

Code quality.
Without the clutter.

A dedicated Mac dashboard for SonarQube. Track quality gates, bugs, vulnerabilities and code smells across projects without living in a browser.

Built for macOS · Multiple SonarQube servers · Native workflow

Project overview

Code health at a glance

✓ PassedQuality gate
12Issues to review
3Projects
1Security hotspots

Illustrative preview, not live project data.

+
Everything in one workspace

See the signals. Investigate the issues.

Designed for developers who need actionable SonarQube information without switching tabs.

01 · Monitor

Quality gates & metrics

See gate status, bugs, vulnerabilities and maintainability at a glance.

02 · Investigate

Issue navigation

Browse issues and move through details quickly, from one native workspace.

03 · Organise

Projects & servers

Switch between projects and manage SonarQube server connections.

04 · Share

Project reports

Export reports for review and AI-assisted analysis.

05 · Native

Made for your Mac

A focused desktop application that respects macOS workflows.

06 · Explore

More than a status badge

Drill into code smells, bugs and security findings by project.

+

Ready to see your code clearly?

Browse the latest installers, release notes and available licence plans.

@endsection diff --git a/resources/views/sonardesk/layout.blade.php b/resources/views/sonardesk/layout.blade.php index fe95d02..27be27a 100644 --- a/resources/views/sonardesk/layout.blade.php +++ b/resources/views/sonardesk/layout.blade.php @@ -2,8 +2,16 @@ $dedicated = in_array(request()->getHost(), ['sonardesk.absdev.net','sonardesk.co.uk','www.sonardesk.co.uk'], true); $base = $dedicated ? '' : '/sonardesk'; @endphp - -@yield('title','SonarDesk') | ABSDEV - -
-
@yield('content')
+ + +@yield('title', 'SonarDesk') · ABSDEV + + +
+
@yield('content')
+ + diff --git a/resources/views/sonardesk/pricing.blade.php b/resources/views/sonardesk/pricing.blade.php index b60d75b..31ba6cb 100644 --- a/resources/views/sonardesk/pricing.blade.php +++ b/resources/views/sonardesk/pricing.blade.php @@ -1,3 +1,3 @@ @extends('sonardesk.layout') @section('title','SonarDesk Pricing') -@section('content')
Straightforward licensing

Choose your SonarDesk plan.

Simple subscriptions for native macOS SonarQube monitoring. Checkout is handled by the existing SonarDesk licensing service.

Personal

For individual developers

£4.99 / month

Or £39.99 per year.

Native project monitoring and issue exploration for your development workflow.

View purchase options →
Professional

For professional workflows

£8.99 / month

Or £79.99 per year.

Professional SonarDesk licensing for developers who work across more projects and environments.

View purchase options →

Prices shown are indicative of the existing SonarDesk plans; final terms and available billing options are confirmed by the checkout service.

@endsection +@section('content')
Licensing

Choose the right SonarDesk plan.

Personal and Professional licensing for a native macOS SonarQube workflow.

Personal

For individual developers

£4.99 / month

Or £39.99 per year

  • Native macOS dashboard
  • Project quality gates and issues
  • Organised SonarQube workflow
Choose Personal →

Final billing options and terms are shown by the existing licensing checkout.

@endsection