Files
lucent-laravel/front/js/svelte/records/Edit.svelte
T
2023-10-02 23:10:49 +03:00

238 lines
7.6 KiB
Svelte

<script>
import {afterUpdate, getContext, onMount} from "svelte";
import {isEqual} from "lodash";
import Manager from "./Manager.svelte";
import EditHeader from "./EditHeader.svelte"
import StatusSelect from "./StatusSelect.svelte"
import FilePreview from "./FilePreview.svelte"
import ContentTabs from "./ContentTabs.svelte"
import FormField from "./FormField.svelte"
import Graph from "./Graph.svelte"
import Info from "./Info.svelte"
import ErrorAlert from "../common/ErrorAlert.svelte"
const channel = getContext("channel");
export let schema;
export let title;
export let record;
export let graph = {
records: [],
edges: []
};
export let recordHistory;
export let isCreateMode;
export let users;
let originalContent;
let activeContentTab = "_default";
let recordGraph = null;
$: 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)),
_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,
_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) ?? null;
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="wrapper-normal transparent">
<Manager managerRecords={recordHistory} {graph}/>
<EditHeader {schema} {record} {isCreateMode} {graph} bind:activeContentTab/>
{#if !["_graph", "_info"].includes(activeContentTab)}
<div
style="position:fixed;bottom:0;left:0px;width:100%;background:rgba(255,255,255,.7);z-index:10"
>
<div
class="d-flex mt-4 mb-3 align-items-center justify-content-center"
>
<StatusSelect bind:status={record._sys.status} {schema}/>
{#if isCreateMode}
<button
class="ms-2 btn btn-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="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>
</div>
{/if}
<ErrorAlert message={errorMessage}/>
<div class=" mt-4" style="margin-bottom:150px">
<ContentTabs
{schema}
{isCreateMode}
bind:active={activeContentTab}
{record}
bind:recordGraph
/>
{#if !["_graph", "_info"].includes(activeContentTab)}
<FilePreview {record} {schema}/>
<!-- <fieldset disabled="disabled"> -->
{#each activeFields as field (field.name)}
{#if fieldToTabs[activeContentTab].includes(field.name)}
<FormField
bind:data={record.data}
bind:graph={graph}
{field}
{schema}
{record}
{validationErrors}
{isCreateMode}
/>
{/if}
{/each}
<!-- </fieldset> -->
{:else if activeContentTab === "_graph"}
<Graph {graph} {record}/>
{:else if activeContentTab === "_info"}
<Info bind:record {users} {schema}/>
{/if}
</div>
</div>