247 lines
8.9 KiB
Svelte
247 lines
8.9 KiB
Svelte
<script>
|
|
import { friendlyDate } from "../../helpers";
|
|
import Avatar from "../../common/Avatar.svelte";
|
|
import { usernameById } from "../account/users";
|
|
import Icon from "../../common/Icon.svelte";
|
|
import RevisionCell from "./revisions/RevisionCell.svelte";
|
|
import { getContext } from "svelte";
|
|
import RevisionEdgeRow from "./revisions/RevisionEdgeRow.svelte";
|
|
|
|
const channel = getContext("channel");
|
|
export let record;
|
|
export let graph;
|
|
export let users;
|
|
export let schema;
|
|
let revisionSection;
|
|
let rollbackError = "";
|
|
$: revisions = [];
|
|
$: fieldsWithDiff = [];
|
|
$: selectedRevision = null;
|
|
$: edgeFieldsDiff = {};
|
|
|
|
axios
|
|
.get(`${channel.lucentUrl}/records/${record.id}/revisions`)
|
|
.then((response) => {
|
|
revisions = response.data;
|
|
})
|
|
.catch((error) => {
|
|
console.log(error);
|
|
});
|
|
|
|
function getEdgesByField(fieldsWithDiff, revision) {
|
|
edgeFieldsDiff = graph.edges
|
|
.filter((e) => e.depth === 1)
|
|
.reduce((c, e) => {
|
|
if (!c[e.field]) {
|
|
c[e.field] = {
|
|
record: [],
|
|
revision: [],
|
|
};
|
|
}
|
|
c[e.field]["record"].push(e);
|
|
return c;
|
|
}, {});
|
|
|
|
edgeFieldsDiff = revision._edges.reduce((c, e) => {
|
|
if (!c[e.field]) {
|
|
c[e.field] = {
|
|
record: [],
|
|
revision: [],
|
|
};
|
|
}
|
|
c[e.field]["revision"].push(e);
|
|
return c;
|
|
}, edgeFieldsDiff);
|
|
}
|
|
|
|
function compare(e, revision) {
|
|
e.preventDefault();
|
|
selectedRevision = revision;
|
|
|
|
fieldsWithDiff = schema.fields.filter((f) => {
|
|
return !isEqual(selectedRevision.data[f.name], record.data[f.name]);
|
|
});
|
|
getEdgesByField(fieldsWithDiff, revision);
|
|
revisionSection.scrollIntoView();
|
|
}
|
|
|
|
function rollback(e) {
|
|
e.preventDefault();
|
|
rollbackError = "";
|
|
axios
|
|
.post(
|
|
`${channel.lucentUrl}/records/${record.id}/rollback/${selectedRevision._sys.version}`,
|
|
)
|
|
.then((response) => {
|
|
window.location.reload();
|
|
})
|
|
.catch((error) => {
|
|
const firstError = error.response.data.error;
|
|
rollbackError =
|
|
firstError.fieldLabel + ": " + firstError.message;
|
|
});
|
|
}
|
|
</script>
|
|
|
|
<div class="lx-card">
|
|
<div class="row">
|
|
<div class="col-8">
|
|
<div>
|
|
<span class="label text-end text-muted">record id </span>
|
|
<small>{record.id}</small>
|
|
</div>
|
|
<div>
|
|
<span class="label text-end text-muted">current version </span>
|
|
{record._sys.version}
|
|
</div>
|
|
<div>
|
|
<span class="label text-end text-muted"> created </span>
|
|
<Avatar
|
|
name={usernameById(users, record._sys.createdBy)}
|
|
side={24}
|
|
/>
|
|
{friendlyDate(record._sys.createdAt)}
|
|
</div>
|
|
<div>
|
|
<span class="label text-end text-muted">updated </span>
|
|
<Avatar
|
|
name={usernameById(users, record._sys.updatedBy)}
|
|
side={24}
|
|
/>
|
|
{friendlyDate(record._sys.updatedAt)}
|
|
</div>
|
|
</div>
|
|
<div class="col-4">
|
|
<span class="label d-block text-muted">Rules for this schema </span>
|
|
<small>
|
|
Each record maintains the last {schema.revisions}
|
|
versions
|
|
</small>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="revisions">
|
|
{#if schema.revisions > 0}
|
|
<div class="header-small mb-3">Revisions</div>
|
|
{#each revisions as revision}
|
|
{#if revision._sys.version !== record._sys.version}
|
|
<div
|
|
class="revision"
|
|
class:active={revision._sys.version ===
|
|
selectedRevision?._sys.version}
|
|
>
|
|
<div class="version">
|
|
<span>version {revision._sys.version}</span>
|
|
<Avatar
|
|
name={usernameById(users, revision._sys.updatedBy)}
|
|
side={24}
|
|
/>
|
|
{friendlyDate(revision._sys.updatedAt)}
|
|
</div>
|
|
|
|
<div class="col-3 text-center">
|
|
<button
|
|
disabled={revision._sys.version ===
|
|
selectedRevision?._sys.version}
|
|
class="button"
|
|
on:click={(e) => compare(e, revision)}
|
|
>Compare
|
|
</button>
|
|
</div>
|
|
</div>
|
|
{/if}
|
|
{/each}
|
|
{:else}
|
|
<div class="card-body">
|
|
<span>Revisions are not enabled for this Schema</span>
|
|
</div>
|
|
{/if}
|
|
</div>
|
|
<div bind:this={revisionSection}>
|
|
{#if selectedRevision}
|
|
<div class="selected-revision">
|
|
{#if fieldsWithDiff.length > 0}
|
|
<p class="text-center fw-bold mb-3 mt-5">
|
|
If you choose to rollback to this revision
|
|
</p>
|
|
<button on:click={rollback} class="button">
|
|
Rollback to version {selectedRevision._sys.version}
|
|
</button>
|
|
|
|
{#if rollbackError}
|
|
<span class="d-block text-danger mt-3">{rollbackError}</span
|
|
>
|
|
{/if}
|
|
<div class="mt-3">
|
|
{#each fieldsWithDiff as field}
|
|
<!-- <div
|
|
class=" lx-card d-flex p-4 mb-4"
|
|
style="overflow:hidden"
|
|
> -->
|
|
<!-- <div class="d-block" style="width:200px;">
|
|
{field.label}
|
|
</div> -->
|
|
<div class="revision-field" style="overflow:hidden">
|
|
<div class="compare-left">
|
|
<RevisionCell
|
|
{field}
|
|
side={record.data[field.name]}
|
|
colorClass="text-danger"
|
|
/>
|
|
</div>
|
|
<div class="compare-center">
|
|
<span class="me-1">{field.label}</span>
|
|
<Icon
|
|
icon="angle-right"
|
|
width="12"
|
|
height="12"
|
|
/>
|
|
</div>
|
|
<div class="compare-right">
|
|
<RevisionCell
|
|
edges={selectedRevision._edges}
|
|
{field}
|
|
side={selectedRevision.data[field.name]}
|
|
colorClass="text-success"
|
|
/>
|
|
</div>
|
|
</div>
|
|
<!-- </div> -->
|
|
{/each}
|
|
</div>
|
|
{:else}
|
|
<div class=" lx-card text-center">
|
|
<span>Nothing will change</span>
|
|
</div>
|
|
{/if}
|
|
|
|
<div class="mt-3">
|
|
<p class="text-center fw-bold mb-3 mt-5">Record References</p>
|
|
{#each Object.entries(edgeFieldsDiff) as [field, edges]}
|
|
<div class="revision-references" style="overflow:hidden">
|
|
<div class="reference-field">
|
|
{field}:
|
|
</div>
|
|
<div class="reference-compare">
|
|
<p class="">Record</p>
|
|
{#each edges.record as edge}
|
|
<RevisionEdgeRow {edge} />
|
|
{:else}
|
|
<p>No references</p>
|
|
{/each}
|
|
</div>
|
|
<div class="reference-compare">
|
|
<p class="text-success">Revision</p>
|
|
{#each edges.revision as edge}
|
|
<RevisionEdgeRow {edge} />
|
|
{:else}
|
|
<p>No references</p>
|
|
{/each}
|
|
</div>
|
|
</div>
|
|
{/each}
|
|
</div>
|
|
</div>
|
|
{/if}
|
|
</div>
|