diff --git a/front/js/entry/FieldEditEntry/FieldEditEntry.svelte b/front/js/entry/FieldEditEntry/FieldEditEntry.svelte
index c34439d..331b126 100644
--- a/front/js/entry/FieldEditEntry/FieldEditEntry.svelte
+++ b/front/js/entry/FieldEditEntry/FieldEditEntry.svelte
@@ -2,6 +2,7 @@
import SchemaLayout from "../../layouts/SchemaLayout.svelte";
import TextFieldProps from "./TextFieldProps.svelte";
import RelationFieldProps from "./RelationFieldProps.svelte";
+ import FileFieldProps from "./FileFieldProps.svelte";
import DeleteButton from "../../common/DeleteButton.svelte";
import { post } from "../../modules/remote";
import { getApp } from "../../app";
@@ -128,6 +129,8 @@
{:else if data.field.type === "relation"}
+ {:else if data.field.type === "file"}
+
{/if}
diff --git a/front/js/entry/FieldEditEntry/FileFieldProps.svelte b/front/js/entry/FieldEditEntry/FileFieldProps.svelte
new file mode 100644
index 0000000..e205c9e
--- /dev/null
+++ b/front/js/entry/FieldEditEntry/FileFieldProps.svelte
@@ -0,0 +1,15 @@
+
+
+
diff --git a/front/js/entry/RecordEditEntry/RecordForm.svelte b/front/js/entry/RecordEditEntry/RecordForm.svelte
index fe0c300..92a6f1a 100644
--- a/front/js/entry/RecordEditEntry/RecordForm.svelte
+++ b/front/js/entry/RecordEditEntry/RecordForm.svelte
@@ -1,6 +1,7 @@
+
+{#if hasError}
+ {validationError.message}
+{:else if schemaField.help != ""}
+ {schemaField.help}
+{/if}
diff --git a/front/js/entry/RecordEditEntry/fields/FieldLabel.svelte b/front/js/entry/RecordEditEntry/fields/FieldLabel.svelte
new file mode 100644
index 0000000..7c88dbd
--- /dev/null
+++ b/front/js/entry/RecordEditEntry/fields/FieldLabel.svelte
@@ -0,0 +1,9 @@
+
+
+{#if locale !== "main"}
+ {getLocaleName(channel, locale)} >
+{/if}
+{schemaField.name}
diff --git a/front/js/entry/RecordEditEntry/fields/FileField.svelte b/front/js/entry/RecordEditEntry/fields/FileField.svelte
new file mode 100644
index 0000000..f43de6a
--- /dev/null
+++ b/front/js/entry/RecordEditEntry/fields/FileField.svelte
@@ -0,0 +1,226 @@
+
+
+
+
+
+
+
+
+
+ {#if edgeRecordPreviews.length == 0}
+ No relations exist
+ {:else}
+
+ {#snippet itemView(edgeRecordPreview)}
+
+ {/snippet}
+
+ {/if}
+
+
diff --git a/front/js/entry/RecordEditEntry/fields/RelationField.svelte b/front/js/entry/RecordEditEntry/fields/RelationField.svelte
index 501f84b..32eec93 100644
--- a/front/js/entry/RecordEditEntry/fields/RelationField.svelte
+++ b/front/js/entry/RecordEditEntry/fields/RelationField.svelte
@@ -1,7 +1,9 @@
-
diff --git a/front/js/modules/upload.js b/front/js/modules/upload.js
new file mode 100644
index 0000000..6cead7b
--- /dev/null
+++ b/front/js/modules/upload.js
@@ -0,0 +1,58 @@
+import { getApp } from "../app";
+
+export function uploadFile(file, recordId, fieldId, locale, progress, error) {
+ const app = getApp();
+ const csrf = document.querySelector('meta[name="csrf-token"]').content;
+ const chunkSize = 2 * 1024 * 1024; // 2MB
+ const totalChunks = Math.ceil(file.size / chunkSize);
+
+ // Start the recursive process
+ sendChunk(0, null);
+
+ function sendChunk(currentChunk, fileId) {
+ const start = currentChunk * chunkSize;
+ const end = Math.min(start + chunkSize, file.size);
+ const chunk = file.slice(start, end);
+
+ const formData = new FormData();
+ formData.append("file", chunk);
+ if (fileId) {
+ formData.append("fileId", fileId);
+ }
+
+ formData.append("recordId", recordId);
+ formData.append("fieldId", fieldId);
+ formData.append("isLast", currentChunk === totalChunks - 1);
+ formData.append("filename", file.name);
+ formData.append("locale", locale);
+ formData.append("_token", csrf);
+
+ const xhr = new XMLHttpRequest();
+ xhr.open("POST", app.url("upload"), true);
+
+ // Success Callback
+ xhr.onload = function () {
+ if (xhr.status === 200) {
+ const response = JSON.parse(xhr.responseText);
+ let fileId = response.fileId;
+ const nextChunk = currentChunk + 1;
+ if (nextChunk < totalChunks) {
+ progress({
+ pct: Math.round((nextChunk / totalChunks) * 100),
+ isComplete: false,
+ });
+ sendChunk(nextChunk, fileId);
+ } else {
+ progress({
+ pct: 100,
+ isComplete: true,
+ });
+ }
+ } else {
+ error("Upload failed at chunk " + currentChunk);
+ }
+ };
+
+ xhr.send(formData);
+ }
+}
diff --git a/src/Core/Data/File.php b/src/Core/Data/File.php
new file mode 100644
index 0000000..cd6e935
--- /dev/null
+++ b/src/Core/Data/File.php
@@ -0,0 +1,16 @@
+ $file->id,
+ "name" => $file->name,
+ "size" => $file->size,
+ "width" => $file->width,
+ "height" => $file->height,
+ "mime" => $file->mime,
+ "checksum" => $file->checksum,
+ "record_id" => $file->recordId,
+ "is_shared" => $file->isShared,
+ ];
+ }
+
+ public static function fromDb(stdClass $data): File
+ {
+ return new File(
+ id: data_get($data, "id"),
+ name: data_get($data, "name"),
+ size: data_get($data, "size"),
+ width: data_get($data, "width"),
+ height: data_get($data, "height"),
+ mime: data_get($data, "mime"),
+ checksum: data_get($data, "checksum"),
+ recordId: data_get($data, "recordId"),
+ isShared: data_get($data, "isShared"),
+ );
+ }
+}
diff --git a/src/Core/File/RecordFileModule.php b/src/Core/File/RecordFileModule.php
new file mode 100644
index 0000000..38d8c47
--- /dev/null
+++ b/src/Core/File/RecordFileModule.php
@@ -0,0 +1,34 @@
+ $file->id,
+ "record_id" => $file->recordId,
+ "file_id" => $file->fileId,
+ "field_id" => $file->fieldId,
+ "mode" => $file->mode,
+ "locale" => $file->locale,
+ "rank" => $file->rank,
+ ];
+ }
+
+ public static function fromDb(stdClass $data): RecordFile
+ {
+ return new RecordFile(
+ id: data_get($data, "id"),
+ recordId: data_get($data, "recordId"),
+ fileId: data_get($data, "file_id"),
+ fieldId: data_get($data, "field_id"),
+ mode: RecordMode::from(data_get($data, "mode")),
+ locale: data_get($data, "locale"),
+ rank: data_get($data, "rank"),
+ );
+ }
+}
diff --git a/src/Core/Record/RecordValidationModule.php b/src/Core/Record/RecordValidationModule.php
index 5bde0d6..18c7f42 100644
--- a/src/Core/Record/RecordValidationModule.php
+++ b/src/Core/Record/RecordValidationModule.php
@@ -14,16 +14,23 @@ class RecordValidationModule
* @param string[] $locales
* @param Field[] $schemaFields
* @param RecordField[] $recordFields
+ * @param Edge[] $recordEdges
* @return RecordError[]
*/
public static function validate(
array $locales,
array $schemaFields,
array $recordFields,
+ array $recordEdges,
): array {
$errors = [];
foreach ($schemaFields as $schemaField) {
- $res = static::validateField("main", $schemaField, $recordFields);
+ $res = static::validateField(
+ "main",
+ $schemaField,
+ $recordFields,
+ $recordEdges,
+ );
$errors[] = $res;
if ($schemaField->translatable) {
foreach ($locales as $locale) {
@@ -31,6 +38,7 @@ class RecordValidationModule
$locale["id"],
$schemaField,
$recordFields,
+ $recordEdges,
);
$errors[] = $res;
}
@@ -47,25 +55,39 @@ class RecordValidationModule
*
* @param Field $schemaField
* @param RecordField[] $recordFields
+ * @param Edge[] $recordEdges
* @return array
*/
public static function validateField(
string $locale,
Field $schemaField,
array $recordFields,
+ array $recordEdges,
): ?RecordError {
// General Validations
- $error = static::validateRequired($locale, $schemaField, $recordFields);
+ $error = static::validateRequired(
+ $locale,
+ $schemaField,
+ $recordFields,
+ $recordEdges,
+ );
+
if (!empty($error)) {
return $error;
}
// Type specific
+
$error = match ($schemaField->type) {
"text" => static::validateText(
$locale,
$schemaField,
$recordFields,
),
+ "relation" => static::validateRelation(
+ $locale,
+ $schemaField,
+ $recordEdges,
+ ),
default => static::validateText(
$locale,
$schemaField,
@@ -80,16 +102,37 @@ class RecordValidationModule
*
* @param Field $schemaField
* @param RecordField[] $recordFields
+ * @param Edge[] $recordEdges
* @return ?RecordError
*/
public static function validateRequired(
string $locale,
Field $schemaField,
array $recordFields,
+ array $recordEdges,
): ?RecordError {
if ($schemaField->required === false) {
return null;
}
+ return match ($schemaField->type) {
+ "relation" => static::validateRequiredRelation(
+ $locale,
+ $schemaField,
+ $recordEdges,
+ ),
+ default => static::validateRequiredField(
+ $locale,
+ $schemaField,
+ $recordFields,
+ ),
+ };
+ }
+
+ private static function validateRequiredField(
+ string $locale,
+ Field $schemaField,
+ array $recordFields,
+ ): ?RecordError {
$recordField = static::findField($recordFields, $schemaField, $locale);
if (empty($recordField) || empty($recordField->value)) {
@@ -102,6 +145,27 @@ class RecordValidationModule
return null;
}
+ private static function validateRequiredRelation(
+ string $locale,
+ Field $schemaField,
+ array $recordEdges,
+ ): ?RecordError {
+ if (
+ collect($recordEdges)
+ ->where("fieldId", $schemaField->id)
+ ->where("locale", $locale)
+ ->where("mode", RecordMode::DRAFT)
+ ->isEmpty()
+ ) {
+ return new RecordError(
+ $schemaField->id,
+ $locale,
+ "This field is required",
+ );
+ }
+
+ return null;
+ }
/**
*
@@ -151,6 +215,45 @@ class RecordValidationModule
return null;
}
+ /**
+ *
+ * @param Field $schemaField
+ * @param Edge[] $recordEdges
+ * @return ?RecordError
+ */
+ public static function validateRelation(
+ string $locale,
+ Field $schemaField,
+ array $recordEdges,
+ ): ?RecordError {
+ $count = collect($recordEdges)
+ ->where("fieldId", $schemaField->id)
+ ->where("locale", $locale)
+ ->where("mode", RecordMode::DRAFT)
+ ->count();
+
+ if ($schemaField->props->min > 0) {
+ if ($count < $schemaField->props->min) {
+ return new RecordError(
+ $schemaField->id,
+ $locale,
+ "You have to have at least {$schemaField->props->min} related records",
+ );
+ }
+ }
+ if ($schemaField->props->max > 0) {
+ if ($count > $schemaField->props->max) {
+ return new RecordError(
+ $schemaField->id,
+ $locale,
+ "You have to have at most {$schemaField->props->max} related records",
+ );
+ }
+ }
+
+ return null;
+ }
+
private static function findField(
array $recordFields,
Field $schemaField,
diff --git a/src/Core/Repository/EdgeRepo.php b/src/Core/Repository/EdgeRepo.php
index 7c8e674..dc43a4d 100644
--- a/src/Core/Repository/EdgeRepo.php
+++ b/src/Core/Repository/EdgeRepo.php
@@ -29,6 +29,11 @@ class EdgeRepo
->delete();
}
+ public static function delete(string $id): void
+ {
+ DB::table(self::TABLE_NAME)->where("id", $id)->delete();
+ }
+
/**
* @return Edge[]
*/
@@ -41,6 +46,22 @@ class EdgeRepo
->toArray();
}
+ /**
+ * @return ?Edge
+ */
+ public static function findOne(string $id): ?Edge
+ {
+ $edges = DB::table(self::TABLE_NAME)->where("id", $id)->get();
+ return $edges->map(EdgeModule::fromDb(...))->first();
+ }
+
+ public static function update(Edge $edge): void
+ {
+ DB::table(self::TABLE_NAME)
+ ->where("id", $edge->id)
+ ->update(EdgeModule::toDb($edge));
+ }
+
public static function findLastOfField(
string $from,
string $fieldId,
diff --git a/src/Core/Repository/FileRepo.php b/src/Core/Repository/FileRepo.php
new file mode 100644
index 0000000..8829136
--- /dev/null
+++ b/src/Core/Repository/FileRepo.php
@@ -0,0 +1,27 @@
+insert(FileModule::toDb($file));
+ }
+
+ // public static function update(File $file): void
+ // {
+ // DB::table(self::TABLE_NAME)
+ // ->where("id", $file->id)
+ // ->update(FileModule::toDb($file));
+ // }
+
+ public static function delete(string $fileId): void
+ {
+ DB::table(self::TABLE_NAME)->where("id", $fileId)->delete();
+ }
+}
diff --git a/src/Core/Repository/RecordFileRepo.php b/src/Core/Repository/RecordFileRepo.php
new file mode 100644
index 0000000..f49b0ab
--- /dev/null
+++ b/src/Core/Repository/RecordFileRepo.php
@@ -0,0 +1,27 @@
+insert(RecordFileModule::toDb($file));
+ }
+
+ // public static function update(File $file): void
+ // {
+ // DB::table(self::TABLE_NAME)
+ // ->where("id", $file->id)
+ // ->update(FileModule::toDb($file));
+ // }
+
+ public static function delete(string $fileId): void
+ {
+ DB::table(self::TABLE_NAME)->where("id", $fileId)->delete();
+ }
+}
diff --git a/src/Core/Repository/RecordRepo.php b/src/Core/Repository/RecordRepo.php
index bef1a2f..c5c9974 100644
--- a/src/Core/Repository/RecordRepo.php
+++ b/src/Core/Repository/RecordRepo.php
@@ -71,6 +71,7 @@ class RecordRepo
->where("records_data.mode", RecordMode::DRAFT->value)
->orderBy("created_at", "desc")
->limit(5)
+ ->distinct()
->get()
->map(fn($row) => RecordModule::recordPreviewFromDb($schemas, $row))
->toArray();
@@ -147,6 +148,7 @@ class RecordRepo
);
})
->orderBy("edges.rank", "asc")
+ ->distinct()
->get()
->map(
diff --git a/src/Core/Schema/Data/FieldProp/FieldProp.php b/src/Core/Schema/Data/FieldProp/FieldProp.php
index 27022c8..c94aa15 100644
--- a/src/Core/Schema/Data/FieldProp/FieldProp.php
+++ b/src/Core/Schema/Data/FieldProp/FieldProp.php
@@ -7,6 +7,7 @@ class FieldProp
return match ($type) {
"text" => new TextFieldProp(min: 0, max: 0, default: ""),
"relation" => new RelationFieldProp(schemas: [], min: 0, max: 0),
+ "file" => new FileFieldProp(min: 0, max: 0),
default => new InvalidFieldProp(),
};
}
@@ -30,6 +31,10 @@ class FieldProp
min: $props["min"] ?? 0,
max: $props["max"] ?? 0,
),
+ "file" => new FileFieldProp(
+ min: $props["min"] ?? 0,
+ max: $props["max"] ?? 0,
+ ),
default => new InvalidFieldProp(),
};
}
diff --git a/src/Core/Schema/Data/FieldProp/FileFieldProp.php b/src/Core/Schema/Data/FieldProp/FileFieldProp.php
new file mode 100644
index 0000000..33080cb
--- /dev/null
+++ b/src/Core/Schema/Data/FieldProp/FileFieldProp.php
@@ -0,0 +1,6 @@
+table("edges")->insert($edgesDB);
}
-
/**
* @return list
*/
public function findAll(): array
{
$edges = Database::make()->table("edges")->get();
- return $edges->map([$this, 'mapEdge'])->toArray();
+ return $edges->map([$this, "mapEdge"])->toArray();
}
public function findForSource(string $recordId): array
{
- $edges = Database::make()->table("edges")->where("source", $recordId)->get();
- return $edges->map([$this, 'mapEdge'])->toArray();
+ $edges = Database::make()
+ ->table("edges")
+ ->where("source", $recordId)
+ ->get();
+ return $edges->map([$this, "mapEdge"])->toArray();
}
public function mapEdge(stdClass $edge): Edge
{
-
return new Edge(
source: $edge->source,
target: $edge->target,
@@ -82,14 +78,14 @@ class EdgeRepo
targetSchema: $edge->targetSchema,
field: $edge->field,
rank: $edge->rank,
- depth: $edge->depth ?? 0
+ depth: $edge->depth ?? 0,
);
-
}
public function remove(Edge $edge): void
{
- Database::make()->table("edges")
+ Database::make()
+ ->table("edges")
->where("source", $edge->source)
->where("target", $edge->target)
->where("sourceSchema", $edge->sourceSchema)
@@ -100,7 +96,8 @@ class EdgeRepo
public function findLastEdgeRank(string $source, string $field): string
{
- $data = Database::make()->table("edges")
+ $data = Database::make()
+ ->table("edges")
->where("source", $source)
->where("field", $field)
->orderBy("rank", "desc")
@@ -108,5 +105,4 @@ class EdgeRepo
return $data->rank ?? "";
}
-
}
diff --git a/src/Http/Controller/EdgeController.php b/src/Http/Controller/EdgeController.php
index 94fba61..a9892b8 100644
--- a/src/Http/Controller/EdgeController.php
+++ b/src/Http/Controller/EdgeController.php
@@ -7,14 +7,17 @@ use Illuminate\Http\Request;
use Lucent\Core\Repository\EdgeRepo;
use Lucent\Core\Repository\SchemaRepo;
use Lucent\Core\Repository\RecordRepo;
+use Lucent\Core\Repository\FieldRepo;
use Lucent\Core\Data\Edge;
use Lucent\Core\Data\RecordMode;
use Lucent\Id\Id;
+use Lucent\Core\Record\RecordValidationModule;
use function Lucent\Response\fail;
use function Lucent\Response\ok;
class EdgeController extends Controller
{
+ // Inserts edges to record, maybe I should move that to RecordController
public function postCreateMany(Request $request)
{
$from = $request->input("from");
@@ -46,7 +49,48 @@ class EdgeController extends Controller
$locale,
$from,
);
+ $field = FieldRepo::findOne($fieldId);
- return ok($edgeRecordPreviews);
+ $recordEdges = array_map(fn($e) => $e->edge, $edgeRecordPreviews);
+ $validationError = RecordValidationModule::validateField(
+ $locale,
+ $field,
+ [],
+ $recordEdges,
+ );
+
+ return ok([
+ "edgeRecordPreviews" => $edgeRecordPreviews,
+ "validationError" => $validationError,
+ ]);
+ }
+
+ public function postDelete(Request $request)
+ {
+ $id = $request->input("id");
+ $fieldId = $request->input("fieldId");
+ $locale = $request->input("locale");
+ $from = $request->input("from");
+ EdgeRepo::delete($id);
+ $schemas = SchemaRepo::all();
+ $edgeRecordPreviews = RecordRepo::findEdgeRecordPreviewsForField(
+ $schemas,
+ $fieldId,
+ $locale,
+ $from,
+ );
+ $field = FieldRepo::findOne($fieldId);
+
+ $recordEdges = array_map(fn($e) => $e->edge, $edgeRecordPreviews);
+ $validationError = RecordValidationModule::validateField(
+ $locale,
+ $field,
+ [],
+ $recordEdges,
+ );
+
+ return ok([
+ "validationError" => $validationError,
+ ]);
}
}
diff --git a/src/Http/Controller/RecordController.php b/src/Http/Controller/RecordController.php
index 19856b0..8b01568 100644
--- a/src/Http/Controller/RecordController.php
+++ b/src/Http/Controller/RecordController.php
@@ -11,6 +11,7 @@ use Lucent\Core\Data\RecordField;
use Lucent\Core\Query\QueryModule;
use Lucent\Core\Repository\FieldRepo;
use Lucent\Core\Repository\SchemaRepo;
+use Lucent\Core\Repository\EdgeRepo;
use Lucent\Core\Repository\RecordFieldRepo;
use Lucent\Core\Record\RecordModule;
use Lucent\Core\Record\RecordFieldModule;
@@ -190,12 +191,6 @@ class RecordController
$fields = FieldRepo::findBySchemaId($record->schemaId);
$locales = ChannelModule::get()->locales;
- $validationErrors = RecordValidationModule::validate(
- $locales,
- $fields,
- $draftData,
- );
-
$recordStatus = RecordModule::getStatus($record);
$edgeRecordPreviews = RecordRepo::findEdgeRecordPreviewsByRecordId(
$schemas,
@@ -210,6 +205,13 @@ class RecordController
->where("edge.mode", RecordMode::LIVE)
->values()
->toArray();
+ $recordEdges = array_map(fn($e) => $e->edge, $edgeRecordPreviewsDraft);
+ $validationErrors = RecordValidationModule::validate(
+ $locales,
+ $fields,
+ $draftData,
+ $recordEdges,
+ );
return Svelte::view(
view: "recordEdit",
@@ -306,6 +308,7 @@ class RecordController
$locale,
$field,
[$recordField],
+ [],
);
return ok([
@@ -314,6 +317,19 @@ class RecordController
]);
}
+ public function postSortEdges(Request $request)
+ {
+ $edgeIds = $request->input("ids");
+ foreach ($edgeIds as $index => $id) {
+ $edge = EdgeRepo::findOne($id);
+ if ($edge) {
+ $edge->rank = $index;
+ EdgeRepo::update($edge);
+ }
+ }
+ return response()->json(["ids" => $edgeIds], 200);
+ }
+
public function clone(Request $request)
{
try {
diff --git a/src/Http/Controller/UploadController.php b/src/Http/Controller/UploadController.php
new file mode 100644
index 0000000..6269633
--- /dev/null
+++ b/src/Http/Controller/UploadController.php
@@ -0,0 +1,101 @@
+hasFile("file")) {
+ return response()->json(["error" => "No file provided"], 400);
+ }
+
+ $file = $request->file("file");
+ $fileId = $request->input("fileId") ?? Id::new();
+
+ $filename = $request->input("filename");
+ $isLast = $request->input("isLast") === "true";
+ $recordId = $request->input("recordId");
+ $fieldId = $request->input("fieldId");
+ $locale = $request->input("locale");
+
+ // 2. Define path (e.g., storage/app/chunks/myvideo.mp4)
+ $extension = $extension = pathinfo($filename, PATHINFO_EXTENSION);
+ $tempPath = "chunks/" . $fileId . "." . $extension;
+ $fullTempPath = Storage::disk("local")->path($tempPath);
+ // 3. Append the raw chunk data to the file
+ // This creates the file if it doesn't exist, or adds to it if it does.
+ Storage::disk("local")->append(
+ $tempPath,
+ file_get_contents($file->getRealPath()),
+ null,
+ );
+
+ // 4. Finalize
+ if ($isLast) {
+ $dimensions = getimagesize($fullTempPath);
+ $width = $dimensions[0] ?? 0;
+ $height = $dimensions[1] ?? 0;
+
+ $file = new File(
+ id: $fileId,
+ name: $filename,
+ size: Storage::disk("local")->size($tempPath),
+ width: $width,
+ height: $height,
+ mime: Storage::disk("local")->mimeType($tempPath),
+ checksum: hash_file("md5", $fullTempPath),
+ recordId: $recordId,
+ isShared: false,
+ );
+
+ $finalPath = "uploads/" . $fileId . "." . $extension;
+ Storage::disk("local")->move($tempPath, $finalPath);
+
+ FileRepo::insert($file);
+
+ $recordFile = new RecordFile(
+ id: Id::new(),
+ recordId: $recordId,
+ fileId: $fileId,
+ fieldId: $fieldId,
+ mode: RecordMode::DRAFT,
+ locale: $locale,
+ rank: 0,
+ );
+ RecordFileRepo::insert($recordFile);
+
+ return response()->json([
+ "status" => "finished",
+ "fileId" => $fileId,
+ "location" => Storage::url($finalPath),
+ ]);
+ }
+
+ return response()->json([
+ "status" => "chunk_saved",
+ "fileId" => $fileId,
+ ]);
+ }
+}
diff --git a/src/Http/web.php b/src/Http/web.php
index 599a721..1d11325 100644
--- a/src/Http/web.php
+++ b/src/Http/web.php
@@ -8,6 +8,7 @@ use Lucent\Http\Controller\EdgeController;
use Lucent\Http\Controller\FieldController;
use Lucent\Http\Controller\FileController;
use Lucent\Http\Controller\HomeController;
+use Lucent\Http\Controller\UploadController;
use Lucent\Http\Controller\MemberController;
use Lucent\Http\Controller\RecordController;
use Lucent\Http\Controller\RevisionController;
@@ -99,11 +100,20 @@ Route::group(
"untrash",
]);
+ Route::post("records/sort-edges", [
+ RecordController::class,
+ "postSortEdges",
+ ]);
+
// EDGES
Route::post("edges/many", [
EdgeController::class,
"postCreateMany",
]);
+ Route::post("edges/delete", [EdgeController::class, "postDelete"]);
+
+ // UPLOAD
+ Route::post("upload", [UploadController::class, "upload"]);
});
//OLD