singleton and embed records

This commit is contained in:
2024-10-05 15:19:53 +03:00
parent 07b72b0a2c
commit 52a1ec5c5a
18 changed files with 262 additions and 148 deletions
+28 -11
View File
@@ -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 @@
</div>
{#if references.length > 0}
<Sortable sortableClass="mt-3" on:update={reorder}>
{#each references as reference (reference.id)}
{#each references as reference (reference.record.id)}
<!--This div helps the sorting thing-->
<div>
<PreviewFile record={reference} hasDelete={true} on:remove={removeReference}></PreviewFile>
<PreviewFile
record={reference.record}
edge={reference.edge}
hasDelete={true}
on:remove={removeReference}
on:restore={restoreReference}
on:fulldelete={fullDelete}
></PreviewFile>
</div>
{/each}
</Sortable>
@@ -1,12 +1,17 @@
<script>
import {getContext} from "svelte";
import {insertEdges} from "./reference";
import {
fullDeleteRecord,
graphToReferences,
insertEdges,
removeReferenceFromGraph,
restoreReferenceToGraph
} from "./reference";
import {getErrorMessage} from "./errorMessage";
import {sortByField} from "../../edges/sortEdges";
import ReferenceInlineButtons from "./ReferenceInlineButtons.svelte";
import Sortable from "../../libs/Sortable.svelte";
import PreviewReference from "../previews/PreviewReference.svelte";
import axios from "axios";
const channel = getContext("channel");
export let record;
@@ -16,11 +21,7 @@
$: errorMessage = getErrorMessage(validationErrors, field.name);
$: 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)
@@ -28,27 +29,25 @@
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 reorder(e) {
graph.edges = sortByField(e.detail.source, e.detail.target, graph.edges, field.name, references);
}
function insert(e) {
e.preventDefault();
// axios.post(channel.lucentUrl + "/edges/insert-many", {
// source: record.id,
// sourceSchema: record.schema,
// targetSchema: e.detail.schema,
// field: field.name,
// targets: e.detail.records.map(r => r.id),
// }).then(function (response) {
// graph = response.data.graph;
// })
graph = insertEdges(graph, record, e.detail.records, field.name, e.detail.action);
}
@@ -69,13 +68,16 @@
</div>
{#if references.length > 0}
<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>
<PreviewReference
{graph}
record={reference}
record={reference.record}
edge={reference.edge}
hasDelete={true}
on:remove={removeReference}
on:restore={restoreReference}
on:fulldelete={fullDelete}
/>
</div>
{/each}
@@ -1,4 +1,5 @@
import {uniqBy} from "lodash";
import axios from "axios";
export function insertEdges(graph, sourceRecord, targetRecords, fieldName, action = "") {
let newEdges = targetRecords.map((r) => {
@@ -22,3 +23,49 @@ export function insertEdges(graph, sourceRecord, targetRecords, fieldName, actio
graph.edges = uniqBy([...replacedEdges, ...newEdges], (edge) => edge.source + edge.target + edge.field + edge.depth);
return graph;
}
export function graphToReferences(graph,record,field){
return graph.edges
.filter((edge) => edge.field === field.name)
.map((edge) => {
return {
record: graph.records.find((increc) => increc.id === edge.target && record.id === edge.source),
edge: edge
};
}).filter((rec) => (rec.record?.id ? true : false)) ?? [];
}
export function removeReferenceFromGraph(graph,field,id){
return graph.edges.map(
(edge) => {
if(edge.target === id && edge.field === field.name){
edge._isTrashed = true;
}
return edge;
}
);
}
export function restoreReferenceToGraph(graph,field,id){
return graph.edges.map(
(edge) => {
if(edge.target === id && edge.field === field.name){
edge._isTrashed = false;
}
return edge;
}
);
}
export function fullDeleteRecord(channel,graph,field,id){
axios
.post(channel.lucentUrl + "/records/status/trashed" , {
records: [id]
});
return graph.edges.filter(
(edge) => !(edge.target === id && edge.field === field.name)
);
}
@@ -11,6 +11,7 @@
const dispatch = createEventDispatcher();
const channel = getContext("channel");
export let record;
export let edge;
export let hasDelete = false;
export let hasInsert = false;
@@ -23,6 +24,16 @@
dispatch("remove", record.id);
}
function restore(e) {
e.preventDefault();
dispatch("restore", record.id);
}
function fullDelete(e) {
e.preventDefault();
dispatch("fulldelete", record.id);
}
function insert(e, preset) {
e.preventDefault();
let html = htmlurl(channel, record, preset)
@@ -37,7 +48,7 @@
</script>
<div class="preview-file">
<div class="preview-file" class:is-trashed={edge._isTrashed}>
<div style="display: flex;align-items: center;gap: 10px;">
<div class="image">
<Preview {record} size="small"/>
@@ -49,6 +60,9 @@
href="{channel.lucentUrl}/records/{record.id}"
>
{cardTitle}
{#if edge._isTrashed}
<span class="trashed-text">Trashed</span>
{/if}
</a>
<small class="d-block">
from {schema.label}
@@ -78,12 +92,30 @@
{/if}
{#if hasDelete}
<div class="reference-action">
<button
class="button"
on:click={remove}
>
<Icon icon="trash-can"/>
</button>
{#if edge._isTrashed}
<button
title="Restore"
class="button"
on:click={restore}
>
<Icon icon="undo"/>
</button>
<button
title="Delete from everywhere"
class="button"
on:click={fullDelete}
>
<Icon icon="destroy"/>
</button>
{:else}
<button
title="Remove"
class="button"
on:click={remove}
>
<Icon icon="trash-can"/>
</button>
{/if}
</div>
{/if}
</div>
@@ -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);
}
</script>
<div class="preview-reference">
<div class="preview-reference" class:is-trashed={edge._isTrashed}>
<div style="display: flex;align-items: center;gap: 10px;">
{#if cardImageRecord}
@@ -38,7 +49,12 @@
class="record-title"
href="{channel.lucentUrl}/records/{record.id}"
>
{cardTitle}
{#if edge._isTrashed}
<span class="trashed-text">Trashed</span>
{/if}
</a>
<small class="d-block">
from {schema.label}
@@ -53,12 +69,30 @@
</div>
{#if hasDelete}
<div class="reference-action">
<button
class="button"
on:click={remove}
>
<Icon icon="trash-can"/>
</button>
{#if edge._isTrashed}
<button
title="Restore"
class="button"
on:click={restore}
>
<Icon icon="undo"/>
</button>
<button
title="Delete from everywhere"
class="button"
on:click={fullDelete}
>
<Icon icon="destroy"/>
</button>
{:else}
<button
title="Remove"
class="button"
on:click={remove}
>
<Icon icon="trash-can"/>
</button>
{/if}
</div>
{/if}
</div>