Files
lucent-laravel/front/js/svelte/records/InlineEdit.svelte
T
2024-10-10 16:44:08 +03:00

210 lines
6.4 KiB
Svelte

<script>
import {afterUpdate, createEventDispatcher, getContext, onMount} from "svelte";
import {hasDataChanged} from "./editor.js";
import FormField from "./FormField.svelte";
import FilePreview from "./FilePreview.svelte";
import ContentTabs from "./header/ContentTabs.svelte";
import ErrorAlert from "../common/ErrorAlert.svelte";
import EditHeader from "./header/EditHeader.svelte";
import axios from "axios";
import Title from "./header/Title.svelte";
const channel = getContext("channel");
const dispatch = createEventDispatcher();
export let schema;
export let record;
export let graph = {
records: [],
edges: []
};
export let isCreateMode;
let originalContent;
let activeContentTab = "";
let 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"
);
let tabname = "_default";
let fieldToTabs = schema.fields.reduce((c, f) => {
if (f.ui === "tab") {
tabname = f.name;
return c;
}
c[tabname] = [...(c[tabname] ?? []), f.name];
return c;
}, []);
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() {
return hasDataChanged(isCreateMode, originalContent, {
data: record.data,
schema: record.schema,
status: record.status,
_sys: record._sys,
_file: record._file,
edges: graph.edges,
});
}
function cancel(e) {
e.preventDefault();
dispatch("cancel");
}
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 INLINE");
record = response.data.records[0];
graph = response.data;
if (!isCreateMode) {
setOriginalContent();
}
dispatch("inlinesaved", {
records: [record],
});
resolve(null);
})
.catch(function (error) {
if (error.response) {
if (typeof error.response.data.error === "string") {
errorMessage = error.response.data.error;
} else {
validationErrors = error.response.data.error;
}
}
resolve(null);
});
});
}
</script>
<svelte:window on:beforeunload={beforeUnload}/>
<div class="inline-edit record-edit">
<div class="tools-header">
<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}
/>
<FilePreview {record} {schema}/>
<!-- <fieldset disabled="disabled"> -->
{#each activeFields as field (field.name)}
{#if activeContentTab === field.group}
<FormField
bind:data={record.data}
bind:graph={graph}
{field}
{schema}
{record}
{validationErrors}
{isCreateMode}
/>
{/if}
{/each}
<!-- </fieldset> -->
</div>
</div>