diff --git a/front/js/entry/RecordEditEntry/RecordEditEntry.svelte b/front/js/entry/RecordEditEntry/RecordEditEntry.svelte index eb2f5e7..515e90b 100644 --- a/front/js/entry/RecordEditEntry/RecordEditEntry.svelte +++ b/front/js/entry/RecordEditEntry/RecordEditEntry.svelte @@ -42,6 +42,7 @@ { return validationErrors.find( (f) => f.fieldId === field.id && f.locale === locale, @@ -20,6 +20,12 @@ (f) => f.fieldId === field.id && f.locale === locale, ); }; + $inspect(edgeRecordPreviews); + const findFieldEdges = (field, locale) => { + return edgeRecordPreviews.filter( + (e) => e.edge.fieldId === field.id && e.edge.locale === locale, + ); + }; {#each fields as field} @@ -62,5 +68,6 @@ schemaField={field} {locale} dataField={findDataField(field, locale)} + edgeRecordPreviews={findFieldEdges(field, locale)} > {/snippet} diff --git a/front/js/entry/RecordEditEntry/fields/RelationField.svelte b/front/js/entry/RecordEditEntry/fields/RelationField.svelte index c088bbb..6472e82 100644 --- a/front/js/entry/RecordEditEntry/fields/RelationField.svelte +++ b/front/js/entry/RecordEditEntry/fields/RelationField.svelte @@ -2,8 +2,15 @@ import { get, post } from "../../../modules/remote"; import { getApp } from "../../../app"; import { getLocaleName } from "../locale.svelte.js"; - let { channel, record, schemaField, dataField, locale, validationError } = - $props(); + let { + channel, + record, + schemaField, + dataField, + locale, + validationError, + edgeRecordPreviews, + } = $props(); let originalValue = dataField?.value ?? schemaField.props.default; let newValue = $state(originalValue); let valuesChanged = $derived(newValue !== originalValue); @@ -14,9 +21,12 @@ let suggestionsLoaded = $state(false); let suggestions = $state([]); + let selectedRecordIds = $state([]); + let dialog = $state(); - function handleAddRecord(e) { + function handleModalOpen(e) { // Add logic to handle adding a record + dialog.showModal(); if (suggestionsLoaded) { return; } @@ -30,26 +40,24 @@ ); } - function save() { - if (!valuesChanged) { - return; - } + function handleModalClose(e) { + dialog.close(); + } + function handleInsertSelected() { + suggestionsLoaded = false; post( - app.url("records/fields"), + app.url("edges/many"), { - recordId: record.id, - id: schemaField.id, + toIds: selectedRecordIds, + from: record.id, + fieldId: schemaField.id, locale: locale, - value: newValue, }, (data, err) => { - if (err.isNotEmpty()) { - errorMessage = err.first(); - } else { - validationError = data.validationError; - originalValue = newValue; - } + suggestionsLoaded = true; + dialog.close(); + edgeRecordPreviews = [...edgeRecordPreviews, ...data]; }, ); } @@ -61,26 +69,68 @@ {getLocaleName(channel, locale)} > {/if} {schemaField.name}
- - - {#if hasError} - {validationError.message} - {:else if schemaField.help != ""} - {schemaField.help} + + +
+ {#if edgeRecordPreviews.length == 0} + No relations exist + {:else} + {#each edgeRecordPreviews as edgeRecordPreview} +
+ {edgeRecordPreview.recordPreview.title} + {edgeRecordPreview.recordPreview.schemaName} +
+ {/each} {/if} - +
diff --git a/src/Core/Data/Edge.php b/src/Core/Data/Edge.php new file mode 100644 index 0000000..608888f --- /dev/null +++ b/src/Core/Data/Edge.php @@ -0,0 +1,14 @@ + $edge->id, + "locale" => $edge->locale, + "mode" => $edge->mode->value, + "from" => $edge->from, + "to" => $edge->to, + "field_id" => $edge->fieldId, + "rank" => $edge->rank, + ]; + } + + public static function fromDb(stdClass $data): Edge + { + return new Edge( + id: data_get($data, "id"), + locale: data_get($data, "locale"), + mode: RecordMode::from(data_get($data, "mode")), + from: data_get($data, "from"), + to: data_get($data, "to"), + fieldId: data_get($data, "field_id"), + rank: data_get($data, "rank"), + ); + } +} diff --git a/src/Core/Record/RecordModule.php b/src/Core/Record/RecordModule.php index 8449632..0fce723 100644 --- a/src/Core/Record/RecordModule.php +++ b/src/Core/Record/RecordModule.php @@ -4,6 +4,8 @@ use Carbon\Carbon; use Lucent\Core\Data\Record; use Lucent\Core\Data\RecordPreview; use Lucent\Core\Data\RecordStatus; +use Lucent\Core\Data\EdgeRecordPreview; +use Lucent\Core\Edge\EdgeModule; use stdClass; class RecordModule @@ -68,12 +70,45 @@ class RecordModule ); } - public static function recordPreviewFromDb(stdClass $data): RecordPreview - { + /** + * @param Schema[] $schemas + * @param stdClass $data + * @return RecordPreview + */ + public static function recordPreviewFromDb( + array $schemas, + stdClass $data, + ): RecordPreview { return new RecordPreview( id: data_get($data, "id"), schemaId: data_get($data, "schema_id"), + schemaName: collect($schemas) + ->where("id", data_get($data, "schema_id")) + ->first()->name, + title: data_get($data, "title"), ); } + + /** + * @param Schema[] $schemas + * @param stdClass $data + * @return EdgeRecordPreview + */ + public static function edgeRecordPreviewFromDb( + array $schemas, + stdClass $data, + ): EdgeRecordPreview { + return new EdgeRecordPreview( + edge: EdgeModule::fromDb($data), + recordPreview: new RecordPreview( + id: data_get($data, "record_id"), + schemaId: data_get($data, "record_schema_id"), + schemaName: collect($schemas) + ->where("id", data_get($data, "record_schema_id")) + ->first()->name, + title: data_get($data, "record_title"), + ), + ); + } } diff --git a/src/Core/Repository/EdgeRepo.php b/src/Core/Repository/EdgeRepo.php new file mode 100644 index 0000000..c476678 --- /dev/null +++ b/src/Core/Repository/EdgeRepo.php @@ -0,0 +1,22 @@ +insert( + array_map(EdgeModule::toDb(...), $edges), + ); + } +} diff --git a/src/Core/Repository/RecordRepo.php b/src/Core/Repository/RecordRepo.php index c9e9b77..6085b66 100644 --- a/src/Core/Repository/RecordRepo.php +++ b/src/Core/Repository/RecordRepo.php @@ -3,6 +3,7 @@ use Illuminate\Support\Facades\DB; use Lucent\Core\Data\Record; use Lucent\Core\Data\RecordPreview; +use Lucent\Core\Data\EdgeRecordPreview; use Lucent\Core\Record\RecordModule; class RecordRepo @@ -30,18 +31,20 @@ class RecordRepo ->first(); } - /* + /** + * @param Schema[] $schemas * @return RecordPreview[] */ public static function findBySchemas(array $schemas): array { + $schemaIds = array_map(fn($schema) => $schema->id, $schemas); return DB::table(self::TABLE_NAME) ->select( "records.id", "records.schema_id", "records_data.value as title", ) - ->whereIn("schema_id", $schemas) + ->whereIn("schema_id", $schemaIds) ->join("records_data", function ($join) { $join ->on("records.id", "=", "records_data.record_id") @@ -54,8 +57,45 @@ class RecordRepo ->orderBy("created_at", "desc") ->limit(5) ->get() + ->map(fn($row) => RecordModule::recordPreviewFromDb($schemas, $row)) + ->toArray(); + } - ->map(RecordModule::recordPreviewFromDb(...)) + /** + * @param Schema[] $schemas + * @return EdgeRecordPreview[] + */ + public static function findEdgeRecordPreviewsByRecordId( + array $schemas, + string $recordId, + ): array { + return DB::table("edges") + ->select( + "edges.*", + "records.id as record_id", + "records.schema_id as record_schema_id", + "records_data.value as record_title", + ) + ->where("edges.from", $recordId) + ->join("records", "edges.from", "=", "records.id") + ->join("records_data", function ($join) { + $join + ->on("records.id", "=", "records_data.record_id") + ->on( + "records.title_field_id", + "=", + "records_data.field_id", + ); + }) + ->orderBy("edges.rank", "asc") + ->get() + + ->map( + fn($row) => RecordModule::edgeRecordPreviewFromDb( + $schemas, + $row, + ), + ) ->toArray(); } } diff --git a/src/Core/Repository/SchemaRepo.php b/src/Core/Repository/SchemaRepo.php index d0ab56f..9bebe6f 100644 --- a/src/Core/Repository/SchemaRepo.php +++ b/src/Core/Repository/SchemaRepo.php @@ -20,6 +20,19 @@ class SchemaRepo ->toArray(); } + /** + * @return Schema[] + */ + public static function findByIds(array $schemaIds): array + { + return DB::table(self::TABLE_NAME) + ->whereIn("id", $schemaIds) + ->orderBy("name") + ->get() + ->map(SchemaModule::fromDb(...)) + ->toArray(); + } + public static function findOne(string $id): ?Schema { return DB::table(self::TABLE_NAME) diff --git a/src/Http/Controller/EdgeController.php b/src/Http/Controller/EdgeController.php index 55bfd00..1c3aa1b 100644 --- a/src/Http/Controller/EdgeController.php +++ b/src/Http/Controller/EdgeController.php @@ -4,10 +4,36 @@ namespace Lucent\Http\Controller; use App\Http\Controllers\Controller; use Illuminate\Http\Request; -use Lucent\Edge\EdgeService; -use Lucent\Query\Query; +use Lucent\Core\Repository\EdgeRepo; +use Lucent\Core\Data\Edge; +use Lucent\Core\Data\RecordMode; +use Lucent\Id\Id; +use function Lucent\Response\fail; +use function Lucent\Response\ok; class EdgeController extends Controller { - public function postCreate(Request $request) {} + public function postCreateMany(Request $request) + { + $from = $request->input("from"); + $toIds = $request->input("toIds"); + $fieldId = $request->input("fieldId"); + $locale = $request->input("locale"); + + $edges = array_map( + fn($to) => new Edge( + id: Id::new(), + from: $from, + to: $to, + fieldId: $fieldId, + locale: $locale, + rank: 0, + mode: RecordMode::DRAFT, + ), + $toIds, + ); + + EdgeRepo::insertMany($edges); + return ok($edges); + } } diff --git a/src/Http/Controller/RecordController.php b/src/Http/Controller/RecordController.php index 18c50fb..83548d8 100644 --- a/src/Http/Controller/RecordController.php +++ b/src/Http/Controller/RecordController.php @@ -183,6 +183,19 @@ class RecordController ); $recordStatus = RecordModule::getStatus($record); + $edgeRecordPreviews = RecordRepo::findEdgeRecordPreviewsByRecordId( + $schemas, + $record->id, + ); + $edgeRecordPreviewsDraft = collect($edgeRecordPreviews) + ->where("edge.mode", RecordMode::DRAFT) + ->values() + ->toArray(); + + $edgeRecordPreviewsLive = collect($edgeRecordPreviews) + ->where("edge.mode", RecordMode::LIVE) + ->values() + ->toArray(); return Svelte::view( view: "recordEdit", @@ -191,7 +204,8 @@ class RecordController "schemas" => $schemas, "schema" => $schema, "fields" => $fields, - // "graph" => toArray($graph), + "edgeRecordPreviewsDraft" => toArray($edgeRecordPreviewsDraft), + "edgeRecordPreviewsLive" => toArray($edgeRecordPreviewsLive), "record" => toArray($record), "draftData" => $draftData, "liveData" => $liveData, @@ -203,7 +217,9 @@ class RecordController public function suggest(Request $request) { - $schemas = $request->input("schemas"); + $schemaIds = $request->input("schemas"); + $schemas = SchemaRepo::findByIds($schemaIds); + $records = RecordRepo::findBySchemas($schemas); return ok(toArray($records)); } diff --git a/src/Http/web.php b/src/Http/web.php index afe4359..599a721 100644 --- a/src/Http/web.php +++ b/src/Http/web.php @@ -98,6 +98,12 @@ Route::group( RecordController::class, "untrash", ]); + + // EDGES + Route::post("edges/many", [ + EdgeController::class, + "postCreateMany", + ]); }); //OLD