Files
lucent-laravel/front/js/svelte/records/Edit.svelte
T
2026-01-07 21:42:18 +02:00

209 lines
6.7 KiB
Svelte

<script>
import { afterUpdate, getContext, onMount } from "svelte";
import axios from "axios";
import EditHeader from "./header/EditHeader.svelte";
import FilePreview from "./FilePreview.svelte";
import ContentTabs from "./header/ContentTabs.svelte";
import FormField from "./FormField.svelte";
import Graph from "./Graph.svelte";
import Info from "./Info.svelte";
import ErrorAlert from "../common/ErrorAlert.svelte";
import Title from "./header/Title.svelte";
const channel = getContext("channel");
export let schema;
export let record;
export let graph = {
records: [],
edges: [],
};
// export let recordHistory;
export let isCreateMode;
// export let isWritable = false;
export let users;
let originalContent;
let activeContentTab = "";
$: hasUnsavedData = false;
$: validationErrors = null;
$: errorMessage = validationErrors
? `Record submission failed. ${
Object.entries(validationErrors).length
} error(s)`
: null;
let activeFields = schema.fields.filter((f) => f.name !== "id");
onMount(() => {
setOriginalContent();
});
function setOriginalContent() {
originalContent = {
data: JSON.parse(JSON.stringify(record.data)),
schema: record.schema,
status: record.status,
_sys: JSON.parse(JSON.stringify(record._sys)),
_file: JSON.parse(JSON.stringify(record._file)),
edges: JSON.parse(JSON.stringify(graph.edges)),
};
}
afterUpdate(() => {
hasUnsavedData = checkUnsavedData();
});
function beforeUnload(e) {
// Cancel the event as stated by the standard.
// e.preventDefault();
// console.log(hasUnsavedData);
if (hasUnsavedData) {
return (e.returnValue =
"You have unsaved changes. Are you sure you want to exit?");
}
// Chrome requires returnValue to be set.
// e.returnValue = "";
delete e["returnValue"];
// more compatibility
// return true;
return "...";
}
function checkUnsavedData() {
if (isCreateMode) {
return false;
}
return !isEqual(originalContent, {
data: record.data,
schema: record.schema,
status: record.status,
_sys: record._sys,
_file: record._file,
edges: graph.edges,
});
}
function save(e) {
e.preventDefault();
console.log("SAVE: Attempt");
validationErrors = null;
errorMessage = "";
return new Promise(function (resolve, reject) {
if (!hasUnsavedData && !isCreateMode) {
resolve(null);
return;
}
if (!record) {
resolve(null);
return;
}
// remove trashed edges
graph.edges = graph.edges?.filter(
(edge) => !edge._isTrashed && edge.source === record.id,
);
axios
.post(channel.lucentUrl + "/records", {
record: record,
edges: graph.edges,
isCreateMode: isCreateMode,
})
.then(function (response) {
console.log("SAVE: SAVED");
if (isCreateMode) {
window.location =
channel.lucentUrl + "/records/" + record.id;
} else {
record = response.data.records[0] ?? null;
if (!record) {
// means trashed
hasUnsavedData = false;
window.location = channel.lucentUrl;
return;
}
graph = response.data;
setOriginalContent();
}
resolve(null);
})
.catch(function (error) {
// setOriginalContent();
if (error.response) {
if (typeof error.response.data.error === "string") {
errorMessage = error.response.data.error;
} else {
validationErrors = error.response.data.error;
console.log(validationErrors);
}
}
resolve(null);
// msgSuccess = null;
// msgError = error.response.data.error;
// submitted = false;
});
});
}
</script>
<svelte:window on:beforeunload={beforeUnload} />
<div class="record-edit">
<div class="tools-header">
<!-- <Manager managerRecords={recordHistory} {graph}/>-->
<EditHeader {schema} bind:record {isCreateMode} bind:activeContentTab />
{#if isCreateMode}
<button class="button primary btn-spinner" on:click={save}>
<span
class="spinner-border spinner-border-sm"
role="status"
aria-hidden="true"
/>
Create
</button>
{:else if hasUnsavedData}
<button
type="button"
class="button primary ms-2 btn btn-primary btn-spinner"
on:click={save}
>
<span
class="spinner-border spinner-border-sm"
role="status"
aria-hidden="true"
/>
Save
</button>
{/if}
</div>
<Title {schema} {record} {isCreateMode} />
<ErrorAlert message={errorMessage} />
<div class=" mt-4" style="margin-bottom:150px;position:relative;">
<ContentTabs {schema} {isCreateMode} bind:active={activeContentTab} />
{#if !["_graph", "_info"].includes(activeContentTab)}
<FilePreview {record} {schema} />
{#each activeFields as field (field.name)}
{#if activeContentTab === field.group}
<FormField
bind:data={record.data}
bind:graph
{field}
{schema}
{record}
{validationErrors}
{isCreateMode}
/>
{/if}
{/each}
{:else if activeContentTab === "_graph"}
<Graph {graph} {record} />
{:else if activeContentTab === "_info"}
<Info {record} {graph} {users} {schema} />
{/if}
</div>
</div>