schemas and fields

This commit is contained in:
2026-01-07 23:49:55 +02:00
parent 874ddd33e2
commit 53f9548966
17 changed files with 573 additions and 240 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
<script>
import { formatDistanceToNow, parseJSON } from "date-fns";
import Avatar from "../../svelte/account/Avatar.svelte";
import Avatar from "../../common/Avatar.svelte";
import { previewTitle } from "../../svelte/records/Preview";
import Preview from "../../svelte/files/Preview.svelte";
import { usernameById } from "../../svelte/account/users";
@@ -0,0 +1,104 @@
<script>
import ChannelLayout from "../../layouts/ChannelLayout.svelte";
import { post } from "../../modules/remote";
let { channel, user, data } = $props();
let newSchemaName = $state("");
let newSchemaAlias = $state("");
function handleSchemaCreate(e) {
e.preventDefault();
post(
channel.lucentUrl + "/schemas",
{
name: newSchemaName,
alias: newSchemaAlias,
},
(data, err) => {
if (err.isEmpty()) {
window.location.reload();
}
},
);
}
</script>
<ChannelLayout {body} {channel} {user}></ChannelLayout>
{#snippet body()}
<h3 class="header-small mb-4 mt-5">Schemas</h3>
<details style="max-width: 400px;">
<summary>Create Schema</summary>
<form onsubmit={handleSchemaCreate}>
<fieldset>
<label>
Name
<input
bind:value={newSchemaName}
placeholder="Schema name"
minlength="2"
maxlength="30"
required
/>
</label>
<label>
Alias
<input
bind:value={newSchemaAlias}
placeholder="Schema alias"
minlength="2"
maxlength="30"
required
/>
</label>
</fieldset>
<button type="submit">Create</button>
</form>
</details>
<div style="display: flex;gap:20px">
{#each data.schemas as schema}
<article style="min-width: 300px;">
<header>{schema.name}</header>
<details>
<summary>Fields</summary>
<table>
<tbody>
<tr>
<td>Title</td>
</tr>
</tbody>
</table>
</details>
<details>
<summary>Add field</summary>
<ul>
<li>
<a
href={`/fields/create?schema=${schema.id}&type=text`}
>Text</a
>
</li>
<li>
<a
href={`/fields/create?schema=${schema.id}&type=text`}
>File</a
>
</li>
<li>
<a
href={`/fields/create?schema=${schema.id}&type=text`}
>Rich</a
>
</li>
</ul>
</details>
<footer>
<small> Id: {schema.id}</small><br />
<small> Alias: {schema.alias}</small><br />
<small> Revisions: {schema.revisions}</small><br />
</footer>
</article>
{/each}
</div>
{/snippet}
+1
View File
@@ -6,6 +6,7 @@
<div class="top-nav">
<a class="top-nav-item" href="{channel.lucentUrl}/members">Members</a>
<a class="top-nav-item" href="{channel.lucentUrl}/schemas">Schemas</a>
<!-- {#if channel.commands.length > 0}
<Dropdown>
+2
View File
@@ -13,6 +13,7 @@ import RecordNotFound from "./svelte/records/NotFound.svelte";
import RecordEdit from "./svelte/records/Edit.svelte";
import ContentIndex from "./svelte/content/Index.svelte";
import HomeEntry from "./entry/HomeEntry/HomeEntry.svelte";
import SchemaEntry from "./entry/SchemaEntry/SchemaEntry.svelte";
import BuildReport from "./svelte/build/Report.svelte";
const entryComponents = {
@@ -27,6 +28,7 @@ const entryComponents = {
verify: Verify,
profile: Profile,
setup: SetupIndex,
schemas: SchemaEntry,
};
let loadedComponents = [];
+22 -21
View File
@@ -1,8 +1,8 @@
<script>
import ErrorAlert from "../common/ErrorAlert.svelte";
import SpinnerButton from "../common/SpinnerButton.svelte";
import Avatar from "./Avatar.svelte";
import {getContext} from "svelte";
import Avatar from "./../../common/Avatar.svelte";
import { getContext } from "svelte";
import SuccessAlert from "../common/SuccessAlert.svelte";
const user = getContext("user");
@@ -25,7 +25,7 @@
})
.catch((error) => {
errorMessage = error.response?.data.error;
console.log({errorMessage});
console.log({ errorMessage });
});
}
@@ -42,46 +42,47 @@
})
.catch((error) => {
errorMessage = error.response?.data.error;
console.log({errorMessage});
console.log({ errorMessage });
});
}
</script>
<div class="wrapper-tiny">
<ErrorAlert message={errorMessage}/>
<ErrorAlert message={errorMessage} />
<SuccessAlert bind:this={successAlert} />
<h3 class="header-small mb-5">
<Avatar name={user.name}/>
<Avatar name={user.name} />
</h3>
<form on:submit={saveName}>
<div class="input-group mb-5">
<input
type="text"
bind:value={name}
class="form-control mb-3"
placeholder="Name"
required
type="text"
bind:value={name}
class="form-control mb-3"
placeholder="Name"
required
/>
<SpinnerButton label="Update Name"/>
<SpinnerButton label="Update Name" />
</div>
</form>
<form on:submit={saveEmail}>
<div class="input-group mb-5">
<input
type="email"
bind:value={email}
class="form-control mb-3"
placeholder="Email"
required
type="email"
bind:value={email}
class="form-control mb-3"
placeholder="Email"
required
/>
<SpinnerButton label="Update Email"/>
<SpinnerButton label="Update Email" />
</div>
</form>
<div class="list-group">
<a class="list-group-item list-group-item-action" href="{ channel.lucentUrl }/logout">Logout from this
device</a>
<a
class="list-group-item list-group-item-action"
href="{channel.lucentUrl}/logout">Logout from this device</a
>
</div>
</div>
+19 -12
View File
@@ -1,9 +1,9 @@
<script>
import RenderField from "./RenderField.svelte";
import Avatar from "../account/Avatar.svelte";
import Avatar from "../../common/Avatar.svelte";
import Status from "../records/Status.svelte";
import {usernameById} from "../account/users";
import {friendlyDate} from "../../helpers";
import { usernameById } from "../account/users";
import { friendlyDate } from "../../helpers";
export let schema;
export let users;
@@ -12,7 +12,6 @@
export let sortParam;
export let sortField;
export let visibleColumns;
</script>
{#each visibleColumns as field, index}
@@ -20,7 +19,7 @@
class="field-ui-{field.info.name}"
class:is-sort={field.name === sortField.name}
>
<RenderField {record} {schema} {graph} {field}/>
<RenderField {record} {schema} {graph} {field} />
</td>
{/each}
{#if schema.visible?.includes("status")}
@@ -28,32 +27,40 @@
class="text-center"
class:is-sort={"-status" == sortParam || "status" == sortParam}
>
<Status status={record.status}/>
<Status status={record.status} />
</td>
{/if}
{#if schema.visible?.includes("_sys.createdBy")}
<td
class="text-center"
class:is-sort={"-_sys.createdBy" == sortParam || "_sys.createdBy" == sortParam}
class:is-sort={"-_sys.createdBy" == sortParam ||
"_sys.createdBy" == sortParam}
>
<Avatar name={usernameById(users, record._sys.createdBy)} side={24}/>
<Avatar name={usernameById(users, record._sys.createdBy)} side={24} />
</td>
{/if}
{#if schema.visible?.includes("_sys.updatedBy")}
<td
class="text-center"
class:is-sort={"-_sys.updatedBy" == sortParam || "_sys.updatedBy" == sortParam}
class:is-sort={"-_sys.updatedBy" == sortParam ||
"_sys.updatedBy" == sortParam}
>
<Avatar name={usernameById(users, record._sys.updatedBy)} side={24}/>
<Avatar name={usernameById(users, record._sys.updatedBy)} side={24} />
</td>
{/if}
{#if schema.visible?.includes("_sys.createdAt")}
<td class:is-sort={"-_sys.createdAt" == sortParam || "_sys.createdAt" == sortParam}>
<td
class:is-sort={"-_sys.createdAt" == sortParam ||
"_sys.createdAt" == sortParam}
>
{friendlyDate(record._sys.createdAt)}
</td>
{/if}
{#if schema.visible?.includes("_sys.updatedAt")}
<td class:is-sort={"-_sys.updatedAt" == sortParam || "_sys.updatedAt" == sortParam}>
<td
class:is-sort={"-_sys.updatedAt" == sortParam ||
"_sys.updatedAt" == sortParam}
>
{friendlyDate(record._sys.updatedAt)}
</td>
{/if}
+115 -92
View File
@@ -1,13 +1,13 @@
<script>
import RecordRow from "./RecordRow.svelte";
import {previewTitle} from "../records/Preview";
import {usernameById} from "../account/users";
import {getContext} from "svelte";
import Avatar from "../account/Avatar.svelte";
import {selectRecord, toggleAll} from "./functions/recordSelect.js";
import { previewTitle } from "../records/Preview";
import { usernameById } from "../account/users";
import { getContext } from "svelte";
import Avatar from "../../common/Avatar.svelte";
import { selectRecord, toggleAll } from "./functions/recordSelect.js";
import Checkbox from "../common/Checkbox.svelte";
import Preview from "../files/Preview.svelte";
import {fileurl} from "../files/imageserver.js";
import { fileurl } from "../files/imageserver.js";
const channel = getContext("channel");
@@ -23,107 +23,134 @@
export let selected = [];
function eventToggleAll(e) {
selected = toggleAll(e, records, selected)
selected = toggleAll(e, records, selected);
}
function select(record) {
selected = selectRecord(record, selected)
selected = selectRecord(record, selected);
}
$: visibleColumns = schema.fields.filter(c => schema.visible?.includes(c.name) ?? [])
$: visibleColumns = schema.fields.filter(
(c) => schema.visible?.includes(c.name) ?? [],
);
</script>
<div class="table mt-5 ">
<div class="table mt-5">
<table>
<thead>
<tr>
{#if isWritable}
<th>
<Checkbox
<tr>
{#if isWritable}
<th>
<Checkbox
value=""
on:change={eventToggleAll}
indeterminate={selected.length > 0 && selected.length < records.length}
indeterminate={selected.length > 0 &&
selected.length < records.length}
checked={selected.length === records.length}
>
</Checkbox>
</th>
{/if}
></Checkbox>
</th>
{/if}
{#each visibleColumns as field}
<th
{#each visibleColumns as field}
<th
class="field-ui-{field.info.name ?? field.ui}"
class:is-sort={field.name === sortField.name}
scope="col"
title={field.help}
>{field.label}</th
>
{/each}
{#each systemFields.filter(c => schema.visible?.includes(c.name)) as sysField}
<th class:is-sort={sysField.name === sortField.name}>{sysField.label}</th>
{/each}
<th></th>
</tr>
title={field.help}>{field.label}</th
>
{/each}
{#each systemFields.filter( (c) => schema.visible?.includes(c.name), ) as sysField}
<th class:is-sort={sysField.name === sortField.name}
>{sysField.label}</th
>
{/each}
<th></th>
</tr>
</thead>
<tbody>
{#each records as record (record.id)}
<tr>
<td class="title-td">
<div
class="title-td-contents"
>
{#if isWritable}
<Checkbox
{#each records as record (record.id)}
<tr>
<td class="title-td">
<div class="title-td-contents">
{#if isWritable}
<Checkbox
on:change={() => select(record)}
checked={selected.find((r) => r.id === record.id)}
checked={selected.find(
(r) => r.id === record.id,
)}
value={record}
>
</Checkbox>
></Checkbox>
{/if}
{#if record._file?.path}
<div class="file-table-row">
<Preview
{record}
size={record._file?.width > 0
? "medium"
: "small"}
/>
{/if}
{#if record._file?.path}
<div class="file-table-row">
<Preview record={record} size={record._file?.width > 0 ? "medium" : "small"}/>
<div>
{#if record.status === "draft"}
<span style="text-transform: uppercase;font-size:10px">{record.status}</span>
{/if}
<a
<div>
{#if record.status === "draft"}
<span
style="text-transform: uppercase;font-size:10px"
>{record.status}</span
>
{/if}
<a
href="{channel.lucentUrl}/records/{record.id}"
target={inModal ? "_blank" : "_self"}
>
{previewTitle(channel.schemas, record, graph)}
</a>
<span>{(record._file.size / 1024).toFixed(1)}kB</span>
target={inModal
? "_blank"
: "_self"}
>
{previewTitle(
channel.schemas,
record,
graph,
)}
</a>
<span
>{(
record._file.size / 1024
).toFixed(1)}kB</span
>
{#if record._file.width > 0}
<span>{record._file.width + "x" + record._file.height}</span>
{/if}
<a
href="{fileurl(channel,record)}"
{#if record._file.width > 0}
<span
>{record._file.width +
"x" +
record._file.height}</span
>
{/if}
<a
href={fileurl(channel, record)}
target="_blank"
>
Download
</a>
>
Download
</a>
</div>
</div>
</div>
{:else}
<a
{:else}
<a
href="{channel.lucentUrl}/records/{record.id}"
target={inModal ? "_blank" : "_self"}
>
{#if record.status === "draft"}
<span style="text-transform: uppercase;font-size:10px">{record.status}</span>
{/if}
{previewTitle(channel.schemas, record, graph)}
</a>
{/if}
</div>
</td>
<RecordRow
>
{#if record.status === "draft"}
<span
style="text-transform: uppercase;font-size:10px"
>{record.status}</span
>
{/if}
{previewTitle(
channel.schemas,
record,
graph,
)}
</a>
{/if}
</div>
</td>
<RecordRow
{record}
{graph}
{schema}
@@ -131,19 +158,15 @@
{sortParam}
{sortField}
{users}
/>
<td>
<Avatar
name={usernameById(
users,
record._sys.updatedBy
)}
side={24}
/>
</td>
</tr>
{/each}
<td>
<Avatar
name={usernameById(users, record._sys.updatedBy)}
side={24}
/>
</td>
</tr>
{/each}
</tbody>
</table>
</div>
@@ -1,14 +1,13 @@
<script>
import Avatar from "../account/Avatar.svelte";
import {fly} from "svelte/transition";
import {createEventDispatcher} from "svelte";
import Avatar from "../../common/Avatar.svelte";
import { fly } from "svelte/transition";
import { createEventDispatcher } from "svelte";
import Dropdown from "../common/Dropdown.svelte";
const dispatch = createEventDispatcher();
export let member;
export let roles;
function removeFrom(e, aRole) {
e.preventDefault();
let newRoles = member.roles.filter((r) => r !== aRole);
@@ -22,24 +21,23 @@
e.preventDefault();
let newRoles = [...member.roles, aRole];
console.log(member.roles)
console.log(aRole)
console.log(newRoles)
console.log(member.roles);
console.log(aRole);
console.log(newRoles);
dispatch("update", {
user: member.id,
roles: newRoles,
});
}
</script>
<div
transition:fly={{ duration: 200 }}
class="member-item"
>
<div class="member-name status-{member.roles.includes('removed') ? 'removed' : 'active'}">
<Avatar name={member.name ?? "" } side={32}/>
<div transition:fly={{ duration: 200 }} class="member-item">
<div
class="member-name status-{member.roles.includes('removed')
? 'removed'
: 'active'}"
>
<Avatar name={member.name ?? ""} side={32} />
<div>
<div>
{member.name}
@@ -50,41 +48,35 @@
</div>
</div>
<Dropdown orientation="right">
<div slot="button">
Roles
</div>
<div slot="button">Roles</div>
<h6 class="dropdown-header">Remove role</h6>
{#each roles as role}
{#if member.roles.includes(role)}
<button
class="dropdown-item button"
on:click={(e) => removeFrom(e,role)}
class="dropdown-item button"
on:click={(e) => removeFrom(e, role)}
>
{role}
</button>
{/if}
{/each}
<h6 class="dropdown-header">Add role</h6>
{#each roles as role}
{#if !member.roles.includes(role)}
<button
class="dropdown-item button"
on:click={(e) => addTo(e,role)}
class="dropdown-item button"
on:click={(e) => addTo(e, role)}
>
{role}
</button>
{/if}
{/each}
</Dropdown>
</div>
<style>
.status-removed {
opacity: .5;
opacity: 0.5;
}
</style>
+1 -1
View File
@@ -1,6 +1,6 @@
<script>
import { friendlyDate } from "../../helpers";
import Avatar from "../account/Avatar.svelte";
import Avatar from "../../common/Avatar.svelte";
import { usernameById } from "../account/users";
import Icon from "../common/Icon.svelte";
import RevisionCell from "./revisions/RevisionCell.svelte";
+15 -4
View File
@@ -4,9 +4,8 @@ namespace Lucent\Commands;
use DirectoryIterator;
use Illuminate\Console\Command;
use Lucent\Schema\Schema;
use Lucent\Core\Schema\SchemaModule;
use Lucent\Schema\SchemaService;
use Lucent\Schema\Type;
use Yosymfony\Toml\Toml;
class CompileSchemas extends Command
@@ -32,8 +31,20 @@ class CompileSchemas extends Command
$schemas[] = $schemaData;
}
$schemas = collect($schemas)->sortBy("label")->values();
$schemas = collect($schemas)
->sortBy("label")
->values()
->map(function ($schemaData) {
$fields = [];
foreach ($schemaData["fields"] as $fieldId => $fieldData) {
$fieldData["id"] = $fieldId;
$fields[] = $fieldData;
}
$schemaData["fields"] = $fields;
return $schemaData;
})
->map(SchemaModule::fromArray(...));
dd($schemas);
if (!file_exists(storage_path("lucent"))) {
mkdir(storage_path("lucent"));
}
+27
View File
@@ -0,0 +1,27 @@
<?php namespace Lucent\Core\Repository;
use Illuminate\Support\Facades\DB;
use Lucent\Core\Schema\Data\Schema;
use Lucent\Core\Schema\SchemaModule;
class SchemaRepo
{
const TABLE_NAME = "schemas";
/**
* @@return Schema[]
*/
public static function all(): array
{
return DB::table(self::TABLE_NAME)
->orderBy("name")
->get()
->map(SchemaModule::fromDb(...))
->toArray();
}
public static function insert(Schema $schema): void
{
DB::table(self::TABLE_NAME)->insert(SchemaModule::toDb($schema));
}
}
+2 -1
View File
@@ -4,7 +4,8 @@ class Field
{
public function __construct(
public string $id,
public string $label,
public string $alias,
public string $name,
public string $type,
) {}
}
+6 -2
View File
@@ -4,12 +4,16 @@ class Schema
{
/**
* @param string $id
* @param string $label
* @param string $alias
* @param string $name
* @param int $revisions
* @param Field[] $fields
*/
public function __construct(
public string $id,
public string $label,
public string $alias,
public string $name,
public int $revisions,
public array $fields,
) {}
}
+26
View File
@@ -0,0 +1,26 @@
<?php namespace Lucent\Core\Schema;
use Lucent\Core\Schema\Data\Field;
class FieldModule
{
public static function fromArray(array $data): Field
{
return new Field(
id: $data["id"],
alias: $data["alias"],
name: $data["name"],
type: $data["type"],
);
}
public static function toDb(Field $field): array
{
return [
"id" => $field->id,
"alias" => $field->alias,
"name" => $field->name,
"type" => $field->type,
];
}
}
+32 -2
View File
@@ -1,9 +1,39 @@
<?php namespace Lucent\Core\Schema;
use Lucent\Core\Schema\Data\Schema;
use stdClass;
class SchemaModule
{
public function __construct()
public static function fromArray(array $data): Schema
{
// Constructor logic here
return new Schema(
id: $data["id"],
alias: $data["alias"],
name: $data["label"],
revisions: $data["revisions"],
fields: array_map(FieldModule::fromArray(...), $data["fields"]),
);
}
public static function fromDb(stdClass $data): Schema
{
return new Schema(
id: data_get($data, "id"),
alias: data_get($data, "alias"),
name: data_get($data, "name"),
revisions: data_get($data, "revisions"),
fields: [],
);
}
public static function toDb(Schema $schema): array
{
return [
"id" => $schema->id,
"alias" => $schema->alias,
"name" => $schema->name,
"revisions" => $schema->revisions,
];
}
}
+61
View File
@@ -0,0 +1,61 @@
<?php
namespace Lucent\Http\Controller;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Lucent\Account\AccountService;
use Lucent\Account\AuthService;
use Lucent\Core\Repository\SchemaRepo;
use Lucent\Core\Schema\Data\Schema;
use Lucent\Id\Id;
use Lucent\Svelte\Svelte;
use Illuminate\Support\Facades\Validator;
class SchemaController extends Controller
{
public function __construct(
private readonly AuthService $authService,
private readonly AccountService $accountService,
private readonly Svelte $svelte,
) {}
public function home()
{
$schemas = SchemaRepo::all();
return $this->svelte->render(
view: "schemas",
title: "Schemas",
data: [
"schemas" => $schemas,
],
);
}
public function postCreate(Request $request)
{
$validator = Validator::make($request->all(), [
"name" => "required|string|max:30|min:2|",
"alias" => "required|alpha_dash:ascii|max:30|min:2|",
]);
if ($validator->fails()) {
return response()->json(["errors" => $validator->errors()], 422);
}
$schema = new Schema(
id: Id::new(),
alias: $request->input("alias"),
name: $request->input("name"),
revisions: 0,
fields: [],
);
SchemaRepo::insert($schema);
return response()->json(
["message" => "Schema created successfully"],
201,
);
}
}
+119 -76
View File
@@ -10,91 +10,134 @@ use Lucent\Http\Controller\HomeController;
use Lucent\Http\Controller\MemberController;
use Lucent\Http\Controller\RecordController;
use Lucent\Http\Controller\RevisionController;
use Lucent\Http\Controller\SchemaController;
use Lucent\Http\Controller\SetupController;
Route::get("/lucent/setup", [SetupController::class, "setup"]);
Route::get("/lfs-{disk}/{any}", [FileController::class, "fromDisk"])->where(
"any",
".*",
);
Route::get('/lucent/setup', [SetupController::class, 'setup']);
Route::get('/lfs-{disk}/{any}', [FileController::class, 'fromDisk'])->where('any', '.*');
Route::group(
[
"middleware" => ["web"],
"prefix" => "lucent",
],
function () {
Route::middleware(["lucent.guest"])->group(function () {
Route::get("/", [AuthController::class, "login"]);
Route::get("/register", [AuthController::class, "register"]);
Route::post("/register", [AuthController::class, "postRegister"]);
Route::get("/login", [AuthController::class, "login"]);
Route::post("/login", [AuthController::class, "postLogin"]);
Route::get("/verify", [AuthController::class, "verify"]);
Route::post("/verify", [AuthController::class, "postVerify"]);
});
Route::group([
'middleware' => ['web'],
'prefix' => "lucent"
], function () {
Route::middleware("lucent.auth")->group(function () {
Route::get("/logout", [AuthController::class, "logout"]);
Route::get("/profile", [AccountController::class, "profile"]);
Route::post("/account/update-name", [
AccountController::class,
"updateName",
]);
Route::post("/account/update-email", [
AccountController::class,
"updateEmail",
]);
Route::get("/command-report/{signature}", [
BuildController::class,
"report",
]);
Route::get("/command-report-source/{signature}", [
BuildController::class,
"reportSource",
]);
Route::post("/command/{signature}", [
BuildController::class,
"build",
]);
Route::get("/schemas", [SchemaController::class, "home"]);
Route::post("/schemas", [SchemaController::class, "postCreate"]);
});
Route::middleware(["lucent.auth"])->group(function () {
Route::get("/members/", [MemberController::class, "index"]);
Route::post("/members/invite", [MemberController::class, "invite"]);
Route::post("/members/update", [MemberController::class, "update"]);
});
Route::middleware(["lucent.auth"])
->prefix("/records")
->group(function () {
Route::get("/new", [RecordController::class, "new"]);
Route::get("/newInline", [
RecordController::class,
"newInline",
]);
Route::get("/suggestions", [
RecordController::class,
"suggestions",
]);
Route::get("/{rid}", [RecordController::class, "edit"]);
Route::post("/clone/{rid}", [RecordController::class, "clone"]);
// Route::get('/editInline/{rid}', [RecordController::class, 'editInline']);
Route::get("/{rid}/parents", [
RecordController::class,
"parents",
]);
Route::post("/", [RecordController::class, "save"]);
Route::post("/status/{status}", [
RecordController::class,
"status",
]);
Route::post("/delete", [RecordController::class, "delete"]);
Route::post("/{rid}/rollback/{version}", [
RecordController::class,
"rollback",
]);
});
Route::middleware(['lucent.guest'])->group(function () {
Route::get('/', [AuthController::class, 'login']);
Route::middleware(["lucent.auth"])
->prefix("/edges")
->group(function () {
Route::post("/insert-many", [
EdgeController::class,
"insertMany",
]);
});
Route::get('/register', [AuthController::class, 'register']);
Route::post('/register', [AuthController::class, 'postRegister']);
Route::get('/login', [AuthController::class, 'login']);
Route::post('/login', [AuthController::class, 'postLogin']);
Route::get('/verify', [AuthController::class, 'verify']);
Route::post('/verify', [AuthController::class, 'postVerify']);
Route::middleware(["lucent.auth"])->group(function () {
Route::get("/records/{rid}/revisions", [
RevisionController::class,
"index",
]);
});
});
Route::middleware(["lucent.auth"])->group(function () {
Route::get("/", [HomeController::class, "home"]);
Route::get("/home/records", [HomeController::class, "records"]);
});
Route::middleware('lucent.auth')->group(function () {
Route::get('/logout', [AuthController::class, 'logout']);
Route::get('/profile', [AccountController::class, 'profile']);
Route::post('/account/update-name', [AccountController::class, 'updateName']);
Route::post('/account/update-email', [AccountController::class, 'updateEmail']);
Route::get('/command-report/{signature}', [BuildController::class, 'report']);
Route::get('/command-report-source/{signature}', [BuildController::class, 'reportSource']);
Route::post('/command/{signature}', [BuildController::class, 'build']);
});
Route::middleware(["lucent.auth"])->group(function () {
Route::get('/members/', [MemberController::class, 'index']);
Route::post('/members/invite', [MemberController::class, 'invite']);
Route::post('/members/update', [MemberController::class, 'update']);
});
Route::middleware(["lucent.auth"])->prefix("/records")->group(function () {
Route::get('/new', [RecordController::class, 'new']);
Route::get('/newInline', [RecordController::class, 'newInline']);
Route::get('/suggestions', [RecordController::class, 'suggestions']);
Route::get('/{rid}', [RecordController::class, 'edit']);
Route::post('/clone/{rid}', [RecordController::class, 'clone']);
// Route::get('/editInline/{rid}', [RecordController::class, 'editInline']);
Route::get('/{rid}/parents', [RecordController::class, 'parents']);
Route::post('/', [RecordController::class, 'save']);
Route::post('/status/{status}', [RecordController::class, 'status']);
Route::post('/delete', [RecordController::class, 'delete']);
Route::post('/{rid}/rollback/{version}', [RecordController::class, 'rollback']);
});
Route::middleware(["lucent.auth"])->prefix("/edges")->group(function () {
Route::post('/insert-many', [EdgeController::class, 'insertMany']);
});
Route::middleware(["lucent.auth"])->group(function () {
Route::get('/records/{rid}/revisions', [RevisionController::class, 'index']);
});
Route::middleware(["lucent.auth"])->group(function () {
Route::get('/', [HomeController::class, 'home']);
Route::get('/home/records', [HomeController::class, 'records']);
});
Route::middleware(["lucent.auth"])->prefix("/content")->group(function () {
Route::get('/{schemaName}', [RecordController::class, 'index']);
Route::get('/{schemaName}/csv', [RecordController::class, 'exportCSV']);
Route::get('/{schemaName}/emptyTrash', [RecordController::class, 'emptyTrash']);
});
Route::middleware(["lucent.auth"])->group(function () {
Route::post('/files/upload', [FileController::class, 'upload']);
Route::get('/files/download', [FileController::class, 'download']);
});
});
Route::middleware(["lucent.auth"])
->prefix("/content")
->group(function () {
Route::get("/{schemaName}", [RecordController::class, "index"]);
Route::get("/{schemaName}/csv", [
RecordController::class,
"exportCSV",
]);
Route::get("/{schemaName}/emptyTrash", [
RecordController::class,
"emptyTrash",
]);
});
Route::middleware(["lucent.auth"])->group(function () {
Route::post("/files/upload", [FileController::class, "upload"]);
Route::get("/files/download", [FileController::class, "download"]);
});
},
);