Files
lucent-laravel/front/js/entry/RecordEditEntry/fields/RelationField.svelte
T

175 lines
5.5 KiB
Svelte
Raw Normal View History

2026-01-10 02:09:50 +02:00
<script>
import { get, post } from "../../../modules/remote";
import { getApp } from "../../../app";
2026-01-13 17:51:19 +02:00
import FieldLabel from "./FieldLabel.svelte";
import FieldError from "./FieldError.svelte";
import Sortable from "../../../common/Sortable.svelte";
2026-01-10 13:40:33 +02:00
let {
channel,
record,
schemaField,
dataField,
locale,
validationError,
edgeRecordPreviews,
} = $props();
2026-01-10 02:09:50 +02:00
let originalValue = dataField?.value ?? schemaField.props.default;
let newValue = $state(originalValue);
let valuesChanged = $derived(newValue !== originalValue);
let errorMessage = $state("");
// let validationErrorState = $state(validationError);
const app = getApp();
let suggestionsLoaded = $state(false);
let suggestions = $state([]);
2026-01-10 13:40:33 +02:00
let selectedRecordIds = $state([]);
let dialog = $state();
2026-01-10 02:09:50 +02:00
2026-01-10 13:40:33 +02:00
function handleModalOpen(e) {
2026-01-10 02:09:50 +02:00
// Add logic to handle adding a record
2026-01-10 13:40:33 +02:00
dialog.showModal();
2026-01-10 02:09:50 +02:00
if (suggestionsLoaded) {
return;
}
get(
app.url("records/suggest"),
{ schemas: schemaField.props.schemas },
(data, err) => {
suggestionsLoaded = true;
suggestions = data;
},
);
}
2026-01-10 13:40:33 +02:00
function handleModalClose(e) {
dialog.close();
}
2026-01-10 02:09:50 +02:00
2026-01-10 13:40:33 +02:00
function handleInsertSelected() {
suggestionsLoaded = false;
2026-01-10 02:09:50 +02:00
post(
2026-01-10 13:40:33 +02:00
app.url("edges/many"),
2026-01-10 02:09:50 +02:00
{
2026-01-10 13:40:33 +02:00
toIds: selectedRecordIds,
from: record.id,
fieldId: schemaField.id,
2026-01-10 02:09:50 +02:00
locale: locale,
},
(data, err) => {
2026-01-10 13:40:33 +02:00
suggestionsLoaded = true;
dialog.close();
2026-01-13 17:51:19 +02:00
edgeRecordPreviews = data.edgeRecordPreviews;
validationError = data.validationError;
},
);
}
function handleSortUpdate(updatedEdges) {
// let updatedFieldIds = updatedFields.map((f) => f.id);
// fields = fields.filter((f) => !updatedFieldIds.includes(f.id));
// fields = [...fields, ...updatedFields];
post(
app.url("records/sort-edges"),
{
ids: updatedEdges.map((e) => e.edge.id),
},
(data, err) => {
edgeRecordPreviews = updatedEdges;
},
);
}
function handleRemoveEdge(edgeId) {
post(
app.url("edges/delete"),
{
id: edgeId,
from: record.id,
fieldId: schemaField.id,
locale: locale,
},
(data, err) => {
edgeRecordPreviews = edgeRecordPreviews.filter(
(e) => e.edge.id !== edgeId,
);
validationError = data.validationError;
2026-01-10 02:09:50 +02:00
},
);
}
</script>
<div style="min-width: 400px;">
<label>
2026-01-13 17:51:19 +02:00
<FieldLabel {locale} {channel} {schemaField}></FieldLabel>
2026-01-10 13:40:33 +02:00
</label>
2026-01-13 17:51:19 +02:00
<FieldError {schemaField} {validationError}></FieldError>
2026-01-10 13:40:33 +02:00
<button onclick={handleModalOpen}>Choose record</button>
<dialog bind:this={dialog}>
<article>
<header>
<button onclick={handleModalClose} aria-label="Close" rel="prev"
></button>
<p>
<strong>Records</strong>
</p>
</header>
2026-01-10 02:09:50 +02:00
{#if suggestionsLoaded}
2026-01-10 13:40:33 +02:00
<form>
<button onclick={handleInsertSelected}>
Insert selected
</button>
<table>
<tbody>
{#each suggestions as suggestion}
<tr>
<td>
<input
type="checkbox"
value={suggestion.id}
bind:group={selectedRecordIds}
/>
</td>
<td>
<a href="#">{suggestion.title}</a>
</td>
<td>
<a href="#">
{suggestion.schemaName}
</a>
</td>
</tr>
{/each}
</tbody>
</table>
</form>
2026-01-10 02:09:50 +02:00
{:else}
<progress />
{/if}
2026-01-10 13:40:33 +02:00
</article>
</dialog>
<div>
{#if edgeRecordPreviews.length == 0}
No relations exist
{:else}
2026-01-13 17:51:19 +02:00
<Sortable
onUpdate={handleSortUpdate}
items={edgeRecordPreviews}
itemKey="edge.id"
>
{#snippet itemView(edgeRecordPreview)}
<div>
<a href="#">{edgeRecordPreview.recordPreview.title}</a>
{edgeRecordPreview.recordPreview.schemaName}
<button
onclick={(e) =>
handleRemoveEdge(edgeRecordPreview.edge.id)}
>remove</button
>
</div>
{/snippet}
</Sortable>
2026-01-10 02:09:50 +02:00
{/if}
2026-01-10 13:40:33 +02:00
</div>
2026-01-10 02:09:50 +02:00
</div>