This commit is contained in:
2023-10-15 23:40:34 +03:00
parent 8d3e8373c0
commit 5ebf3311e4
15 changed files with 393 additions and 240 deletions
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"main.js": { "main.js": {
"file": "assets/main.a36ff043.js", "file": "assets/main.48f7042c.js",
"src": "main.js", "src": "main.js",
"isEntry": true, "isEntry": true,
"css": [ "css": [
+16 -2
View File
@@ -4,7 +4,7 @@
import Icon from "../../common/Icon.svelte"; import Icon from "../../common/Icon.svelte";
import SortFields from "./SortFields.svelte"; import SortFields from "./SortFields.svelte";
import AppliedFilter from "./AppliedFilter.svelte"; import AppliedFilter from "./AppliedFilter.svelte";
import {getContext,createEventDispatcher} from "svelte"; import {getContext, createEventDispatcher} from "svelte";
const channel = getContext("channel"); const channel = getContext("channel");
@@ -23,7 +23,7 @@
let csvUrl = url.pathname + "/csv?" + url.searchParams.toString(); let csvUrl = url.pathname + "/csv?" + url.searchParams.toString();
function search(e){ function search(e) {
e.preventDefault(); e.preventDefault();
const data = new FormData(e.target); const data = new FormData(e.target);
let filterKey = data.keys().next().value; let filterKey = data.keys().next().value;
@@ -38,6 +38,7 @@
} }
} }
function uploadComplete(e) { function uploadComplete(e) {
records = e.detail; records = e.detail;
} }
@@ -107,6 +108,17 @@
</button> </button>
<ul class="dropdown-menu"> <ul class="dropdown-menu">
{#if filter["status_in"] === "trashed"}
<li>
<a
class="dropdown-item"
href="{channel.lucentUrl}/content/{schema.name}/emptyTrash"
>
Empty trash
</a>
</li>
{:else}
<li> <li>
<a <a
class="dropdown-item" class="dropdown-item"
@@ -121,6 +133,8 @@
>View trashed records</a >View trashed records</a
> >
</li> </li>
{/if}
</ul> </ul>
</div> </div>
{/if} {/if}
+1 -1
View File
@@ -20,7 +20,7 @@ class UserRepo
*/ */
public function all(): Collection public function all(): Collection
{ {
$usersData = DB::table("users")->whereNot("status", "invite")->get(); $usersData = DB::table("users")->get();
$users = array_map(fn($userData) => User::fromArray((array)$userData), $usersData->toArray()); $users = array_map(fn($userData) => User::fromArray((array)$userData), $usersData->toArray());
return new Collection($users); return new Collection($users);
+7
View File
@@ -64,6 +64,7 @@ class RecordController extends Controller
->parentsDepth(0) ->parentsDepth(0)
->runWithCount(); ->runWithCount();
$records = $graph->getRootRecords()->toArray(); $records = $graph->getRootRecords()->toArray();
@@ -330,6 +331,12 @@ class RecordController extends Controller
return ok(); return ok();
} }
public function emptyTrash(Request $request){
$this->recordService->emptyTrash($request->route("schemaName"));
return redirect($this->channelService->channel->lucentUrl."/content/".$request->route("schemaName"));
}
public function delete(Request $request) public function delete(Request $request)
{ {
$ids = $request->input("ids"); $ids = $request->input("ids");
+1
View File
@@ -72,6 +72,7 @@ Route::group([
Route::middleware(["lucent.auth"])->prefix("/content")->group(function () { Route::middleware(["lucent.auth"])->prefix("/content")->group(function () {
Route::get('/{schemaName}', [RecordController::class, 'index']); Route::get('/{schemaName}', [RecordController::class, 'index']);
Route::get('/{schemaName}/csv', [RecordController::class, 'exportCSV']); Route::get('/{schemaName}/csv', [RecordController::class, 'exportCSV']);
Route::get('/{schemaName}/emptyTrash', [RecordController::class, 'emptyTrash']);
}); });
Route::middleware(["lucent.auth"])->group(function () { Route::middleware(["lucent.auth"])->group(function () {
+13 -3
View File
@@ -11,6 +11,9 @@ use Lucent\Commands\CompileSchemas;
use Lucent\Commands\RebuildThumbnails; use Lucent\Commands\RebuildThumbnails;
use Lucent\File\FileService; use Lucent\File\FileService;
use Lucent\File\ImageService; use Lucent\File\ImageService;
use Lucent\Query\DatabaseGraph\DatabaseGraph;
use Lucent\Query\DatabaseGraph\PgsqlDatabaseGraph;
use Lucent\Query\DatabaseGraph\SqliteDatabaseGraph;
class LucentServiceProvider extends ServiceProvider class LucentServiceProvider extends ServiceProvider
{ {
@@ -27,6 +30,13 @@ class LucentServiceProvider extends ServiceProvider
return new ImageManager(['driver' => 'imagick']); return new ImageManager(['driver' => 'imagick']);
}); });
$this->app->bind(DatabaseGraph::class, function () {
return match (config("database.lucent")) {
"sqlite" => new SqliteDatabaseGraph(),
"pgsql" => new PgsqlDatabaseGraph(),
};
});
} }
@@ -38,8 +48,8 @@ class LucentServiceProvider extends ServiceProvider
$manifestPath = public_path('vendor/lucent/dist/manifest.json'); $manifestPath = public_path('vendor/lucent/dist/manifest.json');
$manifest = null; $manifest = null;
if(file_exists($manifestPath)){ if (file_exists($manifestPath)) {
$manifest = json_decode(file_get_contents(public_path('vendor/lucent/dist/manifest.json')),true); $manifest = json_decode(file_get_contents(public_path('vendor/lucent/dist/manifest.json')), true);
} }
@@ -68,7 +78,7 @@ class LucentServiceProvider extends ServiceProvider
]); ]);
$this->publishes([ $this->publishes([
__DIR__.'/../front/dist' => public_path('vendor/lucent/dist'), __DIR__ . '/../front/dist' => public_path('vendor/lucent/dist'),
], 'public'); ], 'public');
} }
} }
+14
View File
@@ -0,0 +1,14 @@
<?php
namespace Lucent\Query\DatabaseGraph;
use Lucent\Query\QueryOptions;
interface DatabaseGraph
{
/**
* @param array<string> $ids
*/
public function getChildren(array $ids, QueryOptions $options): array;
public function getParents(array $ids, QueryOptions $options): array;
}
@@ -0,0 +1,61 @@
<?php
namespace Lucent\Query\DatabaseGraph;
use Illuminate\Support\Facades\DB;
use Lucent\Query\QueryOptions;
class PgsqlDatabaseGraph implements DatabaseGraph
{
/**
* @param array<string> $ids
*/
public function getChildren(array $ids, QueryOptions $options): array
{
$subquery = DB::table('edges AS g')
->select(DB::raw('g.source,g.target,g.rank,"g"."sourceSchema","g"."targetSchema",g.field, 1 as depth '))
->whereIn('source', $ids);
if (!empty($options->childrenFields)) {
$subquery->whereIn('field', $options->childrenFields);
}
$subquery->limit($options->childrenLimit)
->unionAll(
DB::table(DB::raw("edges AS g, search_graph AS sg "))
->selectRaw('g.source,g.target,g.rank,"g"."sourceSchema","g"."targetSchema",g.field,sg.depth + 1 as depth')
->whereRaw("g.source = sg.target")
->where("depth", "<", $options->childrenDepth)
->orderBy("rank")
);
return DB::table('search_graph')
// ->select(DB::raw("*, 1 as depth "))
->withRecursiveExpression('search_graph', $subquery)
->get()->toArray();
}
/**
* @param array<string> $ids
*/
public function getParents(array $ids, QueryOptions $options): array
{
$subquery = DB::table('edges AS g')
->select(DB::raw('g.source,g.target,g.rank,"g"."sourceSchema","g"."targetSchema",g.field, 1 as depth '))
->limit($options->parentsLimit)
->whereIn('g.target', $ids)
->unionAll(
DB::table(DB::raw("edges AS g, search_graph AS sg "))
->selectRaw('g.source,g.target,g.rank,"g"."sourceSchema","g"."targetSchema",g.field,sg.depth + 1 as depth')
->whereRaw("g.target = sg.source")
->where("depth", "<", $options->parentsDepth)
->orderBy("rank")
);
return DB::table('search_graph')
// ->select(DB::raw('sg.source,sg.target,sg.rank,sg."sourceSchema",sg."targetSchema",sg.field,sg.depth'))
->withRecursiveExpression('search_graph', $subquery)
->get()->toArray();
}
}
@@ -0,0 +1,60 @@
<?php
namespace Lucent\Query\DatabaseGraph;
use Illuminate\Support\Facades\DB;
use Lucent\Query\QueryOptions;
class SqliteDatabaseGraph implements DatabaseGraph
{
/**
* @param array<string> $ids
*/
public function getChildren(array $ids, QueryOptions $options): array
{
$subquery = DB::table('edges AS g')
->select(DB::raw('g.source,g.target,g.rank,g.sourceSchema,g.targetSchema,g.field, 1 as depth '))
->whereIn('source', $ids);
if (!empty($options->childrenFields)) {
$subquery->whereIn('field', $options->childrenFields);
}
$subquery->limit($options->childrenLimit)
->unionAll(
DB::table(DB::raw("edges AS g, search_graph AS sg "))
->selectRaw('g.source,g.target,g.rank,"g"."sourceSchema","g"."targetSchema",g.field,sg.depth + 1 as depth')
->whereRaw("g.source = sg.target")
->where("depth", "<", $options->childrenDepth)
->orderBy("rank")
);
return DB::table('search_graph')
// ->select(DB::raw("*, 1 as depth "))
->withRecursiveExpression('search_graph', $subquery)
->get()->toArray();
}
/**
* @param array<string> $ids
*/
public function getParents(array $ids, QueryOptions $options): array
{
$subquery = DB::table('edges AS g')
->select(DB::raw('g.source,g.target,g.rank,"g"."sourceSchema","g"."targetSchema",g.field, 1 as depth '))
->limit($options->parentsLimit)
->whereIn('g.target', $ids)
->unionAll(
DB::table(DB::raw("edges AS g, search_graph AS sg "))
->selectRaw('g.source,g.target,g.rank,"g"."sourceSchema","g"."targetSchema",g.field,sg.depth + 1 as depth')
->whereRaw("g.target = sg.source")
->where("depth", "<", $options->parentsDepth)
->orderBy("rank")
);
return DB::table('search_graph')
// ->select(DB::raw('sg.source,sg.target,sg.rank,sg."sourceSchema",sg."targetSchema",sg.field,sg.depth'))
->withRecursiveExpression('search_graph', $subquery)
->get()->toArray();
}
}
+4 -37
View File
@@ -6,6 +6,7 @@ use Illuminate\Database\Query\Builder;
use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\DB;
use Lucent\Edge\Edge; use Lucent\Edge\Edge;
use Lucent\Primitive\Collection; use Lucent\Primitive\Collection;
use Lucent\Query\DatabaseGraph\DatabaseGraph;
use Lucent\Query\Filter\AndFilter; use Lucent\Query\Filter\AndFilter;
use Lucent\Query\Filter\OrFilter; use Lucent\Query\Filter\OrFilter;
use Lucent\Record\InputFormatter; use Lucent\Record\InputFormatter;
@@ -24,6 +25,7 @@ final class Query
public function __construct( public function __construct(
public readonly FilterParser $filterParser, public readonly FilterParser $filterParser,
public readonly InputFormatter $inputFormatter, public readonly InputFormatter $inputFormatter,
public readonly DatabaseGraph $databaseGraph,
) )
{ {
$this->options = new QueryOptions(); $this->options = new QueryOptions();
@@ -156,47 +158,12 @@ final class Query
private private
function getChildren(array $ids): array function getChildren(array $ids): array
{ {
$subquery = DB::table('edges AS g') return $this->databaseGraph->getChildren($ids, $this->options);
->select(DB::raw('g.source,g.target,g.rank,g.sourceSchema,g.targetSchema,g.field, 1 as depth '))
->whereIn('source', $ids);
if (!empty($this->options->childrenFields)) {
$subquery->whereIn('field', $this->options->childrenFields);
}
$subquery->limit($this->options->childrenLimit)
->unionAll(
DB::table(DB::raw("edges AS g, search_graph AS sg "))
->selectRaw('g.source,g.target,g.rank,"g"."sourceSchema","g"."targetSchema",g.field,sg.depth + 1 as depth')
->whereRaw("g.source = sg.target")
->where("depth", "<", $this->options->childrenDepth)
->orderBy("rank")
);
return DB::table('search_graph')
// ->select(DB::raw("*, 1 as depth "))
->withRecursiveExpression('search_graph', $subquery)
->get()->toArray();
} }
private function getParents(array $ids): array private function getParents(array $ids): array
{ {
$subquery = DB::table('edges AS g') return $this->databaseGraph->getParents($ids, $this->options);
->select(DB::raw('g.source,g.target,g.rank,"g"."sourceSchema","g"."targetSchema",g.field, 1 as depth '))
->limit($this->options->parentsLimit)
->whereIn('g.target', $ids)
->unionAll(
DB::table(DB::raw("edges AS g, search_graph AS sg "))
->selectRaw('g.source,g.target,g.rank,"g"."sourceSchema","g"."targetSchema",g.field,sg.depth + 1 as depth')
->whereRaw("g.target = sg.source")
->where("depth", "<", $this->options->parentsDepth)
->orderBy("rank")
);
return DB::table('search_graph')
// ->select(DB::raw('sg.source,sg.target,sg.rank,sg."sourceSchema",sg."targetSchema",sg.field,sg.depth'))
->withRecursiveExpression('search_graph', $subquery)
->get()->toArray();
} }
+12
View File
@@ -48,4 +48,16 @@ class RecordRepo
DB::table("edges")->whereIn("target", $ids)->delete(); DB::table("edges")->whereIn("target", $ids)->delete();
DB::table("revisions")->whereIn("recordId", $ids)->delete(); DB::table("revisions")->whereIn("recordId", $ids)->delete();
} }
public function deleteTrashedBySchema(
string $schemaName,
): void
{
$ids = DB::table("records")
->where("schema", $schemaName)
->where("status", Status::TRASHED->value)
->get()->pluck("id")->toArray();
$this->deleteMany($ids);
}
} }
+9
View File
@@ -226,6 +226,15 @@ readonly class RecordService
$this->recordRepo->deleteMany($recordsIds); $this->recordRepo->deleteMany($recordsIds);
} }
public function emptyTrash(
string $schemaName,
): void
{
$schema = $this->channelService->getSchema($schemaName)->get();
$this->recordRepo->deleteTrashedBySchema($schemaName);
}
/** /**
* @throws LucentException * @throws LucentException
+6 -6
View File
@@ -7,13 +7,13 @@
<meta name="csrf-token" content="{{ csrf_token() }}"> <meta name="csrf-token" content="{{ csrf_token() }}">
<title>@yield('title') - Lucent Data Platform</title> <title>@yield('title') - Lucent Data Platform</title>
<!-- if development --> <!-- if development -->
@php {{-- @php--}}
echo '<script type="module" crossorigin src="http://127.0.0.1:5173/@vite/client"></script>'; {{-- echo '<script type="module" crossorigin src="http://127.0.0.1:5173/@vite/client"></script>';--}}
@endphp {{-- @endphp--}}
<script type="module" crossorigin src="http://127.0.0.1:5173/main.js"></script> {{-- <script type="module" crossorigin src="http://127.0.0.1:5173/main.js"></script>--}}
<!-- if production --> <!-- if production -->
{{-- <link rel="stylesheet" href="/vendor/lucent/dist/{{ $manifest['main.css']["file"] }}" />--}} <link rel="stylesheet" href="/vendor/lucent/dist/{{ $manifest['main.css']["file"] }}" />
{{-- <script type="module" src="/vendor/lucent/dist/{{ $manifest['main.js']["file"] }}"></script>--}} <script type="module" src="/vendor/lucent/dist/{{ $manifest['main.js']["file"] }}"></script>
<link rel="icon" type="image/x-icon" href="/favicon.ico"> <link rel="icon" type="image/x-icon" href="/favicon.ico">