move into sonardesk

This commit is contained in:
Mark Gregory
2026-10-12 14:50:13 +01:00
parent 5f0d2ceb72
commit 38b4a7406f
879 changed files with 24021 additions and 1 deletions
+6
View File
@@ -0,0 +1,6 @@
<?php
return [
'name' => 'Search',
'enabled' => true,
];
@@ -0,0 +1,30 @@
<?php
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::create('search_index', function (Blueprint $table): void {
$table->id();
$table->morphs('searchable');
$table->string('title')->index();
$table->text('summary')->nullable();
$table->longText('content')->nullable();
$table->string('url')->nullable();
$table->json('metadata')->nullable();
$table->boolean('is_public')->default(true)->index();
$table->timestamp('published_at')->nullable()->index();
$table->timestamps();
$table->unique(['searchable_type', 'searchable_id']);
});
}
public function down(): void
{
Schema::dropIfExists('search_index');
}
};
@@ -0,0 +1,18 @@
<?php
namespace Modules\Search\Http\Controllers;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
final class SearchController extends Controller
{
public function index(Request $request)
{
$q = trim((string) $request->query('q'));
$results = DB::table('search_index')->when($q !== '', fn ($query) => $query->where(fn ($w) => $w->where('title', 'like', "%{$q}%")->orWhere('summary', 'like', "%{$q}%")->orWhere('content', 'like', "%{$q}%")))->latest('updated_at')->paginate(25)->withQueryString();
return view('search::index', compact('results', 'q'));
}
}
+17
View File
@@ -0,0 +1,17 @@
<?php
namespace Modules\Search\Providers;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Route;
final class RouteServiceProvider extends ServiceProvider
{
public function boot(): void
{
parent::boot();
$this->routes(function (): void {
Route::middleware('web')->group(module_path('Search', 'Routes/web.php'));
});
}
}
@@ -0,0 +1,21 @@
<?php
namespace Modules\Search\Providers;
use Illuminate\Support\ServiceProvider;
use Modules\Search\Support\ModuleInfo;
final class SearchServiceProvider extends ServiceProvider
{
public function register(): void
{
$this->app->register(RouteServiceProvider::class);
$this->mergeConfigFrom(module_path(ModuleInfo::name(), 'Config/config.php'), ModuleInfo::nameLower());
}
public function boot(): void
{
$this->loadMigrationsFrom(module_path(ModuleInfo::name(), 'Database/Migrations'));
$this->loadViewsFrom(module_path(ModuleInfo::name(), 'Resources/views'), ModuleInfo::nameLower());
}
}
+1
View File
@@ -0,0 +1 @@
<x-layouts.app :title="__('Search index')"><div class="space-y-6"><div><h1 class="text-2xl font-semibold">Search index</h1><p class="mt-1 text-sm text-zinc-500">Inspect content currently available to platform search.</p></div><form method="GET" class="flex gap-2"><flux:input name="q" :value="$q" placeholder="Search indexed content..." class="flex-1"/><flux:button type="submit" variant="primary">Search</flux:button></form><div class="rounded-xl border border-zinc-200 bg-white dark:border-zinc-700 dark:bg-zinc-900"><div class="divide-y divide-zinc-200 dark:divide-zinc-800">@forelse($results as $result)<div class="p-4"><div class="font-medium">{{ $result->title }}</div><div class="mt-1 text-sm text-zinc-500">{{ str($result->summary ?: $result->content)->limit(180) }}</div><div class="mt-2 text-xs text-zinc-400">{{ $result->searchable_type }} #{{ $result->searchable_id }}</div></div>@empty<div class="p-10 text-center text-sm text-zinc-500">No indexed content found.</div>@endforelse</div></div>{{ $results->links() }}</div></x-layouts.app>
+6
View File
@@ -0,0 +1,6 @@
<?php
use Illuminate\Support\Facades\Route;
use Modules\Search\Http\Controllers\SearchController;
Route::middleware(['auth', 'verified'])->get('administration/search', [SearchController::class, 'index'])->name('administration.search.index');
+16
View File
@@ -0,0 +1,16 @@
<?php
namespace Modules\Search\Support;
final class ModuleInfo
{
public static function name(): string
{
return 'Search';
}
public static function nameLower(): string
{
return 'search';
}
}
@@ -0,0 +1,5 @@
<?php
it('boots the Search module', function (): void {
expect(config('search.name'))->toBe('Search');
});
+10
View File
@@ -0,0 +1,10 @@
{
"name": "absdev/search-module",
"description": "Search foundation module for the ABSDEV Laravel application platform.",
"type": "laravel-module",
"autoload": {
"psr-4": {
"Modules\\Search\\": ""
}
}
}
+20
View File
@@ -0,0 +1,20 @@
{
"name": "Search",
"alias": "search",
"version": "1.0.0",
"description": "Search foundation module for the ABSDEV Laravel application platform.",
"keywords": [
"laravel",
"modules",
"search"
],
"priority": 10,
"providers": [
"Modules\\Search\\Providers\\SearchServiceProvider"
],
"aliases": {},
"files": [],
"requires": [
"Core"
]
}