refactor fields

This commit is contained in:
2024-03-21 22:33:41 +02:00
parent bb77a37ff7
commit 8526fd471f
68 changed files with 635 additions and 297 deletions
+2 -2
View File
@@ -90,11 +90,11 @@
class="me-2 text-decoration-none text-dark fs-6" class="me-2 text-decoration-none text-dark fs-6"
href="{channel.lucentUrl}/records/{record.id}" href="{channel.lucentUrl}/records/{record.id}"
target={inModal ? "_blank" : "_self"} target={inModal ? "_blank" : "_self"}
title={previewTitle(channel.schemas, record, graph)} title={previewTitle(record, graph)}
data-bs-toggle="tooltip" data-bs-placement="left" data-bs-toggle="tooltip" data-bs-placement="left"
> >
{previewTitle(channel.schemas, record, graph)} {previewTitle(record, graph)}
</a> </a>
</div> </div>
<div> <div>
@@ -76,7 +76,7 @@
<span class="applied-filter d-inline-block border border-primary rounded lx-small-text me-1 px-2 py-1"> <span class="applied-filter d-inline-block border border-primary rounded lx-small-text me-1 px-2 py-1">
<div class="d-flex align-items-center justify-content-center"> <div class="d-flex align-items-center justify-content-center">
{#if filter.isReference && filterRecord} {#if filter.isReference && filterRecord}
{filter.label} is {previewTitle(channel.schemas, filterRecord)} {filter.label} is {previewTitle(filterRecord)}
{:else} {:else}
{filter.label} {operators.find((o) => o.name === filter.operator)?.symbol ?? ""} {value} {filter.label} {operators.find((o) => o.name === filter.operator)?.symbol ?? ""} {value}
{/if} {/if}
@@ -62,7 +62,7 @@
on:keypress={(e) => apply(e, option)} on:keypress={(e) => apply(e, option)}
> >
<span class="dropdown-item"> <span class="dropdown-item">
{previewTitle(channel.schemas, option)} {previewTitle( option)}
</span> </span>
</div> </div>
+54
View File
@@ -0,0 +1,54 @@
<script>
import {createEventDispatcher, getContext} from "svelte";
const dispatch = createEventDispatcher();
const channel = getContext("channel");
let isOpen = false;
export function open() {
isOpen = true;
}
</script>
<div
class="modal fade show"
tabindex="-1"
class:d-block={isOpen}
aria-modal="true"
role="dialog"
style="background: rgba(100,100,100,.6);"
>
<div class="modal-dialog modal-dialog-centered modal-dialog-scrollable">
<div class="modal-content">
<div class="modal-header">
<button
on:click|preventDefault={(e) => (isOpen = false)}
type="button"
class="btn-close"
data-bs-dismiss="modal"
aria-label="Close"
/>
</div>
<div class="modal-body">
</div>
</div>
</div>
</div>
<style>
.modal-dialog {
width: auto;
max-width: 100%;
}
.modal-content {
margin: 40px auto;
width: auto;
height: 100%;
}
</style>
+61
View File
@@ -0,0 +1,61 @@
<script>
import { getContext, createEventDispatcher } from "svelte";
import PreviewEdge from "./preview/PreviewEdge.svelte";
import PreviewRecord from "./preview/PreviewRecord.svelte";
import Icon from "../common/Icon.svelte";
const dispatch = createEventDispatcher();
const channel = getContext("channel");
export let classes = "";
export let hasDelete = false;
export let record
export let edge
export let graph
export let field
let schema = channel.schemas.find((aschema) => aschema.name === record.schema);
function remove(e) {
e.preventDefault();
dispatch("remove", record.id);
}
</script>
<!-- Preview Edge-->
<div
class="card mb-2 bg-light {classes}"
style="border-color:{schema.color ?? '#ccc'}; border-width: 1px;"
>
<div class="card-body d-flex flex-md-column">
{#if field.data}
<PreviewEdge {record} {edge} {graph} {field} {classes}/>
{:else}
<PreviewRecord {record} {graph} {classes} />
{/if}
</div>
{#if hasDelete}
<div class="position-absolute end-0" style="top:5px">
<button
class="trash-button text-dark btn btn-sm btn-link"
on:click={remove}
>
<Icon icon="trash-can"/>
</button>
</div>
{/if}
</div>
<style>
.card .trash-button {
display: none;
}
.card:hover .trash-button {
display: block;
}
</style>
@@ -0,0 +1,30 @@
<script>
import PreviewRecord from "./PreviewRecord.svelte";
import {previewTitle} from "../../records/Preview.js";
import {getContext} from "svelte";
import EdgeModal from "../../edges/EdgeModal.svelte";
const channel = getContext("channel");
export let record
export let edge
export let graph
export let classes
export let field
let schema = channel.schemas.find((aschema) => aschema.name === record.schema);
let cardTitle = previewTitle({data:edge.data,schema:field.data}, graph);
let modal;
function edit(e){
e.preventDefault();
modal.open();
}
</script>
<button class="btn btn-primary btn-sm" on:click={edit}>{cardTitle}</button>
<PreviewRecord {record} {graph} {classes} />
<EdgeModal bind:this={modal} />
<style>
</style>
@@ -0,0 +1,55 @@
<script>
import Status from "../../records/Status.svelte";
import Preview from "../../files/Preview.svelte";
import {getContext} from "svelte";
import {previewTitle} from "../../records/Preview.js";
const channel = getContext("channel");
export let classes
export let record
export let graph
let schema = channel.schemas.find((aschema) => aschema.name === record.schema);
let cardTitle = previewTitle(record, graph);
</script>
<div
class="card mb-2 bg-light {classes}"
style="border-color:{schema.color ?? '#ccc'}; border-width: 1px;"
>
<div class="card-body d-flex">
{#if schema.type === "files"}
<div style="max-width:94px;margin-right:15px">
<Preview {record} size="small"/>
</div>
{/if}
<div class="overflow-hidden">
<a
class="title-link m-0 fs-5 text-decoration-none text-dark d-block"
href="{channel.lucentUrl}/records/{record.id}"
title={cardTitle}
>
{cardTitle}
</a>
<small class="text-muted">
{schema.label}
</small>
<small class="text-muted">
{#if record.status === "draft"}
<Status status={record.status}/>
{/if}
</small>
</div>
</div>
</div>
<style>
.title-link {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
</style>
+2 -4
View File
@@ -115,7 +115,7 @@
console.log("SAVE: SAVED"); console.log("SAVE: SAVED");
if (isCreateMode) { if (isCreateMode) {
window.location = channel.lucentUrl + "/records/" + record.id; window.location.href = channel.lucentUrl + "/records/" + record.id;
} else { } else {
record = response.data.records[0] ?? null; record = response.data.records[0] ?? null;
if (!record) { if (!record) {
@@ -141,9 +141,7 @@
} }
} }
resolve(null); resolve(null);
// msgSuccess = null;
// msgError = error.response.data.error;
// submitted = false;
}); });
}); });
} }
+1 -1
View File
@@ -29,7 +29,7 @@
<span class="text-dark d-block"> <span class="text-dark d-block">
{#if !isCreateMode} {#if !isCreateMode}
{previewTitle(channel.schemas, record, graph)} {previewTitle( record, graph)}
{:else} {:else}
New Record New Record
{/if} {/if}
+7 -5
View File
@@ -1,8 +1,10 @@
import Mustache from "mustache"; import Mustache from "mustache";
import {stripHtml} from "../../helpers"; import {stripHtml} from "../../helpers";
import {getContext} from "svelte";
export function previewTitle(schemas, record, graph) { export function previewTitle(record, graph) {
let schema = schemas.find((aSchema) => aSchema.name === record?.schema); const channel = getContext("channel");
let schema = channel.schemas.find((aSchema) => aSchema.name === record?.schema);
if (!schema?.titleTemplate) { if (!schema?.titleTemplate) {
return noTemplate(schema, record); return noTemplate(schema, record);
@@ -10,7 +12,7 @@ export function previewTitle(schemas, record, graph) {
let recordData = record.data; let recordData = record.data;
let template = Mustache.parse(schema.titleTemplate); let template = Mustache.parse(schema.titleTemplate);
console.log({template})
let referencePreviews = template let referencePreviews = template
.filter(segment => segment[0] === "name") // keep only template tags .filter(segment => segment[0] === "name") // keep only template tags
.map((segment) => segment[1]) // map to fieldNames .map((segment) => segment[1]) // map to fieldNames
@@ -20,7 +22,7 @@ export function previewTitle(schemas, record, graph) {
}).reduce((carry, field) => { // map to records }).reduce((carry, field) => { // map to records
let edge = graph.edges.find(edge => edge.source === record.id && edge.field === field) let edge = graph.edges.find(edge => edge.source === record.id && edge.field === field)
let referenceRecord = graph.records.find(rec => rec.id === edge?.target) let referenceRecord = graph.records.find(rec => rec.id === edge?.target)
carry[field] = previewTitle(schemas, referenceRecord, graph); carry[field] = previewTitle(referenceRecord, graph);
return carry; return carry;
}, {}); }, {});
recordData = {...recordData, ...referencePreviews} recordData = {...recordData, ...referencePreviews}
@@ -43,7 +45,7 @@ function noTemplate(schema, record) {
record?.data[schema.fields.filter((f) => f.info.name === "text")[0]?.name] record?.data[schema.fields.filter((f) => f.info.name === "text")[0]?.name]
).slice(0, 300); ).slice(0, 300);
if(title == ""){ if(title === ""){
return "Untitled"; return "Untitled";
} }
+1 -2
View File
@@ -13,10 +13,9 @@
export let hasDelete = false; export let hasDelete = false;
let schema = channel.schemas.find((aschema) => aschema.name === record.schema); let schema = channel.schemas.find((aschema) => aschema.name === record.schema);
let cardTitle = previewTitle(channel.schemas, record, graph); let cardTitle = previewTitle(record, graph);
function remove(e) { function remove(e) {
e.preventDefault(); e.preventDefault();
dispatch("remove", record.id); dispatch("remove", record.id);
} }
</script> </script>
@@ -7,7 +7,7 @@
export let graph; export let graph;
$: schema = channel.schemas.find((aschema) => aschema.name === record.schema); $: schema = channel.schemas.find((aschema) => aschema.name === record.schema);
$: title = previewTitle(channel.schemas, record, graph); $: title = previewTitle( record, graph);
</script> </script>
{#if record?.data} {#if record?.data}
+16 -4
View File
@@ -5,6 +5,7 @@
import PreviewCard from "../PreviewCard.svelte"; import PreviewCard from "../PreviewCard.svelte";
import Sortable from "../../libs/Sortable.svelte"; import Sortable from "../../libs/Sortable.svelte";
import BrowseModal from "./BrowseModal.svelte"; import BrowseModal from "./BrowseModal.svelte";
import Preview from "../../newPreview/Preview.svelte";
const channel = getContext("channel"); const channel = getContext("channel");
export let field; export let field;
@@ -16,8 +17,11 @@
$: references = graph?.edges $: references = graph?.edges
.filter((edge) => edge.field === field.name) .filter((edge) => edge.field === field.name)
.map((edge) => { .map((edge) => {
return graph.records.find((increc) => increc.id == edge.target && record.id == edge.source); return {
}).filter((rec) => (rec?.id ? true : false)) ?? []; record: graph.records.find((increc) => increc.id === edge.target && record.id === edge.source),
edge: edge,
}
}).filter((recordEdge) => (!!recordEdge.record?.id)) ?? [];
let collections = channel.schemas.filter((aschema) => let collections = channel.schemas.filter((aschema) =>
field.collections.includes(aschema.name) field.collections.includes(aschema.name)
@@ -101,14 +105,22 @@
</div> </div>
{#if references.length > 0} {#if references.length > 0}
<Sortable sortableClass="row row-cols-3 mt-3" on:update={reorder}> <Sortable sortableClass="row row-cols-3 mt-3" on:update={reorder}>
{#each references as reference (reference.id)} {#each references as reference (reference.record.id)}
<div class="col mb-3"> <div class="col mb-3">
<PreviewCard <PreviewCard
classes="h-100" classes="h-100"
record={reference} record={reference.record}
hasDelete={true} hasDelete={true}
on:remove={removeReference} on:remove={removeReference}
/> />
<!-- <Preview-->
<!-- classes="h-100"-->
<!-- record={reference.record}-->
<!-- edge={reference.edge}-->
<!-- hasDelete={true}-->
<!-- {field}-->
<!-- on:remove={removeReference}-->
<!-- />-->
</div> </div>
{/each} {/each}
</Sortable> </Sortable>
+1 -4
View File
@@ -14,10 +14,7 @@ class ArrayContainer implements ArrayAccess, JsonSerializable
{ {
} }
public function get(string $key, mixed $default = null): mixed
{
return $this->data[$key] ?? $default;
}
public function offsetSet($offset, $value): void public function offsetSet($offset, $value): void
{ {
+32
View File
@@ -0,0 +1,32 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('edges', function (Blueprint $table) {
$table->jsonb('data')->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('records', function (Blueprint $table) {
$table->dropColumn("data");
});
}
};
+5
View File
@@ -4,10 +4,12 @@ namespace Lucent\Edge;
use Lucent\LucentException; use Lucent\LucentException;
use Lucent\Validator\Validator as LucentValidator; use Lucent\Validator\Validator as LucentValidator;
use PhpOption\Option;
final class Edge final class Edge
{ {
/** /**
* @param Option<EdgeData> $data
* @throws LucentException * @throws LucentException
*/ */
public function __construct( public function __construct(
@@ -17,6 +19,7 @@ final class Edge
public string $sourceSchema, public string $sourceSchema,
public string $targetSchema, public string $targetSchema,
public string $field, public string $field,
public Option $data,
public string $rank = "a", public string $rank = "a",
public int $depth = 0, public int $depth = 0,
) )
@@ -40,6 +43,7 @@ final class Edge
public function toDB(): array public function toDB(): array
{ {
$data = $this->toArray(); $data = $this->toArray();
$data["data"] = json_encode($data["data"]);
unset($data["depth"]); unset($data["depth"]);
return $data; return $data;
} }
@@ -54,6 +58,7 @@ final class Edge
sourceSchema: data_get($data, 'sourceSchema'), sourceSchema: data_get($data, 'sourceSchema'),
targetSchema: data_get($data, 'targetSchema'), targetSchema: data_get($data, 'targetSchema'),
field: data_get($data, 'field'), field: data_get($data, 'field'),
data: Option::fromValue(data_get($data,"data")),
rank: data_get($data, 'rank'), rank: data_get($data, 'rank'),
depth: data_get($data, 'depth', 0), depth: data_get($data, 'depth', 0),
); );
+50
View File
@@ -0,0 +1,50 @@
<?php
namespace Lucent\Edge;
use Lucent\ArrayContainer;
class EdgeData extends ArrayContainer
{
public function merge(EdgeData $data): EdgeData
{
$this->data = array_merge($this->data, $data->toArray());
return $this;
}
public function get(string $key, mixed $default = null): mixed
{
return $this->data[$key] ?? $default;
}
public function set(string $key, mixed $value): EdgeData
{
$this->data[$key] = $value;
return $this;
}
public function isEmpty(string $key): bool
{
return empty($this->get($key));
}
public function isDefined(string $key): bool
{
return !empty($this->get($key));
}
public function toArray(): array
{
return $this->data;
}
public function jsonSerialize(): array
{
return $this->data;
}
}
+9 -1
View File
@@ -3,6 +3,7 @@
use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\DB;
use Lucent\LucentException; use Lucent\LucentException;
use PDOException; use PDOException;
use PhpOption\Option;
use stdClass; use stdClass;
class EdgeRepo class EdgeRepo
@@ -27,7 +28,7 @@ class EdgeRepo
public function update(string $from, EdgeCollection $edges): void public function update(string $from, EdgeCollection $edges): void
{ {
$edgesDB = collect($edges)->map(fn($e) => $e->toDB())->toArray(); $edgesDB = collect($edges)->map(fn(Edge $e) => $e->toDB())->toArray();
DB::table("edges")->where("source", $from)->delete(); DB::table("edges")->where("source", $from)->delete();
DB::table("edges")->insert($edgesDB); DB::table("edges")->insert($edgesDB);
} }
@@ -41,6 +42,12 @@ class EdgeRepo
public function mapEdge(stdClass $edge): Edge public function mapEdge(stdClass $edge): Edge
{ {
if(empty($edge->data)){
$data = none();
}else{
$data = some(new EdgeData(json_decode($edge->data)));
}
return new Edge( return new Edge(
source: $edge->source, source: $edge->source,
@@ -48,6 +55,7 @@ class EdgeRepo
sourceSchema: $edge->sourceSchema, sourceSchema: $edge->sourceSchema,
targetSchema: $edge->targetSchema, targetSchema: $edge->targetSchema,
field: $edge->field, field: $edge->field,
data: $data,
rank: $edge->rank, rank: $edge->rank,
depth: $edge->depth ?? 0 depth: $edge->depth ?? 0
); );
-1
View File
@@ -13,7 +13,6 @@ use Lucent\Query\Query;
use Lucent\Record\Manager; use Lucent\Record\Manager;
use Lucent\Record\QueryRecord; use Lucent\Record\QueryRecord;
use Lucent\Record\RecordService; use Lucent\Record\RecordService;
use Lucent\Schema\FieldInterface;
use Lucent\Schema\System; use Lucent\Schema\System;
use Lucent\Schema\Validator\ValidatorException; use Lucent\Schema\Validator\ValidatorException;
use Lucent\Svelte\Svelte; use Lucent\Svelte\Svelte;
@@ -8,7 +8,7 @@ use Lucent\JsonSchema\Definition;
use Lucent\JsonSchema\JsonSchemaService; use Lucent\JsonSchema\JsonSchemaService;
use Lucent\JsonSchema\SchemaData; use Lucent\JsonSchema\SchemaData;
use Lucent\Primitive\Collection; use Lucent\Primitive\Collection;
use Lucent\Schema\FieldInterface; use Lucent\Schema\Field\FieldInterface;
use Lucent\Schema\Schema; use Lucent\Schema\Schema;
use Lucent\Schema\Type; use Lucent\Schema\Type;
-3
View File
@@ -3,11 +3,8 @@
namespace Lucent\JsonSchema; namespace Lucent\JsonSchema;
use Lucent\JsonSchema\Property\Property; use Lucent\JsonSchema\Property\Property;
use Lucent\JsonSchema\Property\PropertyType;
use Lucent\JsonSchema\Property\RefProperty; use Lucent\JsonSchema\Property\RefProperty;
use Lucent\JsonSchema\Property\TypeProperty;
use Lucent\Primitive\Collection; use Lucent\Primitive\Collection;
use Lucent\Schema\FieldInterface;
use PhpOption\Option; use PhpOption\Option;
class Definition class Definition
@@ -22,7 +22,7 @@ class PgsqlDatabaseGraph implements DatabaseGraph
} }
$subquery->limit($options->childrenLimit) $subquery->limit($options->childrenLimit)
->unionAll( ->union(
DB::table(DB::raw("edges AS g, search_graph AS sg ")) 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') ->selectRaw('g.source,g.target,g.rank,"g"."sourceSchema","g"."targetSchema",g.field,sg.depth + 1 as depth')
->whereRaw("g.source = sg.target") ->whereRaw("g.source = sg.target")
@@ -43,9 +43,15 @@ class PgsqlDatabaseGraph implements DatabaseGraph
{ {
$subquery = DB::table('edges AS g') $subquery = DB::table('edges AS g')
->select(DB::raw('g.source,g.target,g.rank,"g"."sourceSchema","g"."targetSchema",g.field, 1 as depth ')) ->select(DB::raw('g.source,g.target,g.rank,"g"."sourceSchema","g"."targetSchema",g.field, 1 as depth '))
->whereIn('g.target', $ids);
if (!empty($options->parentFields)) {
$subquery->whereIn('field', $options->parentFields);
}
$subquery
->limit($options->parentsLimit) ->limit($options->parentsLimit)
->whereIn('g.target', $ids) ->union(
->unionAll(
DB::table(DB::raw("edges AS g, search_graph AS sg ")) 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') ->selectRaw('g.source,g.target,g.rank,"g"."sourceSchema","g"."targetSchema",g.field,sg.depth + 1 as depth')
->whereRaw("g.target = sg.source") ->whereRaw("g.target = sg.source")
@@ -21,7 +21,7 @@ class SqliteDatabaseGraph implements DatabaseGraph
} }
$subquery->limit($options->childrenLimit) $subquery->limit($options->childrenLimit)
->unionAll( ->union(
DB::table(DB::raw("edges AS g, search_graph AS sg ")) 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') ->selectRaw('g.source,g.target,g.rank,"g"."sourceSchema","g"."targetSchema",g.field,sg.depth + 1 as depth')
->whereRaw("g.source = sg.target") ->whereRaw("g.source = sg.target")
@@ -42,9 +42,15 @@ class SqliteDatabaseGraph implements DatabaseGraph
{ {
$subquery = DB::table('edges AS g') $subquery = DB::table('edges AS g')
->select(DB::raw('g.source,g.target,g.rank,"g"."sourceSchema","g"."targetSchema",g.field, 1 as depth ')) ->select(DB::raw('g.source,g.target,g.rank,"g"."sourceSchema","g"."targetSchema",g.field, 1 as depth '))
->whereIn('g.target', $ids);
if (!empty($options->parentFields)) {
$subquery->whereIn('field', $options->parentFields);
}
$subquery
->limit($options->parentsLimit) ->limit($options->parentsLimit)
->whereIn('g.target', $ids) ->union(
->unionAll(
DB::table(DB::raw("edges AS g, search_graph AS sg ")) 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') ->selectRaw('g.source,g.target,g.rank,"g"."sourceSchema","g"."targetSchema",g.field,sg.depth + 1 as depth')
->whereRaw("g.target = sg.source") ->whereRaw("g.target = sg.source")
+4 -4
View File
@@ -154,15 +154,15 @@ final class Operator
"null" => new Operator( "null" => new Operator(
name: "null", name: "null",
label: "Is null", label: "Is null",
symbol: "=", symbol: "is",
db: '$eq', db: '=',
uis: ["*"], uis: ["*"],
), ),
"nnull" => new Operator( "nnull" => new Operator(
name: "nnull", name: "nnull",
label: "Not null", label: "Not null",
symbol: "!=", symbol: "is not",
db: '$ne', db: '!=',
uis: ["*"], uis: ["*"],
), ),
"exists" => new Operator( "exists" => new Operator(
+5 -3
View File
@@ -3,7 +3,8 @@
namespace Lucent\Record; namespace Lucent\Record;
use Lucent\Channel\ChannelService; use Lucent\Channel\ChannelService;
use Lucent\Schema\FieldInterface; use Lucent\Schema\Field\FieldDataInterface;
use Lucent\Schema\Field\FieldInterface;
class InputFormatter class InputFormatter
{ {
@@ -17,8 +18,9 @@ class InputFormatter
public function fill(string $schemaName, RecordData $input): RecordData public function fill(string $schemaName, RecordData $input): RecordData
{ {
$schema = $this->channelService->getSchema($schemaName)->get(); $schema = $this->channelService->getSchema($schemaName)->get();
$data = $schema->fields->reduce(fn(array $carry, FieldInterface $field) => $field->format($input->toArray(), $carry), []); return $schema->fields
return new RecordData($data); ->filter(fn(FieldInterface $field)=> $field instanceof FieldDataInterface)
->reduce(fn(RecordData $carry, FieldDataInterface $field) => $field->format($input, $carry), new RecordData([]));
} }
+28 -1
View File
@@ -15,10 +15,37 @@ class RecordData extends ArrayContainer
return $this; return $this;
} }
public function get(string $key, mixed $default = null): mixed
{
return $this->data[$key] ?? $default;
}
public function set(string $key, mixed $value): RecordData
{
$this->data[$key] = $value;
return $this;
}
public function isEmpty(string $key): bool
{
return empty($this->get($key));
}
public function isDefined(string $key): bool
{
return !empty($this->get($key));
}
public function toArray(): array public function toArray(): array
{ {
return $this->data; return $this->data;
} }
public function jsonSerialize(): array
{
return $this->data;
}
} }
+5 -6
View File
@@ -13,7 +13,7 @@ use Lucent\Id\Id;
use Lucent\LucentException; use Lucent\LucentException;
use Lucent\Query\Query; use Lucent\Query\Query;
use Lucent\Revision\RevisionService; use Lucent\Revision\RevisionService;
use Lucent\Schema\FieldInterface; use Lucent\Schema\Field\FieldInterface;
use Lucent\Schema\Schema; use Lucent\Schema\Schema;
use Lucent\Schema\Validator\Validator; use Lucent\Schema\Validator\Validator;
use Lucent\Schema\Validator\ValidatorException; use Lucent\Schema\Validator\ValidatorException;
@@ -120,14 +120,13 @@ readonly class RecordService
$uniqueEdgesCollection = new EdgeCollection(); $uniqueEdgesCollection = new EdgeCollection();
if ($updateEdges) { if ($updateEdges) {
$uniqueEdges = collect($edges) $uniqueEdges = collect($edges)
->map(function ($edge, $index) { ->map(function ($edge, $index):Edge {
$edge["rank"] = $index; $edge["rank"] = $index;
$edgeData = (array)(new Edge(...$edge)); return Edge::fromArray($edge);
return $edgeData;
}) })
->unique(fn($e) => $e['field'] . $e['source'] . $e['target'] . $e['sourceSchema']) ->unique(fn(Edge $e) => $e->field . $e->source . $e->target . $e->sourceSchema)
->values()->toArray(); ->values()->toArray();
$uniqueEdgesCollection = EdgeCollection::fromArray($uniqueEdges); $uniqueEdgesCollection = new EdgeCollection(...$uniqueEdges);
} }
if (Status::from($status) === Status::PUBLISHED) { if (Status::from($status) === Status::PUBLISHED) {
+1
View File
@@ -3,6 +3,7 @@
namespace Lucent\Schema; namespace Lucent\Schema;
use Lucent\Primitive\Collection; use Lucent\Primitive\Collection;
use Lucent\Schema\Field\FieldInterface;
class BlockSchema implements Schema class BlockSchema implements Schema
{ {
+4 -10
View File
@@ -4,12 +4,11 @@ namespace Lucent\Schema\BlockUi;
use Lucent\JsonSchema\Property\Property; use Lucent\JsonSchema\Property\Property;
use Lucent\JsonSchema\Property\RefProperty; use Lucent\JsonSchema\Property\RefProperty;
use Lucent\JsonSchema\Property\TypeProperty;
use Lucent\Primitive\Collection; use Lucent\Primitive\Collection;
use Lucent\Schema\FieldInfo; use Lucent\Schema\Field\FieldDataInterface;
use Lucent\Schema\FieldInterface; use Lucent\Schema\Field\FieldInfo;
use Lucent\Schema\FieldType; use Lucent\Schema\Field\FieldInterface;
use Lucent\Schema\Type; use Lucent\Schema\Field\FieldType;
use Lucent\Schema\Validator\MinMaxInterface; use Lucent\Schema\Validator\MinMaxInterface;
use PhpOption\Option; use PhpOption\Option;
@@ -35,11 +34,6 @@ class File implements FieldInterface, MinMaxInterface
$this->info = new FieldInfo("file", "File", FieldType::FILE); $this->info = new FieldInfo("file", "File", FieldType::FILE);
} }
public function format(array $input, array $output): array
{
return $output;
}
public function failMin(mixed $value): bool public function failMin(mixed $value): bool
{ {
if (is_null($value)) { if (is_null($value)) {
+9 -8
View File
@@ -2,13 +2,13 @@
namespace Lucent\Schema\BlockUi; namespace Lucent\Schema\BlockUi;
use Lucent\Schema\FieldInfo; use Lucent\Record\RecordData;
use Lucent\Schema\FieldInterface; use Lucent\Schema\Field\FieldDataInterface;
use Lucent\Schema\FieldType; use Lucent\Schema\Field\FieldInfo;
use Lucent\Schema\Nullable; use Lucent\Schema\Field\FieldInterface;
use Lucent\Schema\Validator\RequiredInterface; use Lucent\Schema\Field\FieldType;
class Heading implements FieldInterface class Heading implements FieldInterface,FieldDataInterface
{ {
public FieldInfo $info; public FieldInfo $info;
@@ -23,9 +23,10 @@ class Heading implements FieldInterface
$this->info = new FieldInfo("heading", "Heading", FieldType::STRING); $this->info = new FieldInfo("heading", "Heading", FieldType::STRING);
} }
public function format(array $input, array $output): array public function format(RecordData $input, RecordData $output): RecordData
{ {
$output[$this->name] = $input[$this->name] ?? ""; $value = $input->get($this->name);
$output->set($this->name,$value);
return $output; return $output;
} }
+9 -8
View File
@@ -2,13 +2,13 @@
namespace Lucent\Schema\BlockUi; namespace Lucent\Schema\BlockUi;
use Lucent\Schema\FieldInfo; use Lucent\Record\RecordData;
use Lucent\Schema\FieldInterface; use Lucent\Schema\Field\FieldDataInterface;
use Lucent\Schema\FieldType; use Lucent\Schema\Field\FieldInfo;
use Lucent\Schema\Nullable; use Lucent\Schema\Field\FieldInterface;
use Lucent\Schema\Validator\RequiredInterface; use Lucent\Schema\Field\FieldType;
class Markdown implements FieldInterface class Markdown implements FieldInterface,FieldDataInterface
{ {
public FieldInfo $info; public FieldInfo $info;
@@ -23,9 +23,10 @@ class Markdown implements FieldInterface
$this->info = new FieldInfo("markdown", "Markdown Editor", FieldType::STRING); $this->info = new FieldInfo("markdown", "Markdown Editor", FieldType::STRING);
} }
public function format(array $input, array $output): array public function format(RecordData $input, RecordData $output): RecordData
{ {
$output[$this->name] = $input[$this->name] ?? ""; $value = $input->get($this->name);
$output->set($this->name,$value);
return $output; return $output;
} }
public function isRequired(): bool public function isRequired(): bool
+3 -7
View File
@@ -2,9 +2,9 @@
namespace Lucent\Schema\BlockUi; namespace Lucent\Schema\BlockUi;
use Lucent\Schema\FieldInfo; use Lucent\Schema\Field\FieldInfo;
use Lucent\Schema\FieldInterface; use Lucent\Schema\Field\FieldInterface;
use Lucent\Schema\FieldType; use Lucent\Schema\Field\FieldType;
use Lucent\Schema\Validator\MinMaxInterface; use Lucent\Schema\Validator\MinMaxInterface;
class Reference implements FieldInterface, MinMaxInterface class Reference implements FieldInterface, MinMaxInterface
@@ -27,10 +27,6 @@ class Reference implements FieldInterface, MinMaxInterface
$this->info = new FieldInfo("reference", "Reference", FieldType::REFERENCE); $this->info = new FieldInfo("reference", "Reference", FieldType::REFERENCE);
} }
public function format(array $input, array $output): array
{
return $output;
}
public function failMin(mixed $value): bool public function failMin(mixed $value): bool
{ {
+9 -8
View File
@@ -2,13 +2,13 @@
namespace Lucent\Schema\BlockUi; namespace Lucent\Schema\BlockUi;
use Lucent\Schema\FieldInfo; use Lucent\Record\RecordData;
use Lucent\Schema\FieldInterface; use Lucent\Schema\Field\FieldDataInterface;
use Lucent\Schema\FieldType; use Lucent\Schema\Field\FieldInfo;
use Lucent\Schema\Nullable; use Lucent\Schema\Field\FieldInterface;
use Lucent\Schema\Validator\RequiredInterface; use Lucent\Schema\Field\FieldType;
class Rich implements FieldInterface class Rich implements FieldInterface,FieldDataInterface
{ {
public FieldInfo $info; public FieldInfo $info;
@@ -23,9 +23,10 @@ class Rich implements FieldInterface
$this->info = new FieldInfo("rich", "Rich Editor", FieldType::STRING); $this->info = new FieldInfo("rich", "Rich Editor", FieldType::STRING);
} }
public function format(array $input, array $output): array public function format(RecordData $input, RecordData $output): RecordData
{ {
$output[$this->name] = $input[$this->name] ?? ""; $value = $input->get($this->name);
$output->set($this->name,$value);
return $output; return $output;
} }
public function isRequired(): bool public function isRequired(): bool
+9 -8
View File
@@ -2,13 +2,13 @@
namespace Lucent\Schema\BlockUi; namespace Lucent\Schema\BlockUi;
use Lucent\Schema\FieldInfo; use Lucent\Record\RecordData;
use Lucent\Schema\FieldInterface; use Lucent\Schema\Field\FieldDataInterface;
use Lucent\Schema\FieldType; use Lucent\Schema\Field\FieldInfo;
use Lucent\Schema\Nullable; use Lucent\Schema\Field\FieldInterface;
use Lucent\Schema\Validator\RequiredInterface; use Lucent\Schema\Field\FieldType;
class Textarea implements FieldInterface class Textarea implements FieldInterface,FieldDataInterface
{ {
public FieldInfo $info; public FieldInfo $info;
@@ -23,9 +23,10 @@ class Textarea implements FieldInterface
$this->info = new FieldInfo("textarea", "Textarea", FieldType::STRING); $this->info = new FieldInfo("textarea", "Textarea", FieldType::STRING);
} }
public function format(array $input, array $output): array public function format(RecordData $input, RecordData $output): RecordData
{ {
$output[$this->name] = $input[$this->name] ?? ""; $value = $input->get($this->name);
$output->set($this->name,$value);
return $output; return $output;
} }
public function isRequired(): bool public function isRequired(): bool
+1
View File
@@ -3,6 +3,7 @@
namespace Lucent\Schema; namespace Lucent\Schema;
use Lucent\Primitive\Collection; use Lucent\Primitive\Collection;
use Lucent\Schema\Field\FieldInterface;
class CollectionSchema implements Schema class CollectionSchema implements Schema
{ {
-1
View File
@@ -7,7 +7,6 @@ use Illuminate\Console\Command;
use Lucent\Schema\Schema; use Lucent\Schema\Schema;
use Lucent\Schema\SchemaService; use Lucent\Schema\SchemaService;
use Lucent\Schema\Type; use Lucent\Schema\Type;
use function Lucent\Commands\base_path;
class CompileSchemas extends Command class CompileSchemas extends Command
{ {
+25
View File
@@ -0,0 +1,25 @@
<?php
namespace Lucent\Schema;
use Lucent\Primitive\Collection;
use Lucent\Schema\Field\FieldDataInterface;
class EdgeSchema implements Schema
{
public Type $type = Type::EDGE;
/**
* @param Collection<FieldDataInterface> $fields
*/
function __construct(
public string $name,
public string $label,
public array $groups,
public Collection $fields,
public string $titleTemplate = "",
)
{
}
}
+15
View File
@@ -0,0 +1,15 @@
<?php
namespace Lucent\Schema\Field;
use Lucent\Record\RecordData;
interface FieldDataInterface
{
public function format(RecordData $input, RecordData $output): RecordData;
public function isRequired(): bool;
}
@@ -1,6 +1,6 @@
<?php <?php
namespace Lucent\Schema; namespace Lucent\Schema\Field;
class FieldInfo class FieldInfo
+10
View File
@@ -0,0 +1,10 @@
<?php
namespace Lucent\Schema\Field;
interface FieldInterface
{
}
@@ -1,6 +1,6 @@
<?php <?php
namespace Lucent\Schema; namespace Lucent\Schema\Field;
enum FieldType: string enum FieldType: string
-13
View File
@@ -1,13 +0,0 @@
<?php
namespace Lucent\Schema;
interface FieldInterface
{
public function format(array $input, array $output): array;
public function isRequired(): bool;
}
+1
View File
@@ -3,6 +3,7 @@
namespace Lucent\Schema; namespace Lucent\Schema;
use Lucent\Primitive\Collection; use Lucent\Primitive\Collection;
use Lucent\Schema\Field\FieldInterface;
class FilesSchema implements Schema class FilesSchema implements Schema
{ {
-27
View File
@@ -1,27 +0,0 @@
<?php
namespace Lucent\Schema;
final class Nullable
{
public function __construct(
public bool $nullable,
public mixed $value,
public mixed $default,
)
{
}
public function value(): mixed
{
if (!empty($this->value)) {
return $this->value;
}
if ($this->nullable) {
return null;
}
return $this->default;
}
}
+8
View File
@@ -3,6 +3,7 @@
namespace Lucent\Schema; namespace Lucent\Schema;
use Lucent\Primitive\Collection; use Lucent\Primitive\Collection;
use Lucent\Schema\Field\FieldInterface;
class SchemaService class SchemaService
{ {
@@ -46,6 +47,13 @@ class SchemaService
name: $schemaArr["name"], name: $schemaArr["name"],
label: $schemaArr["label"], label: $schemaArr["label"],
fields: (new Collection($schemaArr["fields"]))->map([$this, 'mapBlockFields']) fields: (new Collection($schemaArr["fields"]))->map([$this, 'mapBlockFields'])
),
"edge" => new EdgeSchema(
name: $schemaArr["name"],
label: $schemaArr["label"],
groups: $schemaArr["groups"] ?? [],
fields: (new Collection($schemaArr["fields"]))->map([$this, 'mapFields']),
titleTemplate: $schemaArr["titleTemplate"] ?? "",
) )
}; };
+1
View File
@@ -8,4 +8,5 @@ enum Type: string
case COLLECTION = 'collection'; case COLLECTION = 'collection';
case FILES = 'files'; case FILES = 'files';
case BLOCK = 'block'; case BLOCK = 'block';
case EDGE = 'edge';
} }
+9 -9
View File
@@ -5,21 +5,21 @@ namespace Lucent\Schema\Ui;
use Lucent\JsonSchema\Property\Property; use Lucent\JsonSchema\Property\Property;
use Lucent\JsonSchema\Property\PropertyType; use Lucent\JsonSchema\Property\PropertyType;
use Lucent\JsonSchema\Property\TypeProperty; use Lucent\JsonSchema\Property\TypeProperty;
use Lucent\Schema\FieldInfo; use Lucent\Record\RecordData;
use Lucent\Schema\FieldInterface; use Lucent\Schema\Field\FieldDataInterface;
use Lucent\Schema\FieldType; use Lucent\Schema\Field\FieldInfo;
use Lucent\Schema\Nullable; use Lucent\Schema\Field\FieldInterface;
use Lucent\Schema\Field\FieldType;
use Lucent\Schema\Validator\RequiredInterface; use Lucent\Schema\Validator\RequiredInterface;
use PhpOption\Option; use PhpOption\Option;
class Block implements FieldInterface, RequiredInterface class Block implements FieldInterface, FieldDataInterface, RequiredInterface
{ {
public FieldInfo $info; public FieldInfo $info;
public function __construct( public function __construct(
public string $name, public string $name,
public string $label, public string $label,
public bool $nullable = false,
public bool $required = false, public bool $required = false,
public string $default = "", public string $default = "",
public string $help = "", public string $help = "",
@@ -31,15 +31,15 @@ class Block implements FieldInterface, RequiredInterface
$this->info = new FieldInfo("block", "Block editor", FieldType::JSON); $this->info = new FieldInfo("block", "Block editor", FieldType::JSON);
} }
public function format(array $input, array $output): array public function format(RecordData $input, RecordData $output): RecordData
{ {
$value = $input[$this->name] ?? null; $value = $input->get($this->name);
if (is_string($value)) { if (is_string($value)) {
$value = json_decode($value, true); $value = json_decode($value, true);
} }
$output[$this->name] = (new Nullable($this->nullable, $value, []))->value(); $output->set($this->name, $value ?? []);
return $output; return $output;
} }
+11 -10
View File
@@ -5,15 +5,16 @@ namespace Lucent\Schema\Ui;
use Lucent\JsonSchema\Property\Property; use Lucent\JsonSchema\Property\Property;
use Lucent\JsonSchema\Property\PropertyType; use Lucent\JsonSchema\Property\PropertyType;
use Lucent\JsonSchema\Property\TypeProperty; use Lucent\JsonSchema\Property\TypeProperty;
use Lucent\Schema\FieldInfo; use Lucent\Record\RecordData;
use Lucent\Schema\FieldInterface; use Lucent\Schema\Field\FieldDataInterface;
use Lucent\Schema\FieldType; use Lucent\Schema\Field\FieldInfo;
use Lucent\Schema\Nullable; use Lucent\Schema\Field\FieldInterface;
use Lucent\Schema\Field\FieldType;
use Lucent\Schema\Validator\RequiredInterface; use Lucent\Schema\Validator\RequiredInterface;
use PhpOption\Option; use PhpOption\Option;
use function is_bool; use function is_bool;
class Checkbox implements FieldInterface, RequiredInterface class Checkbox implements FieldInterface,FieldDataInterface, RequiredInterface
{ {
public FieldInfo $info; public FieldInfo $info;
@@ -22,8 +23,8 @@ class Checkbox implements FieldInterface, RequiredInterface
public string $name, public string $name,
public string $label, public string $label,
public bool $required = false, public bool $required = false,
public bool $nullable = false,
public string $default = "", public string $default = "",
public bool $nullable = false,
public string $help = "", public string $help = "",
public bool $readonly = false, public bool $readonly = false,
public string $group = "", public string $group = "",
@@ -32,16 +33,16 @@ class Checkbox implements FieldInterface, RequiredInterface
$this->info = new FieldInfo("checkbox", "Block Checkbox", FieldType::BOOLEAN); $this->info = new FieldInfo("checkbox", "Block Checkbox", FieldType::BOOLEAN);
} }
public function format(array $input, array $output): array public function format(RecordData $input, RecordData $output): RecordData
{ {
$value = $input[$this->name] ?? null; $value = $input->get($this->name);
if (is_bool($value)) { if (is_bool($value)) {
$newValue = $value; $newValue = $value;
} else { } else {
$newValue = (new Nullable($this->nullable, $value, false))->value(); $newValue = $this->nullable ? null : false;
} }
$output[$this->name] = $newValue; $output->set($this->name, $newValue);
return $output; return $output;
} }
+9 -9
View File
@@ -5,14 +5,15 @@ namespace Lucent\Schema\Ui;
use Lucent\JsonSchema\Property\Property; use Lucent\JsonSchema\Property\Property;
use Lucent\JsonSchema\Property\PropertyType; use Lucent\JsonSchema\Property\PropertyType;
use Lucent\JsonSchema\Property\TypeProperty; use Lucent\JsonSchema\Property\TypeProperty;
use Lucent\Schema\FieldInfo; use Lucent\Record\RecordData;
use Lucent\Schema\FieldInterface; use Lucent\Schema\Field\FieldDataInterface;
use Lucent\Schema\FieldType; use Lucent\Schema\Field\FieldInfo;
use Lucent\Schema\Nullable; use Lucent\Schema\Field\FieldInterface;
use Lucent\Schema\Field\FieldType;
use Lucent\Schema\Validator\RequiredInterface; use Lucent\Schema\Validator\RequiredInterface;
use PhpOption\Option; use PhpOption\Option;
class Color implements FieldInterface, RequiredInterface class Color implements FieldInterface,FieldDataInterface, RequiredInterface
{ {
public FieldInfo $info; public FieldInfo $info;
@@ -21,7 +22,6 @@ class Color implements FieldInterface, RequiredInterface
public string $name, public string $name,
public string $label, public string $label,
public bool $required = false, public bool $required = false,
public bool $nullable = false,
public string $default = "", public string $default = "",
public string $help = "", public string $help = "",
public bool $readonly = false, public bool $readonly = false,
@@ -34,10 +34,10 @@ class Color implements FieldInterface, RequiredInterface
$this->info = new FieldInfo("color", "Color", FieldType::STRING); $this->info = new FieldInfo("color", "Color", FieldType::STRING);
} }
public function format(array $input, array $output): array public function format(RecordData $input, RecordData $output): RecordData
{ {
$value = $input[$this->name] ?? null; $value = $input->get($this->name);
$output[$this->name] = (new Nullable($this->nullable, $value, ""))->value(); $output->set($this->name,$value);
return $output; return $output;
} }
+12 -15
View File
@@ -6,15 +6,16 @@ use Carbon\Carbon;
use Lucent\JsonSchema\Property\Property; use Lucent\JsonSchema\Property\Property;
use Lucent\JsonSchema\Property\PropertyType; use Lucent\JsonSchema\Property\PropertyType;
use Lucent\JsonSchema\Property\TypeProperty; use Lucent\JsonSchema\Property\TypeProperty;
use Lucent\Schema\FieldInfo; use Lucent\Record\RecordData;
use Lucent\Schema\FieldInterface; use Lucent\Schema\Field\FieldDataInterface;
use Lucent\Schema\FieldType; use Lucent\Schema\Field\FieldInfo;
use Lucent\Schema\Nullable; use Lucent\Schema\Field\FieldInterface;
use Lucent\Schema\Field\FieldType;
use Lucent\Schema\Validator\MinMaxInterface; use Lucent\Schema\Validator\MinMaxInterface;
use Lucent\Schema\Validator\RequiredInterface; use Lucent\Schema\Validator\RequiredInterface;
use PhpOption\Option; use PhpOption\Option;
class Date implements FieldInterface, RequiredInterface, MinMaxInterface class Date implements FieldInterface,FieldDataInterface, RequiredInterface, MinMaxInterface
{ {
public FieldInfo $info; public FieldInfo $info;
@@ -22,7 +23,6 @@ class Date implements FieldInterface, RequiredInterface, MinMaxInterface
public string $name, public string $name,
public string $label, public string $label,
public bool $required = false, public bool $required = false,
public bool $nullable = false,
public ?Carbon $min = null, public ?Carbon $min = null,
public ?Carbon $max = null, public ?Carbon $max = null,
public string $default = "", public string $default = "",
@@ -37,19 +37,16 @@ class Date implements FieldInterface, RequiredInterface, MinMaxInterface
$this->info = new FieldInfo("date", "Date", FieldType::STRING); $this->info = new FieldInfo("date", "Date", FieldType::STRING);
} }
public function format(array $input, array $output): array public function format(RecordData $input, RecordData $output): RecordData
{ {
$value = $input[$this->name] ?? null; $value = $input->get($this->name);
if (empty($value)) { if (empty($value)) {
$newValue = (new Nullable($this->nullable, null, ""))->value(); return $output->set($this->name, null);
} else {
$date = Carbon::parse($value);
$dateFormatted = $date->format("Y-m-d");
$newValue = (new Nullable($this->nullable, $dateFormatted, ""))->value();
} }
$output[$this->name] = $newValue; $date = Carbon::parse($value);
return $output; $dateFormatted = $date->format("Y-m-d");
return $output->set($this->name, $dateFormatted);
} }
public function failRequired(mixed $value): bool public function failRequired(mixed $value): bool
+13 -17
View File
@@ -6,15 +6,16 @@ use Carbon\Carbon;
use Lucent\JsonSchema\Property\Property; use Lucent\JsonSchema\Property\Property;
use Lucent\JsonSchema\Property\PropertyType; use Lucent\JsonSchema\Property\PropertyType;
use Lucent\JsonSchema\Property\TypeProperty; use Lucent\JsonSchema\Property\TypeProperty;
use Lucent\Schema\FieldInfo; use Lucent\Record\RecordData;
use Lucent\Schema\FieldInterface; use Lucent\Schema\Field\FieldDataInterface;
use Lucent\Schema\FieldType; use Lucent\Schema\Field\FieldInfo;
use Lucent\Schema\Nullable; use Lucent\Schema\Field\FieldInterface;
use Lucent\Schema\Field\FieldType;
use Lucent\Schema\Validator\MinMaxInterface; use Lucent\Schema\Validator\MinMaxInterface;
use Lucent\Schema\Validator\RequiredInterface; use Lucent\Schema\Validator\RequiredInterface;
use PhpOption\Option; use PhpOption\Option;
class Datetime implements FieldInterface, RequiredInterface, MinMaxInterface class Datetime implements FieldInterface,FieldDataInterface, RequiredInterface, MinMaxInterface
{ {
public FieldInfo $info; public FieldInfo $info;
@@ -22,11 +23,10 @@ class Datetime implements FieldInterface, RequiredInterface, MinMaxInterface
public string $name, public string $name,
public string $label, public string $label,
public bool $required = false, public bool $required = false,
public bool $nullable = false,
public ?Carbon $min = null, public ?Carbon $min = null,
public ?Carbon $max = null, public ?Carbon $max = null,
public string $default = "", public string $default = "",
public string $help = "", public string $help = "",
public bool $readonly = false, public bool $readonly = false,
public string $optionsFrom = "", public string $optionsFrom = "",
public string $optionsField = "", public string $optionsField = "",
@@ -37,19 +37,15 @@ class Datetime implements FieldInterface, RequiredInterface, MinMaxInterface
$this->info = new FieldInfo("datetime", "Datetime", FieldType::STRING); $this->info = new FieldInfo("datetime", "Datetime", FieldType::STRING);
} }
public function format(array $input, array $output): array public function format(RecordData $input, RecordData $output): RecordData
{ {
$value = $input[$this->name] ?? null; $value = $input->get($this->name);
if (empty($value)) { if (empty($value)) {
$newValue = (new Nullable($this->nullable, null, ""))->value(); return $output->set($this->name, null);
} else {
$date = Carbon::parse($value);
$dateFormatted = $date->toJSON();
$newValue = (new Nullable($this->nullable, $dateFormatted, ""))->value();
} }
$date = Carbon::parse($value);
$output[$this->name] = $newValue; $dateFormatted = $date->toJSON();
return $output; return $output->set($this->name, $dateFormatted);
} }
public function failRequired(mixed $value): bool public function failRequired(mixed $value): bool
+4 -9
View File
@@ -4,11 +4,10 @@ namespace Lucent\Schema\Ui;
use Lucent\JsonSchema\Property\Property; use Lucent\JsonSchema\Property\Property;
use Lucent\JsonSchema\Property\RefProperty; use Lucent\JsonSchema\Property\RefProperty;
use Lucent\JsonSchema\Property\RefType;
use Lucent\Primitive\Collection; use Lucent\Primitive\Collection;
use Lucent\Schema\FieldInfo; use Lucent\Schema\Field\FieldInfo;
use Lucent\Schema\FieldInterface; use Lucent\Schema\Field\FieldInterface;
use Lucent\Schema\FieldType; use Lucent\Schema\Field\FieldType;
use Lucent\Schema\Validator\MinMaxInterface; use Lucent\Schema\Validator\MinMaxInterface;
use PhpOption\Option; use PhpOption\Option;
@@ -28,17 +27,13 @@ class File implements FieldInterface, MinMaxInterface
public ?int $min = null, public ?int $min = null,
public ?int $max = null, public ?int $max = null,
public array $collections = [], public array $collections = [],
public string $data = "",
public string $group = "", public string $group = "",
) )
{ {
$this->info = new FieldInfo("file", "File", FieldType::FILE); $this->info = new FieldInfo("file", "File", FieldType::FILE);
} }
public function format(array $input, array $output): array
{
return $output;
}
public function failMin(mixed $value): bool public function failMin(mixed $value): bool
{ {
if (is_null($value)) { if (is_null($value)) {
+10 -9
View File
@@ -5,14 +5,16 @@ namespace Lucent\Schema\Ui;
use Lucent\JsonSchema\Property\Property; use Lucent\JsonSchema\Property\Property;
use Lucent\JsonSchema\Property\PropertyType; use Lucent\JsonSchema\Property\PropertyType;
use Lucent\JsonSchema\Property\TypeProperty; use Lucent\JsonSchema\Property\TypeProperty;
use Lucent\Schema\FieldInfo; use Lucent\Record\RecordData;
use Lucent\Schema\FieldInterface; use Lucent\Schema\Field\FieldDataInterface;
use Lucent\Schema\FieldType; use Lucent\Schema\Field\FieldInfo;
use Lucent\Schema\Nullable; use Lucent\Schema\Field\FieldInterface;
use Lucent\Schema\Field\FieldType;
use Lucent\Schema\Validator\RequiredInterface; use Lucent\Schema\Validator\RequiredInterface;
use PhpOption\Option; use PhpOption\Option;
class Json implements FieldInterface, RequiredInterface
class Json implements FieldInterface,FieldDataInterface, RequiredInterface
{ {
public FieldInfo $info; public FieldInfo $info;
@@ -24,22 +26,21 @@ class Json implements FieldInterface, RequiredInterface
public string $default = "", public string $default = "",
public string $help = "", public string $help = "",
public bool $readonly = false, public bool $readonly = false,
public bool $nullable = false,
public string $group = "", public string $group = "",
) )
{ {
$this->info = new FieldInfo("json", "JSON", FieldType::JSON); $this->info = new FieldInfo("json", "JSON", FieldType::JSON);
} }
public function format(array $input, array $output): array public function format(RecordData $input, RecordData $output): RecordData
{ {
$value = $input[$this->name] ?? null; $value = $input->get($this->name);
if (is_string($value)) { if (is_string($value)) {
$value = json_decode($value, true); $value = json_decode($value, true);
} }
$output[$this->name] = (new Nullable($this->nullable, $value, []))->value(); $output->set($this->name,$value ?? []);
return $output; return $output;
} }
+9 -9
View File
@@ -5,14 +5,15 @@ namespace Lucent\Schema\Ui;
use Lucent\JsonSchema\Property\Property; use Lucent\JsonSchema\Property\Property;
use Lucent\JsonSchema\Property\PropertyType; use Lucent\JsonSchema\Property\PropertyType;
use Lucent\JsonSchema\Property\TypeProperty; use Lucent\JsonSchema\Property\TypeProperty;
use Lucent\Schema\FieldInfo; use Lucent\Record\RecordData;
use Lucent\Schema\FieldInterface; use Lucent\Schema\Field\FieldDataInterface;
use Lucent\Schema\FieldType; use Lucent\Schema\Field\FieldInfo;
use Lucent\Schema\Nullable; use Lucent\Schema\Field\FieldInterface;
use Lucent\Schema\Field\FieldType;
use Lucent\Schema\Validator\RequiredInterface; use Lucent\Schema\Validator\RequiredInterface;
use PhpOption\Option; use PhpOption\Option;
class Markdown implements FieldInterface, RequiredInterface class Markdown implements FieldInterface,FieldDataInterface, RequiredInterface
{ {
public FieldInfo $info; public FieldInfo $info;
@@ -20,7 +21,6 @@ class Markdown implements FieldInterface, RequiredInterface
public string $name, public string $name,
public string $label, public string $label,
public bool $required = false, public bool $required = false,
public bool $nullable = false,
public string $default = "", public string $default = "",
public string $help = "", public string $help = "",
public ?int $min = null, public ?int $min = null,
@@ -32,10 +32,10 @@ class Markdown implements FieldInterface, RequiredInterface
$this->info = new FieldInfo("markdown", "Markdown editor", FieldType::STRING); $this->info = new FieldInfo("markdown", "Markdown editor", FieldType::STRING);
} }
public function format(array $input, array $output): array public function format(RecordData $input, RecordData $output): RecordData
{ {
$value = $input[$this->name] ?? null; $value = $input->get($this->name);
$output[$this->name] = (new Nullable($this->nullable, $value, ""))->value(); $output->set($this->name,$value);
return $output; return $output;
} }
+9 -10
View File
@@ -5,15 +5,16 @@ namespace Lucent\Schema\Ui;
use Lucent\JsonSchema\Property\Property; use Lucent\JsonSchema\Property\Property;
use Lucent\JsonSchema\Property\PropertyType; use Lucent\JsonSchema\Property\PropertyType;
use Lucent\JsonSchema\Property\TypeProperty; use Lucent\JsonSchema\Property\TypeProperty;
use Lucent\Schema\FieldInfo; use Lucent\Record\RecordData;
use Lucent\Schema\FieldInterface; use Lucent\Schema\Field\FieldDataInterface;
use Lucent\Schema\FieldType; use Lucent\Schema\Field\FieldInfo;
use Lucent\Schema\Nullable; use Lucent\Schema\Field\FieldInterface;
use Lucent\Schema\Field\FieldType;
use Lucent\Schema\Validator\MinMaxInterface; use Lucent\Schema\Validator\MinMaxInterface;
use Lucent\Schema\Validator\RequiredInterface; use Lucent\Schema\Validator\RequiredInterface;
use PhpOption\Option; use PhpOption\Option;
class Number implements FieldInterface, RequiredInterface, MinMaxInterface class Number implements FieldInterface, RequiredInterface,FieldDataInterface, MinMaxInterface
{ {
public FieldInfo $info; public FieldInfo $info;
@@ -21,7 +22,6 @@ class Number implements FieldInterface, RequiredInterface, MinMaxInterface
public string $name, public string $name,
public string $label, public string $label,
public bool $required = false, public bool $required = false,
public bool $nullable = false,
public int $decimals = 0, public int $decimals = 0,
public ?int $min = null, public ?int $min = null,
public ?int $max = null, public ?int $max = null,
@@ -37,9 +37,9 @@ class Number implements FieldInterface, RequiredInterface, MinMaxInterface
$this->info = new FieldInfo("number", "Number", FieldType::NUMBER); $this->info = new FieldInfo("number", "Number", FieldType::NUMBER);
} }
public function format(array $input, array $output): array public function format(RecordData $input, RecordData $output): RecordData
{ {
$value = $input[$this->name] ?? null; $value = $input->get($this->name);
if (!is_numeric($value)) { if (!is_numeric($value)) {
$newValue = null; $newValue = null;
} else { } else {
@@ -51,8 +51,7 @@ class Number implements FieldInterface, RequiredInterface, MinMaxInterface
); );
$newValue = $this->decimals === 0 ? (int)$newValue : floatval($newValue); $newValue = $this->decimals === 0 ? (int)$newValue : floatval($newValue);
} }
$output->set($this->name,$newValue);
$output[$this->name] = (new Nullable($this->nullable, $newValue, 0))->value();
return $output; return $output;
} }
+4 -9
View File
@@ -4,11 +4,10 @@ namespace Lucent\Schema\Ui;
use Lucent\JsonSchema\Property\Property; use Lucent\JsonSchema\Property\Property;
use Lucent\JsonSchema\Property\RefProperty; use Lucent\JsonSchema\Property\RefProperty;
use Lucent\JsonSchema\Property\RefType;
use Lucent\Primitive\Collection; use Lucent\Primitive\Collection;
use Lucent\Schema\FieldInfo; use Lucent\Schema\Field\FieldInfo;
use Lucent\Schema\FieldInterface; use Lucent\Schema\Field\FieldInterface;
use Lucent\Schema\FieldType; use Lucent\Schema\Field\FieldType;
use Lucent\Schema\Validator\MinMaxInterface; use Lucent\Schema\Validator\MinMaxInterface;
use PhpOption\Option; use PhpOption\Option;
@@ -26,6 +25,7 @@ class Reference implements FieldInterface, MinMaxInterface
public ?int $min = null, public ?int $min = null,
public ?int $max = null, public ?int $max = null,
public array $collections = [], public array $collections = [],
public string $data = "",
public string $searchField = "", public string $searchField = "",
public string $layout = "", public string $layout = "",
public string $group = "", public string $group = "",
@@ -34,11 +34,6 @@ class Reference implements FieldInterface, MinMaxInterface
$this->info = new FieldInfo("reference", "Reference", FieldType::REFERENCE); $this->info = new FieldInfo("reference", "Reference", FieldType::REFERENCE);
} }
public function format(array $input, array $output): array
{
return $output;
}
public function failMin(mixed $value): bool public function failMin(mixed $value): bool
{ {
if (is_null($value)) { if (is_null($value)) {
+9 -9
View File
@@ -5,14 +5,15 @@ namespace Lucent\Schema\Ui;
use Lucent\JsonSchema\Property\Property; use Lucent\JsonSchema\Property\Property;
use Lucent\JsonSchema\Property\PropertyType; use Lucent\JsonSchema\Property\PropertyType;
use Lucent\JsonSchema\Property\TypeProperty; use Lucent\JsonSchema\Property\TypeProperty;
use Lucent\Schema\FieldInfo; use Lucent\Record\RecordData;
use Lucent\Schema\FieldInterface; use Lucent\Schema\Field\FieldDataInterface;
use Lucent\Schema\FieldType; use Lucent\Schema\Field\FieldInfo;
use Lucent\Schema\Nullable; use Lucent\Schema\Field\FieldInterface;
use Lucent\Schema\Field\FieldType;
use Lucent\Schema\Validator\RequiredInterface; use Lucent\Schema\Validator\RequiredInterface;
use PhpOption\Option; use PhpOption\Option;
class Rich implements FieldInterface, RequiredInterface class Rich implements FieldInterface,FieldDataInterface, RequiredInterface
{ {
public FieldInfo $info; public FieldInfo $info;
@@ -20,7 +21,6 @@ class Rich implements FieldInterface, RequiredInterface
public string $name, public string $name,
public string $label, public string $label,
public bool $required = false, public bool $required = false,
public bool $nullable = false,
public string $default = "", public string $default = "",
public string $help = "", public string $help = "",
public ?int $min = null, public ?int $min = null,
@@ -32,10 +32,10 @@ class Rich implements FieldInterface, RequiredInterface
$this->info = new FieldInfo("rich", "Rich editor", FieldType::STRING); $this->info = new FieldInfo("rich", "Rich editor", FieldType::STRING);
} }
public function format(array $input, array $output): array public function format(RecordData $input, RecordData $output): RecordData
{ {
$value = $input[$this->name] ?? null; $value = $input->get($this->name);
$output[$this->name] = (new Nullable($this->nullable, $value, ""))->value(); $output->set($this->name,$value);
return $output; return $output;
} }
+11 -11
View File
@@ -6,14 +6,15 @@ use Illuminate\Support\Str;
use Lucent\JsonSchema\Property\Property; use Lucent\JsonSchema\Property\Property;
use Lucent\JsonSchema\Property\PropertyType; use Lucent\JsonSchema\Property\PropertyType;
use Lucent\JsonSchema\Property\TypeProperty; use Lucent\JsonSchema\Property\TypeProperty;
use Lucent\Schema\FieldInfo; use Lucent\Record\RecordData;
use Lucent\Schema\FieldInterface; use Lucent\Schema\Field\FieldDataInterface;
use Lucent\Schema\FieldType; use Lucent\Schema\Field\FieldInfo;
use Lucent\Schema\Nullable; use Lucent\Schema\Field\FieldInterface;
use Lucent\Schema\Field\FieldType;
use Lucent\Schema\Validator\RequiredInterface; use Lucent\Schema\Validator\RequiredInterface;
use PhpOption\Option; use PhpOption\Option;
class Slug implements FieldInterface, RequiredInterface class Slug implements FieldInterface,FieldDataInterface, RequiredInterface
{ {
public FieldInfo $info; public FieldInfo $info;
@@ -21,7 +22,6 @@ class Slug implements FieldInterface, RequiredInterface
public string $name, public string $name,
public string $label, public string $label,
public bool $required = false, public bool $required = false,
public bool $nullable = false,
public ?int $min = null, public ?int $min = null,
public ?int $max = null, public ?int $max = null,
public string $default = "", public string $default = "",
@@ -34,14 +34,14 @@ class Slug implements FieldInterface, RequiredInterface
$this->info = new FieldInfo("slug", "Slug", FieldType::STRING); $this->info = new FieldInfo("slug", "Slug", FieldType::STRING);
} }
public function format(array $input, array $output): array public function format(RecordData $input, RecordData $output): RecordData
{ {
$value = !empty($input[$this->name]) ? (string)$input[$this->name] : null; $value = $input->get($this->name);
if(empty($value)){ if (empty($value)) {
$value = Str::slug($input[$this->source]); $value = Str::slug($input->get($this->source, ""));
} }
$output[$this->name] = (new Nullable($this->nullable, $value, ""))->value(); $output->set($this->name, $value);
return $output; return $output;
} }
+9 -9
View File
@@ -5,14 +5,15 @@ namespace Lucent\Schema\Ui;
use Lucent\JsonSchema\Property\Property; use Lucent\JsonSchema\Property\Property;
use Lucent\JsonSchema\Property\PropertyType; use Lucent\JsonSchema\Property\PropertyType;
use Lucent\JsonSchema\Property\TypeProperty; use Lucent\JsonSchema\Property\TypeProperty;
use Lucent\Schema\FieldInfo; use Lucent\Record\RecordData;
use Lucent\Schema\FieldInterface; use Lucent\Schema\Field\FieldDataInterface;
use Lucent\Schema\FieldType; use Lucent\Schema\Field\FieldInfo;
use Lucent\Schema\Nullable; use Lucent\Schema\Field\FieldInterface;
use Lucent\Schema\Field\FieldType;
use Lucent\Schema\Validator\RequiredInterface; use Lucent\Schema\Validator\RequiredInterface;
use PhpOption\Option; use PhpOption\Option;
class Text implements FieldInterface, RequiredInterface class Text implements FieldInterface,FieldDataInterface, RequiredInterface
{ {
public FieldInfo $info; public FieldInfo $info;
@@ -20,7 +21,6 @@ class Text implements FieldInterface, RequiredInterface
public string $name, public string $name,
public string $label, public string $label,
public bool $required = false, public bool $required = false,
public bool $nullable = false,
public ?int $min = null, public ?int $min = null,
public ?int $max = null, public ?int $max = null,
public string $help = "", public string $help = "",
@@ -36,10 +36,10 @@ class Text implements FieldInterface, RequiredInterface
$this->info = new FieldInfo("text", "Text", FieldType::STRING); $this->info = new FieldInfo("text", "Text", FieldType::STRING);
} }
public function format(array $input, array $output): array public function format(RecordData $input, RecordData $output): RecordData
{ {
$value = !empty($input[$this->name]) ? (string)$input[$this->name] : null; $value = $input->get($this->name);
$output[$this->name] = (new Nullable($this->nullable, $value, ""))->value(); $output->set($this->name,$value);
return $output; return $output;
} }
+9 -9
View File
@@ -5,14 +5,15 @@ namespace Lucent\Schema\Ui;
use Lucent\JsonSchema\Property\Property; use Lucent\JsonSchema\Property\Property;
use Lucent\JsonSchema\Property\PropertyType; use Lucent\JsonSchema\Property\PropertyType;
use Lucent\JsonSchema\Property\TypeProperty; use Lucent\JsonSchema\Property\TypeProperty;
use Lucent\Schema\FieldInfo; use Lucent\Record\RecordData;
use Lucent\Schema\FieldInterface; use Lucent\Schema\Field\FieldDataInterface;
use Lucent\Schema\FieldType; use Lucent\Schema\Field\FieldInfo;
use Lucent\Schema\Nullable; use Lucent\Schema\Field\FieldInterface;
use Lucent\Schema\Field\FieldType;
use Lucent\Schema\Validator\RequiredInterface; use Lucent\Schema\Validator\RequiredInterface;
use PhpOption\Option; use PhpOption\Option;
class Textarea implements FieldInterface, RequiredInterface class Textarea implements FieldInterface,FieldDataInterface, RequiredInterface
{ {
public FieldInfo $info; public FieldInfo $info;
@@ -21,7 +22,6 @@ class Textarea implements FieldInterface, RequiredInterface
public string $name, public string $name,
public string $label, public string $label,
public bool $required = false, public bool $required = false,
public bool $nullable = false,
public ?int $min = null, public ?int $min = null,
public ?int $max = null, public ?int $max = null,
public string $default = "", public string $default = "",
@@ -33,10 +33,10 @@ class Textarea implements FieldInterface, RequiredInterface
$this->info = new FieldInfo("textarea", "Textarea", FieldType::STRING); $this->info = new FieldInfo("textarea", "Textarea", FieldType::STRING);
} }
public function format(array $input, array $output): array public function format(RecordData $input, RecordData $output): RecordData
{ {
$value = !empty($input[$this->name]) ? (string)$input[$this->name] : null; $value = $input->get($this->name);
$output[$this->name] = (new Nullable($this->nullable, $value, ""))->value(); $output->set($this->name,$value);
return $output; return $output;
} }
+9 -9
View File
@@ -5,14 +5,15 @@ namespace Lucent\Schema\Ui;
use Lucent\JsonSchema\Property\Property; use Lucent\JsonSchema\Property\Property;
use Lucent\JsonSchema\Property\PropertyType; use Lucent\JsonSchema\Property\PropertyType;
use Lucent\JsonSchema\Property\TypeProperty; use Lucent\JsonSchema\Property\TypeProperty;
use Lucent\Schema\FieldInfo; use Lucent\Record\RecordData;
use Lucent\Schema\FieldInterface; use Lucent\Schema\Field\FieldDataInterface;
use Lucent\Schema\FieldType; use Lucent\Schema\Field\FieldInfo;
use Lucent\Schema\Nullable; use Lucent\Schema\Field\FieldInterface;
use Lucent\Schema\Field\FieldType;
use Lucent\Schema\Validator\RequiredInterface; use Lucent\Schema\Validator\RequiredInterface;
use PhpOption\Option; use PhpOption\Option;
class Uuid implements FieldInterface, RequiredInterface class Uuid implements FieldInterface,FieldDataInterface, RequiredInterface
{ {
public FieldInfo $info; public FieldInfo $info;
@@ -22,7 +23,6 @@ class Uuid implements FieldInterface, RequiredInterface
public string $label, public string $label,
public string $help = "", public string $help = "",
public bool $required = false, public bool $required = false,
public bool $nullable = false,
public bool $readonly = false, public bool $readonly = false,
public string $group = "", public string $group = "",
) )
@@ -30,10 +30,10 @@ class Uuid implements FieldInterface, RequiredInterface
$this->info = new FieldInfo("uuid", "FieldType", FieldType::STRING); $this->info = new FieldInfo("uuid", "FieldType", FieldType::STRING);
} }
public function format(array $input, array $output): array public function format(RecordData $input, RecordData $output): RecordData
{ {
$value = $input[$this->name] ?? null; $value = $input->get($this->name);
$output[$this->name] = (new Nullable($this->nullable, $value, ""))->value(); $output->set($this->name,$value);
return $output; return $output;
} }
+1 -1
View File
@@ -6,7 +6,7 @@ use Lucent\Channel\ChannelService;
use Lucent\Edge\EdgeCollection; use Lucent\Edge\EdgeCollection;
use Lucent\Primitive\Collection; use Lucent\Primitive\Collection;
use Lucent\Record\RecordData; use Lucent\Record\RecordData;
use Lucent\Schema\FieldInterface; use Lucent\Schema\Field\FieldInterface;
class Validator class Validator