diff --git a/front/js/svelte/common/Icon.svelte b/front/js/svelte/common/Icon.svelte index 66000bc..61458d8 100644 --- a/front/js/svelte/common/Icon.svelte +++ b/front/js/svelte/common/Icon.svelte @@ -124,10 +124,17 @@ "italic": { path: '', viewBox: "0 0 24 24", + }, + "undo": { + path: '', + viewBox: "0 0 24 24", + }, + "destroy": { + path: '', + viewBox: "0 0 24 24", } }; - export let width = 16; export let height = 16; export let icon = ""; diff --git a/front/js/svelte/content/ActionsOnSelected.svelte b/front/js/svelte/content/ActionsOnSelected.svelte index e9e08ff..e1f9137 100644 --- a/front/js/svelte/content/ActionsOnSelected.svelte +++ b/front/js/svelte/content/ActionsOnSelected.svelte @@ -1,5 +1,6 @@ diff --git a/front/js/svelte/layout/NavbarMenu.svelte b/front/js/svelte/layout/NavbarMenu.svelte deleted file mode 100644 index e4ee6ca..0000000 --- a/front/js/svelte/layout/NavbarMenu.svelte +++ /dev/null @@ -1,39 +0,0 @@ - - - -{#if expanded} - {#each schemas as aschema} - {aschema.label} - {/each} - - {#each schemas as aschema} - {aschema.label} - {/each} -{/if} \ No newline at end of file diff --git a/front/js/svelte/records/elements/File.svelte b/front/js/svelte/records/elements/File.svelte index 0b2dafe..26a9442 100644 --- a/front/js/svelte/records/elements/File.svelte +++ b/front/js/svelte/records/elements/File.svelte @@ -4,7 +4,13 @@ import PreviewFile from "../previews/PreviewFile.svelte"; import Dropdown from "../../common/Dropdown.svelte"; import Dialog from "../../dialog/Dialog.svelte"; - import {insertEdges} from "./reference.js"; + import { + fullDeleteRecord, + graphToReferences, + insertEdges, + removeReferenceFromGraph, + restoreReferenceToGraph + } from "./reference.js"; import {getContext} from "svelte"; const channel = getContext("channel"); @@ -12,11 +18,7 @@ export let record; export let graph let browseModal; - $: references = graph?.edges - .filter((edge) => edge.field === field.name) - .map((edge) => { - return graph.records.find((increc) => increc.id === edge.target && record.id === edge.source); - }).filter((rec) => (rec?.id ? true : false)) ?? []; + $: references = graphToReferences(graph, record, field) let collections = channel.schemas.filter((aschema) => field.collections.includes(aschema.name) @@ -24,9 +26,17 @@ function removeReference(e) { e.preventDefault(); - graph.edges = graph.edges.filter( - (edge) => !(edge.target === e.detail && edge.field === field.name) - ); + graph.edges = removeReferenceFromGraph(graph, field, e.detail) + } + + function restoreReference(e) { + e.preventDefault(); + graph.edges = restoreReferenceToGraph(graph, field, e.detail) + } + + function fullDelete(e) { + e.preventDefault(); + graph.edges = fullDeleteRecord(channel,graph, field, e.detail) } function openBrowseModal(e, schema) { @@ -73,10 +83,17 @@ {#if references.length > 0} - {#each references as reference (reference.id)} + {#each references as reference (reference.record.id)}
- +
{/each}
diff --git a/front/js/svelte/records/elements/Reference.svelte b/front/js/svelte/records/elements/Reference.svelte index 11d64ca..4ae4e3f 100644 --- a/front/js/svelte/records/elements/Reference.svelte +++ b/front/js/svelte/records/elements/Reference.svelte @@ -1,12 +1,17 @@ -
+
@@ -49,6 +60,9 @@ href="{channel.lucentUrl}/records/{record.id}" > {cardTitle} + {#if edge._isTrashed} + Trashed + {/if} from {schema.label} @@ -78,12 +92,30 @@ {/if} {#if hasDelete}
- + {#if edge._isTrashed} + + + {:else} + + {/if}
{/if}
diff --git a/front/js/svelte/records/previews/PreviewReference.svelte b/front/js/svelte/records/previews/PreviewReference.svelte index 12845cc..5d3e2f0 100644 --- a/front/js/svelte/records/previews/PreviewReference.svelte +++ b/front/js/svelte/records/previews/PreviewReference.svelte @@ -10,21 +10,32 @@ const channel = getContext("channel"); export let graph; export let record; + export let edge; export let hasDelete = false; let schema = channel.schemas.find((aschema) => aschema.name === record.schema); let cardTitle = previewTitle(channel.schemas, record, graph); - const cardImageEdge = graph.edges.find(e => e.source === record.id && e.field === schema.cardImage); + const cardImageEdge = graph.edges.find(e => e.source === record.id && e.field === schema.cardImage); let cardImageRecord = graph.records.find(r => r.id === cardImageEdge?.target); function remove(e) { e.preventDefault(); dispatch("remove", record.id); } + + function restore(e) { + e.preventDefault(); + dispatch("restore", record.id); + } + + function fullDelete(e) { + e.preventDefault(); + dispatch("fulldelete", record.id); + } -
+
{#if cardImageRecord} @@ -38,7 +49,12 @@ class="record-title" href="{channel.lucentUrl}/records/{record.id}" > + {cardTitle} + {#if edge._isTrashed} + Trashed + {/if} + from {schema.label} @@ -53,12 +69,30 @@
{#if hasDelete}
- + {#if edge._isTrashed} + + + {:else} + + {/if}
{/if}
diff --git a/front/sass/_preview.scss b/front/sass/_preview.scss index 1d93d1e..a79af78 100644 --- a/front/sass/_preview.scss +++ b/front/sass/_preview.scss @@ -5,6 +5,17 @@ gap: 10px; background: var(--p10); border-radius: 12px; + + &.is-trashed{ + border: 2px solid var(--err10); + background: var(--p20); + } +.trashed-text{ + background: var(--err10); + font-size: 12px; + padding:2px 10px; +} + .image{ diff --git a/src/Http/Controller/RecordController.php b/src/Http/Controller/RecordController.php index dc9d747..c26078c 100644 --- a/src/Http/Controller/RecordController.php +++ b/src/Http/Controller/RecordController.php @@ -16,6 +16,7 @@ use Lucent\Record\Manager; use Lucent\Record\QueryRecord; use Lucent\Record\RecordService; use Lucent\Record\Status; +use Lucent\Schema\SingletonSchema; use Lucent\Schema\System; use Lucent\Schema\Validator\ValidatorException; use Lucent\Svelte\Svelte; @@ -50,8 +51,9 @@ class RecordController extends Controller $users = $this->accountService->all(); $schema = $this->channelService->getSchema($schemaName)->get(); + $urlParams = $request->all(); - $sort = data_get($urlParams, "sort") ?? $schema->sortBy; + $sort = data_get($urlParams, "sort") ?? $schema->sortBy ?? ""; $filter = data_get($urlParams, "filter") ?? []; $arguments = array_merge([ @@ -80,6 +82,13 @@ class RecordController extends Controller $records = $graph->getRootRecords()->toArray(); + if(get_class($schema) === SingletonSchema::class){ + $id = $records[0]->id ?? null; + if(empty($id)){ + return redirect($this->channelService->channel->lucentUrl."/records/new?schema=".$schemaName); + } + return redirect($this->channelService->channel->lucentUrl."/records/".$id); + } $data = [ "schemas" => $this->channelService->channel->schemas, @@ -341,20 +350,15 @@ class RecordController extends Controller public function status(Request $request) { - - $ids = array_map(fn($rec) => $rec["id"], $request->input("records")); - - $this->recordService->changeStatusBulk( status: $request->route("status"), - recordsIds: $ids, + recordsIds: $request->input("records"), ); return ok(); } public function emptyTrash(Request $request) { - $this->recordService->emptyTrash($request->route("schemaName")); return redirect($this->channelService->channel->lucentUrl . "/content/" . $request->route("schemaName")); } diff --git a/src/Schema/CollectionSchema.php b/src/Schema/CollectionSchema.php index 5da789c..97cb8d5 100644 --- a/src/Schema/CollectionSchema.php +++ b/src/Schema/CollectionSchema.php @@ -15,7 +15,6 @@ class CollectionSchema implements Schema function __construct( public string $name, public string $label, - public array $visible, public array $groups, public Collection $fields, diff --git a/src/Schema/SchemaService.php b/src/Schema/SchemaService.php index 33f8aec..371625a 100644 --- a/src/Schema/SchemaService.php +++ b/src/Schema/SchemaService.php @@ -32,6 +32,19 @@ class SchemaService read: $schemaArr["read"] ?? [], write: $schemaArr["write"] ?? [], ), + "singleton" => new SingletonSchema( + name: $schemaArr["name"], + label: $schemaArr["label"], + groups: $schemaArr["groups"] ?? [], + fields: (new Collection($schemaArr["fields"]))->map([$this, 'mapFields']), + folder: $schemaArr["folder"] ?? "", + color: $schemaArr["color"] ?? "", + cardTitle: $schemaArr["titleTemplate"] ?? $schemaArr["cardTitle"] ?? null, + cardImage: $schemaArr["cardImage"] ?? null, + revisions: $schemaArr["revisions"] ?? 0, + read: $schemaArr["read"] ?? [], + write: $schemaArr["write"] ?? [], + ), "files" => new FilesSchema( name: $schemaArr["name"], label: $schemaArr["label"], diff --git a/src/Schema/SingletonSchema.php b/src/Schema/SingletonSchema.php new file mode 100644 index 0000000..2f6cc99 --- /dev/null +++ b/src/Schema/SingletonSchema.php @@ -0,0 +1,30 @@ + $fields + */ + function __construct( + public string $name, + public string $label, + public array $groups, + public Collection $fields, + public string $folder = "", + public string $color = "", + public ?string $cardTitle = null, + public ?string $cardImage = null, + public int $revisions = 0, + public array $read = [], + public array $write = [], + ) + { + } + +} diff --git a/src/ViewModel/ViewModel.php b/src/ViewModel/ViewModel.php index ee5098f..f171d18 100644 --- a/src/ViewModel/ViewModel.php +++ b/src/ViewModel/ViewModel.php @@ -7,6 +7,7 @@ use Lucent\Record\QueryRecord; use Lucent\Schema\CollectionSchema; use Lucent\Schema\FieldInterface; use Lucent\Schema\FilesSchema; +use Lucent\Schema\SingletonSchema; use Mustache_Engine; class ViewModel @@ -23,7 +24,7 @@ class ViewModel $schema = $this->channelService->getSchema($record->schema)->get(); if (empty($schema->titleTemplate)) { $title = match (get_class($schema)) { - CollectionSchema::class => $record->data[$schema->fields->filter(fn(FieldInterface $f) => $f->info->name === "text")->first()->name], + CollectionSchema::class,SingletonSchema::class => $record->data[$schema->fields->filter(fn(FieldInterface $f) => $f->info->name === "text")->first()->name], FilesSchema::class => $record->_file->path, };